pg: API cleanup
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-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
1131   vec_reset_length (vam->cmd_reply);
1132
1133   vam->retval = retval;
1134   if (retval == 0)
1135     vam->cmd_reply = vl_api_from_api_to_new_vec (&mp->reply);
1136   vam->result_ready = 1;
1137 }
1138
1139 static void
1140 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1141 {
1142   vat_main_t *vam = &vat_main;
1143   vat_json_node_t node;
1144   u8 *reply = 0;                /* reply vector */
1145
1146   reply = vl_api_from_api_to_new_vec (&mp->reply);
1147   vec_reset_length (vam->cmd_reply);
1148
1149   vat_json_init_object (&node);
1150   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1151   vat_json_object_add_string_copy (&node, "reply", reply);
1152
1153   vat_json_print (vam->ofp, &node);
1154   vat_json_free (&node);
1155   vec_free (reply);
1156
1157   vam->retval = ntohl (mp->retval);
1158   vam->result_ready = 1;
1159 }
1160
1161 static void vl_api_classify_add_del_table_reply_t_handler
1162   (vl_api_classify_add_del_table_reply_t * mp)
1163 {
1164   vat_main_t *vam = &vat_main;
1165   i32 retval = ntohl (mp->retval);
1166   if (vam->async_mode)
1167     {
1168       vam->async_errors += (retval < 0);
1169     }
1170   else
1171     {
1172       vam->retval = retval;
1173       if (retval == 0 &&
1174           ((mp->new_table_index != 0xFFFFFFFF) ||
1175            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1176            (mp->match_n_vectors != 0xFFFFFFFF)))
1177         /*
1178          * Note: this is just barely thread-safe, depends on
1179          * the main thread spinning waiting for an answer...
1180          */
1181         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1182                 ntohl (mp->new_table_index),
1183                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1184       vam->result_ready = 1;
1185     }
1186 }
1187
1188 static void vl_api_classify_add_del_table_reply_t_handler_json
1189   (vl_api_classify_add_del_table_reply_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   vat_json_node_t node;
1193
1194   vat_json_init_object (&node);
1195   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1196   vat_json_object_add_uint (&node, "new_table_index",
1197                             ntohl (mp->new_table_index));
1198   vat_json_object_add_uint (&node, "skip_n_vectors",
1199                             ntohl (mp->skip_n_vectors));
1200   vat_json_object_add_uint (&node, "match_n_vectors",
1201                             ntohl (mp->match_n_vectors));
1202
1203   vat_json_print (vam->ofp, &node);
1204   vat_json_free (&node);
1205
1206   vam->retval = ntohl (mp->retval);
1207   vam->result_ready = 1;
1208 }
1209
1210 static void vl_api_get_node_index_reply_t_handler
1211   (vl_api_get_node_index_reply_t * mp)
1212 {
1213   vat_main_t *vam = &vat_main;
1214   i32 retval = ntohl (mp->retval);
1215   if (vam->async_mode)
1216     {
1217       vam->async_errors += (retval < 0);
1218     }
1219   else
1220     {
1221       vam->retval = retval;
1222       if (retval == 0)
1223         errmsg ("node index %d", ntohl (mp->node_index));
1224       vam->result_ready = 1;
1225     }
1226 }
1227
1228 static void vl_api_get_node_index_reply_t_handler_json
1229   (vl_api_get_node_index_reply_t * mp)
1230 {
1231   vat_main_t *vam = &vat_main;
1232   vat_json_node_t node;
1233
1234   vat_json_init_object (&node);
1235   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1236   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1237
1238   vat_json_print (vam->ofp, &node);
1239   vat_json_free (&node);
1240
1241   vam->retval = ntohl (mp->retval);
1242   vam->result_ready = 1;
1243 }
1244
1245 static void vl_api_get_next_index_reply_t_handler
1246   (vl_api_get_next_index_reply_t * mp)
1247 {
1248   vat_main_t *vam = &vat_main;
1249   i32 retval = ntohl (mp->retval);
1250   if (vam->async_mode)
1251     {
1252       vam->async_errors += (retval < 0);
1253     }
1254   else
1255     {
1256       vam->retval = retval;
1257       if (retval == 0)
1258         errmsg ("next node index %d", ntohl (mp->next_index));
1259       vam->result_ready = 1;
1260     }
1261 }
1262
1263 static void vl_api_get_next_index_reply_t_handler_json
1264   (vl_api_get_next_index_reply_t * mp)
1265 {
1266   vat_main_t *vam = &vat_main;
1267   vat_json_node_t node;
1268
1269   vat_json_init_object (&node);
1270   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1271   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1272
1273   vat_json_print (vam->ofp, &node);
1274   vat_json_free (&node);
1275
1276   vam->retval = ntohl (mp->retval);
1277   vam->result_ready = 1;
1278 }
1279
1280 static void vl_api_add_node_next_reply_t_handler
1281   (vl_api_add_node_next_reply_t * mp)
1282 {
1283   vat_main_t *vam = &vat_main;
1284   i32 retval = ntohl (mp->retval);
1285   if (vam->async_mode)
1286     {
1287       vam->async_errors += (retval < 0);
1288     }
1289   else
1290     {
1291       vam->retval = retval;
1292       if (retval == 0)
1293         errmsg ("next index %d", ntohl (mp->next_index));
1294       vam->result_ready = 1;
1295     }
1296 }
1297
1298 static void vl_api_add_node_next_reply_t_handler_json
1299   (vl_api_add_node_next_reply_t * mp)
1300 {
1301   vat_main_t *vam = &vat_main;
1302   vat_json_node_t node;
1303
1304   vat_json_init_object (&node);
1305   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1306   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1307
1308   vat_json_print (vam->ofp, &node);
1309   vat_json_free (&node);
1310
1311   vam->retval = ntohl (mp->retval);
1312   vam->result_ready = 1;
1313 }
1314
1315 static void vl_api_show_version_reply_t_handler
1316   (vl_api_show_version_reply_t * mp)
1317 {
1318   vat_main_t *vam = &vat_main;
1319   i32 retval = ntohl (mp->retval);
1320
1321   if (retval >= 0)
1322     {
1323       errmsg ("        program: %s", mp->program);
1324       errmsg ("        version: %s", mp->version);
1325       errmsg ("     build date: %s", mp->build_date);
1326       errmsg ("build directory: %s", mp->build_directory);
1327     }
1328   vam->retval = retval;
1329   vam->result_ready = 1;
1330 }
1331
1332 static void vl_api_show_version_reply_t_handler_json
1333   (vl_api_show_version_reply_t * mp)
1334 {
1335   vat_main_t *vam = &vat_main;
1336   vat_json_node_t node;
1337
1338   vat_json_init_object (&node);
1339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1340   vat_json_object_add_string_copy (&node, "program", mp->program);
1341   vat_json_object_add_string_copy (&node, "version", mp->version);
1342   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1343   vat_json_object_add_string_copy (&node, "build_directory",
1344                                    mp->build_directory);
1345
1346   vat_json_print (vam->ofp, &node);
1347   vat_json_free (&node);
1348
1349   vam->retval = ntohl (mp->retval);
1350   vam->result_ready = 1;
1351 }
1352
1353 static void vl_api_show_threads_reply_t_handler
1354   (vl_api_show_threads_reply_t * mp)
1355 {
1356   vat_main_t *vam = &vat_main;
1357   i32 retval = ntohl (mp->retval);
1358   int i, count = 0;
1359
1360   if (retval >= 0)
1361     count = ntohl (mp->count);
1362
1363   for (i = 0; i < count; i++)
1364     print (vam->ofp,
1365            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1366            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1367            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1368            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1369            ntohl (mp->thread_data[i].cpu_socket));
1370
1371   vam->retval = retval;
1372   vam->result_ready = 1;
1373 }
1374
1375 static void vl_api_show_threads_reply_t_handler_json
1376   (vl_api_show_threads_reply_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   vat_json_node_t node;
1380   vl_api_thread_data_t *td;
1381   i32 retval = ntohl (mp->retval);
1382   int i, count = 0;
1383
1384   if (retval >= 0)
1385     count = ntohl (mp->count);
1386
1387   vat_json_init_object (&node);
1388   vat_json_object_add_int (&node, "retval", retval);
1389   vat_json_object_add_uint (&node, "count", count);
1390
1391   for (i = 0; i < count; i++)
1392     {
1393       td = &mp->thread_data[i];
1394       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1395       vat_json_object_add_string_copy (&node, "name", td->name);
1396       vat_json_object_add_string_copy (&node, "type", td->type);
1397       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1398       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1399       vat_json_object_add_int (&node, "core", ntohl (td->id));
1400       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1401     }
1402
1403   vat_json_print (vam->ofp, &node);
1404   vat_json_free (&node);
1405
1406   vam->retval = retval;
1407   vam->result_ready = 1;
1408 }
1409
1410 static int
1411 api_show_threads (vat_main_t * vam)
1412 {
1413   vl_api_show_threads_t *mp;
1414   int ret;
1415
1416   print (vam->ofp,
1417          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1418          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1419
1420   M (SHOW_THREADS, mp);
1421
1422   S (mp);
1423   W (ret);
1424   return ret;
1425 }
1426
1427 static void
1428 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1429 {
1430   u32 n_macs = ntohl (mp->n_macs);
1431   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1432           ntohl (mp->pid), mp->client_index, n_macs);
1433   int i;
1434   for (i = 0; i < n_macs; i++)
1435     {
1436       vl_api_mac_entry_t *mac = &mp->mac[i];
1437       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1438               i + 1, ntohl (mac->sw_if_index),
1439               format_ethernet_address, mac->mac_addr, mac->action);
1440       if (i == 1000)
1441         break;
1442     }
1443 }
1444
1445 static void
1446 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1447 {
1448   /* JSON output not supported */
1449 }
1450
1451 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1452 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1453
1454 /*
1455  * Special-case: build the bridge domain table, maintain
1456  * the next bd id vbl.
1457  */
1458 static void vl_api_bridge_domain_details_t_handler
1459   (vl_api_bridge_domain_details_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1463   int i;
1464
1465   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1466          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1467
1468   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1469          ntohl (mp->bd_id), mp->learn, mp->forward,
1470          mp->flood, ntohl (mp->bvi_sw_if_index),
1471          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1472
1473   if (n_sw_ifs)
1474     {
1475       vl_api_bridge_domain_sw_if_t *sw_ifs;
1476       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1477              "Interface Name");
1478
1479       sw_ifs = mp->sw_if_details;
1480       for (i = 0; i < n_sw_ifs; i++)
1481         {
1482           u8 *sw_if_name = 0;
1483           u32 sw_if_index;
1484           hash_pair_t *p;
1485
1486           sw_if_index = ntohl (sw_ifs->sw_if_index);
1487
1488           /* *INDENT-OFF* */
1489           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1490                              ({
1491                                if ((u32) p->value[0] == sw_if_index)
1492                                  {
1493                                    sw_if_name = (u8 *)(p->key);
1494                                    break;
1495                                  }
1496                              }));
1497           /* *INDENT-ON* */
1498           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1499                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1500                  "sw_if_index not found!");
1501
1502           sw_ifs++;
1503         }
1504     }
1505 }
1506
1507 static void vl_api_bridge_domain_details_t_handler_json
1508   (vl_api_bridge_domain_details_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   vat_json_node_t *node, *array = NULL;
1512   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1513
1514   if (VAT_JSON_ARRAY != vam->json_tree.type)
1515     {
1516       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1517       vat_json_init_array (&vam->json_tree);
1518     }
1519   node = vat_json_array_add (&vam->json_tree);
1520
1521   vat_json_init_object (node);
1522   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1523   vat_json_object_add_uint (node, "flood", mp->flood);
1524   vat_json_object_add_uint (node, "forward", mp->forward);
1525   vat_json_object_add_uint (node, "learn", mp->learn);
1526   vat_json_object_add_uint (node, "bvi_sw_if_index",
1527                             ntohl (mp->bvi_sw_if_index));
1528   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1529   array = vat_json_object_add (node, "sw_if");
1530   vat_json_init_array (array);
1531
1532
1533
1534   if (n_sw_ifs)
1535     {
1536       vl_api_bridge_domain_sw_if_t *sw_ifs;
1537       int i;
1538
1539       sw_ifs = mp->sw_if_details;
1540       for (i = 0; i < n_sw_ifs; i++)
1541         {
1542           node = vat_json_array_add (array);
1543           vat_json_init_object (node);
1544           vat_json_object_add_uint (node, "sw_if_index",
1545                                     ntohl (sw_ifs->sw_if_index));
1546           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1547           sw_ifs++;
1548         }
1549     }
1550 }
1551
1552 static void vl_api_control_ping_reply_t_handler
1553   (vl_api_control_ping_reply_t * mp)
1554 {
1555   vat_main_t *vam = &vat_main;
1556   i32 retval = ntohl (mp->retval);
1557   if (vam->async_mode)
1558     {
1559       vam->async_errors += (retval < 0);
1560     }
1561   else
1562     {
1563       vam->retval = retval;
1564       vam->result_ready = 1;
1565     }
1566   if (vam->socket_client_main)
1567     vam->socket_client_main->control_pings_outstanding--;
1568 }
1569
1570 static void vl_api_control_ping_reply_t_handler_json
1571   (vl_api_control_ping_reply_t * mp)
1572 {
1573   vat_main_t *vam = &vat_main;
1574   i32 retval = ntohl (mp->retval);
1575
1576   if (VAT_JSON_NONE != vam->json_tree.type)
1577     {
1578       vat_json_print (vam->ofp, &vam->json_tree);
1579       vat_json_free (&vam->json_tree);
1580       vam->json_tree.type = VAT_JSON_NONE;
1581     }
1582   else
1583     {
1584       /* just print [] */
1585       vat_json_init_array (&vam->json_tree);
1586       vat_json_print (vam->ofp, &vam->json_tree);
1587       vam->json_tree.type = VAT_JSON_NONE;
1588     }
1589
1590   vam->retval = retval;
1591   vam->result_ready = 1;
1592 }
1593
1594 static void
1595   vl_api_bridge_domain_set_mac_age_reply_t_handler
1596   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->result_ready = 1;
1608     }
1609 }
1610
1611 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1612   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1613 {
1614   vat_main_t *vam = &vat_main;
1615   vat_json_node_t node;
1616
1617   vat_json_init_object (&node);
1618   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1619
1620   vat_json_print (vam->ofp, &node);
1621   vat_json_free (&node);
1622
1623   vam->retval = ntohl (mp->retval);
1624   vam->result_ready = 1;
1625 }
1626
1627 static void
1628 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   i32 retval = ntohl (mp->retval);
1632   if (vam->async_mode)
1633     {
1634       vam->async_errors += (retval < 0);
1635     }
1636   else
1637     {
1638       vam->retval = retval;
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_l2_flags_reply_t_handler_json
1644   (vl_api_l2_flags_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1652                             ntohl (mp->resulting_feature_bitmap));
1653
1654   vat_json_print (vam->ofp, &node);
1655   vat_json_free (&node);
1656
1657   vam->retval = ntohl (mp->retval);
1658   vam->result_ready = 1;
1659 }
1660
1661 static void vl_api_bridge_flags_reply_t_handler
1662   (vl_api_bridge_flags_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   i32 retval = ntohl (mp->retval);
1666   if (vam->async_mode)
1667     {
1668       vam->async_errors += (retval < 0);
1669     }
1670   else
1671     {
1672       vam->retval = retval;
1673       vam->result_ready = 1;
1674     }
1675 }
1676
1677 static void vl_api_bridge_flags_reply_t_handler_json
1678   (vl_api_bridge_flags_reply_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   vat_json_node_t node;
1682
1683   vat_json_init_object (&node);
1684   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1685   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1686                             ntohl (mp->resulting_feature_bitmap));
1687
1688   vat_json_print (vam->ofp, &node);
1689   vat_json_free (&node);
1690
1691   vam->retval = ntohl (mp->retval);
1692   vam->result_ready = 1;
1693 }
1694
1695 static void
1696 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1697 {
1698   vat_main_t *vam = &vat_main;
1699   i32 retval = ntohl (mp->retval);
1700   if (vam->async_mode)
1701     {
1702       vam->async_errors += (retval < 0);
1703     }
1704   else
1705     {
1706       vam->retval = retval;
1707       vam->sw_if_index = ntohl (mp->sw_if_index);
1708       vam->result_ready = 1;
1709     }
1710
1711 }
1712
1713 static void vl_api_tap_create_v2_reply_t_handler_json
1714   (vl_api_tap_create_v2_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728
1729 }
1730
1731 static void
1732 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_tap_delete_v2_reply_t_handler_json
1748   (vl_api_tap_delete_v2_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761 }
1762
1763 static void
1764 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1765                                           mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_virtio_pci_create_reply_t_handler_json
1782   (vl_api_virtio_pci_create_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796
1797 }
1798
1799 static void
1800 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1801                                           mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_virtio_pci_delete_reply_t_handler_json
1817   (vl_api_virtio_pci_delete_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void
1833 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->sw_if_index = ntohl (mp->sw_if_index);
1846       vam->result_ready = 1;
1847     }
1848 }
1849
1850 static void vl_api_bond_create_reply_t_handler_json
1851   (vl_api_bond_create_reply_t * mp)
1852 {
1853   vat_main_t *vam = &vat_main;
1854   vat_json_node_t node;
1855
1856   vat_json_init_object (&node);
1857   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1858   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1859
1860   vat_json_print (vam->ofp, &node);
1861   vat_json_free (&node);
1862
1863   vam->retval = ntohl (mp->retval);
1864   vam->result_ready = 1;
1865 }
1866
1867 static void
1868 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872
1873   if (vam->async_mode)
1874     {
1875       vam->async_errors += (retval < 0);
1876     }
1877   else
1878     {
1879       vam->retval = retval;
1880       vam->result_ready = 1;
1881     }
1882 }
1883
1884 static void vl_api_bond_delete_reply_t_handler_json
1885   (vl_api_bond_delete_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   vat_json_node_t node;
1889
1890   vat_json_init_object (&node);
1891   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void
1901 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   i32 retval = ntohl (mp->retval);
1905
1906   if (vam->async_mode)
1907     {
1908       vam->async_errors += (retval < 0);
1909     }
1910   else
1911     {
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_enslave_reply_t_handler_json
1918   (vl_api_bond_enslave_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1935                                           mp)
1936 {
1937   vat_main_t *vam = &vat_main;
1938   i32 retval = ntohl (mp->retval);
1939
1940   if (vam->async_mode)
1941     {
1942       vam->async_errors += (retval < 0);
1943     }
1944   else
1945     {
1946       vam->retval = retval;
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_detach_slave_reply_t_handler_json
1952   (vl_api_bond_detach_slave_reply_t * mp)
1953 {
1954   vat_main_t *vam = &vat_main;
1955   vat_json_node_t node;
1956
1957   vat_json_init_object (&node);
1958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1959
1960   vat_json_print (vam->ofp, &node);
1961   vat_json_free (&node);
1962
1963   vam->retval = ntohl (mp->retval);
1964   vam->result_ready = 1;
1965 }
1966
1967 static int
1968 api_sw_interface_set_bond_weight (vat_main_t * vam)
1969 {
1970   unformat_input_t *i = vam->input;
1971   vl_api_sw_interface_set_bond_weight_t *mp;
1972   u32 sw_if_index = ~0;
1973   u32 weight = 0;
1974   u8 weight_enter = 0;
1975   int ret;
1976
1977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1978     {
1979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1980         ;
1981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
1982         ;
1983       else if (unformat (i, "weight %u", &weight))
1984         weight_enter = 1;
1985       else
1986         break;
1987     }
1988
1989   if (sw_if_index == ~0)
1990     {
1991       errmsg ("missing interface name or sw_if_index");
1992       return -99;
1993     }
1994   if (weight_enter == 0)
1995     {
1996       errmsg ("missing valid weight");
1997       return -99;
1998     }
1999
2000   /* Construct the API message */
2001   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2002   mp->sw_if_index = ntohl (sw_if_index);
2003   mp->weight = ntohl (weight);
2004
2005   S (mp);
2006   W (ret);
2007   return ret;
2008 }
2009
2010 static void vl_api_sw_interface_bond_details_t_handler
2011   (vl_api_sw_interface_bond_details_t * mp)
2012 {
2013   vat_main_t *vam = &vat_main;
2014
2015   print (vam->ofp,
2016          "%-16s %-12d %-12U %-13U %-14u %-14u",
2017          mp->interface_name, ntohl (mp->sw_if_index),
2018          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2019          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2020 }
2021
2022 static void vl_api_sw_interface_bond_details_t_handler_json
2023   (vl_api_sw_interface_bond_details_t * mp)
2024 {
2025   vat_main_t *vam = &vat_main;
2026   vat_json_node_t *node = NULL;
2027
2028   if (VAT_JSON_ARRAY != vam->json_tree.type)
2029     {
2030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2031       vat_json_init_array (&vam->json_tree);
2032     }
2033   node = vat_json_array_add (&vam->json_tree);
2034
2035   vat_json_init_object (node);
2036   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2037   vat_json_object_add_string_copy (node, "interface_name",
2038                                    mp->interface_name);
2039   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2040   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2041   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2042   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2043 }
2044
2045 static int
2046 api_sw_interface_bond_dump (vat_main_t * vam)
2047 {
2048   vl_api_sw_interface_bond_dump_t *mp;
2049   vl_api_control_ping_t *mp_ping;
2050   int ret;
2051
2052   print (vam->ofp,
2053          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2054          "interface name", "sw_if_index", "mode", "load balance",
2055          "active slaves", "slaves");
2056
2057   /* Get list of bond interfaces */
2058   M (SW_INTERFACE_BOND_DUMP, mp);
2059   S (mp);
2060
2061   /* Use a control ping for synchronization */
2062   MPING (CONTROL_PING, mp_ping);
2063   S (mp_ping);
2064
2065   W (ret);
2066   return ret;
2067 }
2068
2069 static void vl_api_sw_interface_slave_details_t_handler
2070   (vl_api_sw_interface_slave_details_t * mp)
2071 {
2072   vat_main_t *vam = &vat_main;
2073
2074   print (vam->ofp,
2075          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2076          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2077          ntohl (mp->weight), mp->is_local_numa);
2078 }
2079
2080 static void vl_api_sw_interface_slave_details_t_handler_json
2081   (vl_api_sw_interface_slave_details_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   vat_json_node_t *node = NULL;
2085
2086   if (VAT_JSON_ARRAY != vam->json_tree.type)
2087     {
2088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2089       vat_json_init_array (&vam->json_tree);
2090     }
2091   node = vat_json_array_add (&vam->json_tree);
2092
2093   vat_json_init_object (node);
2094   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2095   vat_json_object_add_string_copy (node, "interface_name",
2096                                    mp->interface_name);
2097   vat_json_object_add_uint (node, "passive", mp->is_passive);
2098   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2099   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2100   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2101 }
2102
2103 static int
2104 api_sw_interface_slave_dump (vat_main_t * vam)
2105 {
2106   unformat_input_t *i = vam->input;
2107   vl_api_sw_interface_slave_dump_t *mp;
2108   vl_api_control_ping_t *mp_ping;
2109   u32 sw_if_index = ~0;
2110   u8 sw_if_index_set = 0;
2111   int ret;
2112
2113   /* Parse args required to build the message */
2114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2115     {
2116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2117         sw_if_index_set = 1;
2118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2119         sw_if_index_set = 1;
2120       else
2121         break;
2122     }
2123
2124   if (sw_if_index_set == 0)
2125     {
2126       errmsg ("missing vpp interface name. ");
2127       return -99;
2128     }
2129
2130   print (vam->ofp,
2131          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2132          "slave interface name", "sw_if_index", "passive", "long_timeout",
2133          "weight", "local numa");
2134
2135   /* Get list of bond interfaces */
2136   M (SW_INTERFACE_SLAVE_DUMP, mp);
2137   mp->sw_if_index = ntohl (sw_if_index);
2138   S (mp);
2139
2140   /* Use a control ping for synchronization */
2141   MPING (CONTROL_PING, mp_ping);
2142   S (mp_ping);
2143
2144   W (ret);
2145   return ret;
2146 }
2147
2148 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2149   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2150 {
2151   vat_main_t *vam = &vat_main;
2152   i32 retval = ntohl (mp->retval);
2153   if (vam->async_mode)
2154     {
2155       vam->async_errors += (retval < 0);
2156     }
2157   else
2158     {
2159       vam->retval = retval;
2160       vam->sw_if_index = ntohl (mp->sw_if_index);
2161       vam->result_ready = 1;
2162     }
2163   vam->regenerate_interface_table = 1;
2164 }
2165
2166 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2167   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2168 {
2169   vat_main_t *vam = &vat_main;
2170   vat_json_node_t node;
2171
2172   vat_json_init_object (&node);
2173   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2174   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2175                             ntohl (mp->sw_if_index));
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2185   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   i32 retval = ntohl (mp->retval);
2189   if (vam->async_mode)
2190     {
2191       vam->async_errors += (retval < 0);
2192     }
2193   else
2194     {
2195       vam->retval = retval;
2196       vam->sw_if_index = ntohl (mp->sw_if_index);
2197       vam->result_ready = 1;
2198     }
2199 }
2200
2201 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2202   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2203 {
2204   vat_main_t *vam = &vat_main;
2205   vat_json_node_t node;
2206
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2210
2211   vat_json_print (vam->ofp, &node);
2212   vat_json_free (&node);
2213
2214   vam->retval = ntohl (mp->retval);
2215   vam->result_ready = 1;
2216 }
2217
2218 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2219   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2220 {
2221   vat_main_t *vam = &vat_main;
2222   i32 retval = ntohl (mp->retval);
2223   if (vam->async_mode)
2224     {
2225       vam->async_errors += (retval < 0);
2226     }
2227   else
2228     {
2229       vam->retval = retval;
2230       vam->result_ready = 1;
2231     }
2232 }
2233
2234 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2235   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2236 {
2237   vat_main_t *vam = &vat_main;
2238   vat_json_node_t node;
2239
2240   vat_json_init_object (&node);
2241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2242   vat_json_object_add_uint (&node, "fwd_entry_index",
2243                             clib_net_to_host_u32 (mp->fwd_entry_index));
2244
2245   vat_json_print (vam->ofp, &node);
2246   vat_json_free (&node);
2247
2248   vam->retval = ntohl (mp->retval);
2249   vam->result_ready = 1;
2250 }
2251
2252 u8 *
2253 format_lisp_transport_protocol (u8 * s, va_list * args)
2254 {
2255   u32 proto = va_arg (*args, u32);
2256
2257   switch (proto)
2258     {
2259     case 1:
2260       return format (s, "udp");
2261     case 2:
2262       return format (s, "api");
2263     default:
2264       return 0;
2265     }
2266   return 0;
2267 }
2268
2269 static void vl_api_one_get_transport_protocol_reply_t_handler
2270   (vl_api_one_get_transport_protocol_reply_t * mp)
2271 {
2272   vat_main_t *vam = &vat_main;
2273   i32 retval = ntohl (mp->retval);
2274   if (vam->async_mode)
2275     {
2276       vam->async_errors += (retval < 0);
2277     }
2278   else
2279     {
2280       u32 proto = mp->protocol;
2281       print (vam->ofp, "Transport protocol: %U",
2282              format_lisp_transport_protocol, proto);
2283       vam->retval = retval;
2284       vam->result_ready = 1;
2285     }
2286 }
2287
2288 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2289   (vl_api_one_get_transport_protocol_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   vat_json_node_t node;
2293   u8 *s;
2294
2295   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2296   vec_add1 (s, 0);
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2301
2302   vec_free (s);
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_one_add_del_locator_set_reply_t_handler
2311   (vl_api_one_add_del_locator_set_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   i32 retval = ntohl (mp->retval);
2315   if (vam->async_mode)
2316     {
2317       vam->async_errors += (retval < 0);
2318     }
2319   else
2320     {
2321       vam->retval = retval;
2322       vam->result_ready = 1;
2323     }
2324 }
2325
2326 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2327   (vl_api_one_add_del_locator_set_reply_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330   vat_json_node_t node;
2331
2332   vat_json_init_object (&node);
2333   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2334   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2335
2336   vat_json_print (vam->ofp, &node);
2337   vat_json_free (&node);
2338
2339   vam->retval = ntohl (mp->retval);
2340   vam->result_ready = 1;
2341 }
2342
2343 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2344   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2345 {
2346   vat_main_t *vam = &vat_main;
2347   i32 retval = ntohl (mp->retval);
2348   if (vam->async_mode)
2349     {
2350       vam->async_errors += (retval < 0);
2351     }
2352   else
2353     {
2354       vam->retval = retval;
2355       vam->sw_if_index = ntohl (mp->sw_if_index);
2356       vam->result_ready = 1;
2357     }
2358   vam->regenerate_interface_table = 1;
2359 }
2360
2361 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2362   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2363 {
2364   vat_main_t *vam = &vat_main;
2365   vat_json_node_t node;
2366
2367   vat_json_init_object (&node);
2368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2369   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2370
2371   vat_json_print (vam->ofp, &node);
2372   vat_json_free (&node);
2373
2374   vam->retval = ntohl (mp->retval);
2375   vam->result_ready = 1;
2376 }
2377
2378 static void vl_api_vxlan_offload_rx_reply_t_handler
2379   (vl_api_vxlan_offload_rx_reply_t * mp)
2380 {
2381   vat_main_t *vam = &vat_main;
2382   i32 retval = ntohl (mp->retval);
2383   if (vam->async_mode)
2384     {
2385       vam->async_errors += (retval < 0);
2386     }
2387   else
2388     {
2389       vam->retval = retval;
2390       vam->result_ready = 1;
2391     }
2392 }
2393
2394 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2395   (vl_api_vxlan_offload_rx_reply_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398   vat_json_node_t node;
2399
2400   vat_json_init_object (&node);
2401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2402
2403   vat_json_print (vam->ofp, &node);
2404   vat_json_free (&node);
2405
2406   vam->retval = ntohl (mp->retval);
2407   vam->result_ready = 1;
2408 }
2409
2410 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2411   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2412 {
2413   vat_main_t *vam = &vat_main;
2414   i32 retval = ntohl (mp->retval);
2415   if (vam->async_mode)
2416     {
2417       vam->async_errors += (retval < 0);
2418     }
2419   else
2420     {
2421       vam->retval = retval;
2422       vam->sw_if_index = ntohl (mp->sw_if_index);
2423       vam->result_ready = 1;
2424     }
2425 }
2426
2427 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2428   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t node;
2432
2433   vat_json_init_object (&node);
2434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2435   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2436
2437   vat_json_print (vam->ofp, &node);
2438   vat_json_free (&node);
2439
2440   vam->retval = ntohl (mp->retval);
2441   vam->result_ready = 1;
2442 }
2443
2444 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2445   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   i32 retval = ntohl (mp->retval);
2449   if (vam->async_mode)
2450     {
2451       vam->async_errors += (retval < 0);
2452     }
2453   else
2454     {
2455       vam->retval = retval;
2456       vam->sw_if_index = ntohl (mp->sw_if_index);
2457       vam->result_ready = 1;
2458     }
2459   vam->regenerate_interface_table = 1;
2460 }
2461
2462 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2463   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2464 {
2465   vat_main_t *vam = &vat_main;
2466   vat_json_node_t node;
2467
2468   vat_json_init_object (&node);
2469   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2470   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2471
2472   vat_json_print (vam->ofp, &node);
2473   vat_json_free (&node);
2474
2475   vam->retval = ntohl (mp->retval);
2476   vam->result_ready = 1;
2477 }
2478
2479 static void vl_api_gre_tunnel_add_del_reply_t_handler
2480   (vl_api_gre_tunnel_add_del_reply_t * mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   i32 retval = ntohl (mp->retval);
2484   if (vam->async_mode)
2485     {
2486       vam->async_errors += (retval < 0);
2487     }
2488   else
2489     {
2490       vam->retval = retval;
2491       vam->sw_if_index = ntohl (mp->sw_if_index);
2492       vam->result_ready = 1;
2493     }
2494 }
2495
2496 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2497   (vl_api_gre_tunnel_add_del_reply_t * mp)
2498 {
2499   vat_main_t *vam = &vat_main;
2500   vat_json_node_t node;
2501
2502   vat_json_init_object (&node);
2503   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2504   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2505
2506   vat_json_print (vam->ofp, &node);
2507   vat_json_free (&node);
2508
2509   vam->retval = ntohl (mp->retval);
2510   vam->result_ready = 1;
2511 }
2512
2513 static void vl_api_create_vhost_user_if_reply_t_handler
2514   (vl_api_create_vhost_user_if_reply_t * mp)
2515 {
2516   vat_main_t *vam = &vat_main;
2517   i32 retval = ntohl (mp->retval);
2518   if (vam->async_mode)
2519     {
2520       vam->async_errors += (retval < 0);
2521     }
2522   else
2523     {
2524       vam->retval = retval;
2525       vam->sw_if_index = ntohl (mp->sw_if_index);
2526       vam->result_ready = 1;
2527     }
2528   vam->regenerate_interface_table = 1;
2529 }
2530
2531 static void vl_api_create_vhost_user_if_reply_t_handler_json
2532   (vl_api_create_vhost_user_if_reply_t * mp)
2533 {
2534   vat_main_t *vam = &vat_main;
2535   vat_json_node_t node;
2536
2537   vat_json_init_object (&node);
2538   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2539   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2540
2541   vat_json_print (vam->ofp, &node);
2542   vat_json_free (&node);
2543
2544   vam->retval = ntohl (mp->retval);
2545   vam->result_ready = 1;
2546 }
2547
2548 static void vl_api_ip_address_details_t_handler
2549   (vl_api_ip_address_details_t * mp)
2550 {
2551   vat_main_t *vam = &vat_main;
2552   static ip_address_details_t empty_ip_address_details = { {0} };
2553   ip_address_details_t *address = NULL;
2554   ip_details_t *current_ip_details = NULL;
2555   ip_details_t *details = NULL;
2556
2557   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2558
2559   if (!details || vam->current_sw_if_index >= vec_len (details)
2560       || !details[vam->current_sw_if_index].present)
2561     {
2562       errmsg ("ip address details arrived but not stored");
2563       errmsg ("ip_dump should be called first");
2564       return;
2565     }
2566
2567   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2568
2569 #define addresses (current_ip_details->addr)
2570
2571   vec_validate_init_empty (addresses, vec_len (addresses),
2572                            empty_ip_address_details);
2573
2574   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2575
2576   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2577   address->prefix_length = mp->prefix.len;
2578 #undef addresses
2579 }
2580
2581 static void vl_api_ip_address_details_t_handler_json
2582   (vl_api_ip_address_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   vat_json_node_t *node = NULL;
2586
2587   if (VAT_JSON_ARRAY != vam->json_tree.type)
2588     {
2589       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2590       vat_json_init_array (&vam->json_tree);
2591     }
2592   node = vat_json_array_add (&vam->json_tree);
2593
2594   vat_json_init_object (node);
2595   vat_json_object_add_prefix (node, &mp->prefix);
2596 }
2597
2598 static void
2599 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2600 {
2601   vat_main_t *vam = &vat_main;
2602   static ip_details_t empty_ip_details = { 0 };
2603   ip_details_t *ip = NULL;
2604   u32 sw_if_index = ~0;
2605
2606   sw_if_index = ntohl (mp->sw_if_index);
2607
2608   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2609                            sw_if_index, empty_ip_details);
2610
2611   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2612                          sw_if_index);
2613
2614   ip->present = 1;
2615 }
2616
2617 static void
2618 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621
2622   if (VAT_JSON_ARRAY != vam->json_tree.type)
2623     {
2624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2625       vat_json_init_array (&vam->json_tree);
2626     }
2627   vat_json_array_add_uint (&vam->json_tree,
2628                            clib_net_to_host_u32 (mp->sw_if_index));
2629 }
2630
2631 static void vl_api_get_first_msg_id_reply_t_handler
2632   (vl_api_get_first_msg_id_reply_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   i32 retval = ntohl (mp->retval);
2636
2637   if (vam->async_mode)
2638     {
2639       vam->async_errors += (retval < 0);
2640     }
2641   else
2642     {
2643       vam->retval = retval;
2644       vam->result_ready = 1;
2645     }
2646   if (retval >= 0)
2647     {
2648       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2649     }
2650 }
2651
2652 static void vl_api_get_first_msg_id_reply_t_handler_json
2653   (vl_api_get_first_msg_id_reply_t * mp)
2654 {
2655   vat_main_t *vam = &vat_main;
2656   vat_json_node_t node;
2657
2658   vat_json_init_object (&node);
2659   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2660   vat_json_object_add_uint (&node, "first_msg_id",
2661                             (uint) ntohs (mp->first_msg_id));
2662
2663   vat_json_print (vam->ofp, &node);
2664   vat_json_free (&node);
2665
2666   vam->retval = ntohl (mp->retval);
2667   vam->result_ready = 1;
2668 }
2669
2670 static void vl_api_get_node_graph_reply_t_handler
2671   (vl_api_get_node_graph_reply_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   i32 retval = ntohl (mp->retval);
2675   u8 *pvt_copy, *reply;
2676   void *oldheap;
2677   vlib_node_t *node;
2678   int i;
2679
2680   if (vam->async_mode)
2681     {
2682       vam->async_errors += (retval < 0);
2683     }
2684   else
2685     {
2686       vam->retval = retval;
2687       vam->result_ready = 1;
2688     }
2689
2690   /* "Should never happen..." */
2691   if (retval != 0)
2692     return;
2693
2694   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2695   pvt_copy = vec_dup (reply);
2696
2697   /* Toss the shared-memory original... */
2698   oldheap = vl_msg_push_heap ();
2699
2700   vec_free (reply);
2701
2702   vl_msg_pop_heap (oldheap);
2703
2704   if (vam->graph_nodes)
2705     {
2706       hash_free (vam->graph_node_index_by_name);
2707
2708       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2709         {
2710           node = vam->graph_nodes[0][i];
2711           vec_free (node->name);
2712           vec_free (node->next_nodes);
2713           vec_free (node);
2714         }
2715       vec_free (vam->graph_nodes[0]);
2716       vec_free (vam->graph_nodes);
2717     }
2718
2719   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2720   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2721   vec_free (pvt_copy);
2722
2723   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2724     {
2725       node = vam->graph_nodes[0][i];
2726       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2727     }
2728 }
2729
2730 static void vl_api_get_node_graph_reply_t_handler_json
2731   (vl_api_get_node_graph_reply_t * mp)
2732 {
2733   vat_main_t *vam = &vat_main;
2734   void *oldheap;
2735   vat_json_node_t node;
2736   u8 *reply;
2737
2738   /* $$$$ make this real? */
2739   vat_json_init_object (&node);
2740   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2741   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2742
2743   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2744
2745   /* Toss the shared-memory original... */
2746   oldheap = vl_msg_push_heap ();
2747
2748   vec_free (reply);
2749
2750   vl_msg_pop_heap (oldheap);
2751
2752   vat_json_print (vam->ofp, &node);
2753   vat_json_free (&node);
2754
2755   vam->retval = ntohl (mp->retval);
2756   vam->result_ready = 1;
2757 }
2758
2759 static void
2760 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2761 {
2762   vat_main_t *vam = &vat_main;
2763   u8 *s = 0;
2764
2765   if (mp->local)
2766     {
2767       s = format (s, "%=16d%=16d%=16d",
2768                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2769     }
2770   else
2771     {
2772       s = format (s, "%=16U%=16d%=16d",
2773                   mp->is_ipv6 ? format_ip6_address :
2774                   format_ip4_address,
2775                   mp->ip_address, mp->priority, mp->weight);
2776     }
2777
2778   print (vam->ofp, "%v", s);
2779   vec_free (s);
2780 }
2781
2782 static void
2783 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2784 {
2785   vat_main_t *vam = &vat_main;
2786   vat_json_node_t *node = NULL;
2787   struct in6_addr ip6;
2788   struct in_addr ip4;
2789
2790   if (VAT_JSON_ARRAY != vam->json_tree.type)
2791     {
2792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2793       vat_json_init_array (&vam->json_tree);
2794     }
2795   node = vat_json_array_add (&vam->json_tree);
2796   vat_json_init_object (node);
2797
2798   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2799   vat_json_object_add_uint (node, "priority", mp->priority);
2800   vat_json_object_add_uint (node, "weight", mp->weight);
2801
2802   if (mp->local)
2803     vat_json_object_add_uint (node, "sw_if_index",
2804                               clib_net_to_host_u32 (mp->sw_if_index));
2805   else
2806     {
2807       if (mp->is_ipv6)
2808         {
2809           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2810           vat_json_object_add_ip6 (node, "address", ip6);
2811         }
2812       else
2813         {
2814           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2815           vat_json_object_add_ip4 (node, "address", ip4);
2816         }
2817     }
2818 }
2819
2820 static void
2821 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2822                                           mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825   u8 *ls_name = 0;
2826
2827   ls_name = format (0, "%s", mp->ls_name);
2828
2829   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2830          ls_name);
2831   vec_free (ls_name);
2832 }
2833
2834 static void
2835   vl_api_one_locator_set_details_t_handler_json
2836   (vl_api_one_locator_set_details_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   vat_json_node_t *node = 0;
2840   u8 *ls_name = 0;
2841
2842   ls_name = format (0, "%s", mp->ls_name);
2843   vec_add1 (ls_name, 0);
2844
2845   if (VAT_JSON_ARRAY != vam->json_tree.type)
2846     {
2847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2848       vat_json_init_array (&vam->json_tree);
2849     }
2850   node = vat_json_array_add (&vam->json_tree);
2851
2852   vat_json_init_object (node);
2853   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2854   vat_json_object_add_uint (node, "ls_index",
2855                             clib_net_to_host_u32 (mp->ls_index));
2856   vec_free (ls_name);
2857 }
2858
2859 typedef struct
2860 {
2861   u32 spi;
2862   u8 si;
2863 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2864
2865 uword
2866 unformat_nsh_address (unformat_input_t * input, va_list * args)
2867 {
2868   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2869   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2870 }
2871
2872 u8 *
2873 format_nsh_address_vat (u8 * s, va_list * args)
2874 {
2875   nsh_t *a = va_arg (*args, nsh_t *);
2876   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2877 }
2878
2879 static u8 *
2880 format_lisp_flat_eid (u8 * s, va_list * args)
2881 {
2882   u32 type = va_arg (*args, u32);
2883   u8 *eid = va_arg (*args, u8 *);
2884   u32 eid_len = va_arg (*args, u32);
2885
2886   switch (type)
2887     {
2888     case 0:
2889       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2890     case 1:
2891       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2892     case 2:
2893       return format (s, "%U", format_ethernet_address, eid);
2894     case 3:
2895       return format (s, "%U", format_nsh_address_vat, eid);
2896     }
2897   return 0;
2898 }
2899
2900 static u8 *
2901 format_lisp_eid_vat (u8 * s, va_list * args)
2902 {
2903   u32 type = va_arg (*args, u32);
2904   u8 *eid = va_arg (*args, u8 *);
2905   u32 eid_len = va_arg (*args, u32);
2906   u8 *seid = va_arg (*args, u8 *);
2907   u32 seid_len = va_arg (*args, u32);
2908   u32 is_src_dst = va_arg (*args, u32);
2909
2910   if (is_src_dst)
2911     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2912
2913   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2914
2915   return s;
2916 }
2917
2918 static void
2919 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2920 {
2921   vat_main_t *vam = &vat_main;
2922   u8 *s = 0, *eid = 0;
2923
2924   if (~0 == mp->locator_set_index)
2925     s = format (0, "action: %d", mp->action);
2926   else
2927     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2928
2929   eid = format (0, "%U", format_lisp_eid_vat,
2930                 mp->eid_type,
2931                 mp->eid,
2932                 mp->eid_prefix_len,
2933                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2934   vec_add1 (eid, 0);
2935
2936   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2937          clib_net_to_host_u32 (mp->vni),
2938          eid,
2939          mp->is_local ? "local" : "remote",
2940          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2941          clib_net_to_host_u16 (mp->key_id), mp->key);
2942
2943   vec_free (s);
2944   vec_free (eid);
2945 }
2946
2947 static void
2948 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2949                                              * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   vat_json_node_t *node = 0;
2953   u8 *eid = 0;
2954
2955   if (VAT_JSON_ARRAY != vam->json_tree.type)
2956     {
2957       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2958       vat_json_init_array (&vam->json_tree);
2959     }
2960   node = vat_json_array_add (&vam->json_tree);
2961
2962   vat_json_init_object (node);
2963   if (~0 == mp->locator_set_index)
2964     vat_json_object_add_uint (node, "action", mp->action);
2965   else
2966     vat_json_object_add_uint (node, "locator_set_index",
2967                               clib_net_to_host_u32 (mp->locator_set_index));
2968
2969   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2970   if (mp->eid_type == 3)
2971     {
2972       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2973       vat_json_init_object (nsh_json);
2974       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2975       vat_json_object_add_uint (nsh_json, "spi",
2976                                 clib_net_to_host_u32 (nsh->spi));
2977       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2978     }
2979   else
2980     {
2981       eid = format (0, "%U", format_lisp_eid_vat,
2982                     mp->eid_type,
2983                     mp->eid,
2984                     mp->eid_prefix_len,
2985                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2986       vec_add1 (eid, 0);
2987       vat_json_object_add_string_copy (node, "eid", eid);
2988       vec_free (eid);
2989     }
2990   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2991   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2992   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2993
2994   if (mp->key_id)
2995     {
2996       vat_json_object_add_uint (node, "key_id",
2997                                 clib_net_to_host_u16 (mp->key_id));
2998       vat_json_object_add_string_copy (node, "key", mp->key);
2999     }
3000 }
3001
3002 static void
3003 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3004 {
3005   vat_main_t *vam = &vat_main;
3006   u8 *seid = 0, *deid = 0;
3007   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3008
3009   deid = format (0, "%U", format_lisp_eid_vat,
3010                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3011
3012   seid = format (0, "%U", format_lisp_eid_vat,
3013                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3014
3015   vec_add1 (deid, 0);
3016   vec_add1 (seid, 0);
3017
3018   if (mp->is_ip4)
3019     format_ip_address_fcn = format_ip4_address;
3020   else
3021     format_ip_address_fcn = format_ip6_address;
3022
3023
3024   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3025          clib_net_to_host_u32 (mp->vni),
3026          seid, deid,
3027          format_ip_address_fcn, mp->lloc,
3028          format_ip_address_fcn, mp->rloc,
3029          clib_net_to_host_u32 (mp->pkt_count),
3030          clib_net_to_host_u32 (mp->bytes));
3031
3032   vec_free (deid);
3033   vec_free (seid);
3034 }
3035
3036 static void
3037 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3038 {
3039   struct in6_addr ip6;
3040   struct in_addr ip4;
3041   vat_main_t *vam = &vat_main;
3042   vat_json_node_t *node = 0;
3043   u8 *deid = 0, *seid = 0;
3044
3045   if (VAT_JSON_ARRAY != vam->json_tree.type)
3046     {
3047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3048       vat_json_init_array (&vam->json_tree);
3049     }
3050   node = vat_json_array_add (&vam->json_tree);
3051
3052   vat_json_init_object (node);
3053   deid = format (0, "%U", format_lisp_eid_vat,
3054                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3055
3056   seid = format (0, "%U", format_lisp_eid_vat,
3057                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3058
3059   vec_add1 (deid, 0);
3060   vec_add1 (seid, 0);
3061
3062   vat_json_object_add_string_copy (node, "seid", seid);
3063   vat_json_object_add_string_copy (node, "deid", deid);
3064   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3065
3066   if (mp->is_ip4)
3067     {
3068       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3069       vat_json_object_add_ip4 (node, "lloc", ip4);
3070       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3071       vat_json_object_add_ip4 (node, "rloc", ip4);
3072     }
3073   else
3074     {
3075       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3076       vat_json_object_add_ip6 (node, "lloc", ip6);
3077       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3078       vat_json_object_add_ip6 (node, "rloc", ip6);
3079     }
3080   vat_json_object_add_uint (node, "pkt_count",
3081                             clib_net_to_host_u32 (mp->pkt_count));
3082   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3083
3084   vec_free (deid);
3085   vec_free (seid);
3086 }
3087
3088 static void
3089   vl_api_one_eid_table_map_details_t_handler
3090   (vl_api_one_eid_table_map_details_t * mp)
3091 {
3092   vat_main_t *vam = &vat_main;
3093
3094   u8 *line = format (0, "%=10d%=10d",
3095                      clib_net_to_host_u32 (mp->vni),
3096                      clib_net_to_host_u32 (mp->dp_table));
3097   print (vam->ofp, "%v", line);
3098   vec_free (line);
3099 }
3100
3101 static void
3102   vl_api_one_eid_table_map_details_t_handler_json
3103   (vl_api_one_eid_table_map_details_t * mp)
3104 {
3105   vat_main_t *vam = &vat_main;
3106   vat_json_node_t *node = NULL;
3107
3108   if (VAT_JSON_ARRAY != vam->json_tree.type)
3109     {
3110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3111       vat_json_init_array (&vam->json_tree);
3112     }
3113   node = vat_json_array_add (&vam->json_tree);
3114   vat_json_init_object (node);
3115   vat_json_object_add_uint (node, "dp_table",
3116                             clib_net_to_host_u32 (mp->dp_table));
3117   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3118 }
3119
3120 static void
3121   vl_api_one_eid_table_vni_details_t_handler
3122   (vl_api_one_eid_table_vni_details_t * mp)
3123 {
3124   vat_main_t *vam = &vat_main;
3125
3126   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3127   print (vam->ofp, "%v", line);
3128   vec_free (line);
3129 }
3130
3131 static void
3132   vl_api_one_eid_table_vni_details_t_handler_json
3133   (vl_api_one_eid_table_vni_details_t * mp)
3134 {
3135   vat_main_t *vam = &vat_main;
3136   vat_json_node_t *node = NULL;
3137
3138   if (VAT_JSON_ARRAY != vam->json_tree.type)
3139     {
3140       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3141       vat_json_init_array (&vam->json_tree);
3142     }
3143   node = vat_json_array_add (&vam->json_tree);
3144   vat_json_init_object (node);
3145   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3146 }
3147
3148 static void
3149   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3150   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   int retval = clib_net_to_host_u32 (mp->retval);
3154
3155   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3156   print (vam->ofp, "fallback threshold value: %d", mp->value);
3157
3158   vam->retval = retval;
3159   vam->result_ready = 1;
3160 }
3161
3162 static void
3163   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3164   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3165 {
3166   vat_main_t *vam = &vat_main;
3167   vat_json_node_t _node, *node = &_node;
3168   int retval = clib_net_to_host_u32 (mp->retval);
3169
3170   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3171   vat_json_init_object (node);
3172   vat_json_object_add_uint (node, "value", mp->value);
3173
3174   vat_json_print (vam->ofp, node);
3175   vat_json_free (node);
3176
3177   vam->retval = retval;
3178   vam->result_ready = 1;
3179 }
3180
3181 static void
3182   vl_api_show_one_map_register_state_reply_t_handler
3183   (vl_api_show_one_map_register_state_reply_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   int retval = clib_net_to_host_u32 (mp->retval);
3187
3188   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3189
3190   vam->retval = retval;
3191   vam->result_ready = 1;
3192 }
3193
3194 static void
3195   vl_api_show_one_map_register_state_reply_t_handler_json
3196   (vl_api_show_one_map_register_state_reply_t * mp)
3197 {
3198   vat_main_t *vam = &vat_main;
3199   vat_json_node_t _node, *node = &_node;
3200   int retval = clib_net_to_host_u32 (mp->retval);
3201
3202   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3203
3204   vat_json_init_object (node);
3205   vat_json_object_add_string_copy (node, "state", s);
3206
3207   vat_json_print (vam->ofp, node);
3208   vat_json_free (node);
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212   vec_free (s);
3213 }
3214
3215 static void
3216   vl_api_show_one_rloc_probe_state_reply_t_handler
3217   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220   int retval = clib_net_to_host_u32 (mp->retval);
3221
3222   if (retval)
3223     goto end;
3224
3225   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3226 end:
3227   vam->retval = retval;
3228   vam->result_ready = 1;
3229 }
3230
3231 static void
3232   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3233   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   vat_json_node_t _node, *node = &_node;
3237   int retval = clib_net_to_host_u32 (mp->retval);
3238
3239   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3240   vat_json_init_object (node);
3241   vat_json_object_add_string_copy (node, "state", s);
3242
3243   vat_json_print (vam->ofp, node);
3244   vat_json_free (node);
3245
3246   vam->retval = retval;
3247   vam->result_ready = 1;
3248   vec_free (s);
3249 }
3250
3251 static void
3252   vl_api_show_one_stats_enable_disable_reply_t_handler
3253   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   int retval = clib_net_to_host_u32 (mp->retval);
3257
3258   if (retval)
3259     goto end;
3260
3261   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3262 end:
3263   vam->retval = retval;
3264   vam->result_ready = 1;
3265 }
3266
3267 static void
3268   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3269   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272   vat_json_node_t _node, *node = &_node;
3273   int retval = clib_net_to_host_u32 (mp->retval);
3274
3275   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3276   vat_json_init_object (node);
3277   vat_json_object_add_string_copy (node, "state", s);
3278
3279   vat_json_print (vam->ofp, node);
3280   vat_json_free (node);
3281
3282   vam->retval = retval;
3283   vam->result_ready = 1;
3284   vec_free (s);
3285 }
3286
3287 static void
3288 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3289 {
3290   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3291   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3292   e->vni = clib_net_to_host_u32 (e->vni);
3293 }
3294
3295 static void
3296   gpe_fwd_entries_get_reply_t_net_to_host
3297   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3298 {
3299   u32 i;
3300
3301   mp->count = clib_net_to_host_u32 (mp->count);
3302   for (i = 0; i < mp->count; i++)
3303     {
3304       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3305     }
3306 }
3307
3308 static u8 *
3309 format_gpe_encap_mode (u8 * s, va_list * args)
3310 {
3311   u32 mode = va_arg (*args, u32);
3312
3313   switch (mode)
3314     {
3315     case 0:
3316       return format (s, "lisp");
3317     case 1:
3318       return format (s, "vxlan");
3319     }
3320   return 0;
3321 }
3322
3323 static void
3324   vl_api_gpe_get_encap_mode_reply_t_handler
3325   (vl_api_gpe_get_encap_mode_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328
3329   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3330   vam->retval = ntohl (mp->retval);
3331   vam->result_ready = 1;
3332 }
3333
3334 static void
3335   vl_api_gpe_get_encap_mode_reply_t_handler_json
3336   (vl_api_gpe_get_encap_mode_reply_t * mp)
3337 {
3338   vat_main_t *vam = &vat_main;
3339   vat_json_node_t node;
3340
3341   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3342   vec_add1 (encap_mode, 0);
3343
3344   vat_json_init_object (&node);
3345   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3346
3347   vec_free (encap_mode);
3348   vat_json_print (vam->ofp, &node);
3349   vat_json_free (&node);
3350
3351   vam->retval = ntohl (mp->retval);
3352   vam->result_ready = 1;
3353 }
3354
3355 static void
3356   vl_api_gpe_fwd_entry_path_details_t_handler
3357   (vl_api_gpe_fwd_entry_path_details_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3361
3362   if (mp->lcl_loc.is_ip4)
3363     format_ip_address_fcn = format_ip4_address;
3364   else
3365     format_ip_address_fcn = format_ip6_address;
3366
3367   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3368          format_ip_address_fcn, &mp->lcl_loc,
3369          format_ip_address_fcn, &mp->rmt_loc);
3370 }
3371
3372 static void
3373 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3374 {
3375   struct in6_addr ip6;
3376   struct in_addr ip4;
3377
3378   if (loc->is_ip4)
3379     {
3380       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3381       vat_json_object_add_ip4 (n, "address", ip4);
3382     }
3383   else
3384     {
3385       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3386       vat_json_object_add_ip6 (n, "address", ip6);
3387     }
3388   vat_json_object_add_uint (n, "weight", loc->weight);
3389 }
3390
3391 static void
3392   vl_api_gpe_fwd_entry_path_details_t_handler_json
3393   (vl_api_gpe_fwd_entry_path_details_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   vat_json_node_t *node = NULL;
3397   vat_json_node_t *loc_node;
3398
3399   if (VAT_JSON_ARRAY != vam->json_tree.type)
3400     {
3401       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3402       vat_json_init_array (&vam->json_tree);
3403     }
3404   node = vat_json_array_add (&vam->json_tree);
3405   vat_json_init_object (node);
3406
3407   loc_node = vat_json_object_add (node, "local_locator");
3408   vat_json_init_object (loc_node);
3409   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3410
3411   loc_node = vat_json_object_add (node, "remote_locator");
3412   vat_json_init_object (loc_node);
3413   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3414 }
3415
3416 static void
3417   vl_api_gpe_fwd_entries_get_reply_t_handler
3418   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3419 {
3420   vat_main_t *vam = &vat_main;
3421   u32 i;
3422   int retval = clib_net_to_host_u32 (mp->retval);
3423   vl_api_gpe_fwd_entry_t *e;
3424
3425   if (retval)
3426     goto end;
3427
3428   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3429
3430   for (i = 0; i < mp->count; i++)
3431     {
3432       e = &mp->entries[i];
3433       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3434              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3435              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3436     }
3437
3438 end:
3439   vam->retval = retval;
3440   vam->result_ready = 1;
3441 }
3442
3443 static void
3444   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3445   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3446 {
3447   u8 *s = 0;
3448   vat_main_t *vam = &vat_main;
3449   vat_json_node_t *e = 0, root;
3450   u32 i;
3451   int retval = clib_net_to_host_u32 (mp->retval);
3452   vl_api_gpe_fwd_entry_t *fwd;
3453
3454   if (retval)
3455     goto end;
3456
3457   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3458   vat_json_init_array (&root);
3459
3460   for (i = 0; i < mp->count; i++)
3461     {
3462       e = vat_json_array_add (&root);
3463       fwd = &mp->entries[i];
3464
3465       vat_json_init_object (e);
3466       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3467       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3468       vat_json_object_add_int (e, "vni", fwd->vni);
3469       vat_json_object_add_int (e, "action", fwd->action);
3470
3471       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3472                   fwd->leid_prefix_len);
3473       vec_add1 (s, 0);
3474       vat_json_object_add_string_copy (e, "leid", s);
3475       vec_free (s);
3476
3477       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3478                   fwd->reid_prefix_len);
3479       vec_add1 (s, 0);
3480       vat_json_object_add_string_copy (e, "reid", s);
3481       vec_free (s);
3482     }
3483
3484   vat_json_print (vam->ofp, &root);
3485   vat_json_free (&root);
3486
3487 end:
3488   vam->retval = retval;
3489   vam->result_ready = 1;
3490 }
3491
3492 static void
3493   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3494   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3495 {
3496   vat_main_t *vam = &vat_main;
3497   u32 i, n;
3498   int retval = clib_net_to_host_u32 (mp->retval);
3499   vl_api_gpe_native_fwd_rpath_t *r;
3500
3501   if (retval)
3502     goto end;
3503
3504   n = clib_net_to_host_u32 (mp->count);
3505
3506   for (i = 0; i < n; i++)
3507     {
3508       r = &mp->entries[i];
3509       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3510              clib_net_to_host_u32 (r->fib_index),
3511              clib_net_to_host_u32 (r->nh_sw_if_index),
3512              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3513     }
3514
3515 end:
3516   vam->retval = retval;
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3522   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525   vat_json_node_t root, *e;
3526   u32 i, n;
3527   int retval = clib_net_to_host_u32 (mp->retval);
3528   vl_api_gpe_native_fwd_rpath_t *r;
3529   u8 *s;
3530
3531   if (retval)
3532     goto end;
3533
3534   n = clib_net_to_host_u32 (mp->count);
3535   vat_json_init_array (&root);
3536
3537   for (i = 0; i < n; i++)
3538     {
3539       e = vat_json_array_add (&root);
3540       vat_json_init_object (e);
3541       r = &mp->entries[i];
3542       s =
3543         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3544                 r->nh_addr);
3545       vec_add1 (s, 0);
3546       vat_json_object_add_string_copy (e, "ip4", s);
3547       vec_free (s);
3548
3549       vat_json_object_add_uint (e, "fib_index",
3550                                 clib_net_to_host_u32 (r->fib_index));
3551       vat_json_object_add_uint (e, "nh_sw_if_index",
3552                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3553     }
3554
3555   vat_json_print (vam->ofp, &root);
3556   vat_json_free (&root);
3557
3558 end:
3559   vam->retval = retval;
3560   vam->result_ready = 1;
3561 }
3562
3563 static void
3564   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3565   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3566 {
3567   vat_main_t *vam = &vat_main;
3568   u32 i, n;
3569   int retval = clib_net_to_host_u32 (mp->retval);
3570
3571   if (retval)
3572     goto end;
3573
3574   n = clib_net_to_host_u32 (mp->count);
3575
3576   for (i = 0; i < n; i++)
3577     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3578
3579 end:
3580   vam->retval = retval;
3581   vam->result_ready = 1;
3582 }
3583
3584 static void
3585   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3586   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3587 {
3588   vat_main_t *vam = &vat_main;
3589   vat_json_node_t root;
3590   u32 i, n;
3591   int retval = clib_net_to_host_u32 (mp->retval);
3592
3593   if (retval)
3594     goto end;
3595
3596   n = clib_net_to_host_u32 (mp->count);
3597   vat_json_init_array (&root);
3598
3599   for (i = 0; i < n; i++)
3600     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3601
3602   vat_json_print (vam->ofp, &root);
3603   vat_json_free (&root);
3604
3605 end:
3606   vam->retval = retval;
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611   vl_api_one_ndp_entries_get_reply_t_handler
3612   (vl_api_one_ndp_entries_get_reply_t * mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615   u32 i, n;
3616   int retval = clib_net_to_host_u32 (mp->retval);
3617
3618   if (retval)
3619     goto end;
3620
3621   n = clib_net_to_host_u32 (mp->count);
3622
3623   for (i = 0; i < n; i++)
3624     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3625            format_ethernet_address, mp->entries[i].mac);
3626
3627 end:
3628   vam->retval = retval;
3629   vam->result_ready = 1;
3630 }
3631
3632 static void
3633   vl_api_one_ndp_entries_get_reply_t_handler_json
3634   (vl_api_one_ndp_entries_get_reply_t * mp)
3635 {
3636   u8 *s = 0;
3637   vat_main_t *vam = &vat_main;
3638   vat_json_node_t *e = 0, root;
3639   u32 i, n;
3640   int retval = clib_net_to_host_u32 (mp->retval);
3641   vl_api_one_ndp_entry_t *arp_entry;
3642
3643   if (retval)
3644     goto end;
3645
3646   n = clib_net_to_host_u32 (mp->count);
3647   vat_json_init_array (&root);
3648
3649   for (i = 0; i < n; i++)
3650     {
3651       e = vat_json_array_add (&root);
3652       arp_entry = &mp->entries[i];
3653
3654       vat_json_init_object (e);
3655       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3656       vec_add1 (s, 0);
3657
3658       vat_json_object_add_string_copy (e, "mac", s);
3659       vec_free (s);
3660
3661       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3662       vec_add1 (s, 0);
3663       vat_json_object_add_string_copy (e, "ip6", s);
3664       vec_free (s);
3665     }
3666
3667   vat_json_print (vam->ofp, &root);
3668   vat_json_free (&root);
3669
3670 end:
3671   vam->retval = retval;
3672   vam->result_ready = 1;
3673 }
3674
3675 static void
3676   vl_api_one_l2_arp_entries_get_reply_t_handler
3677   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   u32 i, n;
3681   int retval = clib_net_to_host_u32 (mp->retval);
3682
3683   if (retval)
3684     goto end;
3685
3686   n = clib_net_to_host_u32 (mp->count);
3687
3688   for (i = 0; i < n; i++)
3689     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3690            format_ethernet_address, mp->entries[i].mac);
3691
3692 end:
3693   vam->retval = retval;
3694   vam->result_ready = 1;
3695 }
3696
3697 static void
3698   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3699   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3700 {
3701   u8 *s = 0;
3702   vat_main_t *vam = &vat_main;
3703   vat_json_node_t *e = 0, root;
3704   u32 i, n;
3705   int retval = clib_net_to_host_u32 (mp->retval);
3706   vl_api_one_l2_arp_entry_t *arp_entry;
3707
3708   if (retval)
3709     goto end;
3710
3711   n = clib_net_to_host_u32 (mp->count);
3712   vat_json_init_array (&root);
3713
3714   for (i = 0; i < n; i++)
3715     {
3716       e = vat_json_array_add (&root);
3717       arp_entry = &mp->entries[i];
3718
3719       vat_json_init_object (e);
3720       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3721       vec_add1 (s, 0);
3722
3723       vat_json_object_add_string_copy (e, "mac", s);
3724       vec_free (s);
3725
3726       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3727       vec_add1 (s, 0);
3728       vat_json_object_add_string_copy (e, "ip4", s);
3729       vec_free (s);
3730     }
3731
3732   vat_json_print (vam->ofp, &root);
3733   vat_json_free (&root);
3734
3735 end:
3736   vam->retval = retval;
3737   vam->result_ready = 1;
3738 }
3739
3740 static void
3741 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3742 {
3743   vat_main_t *vam = &vat_main;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746
3747   if (retval)
3748     goto end;
3749
3750   n = clib_net_to_host_u32 (mp->count);
3751
3752   for (i = 0; i < n; i++)
3753     {
3754       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3755     }
3756
3757 end:
3758   vam->retval = retval;
3759   vam->result_ready = 1;
3760 }
3761
3762 static void
3763   vl_api_one_ndp_bd_get_reply_t_handler_json
3764   (vl_api_one_ndp_bd_get_reply_t * mp)
3765 {
3766   vat_main_t *vam = &vat_main;
3767   vat_json_node_t root;
3768   u32 i, n;
3769   int retval = clib_net_to_host_u32 (mp->retval);
3770
3771   if (retval)
3772     goto end;
3773
3774   n = clib_net_to_host_u32 (mp->count);
3775   vat_json_init_array (&root);
3776
3777   for (i = 0; i < n; i++)
3778     {
3779       vat_json_array_add_uint (&root,
3780                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3781     }
3782
3783   vat_json_print (vam->ofp, &root);
3784   vat_json_free (&root);
3785
3786 end:
3787   vam->retval = retval;
3788   vam->result_ready = 1;
3789 }
3790
3791 static void
3792   vl_api_one_l2_arp_bd_get_reply_t_handler
3793   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3794 {
3795   vat_main_t *vam = &vat_main;
3796   u32 i, n;
3797   int retval = clib_net_to_host_u32 (mp->retval);
3798
3799   if (retval)
3800     goto end;
3801
3802   n = clib_net_to_host_u32 (mp->count);
3803
3804   for (i = 0; i < n; i++)
3805     {
3806       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3807     }
3808
3809 end:
3810   vam->retval = retval;
3811   vam->result_ready = 1;
3812 }
3813
3814 static void
3815   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3816   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3817 {
3818   vat_main_t *vam = &vat_main;
3819   vat_json_node_t root;
3820   u32 i, n;
3821   int retval = clib_net_to_host_u32 (mp->retval);
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       vat_json_array_add_uint (&root,
3832                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3833     }
3834
3835   vat_json_print (vam->ofp, &root);
3836   vat_json_free (&root);
3837
3838 end:
3839   vam->retval = retval;
3840   vam->result_ready = 1;
3841 }
3842
3843 static void
3844   vl_api_one_adjacencies_get_reply_t_handler
3845   (vl_api_one_adjacencies_get_reply_t * mp)
3846 {
3847   vat_main_t *vam = &vat_main;
3848   u32 i, n;
3849   int retval = clib_net_to_host_u32 (mp->retval);
3850   vl_api_one_adjacency_t *a;
3851
3852   if (retval)
3853     goto end;
3854
3855   n = clib_net_to_host_u32 (mp->count);
3856
3857   for (i = 0; i < n; i++)
3858     {
3859       a = &mp->adjacencies[i];
3860       print (vam->ofp, "%U %40U",
3861              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3862              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3863     }
3864
3865 end:
3866   vam->retval = retval;
3867   vam->result_ready = 1;
3868 }
3869
3870 static void
3871   vl_api_one_adjacencies_get_reply_t_handler_json
3872   (vl_api_one_adjacencies_get_reply_t * mp)
3873 {
3874   u8 *s = 0;
3875   vat_main_t *vam = &vat_main;
3876   vat_json_node_t *e = 0, root;
3877   u32 i, n;
3878   int retval = clib_net_to_host_u32 (mp->retval);
3879   vl_api_one_adjacency_t *a;
3880
3881   if (retval)
3882     goto end;
3883
3884   n = clib_net_to_host_u32 (mp->count);
3885   vat_json_init_array (&root);
3886
3887   for (i = 0; i < n; i++)
3888     {
3889       e = vat_json_array_add (&root);
3890       a = &mp->adjacencies[i];
3891
3892       vat_json_init_object (e);
3893       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3894                   a->leid_prefix_len);
3895       vec_add1 (s, 0);
3896       vat_json_object_add_string_copy (e, "leid", s);
3897       vec_free (s);
3898
3899       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3900                   a->reid_prefix_len);
3901       vec_add1 (s, 0);
3902       vat_json_object_add_string_copy (e, "reid", s);
3903       vec_free (s);
3904     }
3905
3906   vat_json_print (vam->ofp, &root);
3907   vat_json_free (&root);
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918
3919   print (vam->ofp, "%=20U",
3920          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3921          mp->ip_address);
3922 }
3923
3924 static void
3925   vl_api_one_map_server_details_t_handler_json
3926   (vl_api_one_map_server_details_t * mp)
3927 {
3928   vat_main_t *vam = &vat_main;
3929   vat_json_node_t *node = NULL;
3930   struct in6_addr ip6;
3931   struct in_addr ip4;
3932
3933   if (VAT_JSON_ARRAY != vam->json_tree.type)
3934     {
3935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3936       vat_json_init_array (&vam->json_tree);
3937     }
3938   node = vat_json_array_add (&vam->json_tree);
3939
3940   vat_json_init_object (node);
3941   if (mp->is_ipv6)
3942     {
3943       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3944       vat_json_object_add_ip6 (node, "map-server", ip6);
3945     }
3946   else
3947     {
3948       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3949       vat_json_object_add_ip4 (node, "map-server", ip4);
3950     }
3951 }
3952
3953 static void
3954 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3955                                            * mp)
3956 {
3957   vat_main_t *vam = &vat_main;
3958
3959   print (vam->ofp, "%=20U",
3960          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3961          mp->ip_address);
3962 }
3963
3964 static void
3965   vl_api_one_map_resolver_details_t_handler_json
3966   (vl_api_one_map_resolver_details_t * mp)
3967 {
3968   vat_main_t *vam = &vat_main;
3969   vat_json_node_t *node = NULL;
3970   struct in6_addr ip6;
3971   struct in_addr ip4;
3972
3973   if (VAT_JSON_ARRAY != vam->json_tree.type)
3974     {
3975       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3976       vat_json_init_array (&vam->json_tree);
3977     }
3978   node = vat_json_array_add (&vam->json_tree);
3979
3980   vat_json_init_object (node);
3981   if (mp->is_ipv6)
3982     {
3983       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3984       vat_json_object_add_ip6 (node, "map resolver", ip6);
3985     }
3986   else
3987     {
3988       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3989       vat_json_object_add_ip4 (node, "map resolver", ip4);
3990     }
3991 }
3992
3993 static void
3994 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3995 {
3996   vat_main_t *vam = &vat_main;
3997   i32 retval = ntohl (mp->retval);
3998
3999   if (0 <= retval)
4000     {
4001       print (vam->ofp, "feature: %s\ngpe: %s",
4002              mp->feature_status ? "enabled" : "disabled",
4003              mp->gpe_status ? "enabled" : "disabled");
4004     }
4005
4006   vam->retval = retval;
4007   vam->result_ready = 1;
4008 }
4009
4010 static void
4011   vl_api_show_one_status_reply_t_handler_json
4012   (vl_api_show_one_status_reply_t * mp)
4013 {
4014   vat_main_t *vam = &vat_main;
4015   vat_json_node_t node;
4016   u8 *gpe_status = NULL;
4017   u8 *feature_status = NULL;
4018
4019   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4020   feature_status = format (0, "%s",
4021                            mp->feature_status ? "enabled" : "disabled");
4022   vec_add1 (gpe_status, 0);
4023   vec_add1 (feature_status, 0);
4024
4025   vat_json_init_object (&node);
4026   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4027   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4028
4029   vec_free (gpe_status);
4030   vec_free (feature_status);
4031
4032   vat_json_print (vam->ofp, &node);
4033   vat_json_free (&node);
4034
4035   vam->retval = ntohl (mp->retval);
4036   vam->result_ready = 1;
4037 }
4038
4039 static void
4040   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4041   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4042 {
4043   vat_main_t *vam = &vat_main;
4044   i32 retval = ntohl (mp->retval);
4045
4046   if (retval >= 0)
4047     {
4048       print (vam->ofp, "%=20s", mp->locator_set_name);
4049     }
4050
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4057   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   vat_json_node_t *node = NULL;
4061
4062   if (VAT_JSON_ARRAY != vam->json_tree.type)
4063     {
4064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4065       vat_json_init_array (&vam->json_tree);
4066     }
4067   node = vat_json_array_add (&vam->json_tree);
4068
4069   vat_json_init_object (node);
4070   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4071
4072   vat_json_print (vam->ofp, node);
4073   vat_json_free (node);
4074
4075   vam->retval = ntohl (mp->retval);
4076   vam->result_ready = 1;
4077 }
4078
4079 static u8 *
4080 format_lisp_map_request_mode (u8 * s, va_list * args)
4081 {
4082   u32 mode = va_arg (*args, u32);
4083
4084   switch (mode)
4085     {
4086     case 0:
4087       return format (0, "dst-only");
4088     case 1:
4089       return format (0, "src-dst");
4090     }
4091   return 0;
4092 }
4093
4094 static void
4095   vl_api_show_one_map_request_mode_reply_t_handler
4096   (vl_api_show_one_map_request_mode_reply_t * mp)
4097 {
4098   vat_main_t *vam = &vat_main;
4099   i32 retval = ntohl (mp->retval);
4100
4101   if (0 <= retval)
4102     {
4103       u32 mode = mp->mode;
4104       print (vam->ofp, "map_request_mode: %U",
4105              format_lisp_map_request_mode, mode);
4106     }
4107
4108   vam->retval = retval;
4109   vam->result_ready = 1;
4110 }
4111
4112 static void
4113   vl_api_show_one_map_request_mode_reply_t_handler_json
4114   (vl_api_show_one_map_request_mode_reply_t * mp)
4115 {
4116   vat_main_t *vam = &vat_main;
4117   vat_json_node_t node;
4118   u8 *s = 0;
4119   u32 mode;
4120
4121   mode = mp->mode;
4122   s = format (0, "%U", format_lisp_map_request_mode, mode);
4123   vec_add1 (s, 0);
4124
4125   vat_json_init_object (&node);
4126   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4127   vat_json_print (vam->ofp, &node);
4128   vat_json_free (&node);
4129
4130   vec_free (s);
4131   vam->retval = ntohl (mp->retval);
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_show_xtr_mode_reply_t_handler
4137   (vl_api_one_show_xtr_mode_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   i32 retval = ntohl (mp->retval);
4141
4142   if (0 <= retval)
4143     {
4144       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4145     }
4146
4147   vam->retval = retval;
4148   vam->result_ready = 1;
4149 }
4150
4151 static void
4152   vl_api_one_show_xtr_mode_reply_t_handler_json
4153   (vl_api_one_show_xtr_mode_reply_t * mp)
4154 {
4155   vat_main_t *vam = &vat_main;
4156   vat_json_node_t node;
4157   u8 *status = 0;
4158
4159   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4160   vec_add1 (status, 0);
4161
4162   vat_json_init_object (&node);
4163   vat_json_object_add_string_copy (&node, "status", status);
4164
4165   vec_free (status);
4166
4167   vat_json_print (vam->ofp, &node);
4168   vat_json_free (&node);
4169
4170   vam->retval = ntohl (mp->retval);
4171   vam->result_ready = 1;
4172 }
4173
4174 static void
4175   vl_api_one_show_pitr_mode_reply_t_handler
4176   (vl_api_one_show_pitr_mode_reply_t * mp)
4177 {
4178   vat_main_t *vam = &vat_main;
4179   i32 retval = ntohl (mp->retval);
4180
4181   if (0 <= retval)
4182     {
4183       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4184     }
4185
4186   vam->retval = retval;
4187   vam->result_ready = 1;
4188 }
4189
4190 static void
4191   vl_api_one_show_pitr_mode_reply_t_handler_json
4192   (vl_api_one_show_pitr_mode_reply_t * mp)
4193 {
4194   vat_main_t *vam = &vat_main;
4195   vat_json_node_t node;
4196   u8 *status = 0;
4197
4198   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4199   vec_add1 (status, 0);
4200
4201   vat_json_init_object (&node);
4202   vat_json_object_add_string_copy (&node, "status", status);
4203
4204   vec_free (status);
4205
4206   vat_json_print (vam->ofp, &node);
4207   vat_json_free (&node);
4208
4209   vam->retval = ntohl (mp->retval);
4210   vam->result_ready = 1;
4211 }
4212
4213 static void
4214   vl_api_one_show_petr_mode_reply_t_handler
4215   (vl_api_one_show_petr_mode_reply_t * mp)
4216 {
4217   vat_main_t *vam = &vat_main;
4218   i32 retval = ntohl (mp->retval);
4219
4220   if (0 <= retval)
4221     {
4222       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4223     }
4224
4225   vam->retval = retval;
4226   vam->result_ready = 1;
4227 }
4228
4229 static void
4230   vl_api_one_show_petr_mode_reply_t_handler_json
4231   (vl_api_one_show_petr_mode_reply_t * mp)
4232 {
4233   vat_main_t *vam = &vat_main;
4234   vat_json_node_t node;
4235   u8 *status = 0;
4236
4237   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4238   vec_add1 (status, 0);
4239
4240   vat_json_init_object (&node);
4241   vat_json_object_add_string_copy (&node, "status", status);
4242
4243   vec_free (status);
4244
4245   vat_json_print (vam->ofp, &node);
4246   vat_json_free (&node);
4247
4248   vam->retval = ntohl (mp->retval);
4249   vam->result_ready = 1;
4250 }
4251
4252 static void
4253   vl_api_show_one_use_petr_reply_t_handler
4254   (vl_api_show_one_use_petr_reply_t * mp)
4255 {
4256   vat_main_t *vam = &vat_main;
4257   i32 retval = ntohl (mp->retval);
4258
4259   if (0 <= retval)
4260     {
4261       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4262       if (mp->status)
4263         {
4264           print (vam->ofp, "Proxy-ETR address; %U",
4265                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4266                  mp->address);
4267         }
4268     }
4269
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_show_one_use_petr_reply_t_handler_json
4276   (vl_api_show_one_use_petr_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t node;
4280   u8 *status = 0;
4281   struct in_addr ip4;
4282   struct in6_addr ip6;
4283
4284   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4285   vec_add1 (status, 0);
4286
4287   vat_json_init_object (&node);
4288   vat_json_object_add_string_copy (&node, "status", status);
4289   if (mp->status)
4290     {
4291       if (mp->is_ip4)
4292         {
4293           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4294           vat_json_object_add_ip6 (&node, "address", ip6);
4295         }
4296       else
4297         {
4298           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4299           vat_json_object_add_ip4 (&node, "address", ip4);
4300         }
4301     }
4302
4303   vec_free (status);
4304
4305   vat_json_print (vam->ofp, &node);
4306   vat_json_free (&node);
4307
4308   vam->retval = ntohl (mp->retval);
4309   vam->result_ready = 1;
4310 }
4311
4312 static void
4313   vl_api_show_one_nsh_mapping_reply_t_handler
4314   (vl_api_show_one_nsh_mapping_reply_t * mp)
4315 {
4316   vat_main_t *vam = &vat_main;
4317   i32 retval = ntohl (mp->retval);
4318
4319   if (0 <= retval)
4320     {
4321       print (vam->ofp, "%-20s%-16s",
4322              mp->is_set ? "set" : "not-set",
4323              mp->is_set ? (char *) mp->locator_set_name : "");
4324     }
4325
4326   vam->retval = retval;
4327   vam->result_ready = 1;
4328 }
4329
4330 static void
4331   vl_api_show_one_nsh_mapping_reply_t_handler_json
4332   (vl_api_show_one_nsh_mapping_reply_t * mp)
4333 {
4334   vat_main_t *vam = &vat_main;
4335   vat_json_node_t node;
4336   u8 *status = 0;
4337
4338   status = format (0, "%s", mp->is_set ? "yes" : "no");
4339   vec_add1 (status, 0);
4340
4341   vat_json_init_object (&node);
4342   vat_json_object_add_string_copy (&node, "is_set", status);
4343   if (mp->is_set)
4344     {
4345       vat_json_object_add_string_copy (&node, "locator_set",
4346                                        mp->locator_set_name);
4347     }
4348
4349   vec_free (status);
4350
4351   vat_json_print (vam->ofp, &node);
4352   vat_json_free (&node);
4353
4354   vam->retval = ntohl (mp->retval);
4355   vam->result_ready = 1;
4356 }
4357
4358 static void
4359   vl_api_show_one_map_register_ttl_reply_t_handler
4360   (vl_api_show_one_map_register_ttl_reply_t * mp)
4361 {
4362   vat_main_t *vam = &vat_main;
4363   i32 retval = ntohl (mp->retval);
4364
4365   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4366
4367   if (0 <= retval)
4368     {
4369       print (vam->ofp, "ttl: %u", mp->ttl);
4370     }
4371
4372   vam->retval = retval;
4373   vam->result_ready = 1;
4374 }
4375
4376 static void
4377   vl_api_show_one_map_register_ttl_reply_t_handler_json
4378   (vl_api_show_one_map_register_ttl_reply_t * mp)
4379 {
4380   vat_main_t *vam = &vat_main;
4381   vat_json_node_t node;
4382
4383   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4384   vat_json_init_object (&node);
4385   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4386
4387   vat_json_print (vam->ofp, &node);
4388   vat_json_free (&node);
4389
4390   vam->retval = ntohl (mp->retval);
4391   vam->result_ready = 1;
4392 }
4393
4394 static void
4395 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4396 {
4397   vat_main_t *vam = &vat_main;
4398   i32 retval = ntohl (mp->retval);
4399
4400   if (0 <= retval)
4401     {
4402       print (vam->ofp, "%-20s%-16s",
4403              mp->status ? "enabled" : "disabled",
4404              mp->status ? (char *) mp->locator_set_name : "");
4405     }
4406
4407   vam->retval = retval;
4408   vam->result_ready = 1;
4409 }
4410
4411 static void
4412 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4413 {
4414   vat_main_t *vam = &vat_main;
4415   vat_json_node_t node;
4416   u8 *status = 0;
4417
4418   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4419   vec_add1 (status, 0);
4420
4421   vat_json_init_object (&node);
4422   vat_json_object_add_string_copy (&node, "status", status);
4423   if (mp->status)
4424     {
4425       vat_json_object_add_string_copy (&node, "locator_set",
4426                                        mp->locator_set_name);
4427     }
4428
4429   vec_free (status);
4430
4431   vat_json_print (vam->ofp, &node);
4432   vat_json_free (&node);
4433
4434   vam->retval = ntohl (mp->retval);
4435   vam->result_ready = 1;
4436 }
4437
4438 static u8 *
4439 format_policer_type (u8 * s, va_list * va)
4440 {
4441   u32 i = va_arg (*va, u32);
4442
4443   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4444     s = format (s, "1r2c");
4445   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4446     s = format (s, "1r3c");
4447   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4448     s = format (s, "2r3c-2698");
4449   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4450     s = format (s, "2r3c-4115");
4451   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4452     s = format (s, "2r3c-mef5cf1");
4453   else
4454     s = format (s, "ILLEGAL");
4455   return s;
4456 }
4457
4458 static u8 *
4459 format_policer_rate_type (u8 * s, va_list * va)
4460 {
4461   u32 i = va_arg (*va, u32);
4462
4463   if (i == SSE2_QOS_RATE_KBPS)
4464     s = format (s, "kbps");
4465   else if (i == SSE2_QOS_RATE_PPS)
4466     s = format (s, "pps");
4467   else
4468     s = format (s, "ILLEGAL");
4469   return s;
4470 }
4471
4472 static u8 *
4473 format_policer_round_type (u8 * s, va_list * va)
4474 {
4475   u32 i = va_arg (*va, u32);
4476
4477   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4478     s = format (s, "closest");
4479   else if (i == SSE2_QOS_ROUND_TO_UP)
4480     s = format (s, "up");
4481   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4482     s = format (s, "down");
4483   else
4484     s = format (s, "ILLEGAL");
4485   return s;
4486 }
4487
4488 static u8 *
4489 format_policer_action_type (u8 * s, va_list * va)
4490 {
4491   u32 i = va_arg (*va, u32);
4492
4493   if (i == SSE2_QOS_ACTION_DROP)
4494     s = format (s, "drop");
4495   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4496     s = format (s, "transmit");
4497   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4498     s = format (s, "mark-and-transmit");
4499   else
4500     s = format (s, "ILLEGAL");
4501   return s;
4502 }
4503
4504 static u8 *
4505 format_dscp (u8 * s, va_list * va)
4506 {
4507   u32 i = va_arg (*va, u32);
4508   char *t = 0;
4509
4510   switch (i)
4511     {
4512 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4513       foreach_vnet_dscp
4514 #undef _
4515     default:
4516       return format (s, "ILLEGAL");
4517     }
4518   s = format (s, "%s", t);
4519   return s;
4520 }
4521
4522 static void
4523 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4527
4528   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4529     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4530   else
4531     conform_dscp_str = format (0, "");
4532
4533   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4534     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4535   else
4536     exceed_dscp_str = format (0, "");
4537
4538   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4539     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4540   else
4541     violate_dscp_str = format (0, "");
4542
4543   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4544          "rate type %U, round type %U, %s rate, %s color-aware, "
4545          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4546          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4547          "conform action %U%s, exceed action %U%s, violate action %U%s",
4548          mp->name,
4549          format_policer_type, mp->type,
4550          ntohl (mp->cir),
4551          ntohl (mp->eir),
4552          clib_net_to_host_u64 (mp->cb),
4553          clib_net_to_host_u64 (mp->eb),
4554          format_policer_rate_type, mp->rate_type,
4555          format_policer_round_type, mp->round_type,
4556          mp->single_rate ? "single" : "dual",
4557          mp->color_aware ? "is" : "not",
4558          ntohl (mp->cir_tokens_per_period),
4559          ntohl (mp->pir_tokens_per_period),
4560          ntohl (mp->scale),
4561          ntohl (mp->current_limit),
4562          ntohl (mp->current_bucket),
4563          ntohl (mp->extended_limit),
4564          ntohl (mp->extended_bucket),
4565          clib_net_to_host_u64 (mp->last_update_time),
4566          format_policer_action_type, mp->conform_action_type,
4567          conform_dscp_str,
4568          format_policer_action_type, mp->exceed_action_type,
4569          exceed_dscp_str,
4570          format_policer_action_type, mp->violate_action_type,
4571          violate_dscp_str);
4572
4573   vec_free (conform_dscp_str);
4574   vec_free (exceed_dscp_str);
4575   vec_free (violate_dscp_str);
4576 }
4577
4578 static void vl_api_policer_details_t_handler_json
4579   (vl_api_policer_details_t * mp)
4580 {
4581   vat_main_t *vam = &vat_main;
4582   vat_json_node_t *node;
4583   u8 *rate_type_str, *round_type_str, *type_str;
4584   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4585
4586   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4587   round_type_str =
4588     format (0, "%U", format_policer_round_type, mp->round_type);
4589   type_str = format (0, "%U", format_policer_type, mp->type);
4590   conform_action_str = format (0, "%U", format_policer_action_type,
4591                                mp->conform_action_type);
4592   exceed_action_str = format (0, "%U", format_policer_action_type,
4593                               mp->exceed_action_type);
4594   violate_action_str = format (0, "%U", format_policer_action_type,
4595                                mp->violate_action_type);
4596
4597   if (VAT_JSON_ARRAY != vam->json_tree.type)
4598     {
4599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4600       vat_json_init_array (&vam->json_tree);
4601     }
4602   node = vat_json_array_add (&vam->json_tree);
4603
4604   vat_json_init_object (node);
4605   vat_json_object_add_string_copy (node, "name", mp->name);
4606   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4607   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4608   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4609   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4610   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4611   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4612   vat_json_object_add_string_copy (node, "type", type_str);
4613   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4614   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4615   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4616   vat_json_object_add_uint (node, "cir_tokens_per_period",
4617                             ntohl (mp->cir_tokens_per_period));
4618   vat_json_object_add_uint (node, "eir_tokens_per_period",
4619                             ntohl (mp->pir_tokens_per_period));
4620   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4621   vat_json_object_add_uint (node, "current_bucket",
4622                             ntohl (mp->current_bucket));
4623   vat_json_object_add_uint (node, "extended_limit",
4624                             ntohl (mp->extended_limit));
4625   vat_json_object_add_uint (node, "extended_bucket",
4626                             ntohl (mp->extended_bucket));
4627   vat_json_object_add_uint (node, "last_update_time",
4628                             ntohl (mp->last_update_time));
4629   vat_json_object_add_string_copy (node, "conform_action",
4630                                    conform_action_str);
4631   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4632     {
4633       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4634       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4635       vec_free (dscp_str);
4636     }
4637   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4638   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4639     {
4640       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4641       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4642       vec_free (dscp_str);
4643     }
4644   vat_json_object_add_string_copy (node, "violate_action",
4645                                    violate_action_str);
4646   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4647     {
4648       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4649       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4650       vec_free (dscp_str);
4651     }
4652
4653   vec_free (rate_type_str);
4654   vec_free (round_type_str);
4655   vec_free (type_str);
4656   vec_free (conform_action_str);
4657   vec_free (exceed_action_str);
4658   vec_free (violate_action_str);
4659 }
4660
4661 static void
4662 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4663                                            mp)
4664 {
4665   vat_main_t *vam = &vat_main;
4666   int i, count = ntohl (mp->count);
4667
4668   if (count > 0)
4669     print (vam->ofp, "classify table ids (%d) : ", count);
4670   for (i = 0; i < count; i++)
4671     {
4672       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4673       print (vam->ofp, (i < count - 1) ? "," : "");
4674     }
4675   vam->retval = ntohl (mp->retval);
4676   vam->result_ready = 1;
4677 }
4678
4679 static void
4680   vl_api_classify_table_ids_reply_t_handler_json
4681   (vl_api_classify_table_ids_reply_t * mp)
4682 {
4683   vat_main_t *vam = &vat_main;
4684   int i, count = ntohl (mp->count);
4685
4686   if (count > 0)
4687     {
4688       vat_json_node_t node;
4689
4690       vat_json_init_object (&node);
4691       for (i = 0; i < count; i++)
4692         {
4693           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4694         }
4695       vat_json_print (vam->ofp, &node);
4696       vat_json_free (&node);
4697     }
4698   vam->retval = ntohl (mp->retval);
4699   vam->result_ready = 1;
4700 }
4701
4702 static void
4703   vl_api_classify_table_by_interface_reply_t_handler
4704   (vl_api_classify_table_by_interface_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   u32 table_id;
4708
4709   table_id = ntohl (mp->l2_table_id);
4710   if (table_id != ~0)
4711     print (vam->ofp, "l2 table id : %d", table_id);
4712   else
4713     print (vam->ofp, "l2 table id : No input ACL tables configured");
4714   table_id = ntohl (mp->ip4_table_id);
4715   if (table_id != ~0)
4716     print (vam->ofp, "ip4 table id : %d", table_id);
4717   else
4718     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4719   table_id = ntohl (mp->ip6_table_id);
4720   if (table_id != ~0)
4721     print (vam->ofp, "ip6 table id : %d", table_id);
4722   else
4723     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4724   vam->retval = ntohl (mp->retval);
4725   vam->result_ready = 1;
4726 }
4727
4728 static void
4729   vl_api_classify_table_by_interface_reply_t_handler_json
4730   (vl_api_classify_table_by_interface_reply_t * mp)
4731 {
4732   vat_main_t *vam = &vat_main;
4733   vat_json_node_t node;
4734
4735   vat_json_init_object (&node);
4736
4737   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4738   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4739   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4740
4741   vat_json_print (vam->ofp, &node);
4742   vat_json_free (&node);
4743
4744   vam->retval = ntohl (mp->retval);
4745   vam->result_ready = 1;
4746 }
4747
4748 static void vl_api_policer_add_del_reply_t_handler
4749   (vl_api_policer_add_del_reply_t * mp)
4750 {
4751   vat_main_t *vam = &vat_main;
4752   i32 retval = ntohl (mp->retval);
4753   if (vam->async_mode)
4754     {
4755       vam->async_errors += (retval < 0);
4756     }
4757   else
4758     {
4759       vam->retval = retval;
4760       vam->result_ready = 1;
4761       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4762         /*
4763          * Note: this is just barely thread-safe, depends on
4764          * the main thread spinning waiting for an answer...
4765          */
4766         errmsg ("policer index %d", ntohl (mp->policer_index));
4767     }
4768 }
4769
4770 static void vl_api_policer_add_del_reply_t_handler_json
4771   (vl_api_policer_add_del_reply_t * mp)
4772 {
4773   vat_main_t *vam = &vat_main;
4774   vat_json_node_t node;
4775
4776   vat_json_init_object (&node);
4777   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4778   vat_json_object_add_uint (&node, "policer_index",
4779                             ntohl (mp->policer_index));
4780
4781   vat_json_print (vam->ofp, &node);
4782   vat_json_free (&node);
4783
4784   vam->retval = ntohl (mp->retval);
4785   vam->result_ready = 1;
4786 }
4787
4788 /* Format hex dump. */
4789 u8 *
4790 format_hex_bytes (u8 * s, va_list * va)
4791 {
4792   u8 *bytes = va_arg (*va, u8 *);
4793   int n_bytes = va_arg (*va, int);
4794   uword i;
4795
4796   /* Print short or long form depending on byte count. */
4797   uword short_form = n_bytes <= 32;
4798   u32 indent = format_get_indent (s);
4799
4800   if (n_bytes == 0)
4801     return s;
4802
4803   for (i = 0; i < n_bytes; i++)
4804     {
4805       if (!short_form && (i % 32) == 0)
4806         s = format (s, "%08x: ", i);
4807       s = format (s, "%02x", bytes[i]);
4808       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4809         s = format (s, "\n%U", format_white_space, indent);
4810     }
4811
4812   return s;
4813 }
4814
4815 static void
4816 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4817                                             * mp)
4818 {
4819   vat_main_t *vam = &vat_main;
4820   i32 retval = ntohl (mp->retval);
4821   if (retval == 0)
4822     {
4823       print (vam->ofp, "classify table info :");
4824       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4825              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4826              ntohl (mp->miss_next_index));
4827       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4828              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4829              ntohl (mp->match_n_vectors));
4830       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4831              ntohl (mp->mask_length));
4832     }
4833   vam->retval = retval;
4834   vam->result_ready = 1;
4835 }
4836
4837 static void
4838   vl_api_classify_table_info_reply_t_handler_json
4839   (vl_api_classify_table_info_reply_t * mp)
4840 {
4841   vat_main_t *vam = &vat_main;
4842   vat_json_node_t node;
4843
4844   i32 retval = ntohl (mp->retval);
4845   if (retval == 0)
4846     {
4847       vat_json_init_object (&node);
4848
4849       vat_json_object_add_int (&node, "sessions",
4850                                ntohl (mp->active_sessions));
4851       vat_json_object_add_int (&node, "nexttbl",
4852                                ntohl (mp->next_table_index));
4853       vat_json_object_add_int (&node, "nextnode",
4854                                ntohl (mp->miss_next_index));
4855       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4856       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4857       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4858       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4859                       ntohl (mp->mask_length), 0);
4860       vat_json_object_add_string_copy (&node, "mask", s);
4861
4862       vat_json_print (vam->ofp, &node);
4863       vat_json_free (&node);
4864     }
4865   vam->retval = ntohl (mp->retval);
4866   vam->result_ready = 1;
4867 }
4868
4869 static void
4870 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4871                                            mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874
4875   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4876          ntohl (mp->hit_next_index), ntohl (mp->advance),
4877          ntohl (mp->opaque_index));
4878   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4879          ntohl (mp->match_length));
4880 }
4881
4882 static void
4883   vl_api_classify_session_details_t_handler_json
4884   (vl_api_classify_session_details_t * mp)
4885 {
4886   vat_main_t *vam = &vat_main;
4887   vat_json_node_t *node = NULL;
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4898   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4899   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4900   u8 *s =
4901     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4902             0);
4903   vat_json_object_add_string_copy (node, "match", s);
4904 }
4905
4906 static void vl_api_pg_create_interface_reply_t_handler
4907   (vl_api_pg_create_interface_reply_t * mp)
4908 {
4909   vat_main_t *vam = &vat_main;
4910
4911   vam->retval = ntohl (mp->retval);
4912   vam->result_ready = 1;
4913 }
4914
4915 static void vl_api_pg_create_interface_reply_t_handler_json
4916   (vl_api_pg_create_interface_reply_t * mp)
4917 {
4918   vat_main_t *vam = &vat_main;
4919   vat_json_node_t node;
4920
4921   i32 retval = ntohl (mp->retval);
4922   if (retval == 0)
4923     {
4924       vat_json_init_object (&node);
4925
4926       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4927
4928       vat_json_print (vam->ofp, &node);
4929       vat_json_free (&node);
4930     }
4931   vam->retval = ntohl (mp->retval);
4932   vam->result_ready = 1;
4933 }
4934
4935 static void vl_api_policer_classify_details_t_handler
4936   (vl_api_policer_classify_details_t * mp)
4937 {
4938   vat_main_t *vam = &vat_main;
4939
4940   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4941          ntohl (mp->table_index));
4942 }
4943
4944 static void vl_api_policer_classify_details_t_handler_json
4945   (vl_api_policer_classify_details_t * mp)
4946 {
4947   vat_main_t *vam = &vat_main;
4948   vat_json_node_t *node;
4949
4950   if (VAT_JSON_ARRAY != vam->json_tree.type)
4951     {
4952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4953       vat_json_init_array (&vam->json_tree);
4954     }
4955   node = vat_json_array_add (&vam->json_tree);
4956
4957   vat_json_init_object (node);
4958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4959   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4960 }
4961
4962 static void vl_api_flow_classify_details_t_handler
4963   (vl_api_flow_classify_details_t * mp)
4964 {
4965   vat_main_t *vam = &vat_main;
4966
4967   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4968          ntohl (mp->table_index));
4969 }
4970
4971 static void vl_api_flow_classify_details_t_handler_json
4972   (vl_api_flow_classify_details_t * mp)
4973 {
4974   vat_main_t *vam = &vat_main;
4975   vat_json_node_t *node;
4976
4977   if (VAT_JSON_ARRAY != vam->json_tree.type)
4978     {
4979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4980       vat_json_init_array (&vam->json_tree);
4981     }
4982   node = vat_json_array_add (&vam->json_tree);
4983
4984   vat_json_init_object (node);
4985   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4986   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4987 }
4988
4989 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4990 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4991 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4992 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4993 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4994 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4995 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
4996 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
4997 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
4999
5000 /*
5001  * Generate boilerplate reply handlers, which
5002  * dig the return value out of the xxx_reply_t API message,
5003  * stick it into vam->retval, and set vam->result_ready
5004  *
5005  * Could also do this by pointing N message decode slots at
5006  * a single function, but that could break in subtle ways.
5007  */
5008
5009 #define foreach_standard_reply_retval_handler           \
5010 _(sw_interface_set_flags_reply)                         \
5011 _(sw_interface_add_del_address_reply)                   \
5012 _(sw_interface_set_rx_mode_reply)                       \
5013 _(sw_interface_set_rx_placement_reply)                  \
5014 _(sw_interface_set_table_reply)                         \
5015 _(sw_interface_set_mpls_enable_reply)                   \
5016 _(sw_interface_set_vpath_reply)                         \
5017 _(sw_interface_set_vxlan_bypass_reply)                  \
5018 _(sw_interface_set_geneve_bypass_reply)                 \
5019 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5020 _(sw_interface_set_l2_bridge_reply)                     \
5021 _(sw_interface_set_bond_weight_reply)                   \
5022 _(bridge_domain_add_del_reply)                          \
5023 _(sw_interface_set_l2_xconnect_reply)                   \
5024 _(l2fib_add_del_reply)                                  \
5025 _(l2fib_flush_int_reply)                                \
5026 _(l2fib_flush_bd_reply)                                 \
5027 _(ip_route_add_del_reply)                               \
5028 _(ip_table_add_del_reply)                               \
5029 _(ip_table_replace_begin_reply)                         \
5030 _(ip_table_flush_reply)                                 \
5031 _(ip_table_replace_end_reply)                           \
5032 _(ip_mroute_add_del_reply)                              \
5033 _(mpls_route_add_del_reply)                             \
5034 _(mpls_table_add_del_reply)                             \
5035 _(mpls_ip_bind_unbind_reply)                            \
5036 _(bier_route_add_del_reply)                             \
5037 _(bier_table_add_del_reply)                             \
5038 _(sw_interface_set_unnumbered_reply)                    \
5039 _(set_ip_flow_hash_reply)                               \
5040 _(sw_interface_ip6_enable_disable_reply)                \
5041 _(l2_patch_add_del_reply)                               \
5042 _(sr_mpls_policy_add_reply)                             \
5043 _(sr_mpls_policy_mod_reply)                             \
5044 _(sr_mpls_policy_del_reply)                             \
5045 _(sr_policy_add_reply)                                  \
5046 _(sr_policy_mod_reply)                                  \
5047 _(sr_policy_del_reply)                                  \
5048 _(sr_localsid_add_del_reply)                            \
5049 _(sr_steering_add_del_reply)                            \
5050 _(classify_add_del_session_reply)                       \
5051 _(classify_set_interface_ip_table_reply)                \
5052 _(classify_set_interface_l2_tables_reply)               \
5053 _(l2tpv3_set_tunnel_cookies_reply)                      \
5054 _(l2tpv3_interface_enable_disable_reply)                \
5055 _(l2tpv3_set_lookup_key_reply)                          \
5056 _(l2_fib_clear_table_reply)                             \
5057 _(l2_interface_efp_filter_reply)                        \
5058 _(l2_interface_vlan_tag_rewrite_reply)                  \
5059 _(modify_vhost_user_if_reply)                           \
5060 _(delete_vhost_user_if_reply)                           \
5061 _(want_l2_macs_events_reply)                            \
5062 _(input_acl_set_interface_reply)                        \
5063 _(ipsec_spd_add_del_reply)                              \
5064 _(ipsec_interface_add_del_spd_reply)                    \
5065 _(ipsec_spd_entry_add_del_reply)                        \
5066 _(ipsec_sad_entry_add_del_reply)                        \
5067 _(ipsec_tunnel_if_add_del_reply)                        \
5068 _(ipsec_tunnel_if_set_sa_reply)                         \
5069 _(delete_loopback_reply)                                \
5070 _(bd_ip_mac_add_del_reply)                              \
5071 _(bd_ip_mac_flush_reply)                                \
5072 _(want_interface_events_reply)                          \
5073 _(cop_interface_enable_disable_reply)                   \
5074 _(cop_whitelist_enable_disable_reply)                   \
5075 _(sw_interface_clear_stats_reply)                       \
5076 _(ioam_enable_reply)                                    \
5077 _(ioam_disable_reply)                                   \
5078 _(one_add_del_locator_reply)                            \
5079 _(one_add_del_local_eid_reply)                          \
5080 _(one_add_del_remote_mapping_reply)                     \
5081 _(one_add_del_adjacency_reply)                          \
5082 _(one_add_del_map_resolver_reply)                       \
5083 _(one_add_del_map_server_reply)                         \
5084 _(one_enable_disable_reply)                             \
5085 _(one_rloc_probe_enable_disable_reply)                  \
5086 _(one_map_register_enable_disable_reply)                \
5087 _(one_map_register_set_ttl_reply)                       \
5088 _(one_set_transport_protocol_reply)                     \
5089 _(one_map_register_fallback_threshold_reply)            \
5090 _(one_pitr_set_locator_set_reply)                       \
5091 _(one_map_request_mode_reply)                           \
5092 _(one_add_del_map_request_itr_rlocs_reply)              \
5093 _(one_eid_table_add_del_map_reply)                      \
5094 _(one_use_petr_reply)                                   \
5095 _(one_stats_enable_disable_reply)                       \
5096 _(one_add_del_l2_arp_entry_reply)                       \
5097 _(one_add_del_ndp_entry_reply)                          \
5098 _(one_stats_flush_reply)                                \
5099 _(one_enable_disable_xtr_mode_reply)                    \
5100 _(one_enable_disable_pitr_mode_reply)                   \
5101 _(one_enable_disable_petr_mode_reply)                   \
5102 _(gpe_enable_disable_reply)                             \
5103 _(gpe_set_encap_mode_reply)                             \
5104 _(gpe_add_del_iface_reply)                              \
5105 _(gpe_add_del_native_fwd_rpath_reply)                   \
5106 _(af_packet_delete_reply)                               \
5107 _(policer_classify_set_interface_reply)                 \
5108 _(set_ipfix_exporter_reply)                             \
5109 _(set_ipfix_classify_stream_reply)                      \
5110 _(ipfix_classify_table_add_del_reply)                   \
5111 _(flow_classify_set_interface_reply)                    \
5112 _(sw_interface_span_enable_disable_reply)               \
5113 _(pg_capture_reply)                                     \
5114 _(pg_enable_disable_reply)                              \
5115 _(ip_source_and_port_range_check_add_del_reply)         \
5116 _(ip_source_and_port_range_check_interface_add_del_reply)\
5117 _(delete_subif_reply)                                   \
5118 _(l2_interface_pbb_tag_rewrite_reply)                   \
5119 _(set_punt_reply)                                       \
5120 _(feature_enable_disable_reply)                         \
5121 _(feature_gso_enable_disable_reply)                     \
5122 _(sw_interface_tag_add_del_reply)                       \
5123 _(sw_interface_add_del_mac_address_reply)               \
5124 _(hw_interface_set_mtu_reply)                           \
5125 _(p2p_ethernet_add_reply)                               \
5126 _(p2p_ethernet_del_reply)                               \
5127 _(lldp_config_reply)                                    \
5128 _(sw_interface_set_lldp_reply)                          \
5129 _(tcp_configure_src_addresses_reply)                    \
5130 _(session_rule_add_del_reply)                           \
5131 _(ip_container_proxy_add_del_reply)                     \
5132 _(output_acl_set_interface_reply)                       \
5133 _(qos_record_enable_disable_reply)
5134
5135 #define _(n)                                    \
5136     static void vl_api_##n##_t_handler          \
5137     (vl_api_##n##_t * mp)                       \
5138     {                                           \
5139         vat_main_t * vam = &vat_main;           \
5140         i32 retval = ntohl(mp->retval);         \
5141         if (vam->async_mode) {                  \
5142             vam->async_errors += (retval < 0);  \
5143         } else {                                \
5144             vam->retval = retval;               \
5145             vam->result_ready = 1;              \
5146         }                                       \
5147     }
5148 foreach_standard_reply_retval_handler;
5149 #undef _
5150
5151 #define _(n)                                    \
5152     static void vl_api_##n##_t_handler_json     \
5153     (vl_api_##n##_t * mp)                       \
5154     {                                           \
5155         vat_main_t * vam = &vat_main;           \
5156         vat_json_node_t node;                   \
5157         vat_json_init_object(&node);            \
5158         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5159         vat_json_print(vam->ofp, &node);        \
5160         vam->retval = ntohl(mp->retval);        \
5161         vam->result_ready = 1;                  \
5162     }
5163 foreach_standard_reply_retval_handler;
5164 #undef _
5165
5166 /*
5167  * Table of message reply handlers, must include boilerplate handlers
5168  * we just generated
5169  */
5170
5171 #define foreach_vpe_api_reply_msg                                       \
5172 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5173 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5174 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5175 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5176 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5177 _(CLI_REPLY, cli_reply)                                                 \
5178 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5179 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5180   sw_interface_add_del_address_reply)                                   \
5181 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5182 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5183 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5184 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5185 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5186 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5187 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5188 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5189 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5190 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5191   sw_interface_set_l2_xconnect_reply)                                   \
5192 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5193   sw_interface_set_l2_bridge_reply)                                     \
5194 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5195 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5196 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5197 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5198 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5199 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5200 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5201 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5202 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5203 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5204 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5205 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5206 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5207 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5208 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5209 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5210 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5211 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5212 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5213 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5214 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5215 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5216 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5217 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5218 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5219 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5220 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5221 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5222 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5223 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5224 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5225 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5226 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5227 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5228   sw_interface_set_unnumbered_reply)                                    \
5229 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5230 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5231 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5232 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5233   sw_interface_ip6_enable_disable_reply)                                \
5234 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5235 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5236 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5237 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5238 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5239 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5240 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5241 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5242 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5243 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5244 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5245 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5246 classify_set_interface_ip_table_reply)                                  \
5247 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5248   classify_set_interface_l2_tables_reply)                               \
5249 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5250 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5251 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5252 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5253 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5254   l2tpv3_interface_enable_disable_reply)                                \
5255 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5256 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5257 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5258 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5259 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5260 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5261 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5262 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5263 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5264 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5265 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5266 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5267 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5268 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5269 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5270 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5271 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5272 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5273 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5274 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5275 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5276 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5277 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5278 _(L2_MACS_EVENT, l2_macs_event)                                         \
5279 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5280 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5281 _(IP_DETAILS, ip_details)                                               \
5282 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5283 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5284 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5285 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5286 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5287 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5288 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5289 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5290 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5291 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5292 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5293 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5294 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5295 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5296 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5297 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5298 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5299 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5300 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5301 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5302 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5303 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5304 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5305 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5306 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5307 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5308 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5309 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5310   one_map_register_enable_disable_reply)                                \
5311 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5312 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5313 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5314 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5315   one_map_register_fallback_threshold_reply)                            \
5316 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5317   one_rloc_probe_enable_disable_reply)                                  \
5318 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5319 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5320 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5321 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5322 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5323 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5324 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5325 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5326 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5327 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5328 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5329 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5330 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5331 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5332 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5333 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5334   show_one_stats_enable_disable_reply)                                  \
5335 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5336 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5337 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5338 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5339 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5340 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5341 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5342 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5343   one_enable_disable_pitr_mode_reply)                                   \
5344 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5345   one_enable_disable_petr_mode_reply)                                   \
5346 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5347 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5348 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5349 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5350 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5351 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5352 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5353 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5354 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5355 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5356 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5357 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5358   gpe_add_del_native_fwd_rpath_reply)                                   \
5359 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5360   gpe_fwd_entry_path_details)                                           \
5361 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5362 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5363   one_add_del_map_request_itr_rlocs_reply)                              \
5364 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5365   one_get_map_request_itr_rlocs_reply)                                  \
5366 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5367 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5368 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5369 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5370 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5371 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5372   show_one_map_register_state_reply)                                    \
5373 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5374 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5375   show_one_map_register_fallback_threshold_reply)                       \
5376 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5377 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5378 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5379 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5380 _(POLICER_DETAILS, policer_details)                                     \
5381 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5382 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5383 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5384 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5385 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5386 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5387 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5388 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5389 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5390 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5391 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5392 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5393 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5394 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5395 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5396 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5397 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5398 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5399 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5400 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5401 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5402 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5403 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5404 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5405  ip_source_and_port_range_check_add_del_reply)                          \
5406 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5407  ip_source_and_port_range_check_interface_add_del_reply)                \
5408 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5409 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5410 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5411 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5412 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5413 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5414 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5415 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5416 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5417 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5418 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5419 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5420 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5421 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5422 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5423 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5424 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5425 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5426 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5427 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5428 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5429 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5430 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5431
5432 #define foreach_standalone_reply_msg                                    \
5433 _(SW_INTERFACE_EVENT, sw_interface_event)
5434
5435 typedef struct
5436 {
5437   u8 *name;
5438   u32 value;
5439 } name_sort_t;
5440
5441 #define STR_VTR_OP_CASE(op)     \
5442     case L2_VTR_ ## op:         \
5443         return "" # op;
5444
5445 static const char *
5446 str_vtr_op (u32 vtr_op)
5447 {
5448   switch (vtr_op)
5449     {
5450       STR_VTR_OP_CASE (DISABLED);
5451       STR_VTR_OP_CASE (PUSH_1);
5452       STR_VTR_OP_CASE (PUSH_2);
5453       STR_VTR_OP_CASE (POP_1);
5454       STR_VTR_OP_CASE (POP_2);
5455       STR_VTR_OP_CASE (TRANSLATE_1_1);
5456       STR_VTR_OP_CASE (TRANSLATE_1_2);
5457       STR_VTR_OP_CASE (TRANSLATE_2_1);
5458       STR_VTR_OP_CASE (TRANSLATE_2_2);
5459     }
5460
5461   return "UNKNOWN";
5462 }
5463
5464 static int
5465 dump_sub_interface_table (vat_main_t * vam)
5466 {
5467   const sw_interface_subif_t *sub = NULL;
5468
5469   if (vam->json_output)
5470     {
5471       clib_warning
5472         ("JSON output supported only for VPE API calls and dump_stats_table");
5473       return -99;
5474     }
5475
5476   print (vam->ofp,
5477          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5478          "Interface", "sw_if_index",
5479          "sub id", "dot1ad", "tags", "outer id",
5480          "inner id", "exact", "default", "outer any", "inner any");
5481
5482   vec_foreach (sub, vam->sw_if_subif_table)
5483   {
5484     print (vam->ofp,
5485            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5486            sub->interface_name,
5487            sub->sw_if_index,
5488            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5489            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5490            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5491            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5492     if (sub->vtr_op != L2_VTR_DISABLED)
5493       {
5494         print (vam->ofp,
5495                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5496                "tag1: %d tag2: %d ]",
5497                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5498                sub->vtr_tag1, sub->vtr_tag2);
5499       }
5500   }
5501
5502   return 0;
5503 }
5504
5505 static int
5506 name_sort_cmp (void *a1, void *a2)
5507 {
5508   name_sort_t *n1 = a1;
5509   name_sort_t *n2 = a2;
5510
5511   return strcmp ((char *) n1->name, (char *) n2->name);
5512 }
5513
5514 static int
5515 dump_interface_table (vat_main_t * vam)
5516 {
5517   hash_pair_t *p;
5518   name_sort_t *nses = 0, *ns;
5519
5520   if (vam->json_output)
5521     {
5522       clib_warning
5523         ("JSON output supported only for VPE API calls and dump_stats_table");
5524       return -99;
5525     }
5526
5527   /* *INDENT-OFF* */
5528   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5529   ({
5530     vec_add2 (nses, ns, 1);
5531     ns->name = (u8 *)(p->key);
5532     ns->value = (u32) p->value[0];
5533   }));
5534   /* *INDENT-ON* */
5535
5536   vec_sort_with_function (nses, name_sort_cmp);
5537
5538   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5539   vec_foreach (ns, nses)
5540   {
5541     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5542   }
5543   vec_free (nses);
5544   return 0;
5545 }
5546
5547 static int
5548 dump_ip_table (vat_main_t * vam, int is_ipv6)
5549 {
5550   const ip_details_t *det = NULL;
5551   const ip_address_details_t *address = NULL;
5552   u32 i = ~0;
5553
5554   print (vam->ofp, "%-12s", "sw_if_index");
5555
5556   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5557   {
5558     i++;
5559     if (!det->present)
5560       {
5561         continue;
5562       }
5563     print (vam->ofp, "%-12d", i);
5564     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5565     if (!det->addr)
5566       {
5567         continue;
5568       }
5569     vec_foreach (address, det->addr)
5570     {
5571       print (vam->ofp,
5572              "            %-30U%-13d",
5573              is_ipv6 ? format_ip6_address : format_ip4_address,
5574              address->ip, address->prefix_length);
5575     }
5576   }
5577
5578   return 0;
5579 }
5580
5581 static int
5582 dump_ipv4_table (vat_main_t * vam)
5583 {
5584   if (vam->json_output)
5585     {
5586       clib_warning
5587         ("JSON output supported only for VPE API calls and dump_stats_table");
5588       return -99;
5589     }
5590
5591   return dump_ip_table (vam, 0);
5592 }
5593
5594 static int
5595 dump_ipv6_table (vat_main_t * vam)
5596 {
5597   if (vam->json_output)
5598     {
5599       clib_warning
5600         ("JSON output supported only for VPE API calls and dump_stats_table");
5601       return -99;
5602     }
5603
5604   return dump_ip_table (vam, 1);
5605 }
5606
5607 /*
5608  * Pass CLI buffers directly in the CLI_INBAND API message,
5609  * instead of an additional shared memory area.
5610  */
5611 static int
5612 exec_inband (vat_main_t * vam)
5613 {
5614   vl_api_cli_inband_t *mp;
5615   unformat_input_t *i = vam->input;
5616   int ret;
5617
5618   if (vec_len (i->buffer) == 0)
5619     return -1;
5620
5621   if (vam->exec_mode == 0 && unformat (i, "mode"))
5622     {
5623       vam->exec_mode = 1;
5624       return 0;
5625     }
5626   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5627     {
5628       vam->exec_mode = 0;
5629       return 0;
5630     }
5631
5632   /*
5633    * In order for the CLI command to work, it
5634    * must be a vector ending in \n, not a C-string ending
5635    * in \n\0.
5636    */
5637   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5638   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5639
5640   S (mp);
5641   W (ret);
5642   /* json responses may or may not include a useful reply... */
5643   if (vec_len (vam->cmd_reply))
5644     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5645   return ret;
5646 }
5647
5648 int
5649 exec (vat_main_t * vam)
5650 {
5651   return exec_inband (vam);
5652 }
5653
5654 static int
5655 api_create_loopback (vat_main_t * vam)
5656 {
5657   unformat_input_t *i = vam->input;
5658   vl_api_create_loopback_t *mp;
5659   vl_api_create_loopback_instance_t *mp_lbi;
5660   u8 mac_address[6];
5661   u8 mac_set = 0;
5662   u8 is_specified = 0;
5663   u32 user_instance = 0;
5664   int ret;
5665
5666   clib_memset (mac_address, 0, sizeof (mac_address));
5667
5668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5669     {
5670       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5671         mac_set = 1;
5672       if (unformat (i, "instance %d", &user_instance))
5673         is_specified = 1;
5674       else
5675         break;
5676     }
5677
5678   if (is_specified)
5679     {
5680       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5681       mp_lbi->is_specified = is_specified;
5682       if (is_specified)
5683         mp_lbi->user_instance = htonl (user_instance);
5684       if (mac_set)
5685         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5686       S (mp_lbi);
5687     }
5688   else
5689     {
5690       /* Construct the API message */
5691       M (CREATE_LOOPBACK, mp);
5692       if (mac_set)
5693         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5694       S (mp);
5695     }
5696
5697   W (ret);
5698   return ret;
5699 }
5700
5701 static int
5702 api_delete_loopback (vat_main_t * vam)
5703 {
5704   unformat_input_t *i = vam->input;
5705   vl_api_delete_loopback_t *mp;
5706   u32 sw_if_index = ~0;
5707   int ret;
5708
5709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710     {
5711       if (unformat (i, "sw_if_index %d", &sw_if_index))
5712         ;
5713       else
5714         break;
5715     }
5716
5717   if (sw_if_index == ~0)
5718     {
5719       errmsg ("missing sw_if_index");
5720       return -99;
5721     }
5722
5723   /* Construct the API message */
5724   M (DELETE_LOOPBACK, mp);
5725   mp->sw_if_index = ntohl (sw_if_index);
5726
5727   S (mp);
5728   W (ret);
5729   return ret;
5730 }
5731
5732 static int
5733 api_want_interface_events (vat_main_t * vam)
5734 {
5735   unformat_input_t *i = vam->input;
5736   vl_api_want_interface_events_t *mp;
5737   int enable = -1;
5738   int ret;
5739
5740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5741     {
5742       if (unformat (i, "enable"))
5743         enable = 1;
5744       else if (unformat (i, "disable"))
5745         enable = 0;
5746       else
5747         break;
5748     }
5749
5750   if (enable == -1)
5751     {
5752       errmsg ("missing enable|disable");
5753       return -99;
5754     }
5755
5756   M (WANT_INTERFACE_EVENTS, mp);
5757   mp->enable_disable = enable;
5758
5759   vam->interface_event_display = enable;
5760
5761   S (mp);
5762   W (ret);
5763   return ret;
5764 }
5765
5766
5767 /* Note: non-static, called once to set up the initial intfc table */
5768 int
5769 api_sw_interface_dump (vat_main_t * vam)
5770 {
5771   vl_api_sw_interface_dump_t *mp;
5772   vl_api_control_ping_t *mp_ping;
5773   hash_pair_t *p;
5774   name_sort_t *nses = 0, *ns;
5775   sw_interface_subif_t *sub = NULL;
5776   int ret;
5777
5778   /* Toss the old name table */
5779   /* *INDENT-OFF* */
5780   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5781   ({
5782     vec_add2 (nses, ns, 1);
5783     ns->name = (u8 *)(p->key);
5784     ns->value = (u32) p->value[0];
5785   }));
5786   /* *INDENT-ON* */
5787
5788   hash_free (vam->sw_if_index_by_interface_name);
5789
5790   vec_foreach (ns, nses) vec_free (ns->name);
5791
5792   vec_free (nses);
5793
5794   vec_foreach (sub, vam->sw_if_subif_table)
5795   {
5796     vec_free (sub->interface_name);
5797   }
5798   vec_free (vam->sw_if_subif_table);
5799
5800   /* recreate the interface name hash table */
5801   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5802
5803   /*
5804    * Ask for all interface names. Otherwise, the epic catalog of
5805    * name filters becomes ridiculously long, and vat ends up needing
5806    * to be taught about new interface types.
5807    */
5808   M (SW_INTERFACE_DUMP, mp);
5809   S (mp);
5810
5811   /* Use a control ping for synchronization */
5812   MPING (CONTROL_PING, mp_ping);
5813   S (mp_ping);
5814
5815   W (ret);
5816   return ret;
5817 }
5818
5819 static int
5820 api_sw_interface_set_flags (vat_main_t * vam)
5821 {
5822   unformat_input_t *i = vam->input;
5823   vl_api_sw_interface_set_flags_t *mp;
5824   u32 sw_if_index;
5825   u8 sw_if_index_set = 0;
5826   u8 admin_up = 0;
5827   int ret;
5828
5829   /* Parse args required to build the message */
5830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5831     {
5832       if (unformat (i, "admin-up"))
5833         admin_up = 1;
5834       else if (unformat (i, "admin-down"))
5835         admin_up = 0;
5836       else
5837         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5838         sw_if_index_set = 1;
5839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5840         sw_if_index_set = 1;
5841       else
5842         break;
5843     }
5844
5845   if (sw_if_index_set == 0)
5846     {
5847       errmsg ("missing interface name or sw_if_index");
5848       return -99;
5849     }
5850
5851   /* Construct the API message */
5852   M (SW_INTERFACE_SET_FLAGS, mp);
5853   mp->sw_if_index = ntohl (sw_if_index);
5854   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5855
5856   /* send it... */
5857   S (mp);
5858
5859   /* Wait for a reply, return the good/bad news... */
5860   W (ret);
5861   return ret;
5862 }
5863
5864 static int
5865 api_sw_interface_set_rx_mode (vat_main_t * vam)
5866 {
5867   unformat_input_t *i = vam->input;
5868   vl_api_sw_interface_set_rx_mode_t *mp;
5869   u32 sw_if_index;
5870   u8 sw_if_index_set = 0;
5871   int ret;
5872   u8 queue_id_valid = 0;
5873   u32 queue_id;
5874   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5875
5876   /* Parse args required to build the message */
5877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5878     {
5879       if (unformat (i, "queue %d", &queue_id))
5880         queue_id_valid = 1;
5881       else if (unformat (i, "polling"))
5882         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5883       else if (unformat (i, "interrupt"))
5884         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5885       else if (unformat (i, "adaptive"))
5886         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5887       else
5888         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5889         sw_if_index_set = 1;
5890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5891         sw_if_index_set = 1;
5892       else
5893         break;
5894     }
5895
5896   if (sw_if_index_set == 0)
5897     {
5898       errmsg ("missing interface name or sw_if_index");
5899       return -99;
5900     }
5901   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5902     {
5903       errmsg ("missing rx-mode");
5904       return -99;
5905     }
5906
5907   /* Construct the API message */
5908   M (SW_INTERFACE_SET_RX_MODE, mp);
5909   mp->sw_if_index = ntohl (sw_if_index);
5910   mp->mode = (vl_api_rx_mode_t) mode;
5911   mp->queue_id_valid = queue_id_valid;
5912   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5913
5914   /* send it... */
5915   S (mp);
5916
5917   /* Wait for a reply, return the good/bad news... */
5918   W (ret);
5919   return ret;
5920 }
5921
5922 static int
5923 api_sw_interface_set_rx_placement (vat_main_t * vam)
5924 {
5925   unformat_input_t *i = vam->input;
5926   vl_api_sw_interface_set_rx_placement_t *mp;
5927   u32 sw_if_index;
5928   u8 sw_if_index_set = 0;
5929   int ret;
5930   u8 is_main = 0;
5931   u32 queue_id, thread_index;
5932
5933   /* Parse args required to build the message */
5934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5935     {
5936       if (unformat (i, "queue %d", &queue_id))
5937         ;
5938       else if (unformat (i, "main"))
5939         is_main = 1;
5940       else if (unformat (i, "worker %d", &thread_index))
5941         ;
5942       else
5943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5944         sw_if_index_set = 1;
5945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5946         sw_if_index_set = 1;
5947       else
5948         break;
5949     }
5950
5951   if (sw_if_index_set == 0)
5952     {
5953       errmsg ("missing interface name or sw_if_index");
5954       return -99;
5955     }
5956
5957   if (is_main)
5958     thread_index = 0;
5959   /* Construct the API message */
5960   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5961   mp->sw_if_index = ntohl (sw_if_index);
5962   mp->worker_id = ntohl (thread_index);
5963   mp->queue_id = ntohl (queue_id);
5964   mp->is_main = is_main;
5965
5966   /* send it... */
5967   S (mp);
5968   /* Wait for a reply, return the good/bad news... */
5969   W (ret);
5970   return ret;
5971 }
5972
5973 static void vl_api_sw_interface_rx_placement_details_t_handler
5974   (vl_api_sw_interface_rx_placement_details_t * mp)
5975 {
5976   vat_main_t *vam = &vat_main;
5977   u32 worker_id = ntohl (mp->worker_id);
5978
5979   print (vam->ofp,
5980          "\n%-11d %-11s %-6d %-5d %-9s",
5981          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5982          worker_id, ntohl (mp->queue_id),
5983          (mp->mode ==
5984           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5985 }
5986
5987 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5988   (vl_api_sw_interface_rx_placement_details_t * mp)
5989 {
5990   vat_main_t *vam = &vat_main;
5991   vat_json_node_t *node = NULL;
5992
5993   if (VAT_JSON_ARRAY != vam->json_tree.type)
5994     {
5995       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5996       vat_json_init_array (&vam->json_tree);
5997     }
5998   node = vat_json_array_add (&vam->json_tree);
5999
6000   vat_json_init_object (node);
6001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6002   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6003   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6004   vat_json_object_add_uint (node, "mode", mp->mode);
6005 }
6006
6007 static int
6008 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_sw_interface_rx_placement_dump_t *mp;
6012   vl_api_control_ping_t *mp_ping;
6013   int ret;
6014   u32 sw_if_index;
6015   u8 sw_if_index_set = 0;
6016
6017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6018     {
6019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6020         sw_if_index_set++;
6021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6022         sw_if_index_set++;
6023       else
6024         break;
6025     }
6026
6027   print (vam->ofp,
6028          "\n%-11s %-11s %-6s %-5s %-4s",
6029          "sw_if_index", "main/worker", "thread", "queue", "mode");
6030
6031   /* Dump Interface rx placement */
6032   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6033
6034   if (sw_if_index_set)
6035     mp->sw_if_index = htonl (sw_if_index);
6036   else
6037     mp->sw_if_index = ~0;
6038
6039   S (mp);
6040
6041   /* Use a control ping for synchronization */
6042   MPING (CONTROL_PING, mp_ping);
6043   S (mp_ping);
6044
6045   W (ret);
6046   return ret;
6047 }
6048
6049 static int
6050 api_sw_interface_clear_stats (vat_main_t * vam)
6051 {
6052   unformat_input_t *i = vam->input;
6053   vl_api_sw_interface_clear_stats_t *mp;
6054   u32 sw_if_index;
6055   u8 sw_if_index_set = 0;
6056   int ret;
6057
6058   /* Parse args required to build the message */
6059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6060     {
6061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6062         sw_if_index_set = 1;
6063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6064         sw_if_index_set = 1;
6065       else
6066         break;
6067     }
6068
6069   /* Construct the API message */
6070   M (SW_INTERFACE_CLEAR_STATS, mp);
6071
6072   if (sw_if_index_set == 1)
6073     mp->sw_if_index = ntohl (sw_if_index);
6074   else
6075     mp->sw_if_index = ~0;
6076
6077   /* send it... */
6078   S (mp);
6079
6080   /* Wait for a reply, return the good/bad news... */
6081   W (ret);
6082   return ret;
6083 }
6084
6085 static int
6086 api_sw_interface_add_del_address (vat_main_t * vam)
6087 {
6088   unformat_input_t *i = vam->input;
6089   vl_api_sw_interface_add_del_address_t *mp;
6090   u32 sw_if_index;
6091   u8 sw_if_index_set = 0;
6092   u8 is_add = 1, del_all = 0;
6093   u32 address_length = 0;
6094   u8 v4_address_set = 0;
6095   u8 v6_address_set = 0;
6096   ip4_address_t v4address;
6097   ip6_address_t v6address;
6098   int ret;
6099
6100   /* Parse args required to build the message */
6101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6102     {
6103       if (unformat (i, "del-all"))
6104         del_all = 1;
6105       else if (unformat (i, "del"))
6106         is_add = 0;
6107       else
6108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6109         sw_if_index_set = 1;
6110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6111         sw_if_index_set = 1;
6112       else if (unformat (i, "%U/%d",
6113                          unformat_ip4_address, &v4address, &address_length))
6114         v4_address_set = 1;
6115       else if (unformat (i, "%U/%d",
6116                          unformat_ip6_address, &v6address, &address_length))
6117         v6_address_set = 1;
6118       else
6119         break;
6120     }
6121
6122   if (sw_if_index_set == 0)
6123     {
6124       errmsg ("missing interface name or sw_if_index");
6125       return -99;
6126     }
6127   if (v4_address_set && v6_address_set)
6128     {
6129       errmsg ("both v4 and v6 addresses set");
6130       return -99;
6131     }
6132   if (!v4_address_set && !v6_address_set && !del_all)
6133     {
6134       errmsg ("no addresses set");
6135       return -99;
6136     }
6137
6138   /* Construct the API message */
6139   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6140
6141   mp->sw_if_index = ntohl (sw_if_index);
6142   mp->is_add = is_add;
6143   mp->del_all = del_all;
6144   if (v6_address_set)
6145     {
6146       mp->prefix.address.af = ADDRESS_IP6;
6147       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6148     }
6149   else
6150     {
6151       mp->prefix.address.af = ADDRESS_IP4;
6152       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6153     }
6154   mp->prefix.len = address_length;
6155
6156   /* send it... */
6157   S (mp);
6158
6159   /* Wait for a reply, return good/bad news  */
6160   W (ret);
6161   return ret;
6162 }
6163
6164 static int
6165 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6166 {
6167   unformat_input_t *i = vam->input;
6168   vl_api_sw_interface_set_mpls_enable_t *mp;
6169   u32 sw_if_index;
6170   u8 sw_if_index_set = 0;
6171   u8 enable = 1;
6172   int ret;
6173
6174   /* Parse args required to build the message */
6175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6176     {
6177       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6178         sw_if_index_set = 1;
6179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6180         sw_if_index_set = 1;
6181       else if (unformat (i, "disable"))
6182         enable = 0;
6183       else if (unformat (i, "dis"))
6184         enable = 0;
6185       else
6186         break;
6187     }
6188
6189   if (sw_if_index_set == 0)
6190     {
6191       errmsg ("missing interface name or sw_if_index");
6192       return -99;
6193     }
6194
6195   /* Construct the API message */
6196   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6197
6198   mp->sw_if_index = ntohl (sw_if_index);
6199   mp->enable = enable;
6200
6201   /* send it... */
6202   S (mp);
6203
6204   /* Wait for a reply... */
6205   W (ret);
6206   return ret;
6207 }
6208
6209 static int
6210 api_sw_interface_set_table (vat_main_t * vam)
6211 {
6212   unformat_input_t *i = vam->input;
6213   vl_api_sw_interface_set_table_t *mp;
6214   u32 sw_if_index, vrf_id = 0;
6215   u8 sw_if_index_set = 0;
6216   u8 is_ipv6 = 0;
6217   int ret;
6218
6219   /* Parse args required to build the message */
6220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6221     {
6222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6223         sw_if_index_set = 1;
6224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6225         sw_if_index_set = 1;
6226       else if (unformat (i, "vrf %d", &vrf_id))
6227         ;
6228       else if (unformat (i, "ipv6"))
6229         is_ipv6 = 1;
6230       else
6231         break;
6232     }
6233
6234   if (sw_if_index_set == 0)
6235     {
6236       errmsg ("missing interface name or sw_if_index");
6237       return -99;
6238     }
6239
6240   /* Construct the API message */
6241   M (SW_INTERFACE_SET_TABLE, mp);
6242
6243   mp->sw_if_index = ntohl (sw_if_index);
6244   mp->is_ipv6 = is_ipv6;
6245   mp->vrf_id = ntohl (vrf_id);
6246
6247   /* send it... */
6248   S (mp);
6249
6250   /* Wait for a reply... */
6251   W (ret);
6252   return ret;
6253 }
6254
6255 static void vl_api_sw_interface_get_table_reply_t_handler
6256   (vl_api_sw_interface_get_table_reply_t * mp)
6257 {
6258   vat_main_t *vam = &vat_main;
6259
6260   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6261
6262   vam->retval = ntohl (mp->retval);
6263   vam->result_ready = 1;
6264
6265 }
6266
6267 static void vl_api_sw_interface_get_table_reply_t_handler_json
6268   (vl_api_sw_interface_get_table_reply_t * mp)
6269 {
6270   vat_main_t *vam = &vat_main;
6271   vat_json_node_t node;
6272
6273   vat_json_init_object (&node);
6274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6275   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6276
6277   vat_json_print (vam->ofp, &node);
6278   vat_json_free (&node);
6279
6280   vam->retval = ntohl (mp->retval);
6281   vam->result_ready = 1;
6282 }
6283
6284 static int
6285 api_sw_interface_get_table (vat_main_t * vam)
6286 {
6287   unformat_input_t *i = vam->input;
6288   vl_api_sw_interface_get_table_t *mp;
6289   u32 sw_if_index;
6290   u8 sw_if_index_set = 0;
6291   u8 is_ipv6 = 0;
6292   int ret;
6293
6294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6295     {
6296       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6297         sw_if_index_set = 1;
6298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6299         sw_if_index_set = 1;
6300       else if (unformat (i, "ipv6"))
6301         is_ipv6 = 1;
6302       else
6303         break;
6304     }
6305
6306   if (sw_if_index_set == 0)
6307     {
6308       errmsg ("missing interface name or sw_if_index");
6309       return -99;
6310     }
6311
6312   M (SW_INTERFACE_GET_TABLE, mp);
6313   mp->sw_if_index = htonl (sw_if_index);
6314   mp->is_ipv6 = is_ipv6;
6315
6316   S (mp);
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_sw_interface_set_vpath (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_sw_interface_set_vpath_t *mp;
6326   u32 sw_if_index = 0;
6327   u8 sw_if_index_set = 0;
6328   u8 is_enable = 0;
6329   int ret;
6330
6331   /* Parse args required to build the message */
6332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6333     {
6334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6335         sw_if_index_set = 1;
6336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6337         sw_if_index_set = 1;
6338       else if (unformat (i, "enable"))
6339         is_enable = 1;
6340       else if (unformat (i, "disable"))
6341         is_enable = 0;
6342       else
6343         break;
6344     }
6345
6346   if (sw_if_index_set == 0)
6347     {
6348       errmsg ("missing interface name or sw_if_index");
6349       return -99;
6350     }
6351
6352   /* Construct the API message */
6353   M (SW_INTERFACE_SET_VPATH, mp);
6354
6355   mp->sw_if_index = ntohl (sw_if_index);
6356   mp->enable = is_enable;
6357
6358   /* send it... */
6359   S (mp);
6360
6361   /* Wait for a reply... */
6362   W (ret);
6363   return ret;
6364 }
6365
6366 static int
6367 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6368 {
6369   unformat_input_t *i = vam->input;
6370   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6371   u32 sw_if_index = 0;
6372   u8 sw_if_index_set = 0;
6373   u8 is_enable = 1;
6374   u8 is_ipv6 = 0;
6375   int ret;
6376
6377   /* Parse args required to build the message */
6378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6379     {
6380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6381         sw_if_index_set = 1;
6382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6383         sw_if_index_set = 1;
6384       else if (unformat (i, "enable"))
6385         is_enable = 1;
6386       else if (unformat (i, "disable"))
6387         is_enable = 0;
6388       else if (unformat (i, "ip4"))
6389         is_ipv6 = 0;
6390       else if (unformat (i, "ip6"))
6391         is_ipv6 = 1;
6392       else
6393         break;
6394     }
6395
6396   if (sw_if_index_set == 0)
6397     {
6398       errmsg ("missing interface name or sw_if_index");
6399       return -99;
6400     }
6401
6402   /* Construct the API message */
6403   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6404
6405   mp->sw_if_index = ntohl (sw_if_index);
6406   mp->enable = is_enable;
6407   mp->is_ipv6 = is_ipv6;
6408
6409   /* send it... */
6410   S (mp);
6411
6412   /* Wait for a reply... */
6413   W (ret);
6414   return ret;
6415 }
6416
6417 static int
6418 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6419 {
6420   unformat_input_t *i = vam->input;
6421   vl_api_sw_interface_set_geneve_bypass_t *mp;
6422   u32 sw_if_index = 0;
6423   u8 sw_if_index_set = 0;
6424   u8 is_enable = 1;
6425   u8 is_ipv6 = 0;
6426   int ret;
6427
6428   /* Parse args required to build the message */
6429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6430     {
6431       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6432         sw_if_index_set = 1;
6433       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6434         sw_if_index_set = 1;
6435       else if (unformat (i, "enable"))
6436         is_enable = 1;
6437       else if (unformat (i, "disable"))
6438         is_enable = 0;
6439       else if (unformat (i, "ip4"))
6440         is_ipv6 = 0;
6441       else if (unformat (i, "ip6"))
6442         is_ipv6 = 1;
6443       else
6444         break;
6445     }
6446
6447   if (sw_if_index_set == 0)
6448     {
6449       errmsg ("missing interface name or sw_if_index");
6450       return -99;
6451     }
6452
6453   /* Construct the API message */
6454   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6455
6456   mp->sw_if_index = ntohl (sw_if_index);
6457   mp->enable = is_enable;
6458   mp->is_ipv6 = is_ipv6;
6459
6460   /* send it... */
6461   S (mp);
6462
6463   /* Wait for a reply... */
6464   W (ret);
6465   return ret;
6466 }
6467
6468 static int
6469 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6470 {
6471   unformat_input_t *i = vam->input;
6472   vl_api_sw_interface_set_l2_xconnect_t *mp;
6473   u32 rx_sw_if_index;
6474   u8 rx_sw_if_index_set = 0;
6475   u32 tx_sw_if_index;
6476   u8 tx_sw_if_index_set = 0;
6477   u8 enable = 1;
6478   int ret;
6479
6480   /* Parse args required to build the message */
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6484         rx_sw_if_index_set = 1;
6485       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6486         tx_sw_if_index_set = 1;
6487       else if (unformat (i, "rx"))
6488         {
6489           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6490             {
6491               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6492                             &rx_sw_if_index))
6493                 rx_sw_if_index_set = 1;
6494             }
6495           else
6496             break;
6497         }
6498       else if (unformat (i, "tx"))
6499         {
6500           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6501             {
6502               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6503                             &tx_sw_if_index))
6504                 tx_sw_if_index_set = 1;
6505             }
6506           else
6507             break;
6508         }
6509       else if (unformat (i, "enable"))
6510         enable = 1;
6511       else if (unformat (i, "disable"))
6512         enable = 0;
6513       else
6514         break;
6515     }
6516
6517   if (rx_sw_if_index_set == 0)
6518     {
6519       errmsg ("missing rx interface name or rx_sw_if_index");
6520       return -99;
6521     }
6522
6523   if (enable && (tx_sw_if_index_set == 0))
6524     {
6525       errmsg ("missing tx interface name or tx_sw_if_index");
6526       return -99;
6527     }
6528
6529   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6530
6531   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6532   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6533   mp->enable = enable;
6534
6535   S (mp);
6536   W (ret);
6537   return ret;
6538 }
6539
6540 static int
6541 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6542 {
6543   unformat_input_t *i = vam->input;
6544   vl_api_sw_interface_set_l2_bridge_t *mp;
6545   vl_api_l2_port_type_t port_type;
6546   u32 rx_sw_if_index;
6547   u8 rx_sw_if_index_set = 0;
6548   u32 bd_id;
6549   u8 bd_id_set = 0;
6550   u32 shg = 0;
6551   u8 enable = 1;
6552   int ret;
6553
6554   port_type = L2_API_PORT_TYPE_NORMAL;
6555
6556   /* Parse args required to build the message */
6557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6558     {
6559       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6560         rx_sw_if_index_set = 1;
6561       else if (unformat (i, "bd_id %d", &bd_id))
6562         bd_id_set = 1;
6563       else
6564         if (unformat
6565             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6566         rx_sw_if_index_set = 1;
6567       else if (unformat (i, "shg %d", &shg))
6568         ;
6569       else if (unformat (i, "bvi"))
6570         port_type = L2_API_PORT_TYPE_BVI;
6571       else if (unformat (i, "uu-fwd"))
6572         port_type = L2_API_PORT_TYPE_UU_FWD;
6573       else if (unformat (i, "enable"))
6574         enable = 1;
6575       else if (unformat (i, "disable"))
6576         enable = 0;
6577       else
6578         break;
6579     }
6580
6581   if (rx_sw_if_index_set == 0)
6582     {
6583       errmsg ("missing rx interface name or sw_if_index");
6584       return -99;
6585     }
6586
6587   if (enable && (bd_id_set == 0))
6588     {
6589       errmsg ("missing bridge domain");
6590       return -99;
6591     }
6592
6593   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6594
6595   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6596   mp->bd_id = ntohl (bd_id);
6597   mp->shg = (u8) shg;
6598   mp->port_type = ntohl (port_type);
6599   mp->enable = enable;
6600
6601   S (mp);
6602   W (ret);
6603   return ret;
6604 }
6605
6606 static int
6607 api_bridge_domain_dump (vat_main_t * vam)
6608 {
6609   unformat_input_t *i = vam->input;
6610   vl_api_bridge_domain_dump_t *mp;
6611   vl_api_control_ping_t *mp_ping;
6612   u32 bd_id = ~0;
6613   int ret;
6614
6615   /* Parse args required to build the message */
6616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6617     {
6618       if (unformat (i, "bd_id %d", &bd_id))
6619         ;
6620       else
6621         break;
6622     }
6623
6624   M (BRIDGE_DOMAIN_DUMP, mp);
6625   mp->bd_id = ntohl (bd_id);
6626   S (mp);
6627
6628   /* Use a control ping for synchronization */
6629   MPING (CONTROL_PING, mp_ping);
6630   S (mp_ping);
6631
6632   W (ret);
6633   return ret;
6634 }
6635
6636 static int
6637 api_bridge_domain_add_del (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_bridge_domain_add_del_t *mp;
6641   u32 bd_id = ~0;
6642   u8 is_add = 1;
6643   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6644   u8 *bd_tag = NULL;
6645   u32 mac_age = 0;
6646   int ret;
6647
6648   /* Parse args required to build the message */
6649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6650     {
6651       if (unformat (i, "bd_id %d", &bd_id))
6652         ;
6653       else if (unformat (i, "flood %d", &flood))
6654         ;
6655       else if (unformat (i, "uu-flood %d", &uu_flood))
6656         ;
6657       else if (unformat (i, "forward %d", &forward))
6658         ;
6659       else if (unformat (i, "learn %d", &learn))
6660         ;
6661       else if (unformat (i, "arp-term %d", &arp_term))
6662         ;
6663       else if (unformat (i, "mac-age %d", &mac_age))
6664         ;
6665       else if (unformat (i, "bd-tag %s", &bd_tag))
6666         ;
6667       else if (unformat (i, "del"))
6668         {
6669           is_add = 0;
6670           flood = uu_flood = forward = learn = 0;
6671         }
6672       else
6673         break;
6674     }
6675
6676   if (bd_id == ~0)
6677     {
6678       errmsg ("missing bridge domain");
6679       ret = -99;
6680       goto done;
6681     }
6682
6683   if (mac_age > 255)
6684     {
6685       errmsg ("mac age must be less than 256 ");
6686       ret = -99;
6687       goto done;
6688     }
6689
6690   if ((bd_tag) && (vec_len (bd_tag) > 63))
6691     {
6692       errmsg ("bd-tag cannot be longer than 63");
6693       ret = -99;
6694       goto done;
6695     }
6696
6697   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6698
6699   mp->bd_id = ntohl (bd_id);
6700   mp->flood = flood;
6701   mp->uu_flood = uu_flood;
6702   mp->forward = forward;
6703   mp->learn = learn;
6704   mp->arp_term = arp_term;
6705   mp->is_add = is_add;
6706   mp->mac_age = (u8) mac_age;
6707   if (bd_tag)
6708     {
6709       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6710       mp->bd_tag[vec_len (bd_tag)] = 0;
6711     }
6712   S (mp);
6713   W (ret);
6714
6715 done:
6716   vec_free (bd_tag);
6717   return ret;
6718 }
6719
6720 static int
6721 api_l2fib_flush_bd (vat_main_t * vam)
6722 {
6723   unformat_input_t *i = vam->input;
6724   vl_api_l2fib_flush_bd_t *mp;
6725   u32 bd_id = ~0;
6726   int ret;
6727
6728   /* Parse args required to build the message */
6729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6730     {
6731       if (unformat (i, "bd_id %d", &bd_id));
6732       else
6733         break;
6734     }
6735
6736   if (bd_id == ~0)
6737     {
6738       errmsg ("missing bridge domain");
6739       return -99;
6740     }
6741
6742   M (L2FIB_FLUSH_BD, mp);
6743
6744   mp->bd_id = htonl (bd_id);
6745
6746   S (mp);
6747   W (ret);
6748   return ret;
6749 }
6750
6751 static int
6752 api_l2fib_flush_int (vat_main_t * vam)
6753 {
6754   unformat_input_t *i = vam->input;
6755   vl_api_l2fib_flush_int_t *mp;
6756   u32 sw_if_index = ~0;
6757   int ret;
6758
6759   /* Parse args required to build the message */
6760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6761     {
6762       if (unformat (i, "sw_if_index %d", &sw_if_index));
6763       else
6764         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6765       else
6766         break;
6767     }
6768
6769   if (sw_if_index == ~0)
6770     {
6771       errmsg ("missing interface name or sw_if_index");
6772       return -99;
6773     }
6774
6775   M (L2FIB_FLUSH_INT, mp);
6776
6777   mp->sw_if_index = ntohl (sw_if_index);
6778
6779   S (mp);
6780   W (ret);
6781   return ret;
6782 }
6783
6784 static int
6785 api_l2fib_add_del (vat_main_t * vam)
6786 {
6787   unformat_input_t *i = vam->input;
6788   vl_api_l2fib_add_del_t *mp;
6789   f64 timeout;
6790   u8 mac[6] = { 0 };
6791   u8 mac_set = 0;
6792   u32 bd_id;
6793   u8 bd_id_set = 0;
6794   u32 sw_if_index = 0;
6795   u8 sw_if_index_set = 0;
6796   u8 is_add = 1;
6797   u8 static_mac = 0;
6798   u8 filter_mac = 0;
6799   u8 bvi_mac = 0;
6800   int count = 1;
6801   f64 before = 0;
6802   int j;
6803
6804   /* Parse args required to build the message */
6805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6806     {
6807       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6808         mac_set = 1;
6809       else if (unformat (i, "bd_id %d", &bd_id))
6810         bd_id_set = 1;
6811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6812         sw_if_index_set = 1;
6813       else if (unformat (i, "sw_if"))
6814         {
6815           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6816             {
6817               if (unformat
6818                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6819                 sw_if_index_set = 1;
6820             }
6821           else
6822             break;
6823         }
6824       else if (unformat (i, "static"))
6825         static_mac = 1;
6826       else if (unformat (i, "filter"))
6827         {
6828           filter_mac = 1;
6829           static_mac = 1;
6830         }
6831       else if (unformat (i, "bvi"))
6832         {
6833           bvi_mac = 1;
6834           static_mac = 1;
6835         }
6836       else if (unformat (i, "del"))
6837         is_add = 0;
6838       else if (unformat (i, "count %d", &count))
6839         ;
6840       else
6841         break;
6842     }
6843
6844   if (mac_set == 0)
6845     {
6846       errmsg ("missing mac address");
6847       return -99;
6848     }
6849
6850   if (bd_id_set == 0)
6851     {
6852       errmsg ("missing bridge domain");
6853       return -99;
6854     }
6855
6856   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6857     {
6858       errmsg ("missing interface name or sw_if_index");
6859       return -99;
6860     }
6861
6862   if (count > 1)
6863     {
6864       /* Turn on async mode */
6865       vam->async_mode = 1;
6866       vam->async_errors = 0;
6867       before = vat_time_now (vam);
6868     }
6869
6870   for (j = 0; j < count; j++)
6871     {
6872       M (L2FIB_ADD_DEL, mp);
6873
6874       clib_memcpy (mp->mac, mac, 6);
6875       mp->bd_id = ntohl (bd_id);
6876       mp->is_add = is_add;
6877       mp->sw_if_index = ntohl (sw_if_index);
6878
6879       if (is_add)
6880         {
6881           mp->static_mac = static_mac;
6882           mp->filter_mac = filter_mac;
6883           mp->bvi_mac = bvi_mac;
6884         }
6885       increment_mac_address (mac);
6886       /* send it... */
6887       S (mp);
6888     }
6889
6890   if (count > 1)
6891     {
6892       vl_api_control_ping_t *mp_ping;
6893       f64 after;
6894
6895       /* Shut off async mode */
6896       vam->async_mode = 0;
6897
6898       MPING (CONTROL_PING, mp_ping);
6899       S (mp_ping);
6900
6901       timeout = vat_time_now (vam) + 1.0;
6902       while (vat_time_now (vam) < timeout)
6903         if (vam->result_ready == 1)
6904           goto out;
6905       vam->retval = -99;
6906
6907     out:
6908       if (vam->retval == -99)
6909         errmsg ("timeout");
6910
6911       if (vam->async_errors > 0)
6912         {
6913           errmsg ("%d asynchronous errors", vam->async_errors);
6914           vam->retval = -98;
6915         }
6916       vam->async_errors = 0;
6917       after = vat_time_now (vam);
6918
6919       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6920              count, after - before, count / (after - before));
6921     }
6922   else
6923     {
6924       int ret;
6925
6926       /* Wait for a reply... */
6927       W (ret);
6928       return ret;
6929     }
6930   /* Return the good/bad news */
6931   return (vam->retval);
6932 }
6933
6934 static int
6935 api_bridge_domain_set_mac_age (vat_main_t * vam)
6936 {
6937   unformat_input_t *i = vam->input;
6938   vl_api_bridge_domain_set_mac_age_t *mp;
6939   u32 bd_id = ~0;
6940   u32 mac_age = 0;
6941   int ret;
6942
6943   /* Parse args required to build the message */
6944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6945     {
6946       if (unformat (i, "bd_id %d", &bd_id));
6947       else if (unformat (i, "mac-age %d", &mac_age));
6948       else
6949         break;
6950     }
6951
6952   if (bd_id == ~0)
6953     {
6954       errmsg ("missing bridge domain");
6955       return -99;
6956     }
6957
6958   if (mac_age > 255)
6959     {
6960       errmsg ("mac age must be less than 256 ");
6961       return -99;
6962     }
6963
6964   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6965
6966   mp->bd_id = htonl (bd_id);
6967   mp->mac_age = (u8) mac_age;
6968
6969   S (mp);
6970   W (ret);
6971   return ret;
6972 }
6973
6974 static int
6975 api_l2_flags (vat_main_t * vam)
6976 {
6977   unformat_input_t *i = vam->input;
6978   vl_api_l2_flags_t *mp;
6979   u32 sw_if_index;
6980   u32 flags = 0;
6981   u8 sw_if_index_set = 0;
6982   u8 is_set = 0;
6983   int ret;
6984
6985   /* Parse args required to build the message */
6986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6987     {
6988       if (unformat (i, "sw_if_index %d", &sw_if_index))
6989         sw_if_index_set = 1;
6990       else if (unformat (i, "sw_if"))
6991         {
6992           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993             {
6994               if (unformat
6995                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6996                 sw_if_index_set = 1;
6997             }
6998           else
6999             break;
7000         }
7001       else if (unformat (i, "learn"))
7002         flags |= L2_LEARN;
7003       else if (unformat (i, "forward"))
7004         flags |= L2_FWD;
7005       else if (unformat (i, "flood"))
7006         flags |= L2_FLOOD;
7007       else if (unformat (i, "uu-flood"))
7008         flags |= L2_UU_FLOOD;
7009       else if (unformat (i, "arp-term"))
7010         flags |= L2_ARP_TERM;
7011       else if (unformat (i, "off"))
7012         is_set = 0;
7013       else if (unformat (i, "disable"))
7014         is_set = 0;
7015       else
7016         break;
7017     }
7018
7019   if (sw_if_index_set == 0)
7020     {
7021       errmsg ("missing interface name or sw_if_index");
7022       return -99;
7023     }
7024
7025   M (L2_FLAGS, mp);
7026
7027   mp->sw_if_index = ntohl (sw_if_index);
7028   mp->feature_bitmap = ntohl (flags);
7029   mp->is_set = is_set;
7030
7031   S (mp);
7032   W (ret);
7033   return ret;
7034 }
7035
7036 static int
7037 api_bridge_flags (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_bridge_flags_t *mp;
7041   u32 bd_id;
7042   u8 bd_id_set = 0;
7043   u8 is_set = 1;
7044   bd_flags_t flags = 0;
7045   int ret;
7046
7047   /* Parse args required to build the message */
7048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049     {
7050       if (unformat (i, "bd_id %d", &bd_id))
7051         bd_id_set = 1;
7052       else if (unformat (i, "learn"))
7053         flags |= BRIDGE_API_FLAG_LEARN;
7054       else if (unformat (i, "forward"))
7055         flags |= BRIDGE_API_FLAG_FWD;
7056       else if (unformat (i, "flood"))
7057         flags |= BRIDGE_API_FLAG_FLOOD;
7058       else if (unformat (i, "uu-flood"))
7059         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7060       else if (unformat (i, "arp-term"))
7061         flags |= BRIDGE_API_FLAG_ARP_TERM;
7062       else if (unformat (i, "off"))
7063         is_set = 0;
7064       else if (unformat (i, "disable"))
7065         is_set = 0;
7066       else
7067         break;
7068     }
7069
7070   if (bd_id_set == 0)
7071     {
7072       errmsg ("missing bridge domain");
7073       return -99;
7074     }
7075
7076   M (BRIDGE_FLAGS, mp);
7077
7078   mp->bd_id = ntohl (bd_id);
7079   mp->flags = ntohl (flags);
7080   mp->is_set = is_set;
7081
7082   S (mp);
7083   W (ret);
7084   return ret;
7085 }
7086
7087 static int
7088 api_bd_ip_mac_add_del (vat_main_t * vam)
7089 {
7090   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7091   vl_api_mac_address_t mac = { 0 };
7092   unformat_input_t *i = vam->input;
7093   vl_api_bd_ip_mac_add_del_t *mp;
7094   u32 bd_id;
7095   u8 is_add = 1;
7096   u8 bd_id_set = 0;
7097   u8 ip_set = 0;
7098   u8 mac_set = 0;
7099   int ret;
7100
7101
7102   /* Parse args required to build the message */
7103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7104     {
7105       if (unformat (i, "bd_id %d", &bd_id))
7106         {
7107           bd_id_set++;
7108         }
7109       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7110         {
7111           ip_set++;
7112         }
7113       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7114         {
7115           mac_set++;
7116         }
7117       else if (unformat (i, "del"))
7118         is_add = 0;
7119       else
7120         break;
7121     }
7122
7123   if (bd_id_set == 0)
7124     {
7125       errmsg ("missing bridge domain");
7126       return -99;
7127     }
7128   else if (ip_set == 0)
7129     {
7130       errmsg ("missing IP address");
7131       return -99;
7132     }
7133   else if (mac_set == 0)
7134     {
7135       errmsg ("missing MAC address");
7136       return -99;
7137     }
7138
7139   M (BD_IP_MAC_ADD_DEL, mp);
7140
7141   mp->entry.bd_id = ntohl (bd_id);
7142   mp->is_add = is_add;
7143
7144   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7145   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7146
7147   S (mp);
7148   W (ret);
7149   return ret;
7150 }
7151
7152 static int
7153 api_bd_ip_mac_flush (vat_main_t * vam)
7154 {
7155   unformat_input_t *i = vam->input;
7156   vl_api_bd_ip_mac_flush_t *mp;
7157   u32 bd_id;
7158   u8 bd_id_set = 0;
7159   int ret;
7160
7161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7162     {
7163       if (unformat (i, "bd_id %d", &bd_id))
7164         {
7165           bd_id_set++;
7166         }
7167       else
7168         break;
7169     }
7170
7171   if (bd_id_set == 0)
7172     {
7173       errmsg ("missing bridge domain");
7174       return -99;
7175     }
7176
7177   M (BD_IP_MAC_FLUSH, mp);
7178
7179   mp->bd_id = ntohl (bd_id);
7180
7181   S (mp);
7182   W (ret);
7183   return ret;
7184 }
7185
7186 static void vl_api_bd_ip_mac_details_t_handler
7187   (vl_api_bd_ip_mac_details_t * mp)
7188 {
7189   vat_main_t *vam = &vat_main;
7190
7191   print (vam->ofp,
7192          "\n%-5d %U %U",
7193          ntohl (mp->entry.bd_id),
7194          format_vl_api_mac_address, mp->entry.mac,
7195          format_vl_api_address, &mp->entry.ip);
7196 }
7197
7198 static void vl_api_bd_ip_mac_details_t_handler_json
7199   (vl_api_bd_ip_mac_details_t * mp)
7200 {
7201   vat_main_t *vam = &vat_main;
7202   vat_json_node_t *node = NULL;
7203
7204   if (VAT_JSON_ARRAY != vam->json_tree.type)
7205     {
7206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7207       vat_json_init_array (&vam->json_tree);
7208     }
7209   node = vat_json_array_add (&vam->json_tree);
7210
7211   vat_json_init_object (node);
7212   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7213   vat_json_object_add_string_copy (node, "mac_address",
7214                                    format (0, "%U", format_vl_api_mac_address,
7215                                            &mp->entry.mac));
7216   u8 *ip = 0;
7217
7218   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7219   vat_json_object_add_string_copy (node, "ip_address", ip);
7220   vec_free (ip);
7221 }
7222
7223 static int
7224 api_bd_ip_mac_dump (vat_main_t * vam)
7225 {
7226   unformat_input_t *i = vam->input;
7227   vl_api_bd_ip_mac_dump_t *mp;
7228   vl_api_control_ping_t *mp_ping;
7229   int ret;
7230   u32 bd_id;
7231   u8 bd_id_set = 0;
7232
7233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7234     {
7235       if (unformat (i, "bd_id %d", &bd_id))
7236         {
7237           bd_id_set++;
7238         }
7239       else
7240         break;
7241     }
7242
7243   print (vam->ofp,
7244          "\n%-5s %-7s %-20s %-30s",
7245          "bd_id", "is_ipv6", "mac_address", "ip_address");
7246
7247   /* Dump Bridge Domain Ip to Mac entries */
7248   M (BD_IP_MAC_DUMP, mp);
7249
7250   if (bd_id_set)
7251     mp->bd_id = htonl (bd_id);
7252   else
7253     mp->bd_id = ~0;
7254
7255   S (mp);
7256
7257   /* Use a control ping for synchronization */
7258   MPING (CONTROL_PING, mp_ping);
7259   S (mp_ping);
7260
7261   W (ret);
7262   return ret;
7263 }
7264
7265 static int
7266 api_tap_create_v2 (vat_main_t * vam)
7267 {
7268   unformat_input_t *i = vam->input;
7269   vl_api_tap_create_v2_t *mp;
7270   u8 mac_address[6];
7271   u8 random_mac = 1;
7272   u32 id = ~0;
7273   u32 num_rx_queues = 0;
7274   u8 *host_if_name = 0;
7275   u8 host_if_name_set = 0;
7276   u8 *host_ns = 0;
7277   u8 host_ns_set = 0;
7278   u8 host_mac_addr[6];
7279   u8 host_mac_addr_set = 0;
7280   u8 *host_bridge = 0;
7281   u8 host_bridge_set = 0;
7282   u8 host_ip4_prefix_set = 0;
7283   u8 host_ip6_prefix_set = 0;
7284   ip4_address_t host_ip4_addr;
7285   ip4_address_t host_ip4_gw;
7286   u8 host_ip4_gw_set = 0;
7287   u32 host_ip4_prefix_len = 0;
7288   ip6_address_t host_ip6_addr;
7289   ip6_address_t host_ip6_gw;
7290   u8 host_ip6_gw_set = 0;
7291   u32 host_ip6_prefix_len = 0;
7292   u32 host_mtu_size = 0;
7293   u8 host_mtu_set = 0;
7294   u32 tap_flags = 0;
7295   int ret;
7296   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7297
7298   clib_memset (mac_address, 0, sizeof (mac_address));
7299
7300   /* Parse args required to build the message */
7301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7302     {
7303       if (unformat (i, "id %u", &id))
7304         ;
7305       else
7306         if (unformat
7307             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7308         random_mac = 0;
7309       else if (unformat (i, "host-if-name %s", &host_if_name))
7310         host_if_name_set = 1;
7311       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7312         ;
7313       else if (unformat (i, "host-ns %s", &host_ns))
7314         host_ns_set = 1;
7315       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7316                          host_mac_addr))
7317         host_mac_addr_set = 1;
7318       else if (unformat (i, "host-bridge %s", &host_bridge))
7319         host_bridge_set = 1;
7320       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7321                          &host_ip4_addr, &host_ip4_prefix_len))
7322         host_ip4_prefix_set = 1;
7323       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7324                          &host_ip6_addr, &host_ip6_prefix_len))
7325         host_ip6_prefix_set = 1;
7326       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7327                          &host_ip4_gw))
7328         host_ip4_gw_set = 1;
7329       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7330                          &host_ip6_gw))
7331         host_ip6_gw_set = 1;
7332       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7333         ;
7334       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7335         ;
7336       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7337         host_mtu_set = 1;
7338       else if (unformat (i, "no-gso"))
7339         tap_flags &= ~TAP_FLAG_GSO;
7340       else if (unformat (i, "gso"))
7341         tap_flags |= TAP_FLAG_GSO;
7342       else if (unformat (i, "csum-offload"))
7343         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7344       else
7345         break;
7346     }
7347
7348   if (vec_len (host_if_name) > 63)
7349     {
7350       errmsg ("tap name too long. ");
7351       return -99;
7352     }
7353   if (vec_len (host_ns) > 63)
7354     {
7355       errmsg ("host name space too long. ");
7356       return -99;
7357     }
7358   if (vec_len (host_bridge) > 63)
7359     {
7360       errmsg ("host bridge name too long. ");
7361       return -99;
7362     }
7363   if (host_ip4_prefix_len > 32)
7364     {
7365       errmsg ("host ip4 prefix length not valid. ");
7366       return -99;
7367     }
7368   if (host_ip6_prefix_len > 128)
7369     {
7370       errmsg ("host ip6 prefix length not valid. ");
7371       return -99;
7372     }
7373   if (!is_pow2 (rx_ring_sz))
7374     {
7375       errmsg ("rx ring size must be power of 2. ");
7376       return -99;
7377     }
7378   if (rx_ring_sz > 32768)
7379     {
7380       errmsg ("rx ring size must be 32768 or lower. ");
7381       return -99;
7382     }
7383   if (!is_pow2 (tx_ring_sz))
7384     {
7385       errmsg ("tx ring size must be power of 2. ");
7386       return -99;
7387     }
7388   if (tx_ring_sz > 32768)
7389     {
7390       errmsg ("tx ring size must be 32768 or lower. ");
7391       return -99;
7392     }
7393   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7394     {
7395       errmsg ("host MTU size must be in between 64 and 65355. ");
7396       return -99;
7397     }
7398
7399   /* Construct the API message */
7400   M (TAP_CREATE_V2, mp);
7401
7402   mp->id = ntohl (id);
7403   mp->use_random_mac = random_mac;
7404   mp->num_rx_queues = (u8) num_rx_queues;
7405   mp->tx_ring_sz = ntohs (tx_ring_sz);
7406   mp->rx_ring_sz = ntohs (rx_ring_sz);
7407   mp->host_mtu_set = host_mtu_set;
7408   mp->host_mtu_size = ntohl (host_mtu_size);
7409   mp->host_mac_addr_set = host_mac_addr_set;
7410   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7411   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7412   mp->host_ip4_gw_set = host_ip4_gw_set;
7413   mp->host_ip6_gw_set = host_ip6_gw_set;
7414   mp->tap_flags = ntohl (tap_flags);
7415   mp->host_namespace_set = host_ns_set;
7416   mp->host_if_name_set = host_if_name_set;
7417   mp->host_bridge_set = host_bridge_set;
7418
7419   if (random_mac == 0)
7420     clib_memcpy (mp->mac_address, mac_address, 6);
7421   if (host_mac_addr_set)
7422     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7423   if (host_if_name_set)
7424     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7425   if (host_ns_set)
7426     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7427   if (host_bridge_set)
7428     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7429   if (host_ip4_prefix_set)
7430     {
7431       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7432       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7433     }
7434   if (host_ip6_prefix_set)
7435     {
7436       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7437       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7438     }
7439   if (host_ip4_gw_set)
7440     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7441   if (host_ip6_gw_set)
7442     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7443
7444   vec_free (host_ns);
7445   vec_free (host_if_name);
7446   vec_free (host_bridge);
7447
7448   /* send it... */
7449   S (mp);
7450
7451   /* Wait for a reply... */
7452   W (ret);
7453   return ret;
7454 }
7455
7456 static int
7457 api_tap_delete_v2 (vat_main_t * vam)
7458 {
7459   unformat_input_t *i = vam->input;
7460   vl_api_tap_delete_v2_t *mp;
7461   u32 sw_if_index = ~0;
7462   u8 sw_if_index_set = 0;
7463   int ret;
7464
7465   /* Parse args required to build the message */
7466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467     {
7468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7469         sw_if_index_set = 1;
7470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7471         sw_if_index_set = 1;
7472       else
7473         break;
7474     }
7475
7476   if (sw_if_index_set == 0)
7477     {
7478       errmsg ("missing vpp interface name. ");
7479       return -99;
7480     }
7481
7482   /* Construct the API message */
7483   M (TAP_DELETE_V2, mp);
7484
7485   mp->sw_if_index = ntohl (sw_if_index);
7486
7487   /* send it... */
7488   S (mp);
7489
7490   /* Wait for a reply... */
7491   W (ret);
7492   return ret;
7493 }
7494
7495 uword
7496 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7497 {
7498   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7499   u32 x[4];
7500
7501   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7502     return 0;
7503
7504   addr->domain = x[0];
7505   addr->bus = x[1];
7506   addr->slot = x[2];
7507   addr->function = x[3];
7508
7509   return 1;
7510 }
7511
7512 static int
7513 api_virtio_pci_create (vat_main_t * vam)
7514 {
7515   unformat_input_t *i = vam->input;
7516   vl_api_virtio_pci_create_t *mp;
7517   u8 mac_address[6];
7518   u8 random_mac = 1;
7519   u8 gso_enabled = 0;
7520   u8 checksum_offload_enabled = 0;
7521   u32 pci_addr = 0;
7522   u64 features = (u64) ~ (0ULL);
7523   int ret;
7524
7525   clib_memset (mac_address, 0, sizeof (mac_address));
7526
7527   /* Parse args required to build the message */
7528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7529     {
7530       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7531         {
7532           random_mac = 0;
7533         }
7534       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7535         ;
7536       else if (unformat (i, "features 0x%llx", &features))
7537         ;
7538       else if (unformat (i, "gso-enabled"))
7539         gso_enabled = 1;
7540       else if (unformat (i, "csum-offload-enabled"))
7541         checksum_offload_enabled = 1;
7542       else
7543         break;
7544     }
7545
7546   if (pci_addr == 0)
7547     {
7548       errmsg ("pci address must be non zero. ");
7549       return -99;
7550     }
7551
7552   /* Construct the API message */
7553   M (VIRTIO_PCI_CREATE, mp);
7554
7555   mp->use_random_mac = random_mac;
7556
7557   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7558   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7559   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7560   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7561
7562   mp->features = clib_host_to_net_u64 (features);
7563   mp->gso_enabled = gso_enabled;
7564   mp->checksum_offload_enabled = checksum_offload_enabled;
7565
7566   if (random_mac == 0)
7567     clib_memcpy (mp->mac_address, mac_address, 6);
7568
7569   /* send it... */
7570   S (mp);
7571
7572   /* Wait for a reply... */
7573   W (ret);
7574   return ret;
7575 }
7576
7577 static int
7578 api_virtio_pci_delete (vat_main_t * vam)
7579 {
7580   unformat_input_t *i = vam->input;
7581   vl_api_virtio_pci_delete_t *mp;
7582   u32 sw_if_index = ~0;
7583   u8 sw_if_index_set = 0;
7584   int ret;
7585
7586   /* Parse args required to build the message */
7587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7588     {
7589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7590         sw_if_index_set = 1;
7591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7592         sw_if_index_set = 1;
7593       else
7594         break;
7595     }
7596
7597   if (sw_if_index_set == 0)
7598     {
7599       errmsg ("missing vpp interface name. ");
7600       return -99;
7601     }
7602
7603   /* Construct the API message */
7604   M (VIRTIO_PCI_DELETE, mp);
7605
7606   mp->sw_if_index = htonl (sw_if_index);
7607
7608   /* send it... */
7609   S (mp);
7610
7611   /* Wait for a reply... */
7612   W (ret);
7613   return ret;
7614 }
7615
7616 static int
7617 api_bond_create (vat_main_t * vam)
7618 {
7619   unformat_input_t *i = vam->input;
7620   vl_api_bond_create_t *mp;
7621   u8 mac_address[6];
7622   u8 custom_mac = 0;
7623   int ret;
7624   u8 mode;
7625   u8 lb;
7626   u8 mode_is_set = 0;
7627   u32 id = ~0;
7628   u8 numa_only = 0;
7629
7630   clib_memset (mac_address, 0, sizeof (mac_address));
7631   lb = BOND_LB_L2;
7632
7633   /* Parse args required to build the message */
7634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7635     {
7636       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7637         mode_is_set = 1;
7638       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7639                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7640         ;
7641       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7642                          mac_address))
7643         custom_mac = 1;
7644       else if (unformat (i, "numa-only"))
7645         numa_only = 1;
7646       else if (unformat (i, "id %u", &id))
7647         ;
7648       else
7649         break;
7650     }
7651
7652   if (mode_is_set == 0)
7653     {
7654       errmsg ("Missing bond mode. ");
7655       return -99;
7656     }
7657
7658   /* Construct the API message */
7659   M (BOND_CREATE, mp);
7660
7661   mp->use_custom_mac = custom_mac;
7662
7663   mp->mode = htonl (mode);
7664   mp->lb = htonl (lb);
7665   mp->id = htonl (id);
7666   mp->numa_only = numa_only;
7667
7668   if (custom_mac)
7669     clib_memcpy (mp->mac_address, mac_address, 6);
7670
7671   /* send it... */
7672   S (mp);
7673
7674   /* Wait for a reply... */
7675   W (ret);
7676   return ret;
7677 }
7678
7679 static int
7680 api_bond_delete (vat_main_t * vam)
7681 {
7682   unformat_input_t *i = vam->input;
7683   vl_api_bond_delete_t *mp;
7684   u32 sw_if_index = ~0;
7685   u8 sw_if_index_set = 0;
7686   int ret;
7687
7688   /* Parse args required to build the message */
7689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7690     {
7691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7692         sw_if_index_set = 1;
7693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7694         sw_if_index_set = 1;
7695       else
7696         break;
7697     }
7698
7699   if (sw_if_index_set == 0)
7700     {
7701       errmsg ("missing vpp interface name. ");
7702       return -99;
7703     }
7704
7705   /* Construct the API message */
7706   M (BOND_DELETE, mp);
7707
7708   mp->sw_if_index = ntohl (sw_if_index);
7709
7710   /* send it... */
7711   S (mp);
7712
7713   /* Wait for a reply... */
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_bond_enslave (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_bond_enslave_t *mp;
7723   u32 bond_sw_if_index;
7724   int ret;
7725   u8 is_passive;
7726   u8 is_long_timeout;
7727   u32 bond_sw_if_index_is_set = 0;
7728   u32 sw_if_index;
7729   u8 sw_if_index_is_set = 0;
7730
7731   /* Parse args required to build the message */
7732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7733     {
7734       if (unformat (i, "sw_if_index %d", &sw_if_index))
7735         sw_if_index_is_set = 1;
7736       else if (unformat (i, "bond %u", &bond_sw_if_index))
7737         bond_sw_if_index_is_set = 1;
7738       else if (unformat (i, "passive %d", &is_passive))
7739         ;
7740       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7741         ;
7742       else
7743         break;
7744     }
7745
7746   if (bond_sw_if_index_is_set == 0)
7747     {
7748       errmsg ("Missing bond sw_if_index. ");
7749       return -99;
7750     }
7751   if (sw_if_index_is_set == 0)
7752     {
7753       errmsg ("Missing slave sw_if_index. ");
7754       return -99;
7755     }
7756
7757   /* Construct the API message */
7758   M (BOND_ENSLAVE, mp);
7759
7760   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7761   mp->sw_if_index = ntohl (sw_if_index);
7762   mp->is_long_timeout = is_long_timeout;
7763   mp->is_passive = is_passive;
7764
7765   /* send it... */
7766   S (mp);
7767
7768   /* Wait for a reply... */
7769   W (ret);
7770   return ret;
7771 }
7772
7773 static int
7774 api_bond_detach_slave (vat_main_t * vam)
7775 {
7776   unformat_input_t *i = vam->input;
7777   vl_api_bond_detach_slave_t *mp;
7778   u32 sw_if_index = ~0;
7779   u8 sw_if_index_set = 0;
7780   int ret;
7781
7782   /* Parse args required to build the message */
7783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7784     {
7785       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7786         sw_if_index_set = 1;
7787       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7788         sw_if_index_set = 1;
7789       else
7790         break;
7791     }
7792
7793   if (sw_if_index_set == 0)
7794     {
7795       errmsg ("missing vpp interface name. ");
7796       return -99;
7797     }
7798
7799   /* Construct the API message */
7800   M (BOND_DETACH_SLAVE, mp);
7801
7802   mp->sw_if_index = ntohl (sw_if_index);
7803
7804   /* send it... */
7805   S (mp);
7806
7807   /* Wait for a reply... */
7808   W (ret);
7809   return ret;
7810 }
7811
7812 static int
7813 api_ip_table_add_del (vat_main_t * vam)
7814 {
7815   unformat_input_t *i = vam->input;
7816   vl_api_ip_table_add_del_t *mp;
7817   u32 table_id = ~0;
7818   u8 is_ipv6 = 0;
7819   u8 is_add = 1;
7820   int ret = 0;
7821
7822   /* Parse args required to build the message */
7823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7824     {
7825       if (unformat (i, "ipv6"))
7826         is_ipv6 = 1;
7827       else if (unformat (i, "del"))
7828         is_add = 0;
7829       else if (unformat (i, "add"))
7830         is_add = 1;
7831       else if (unformat (i, "table %d", &table_id))
7832         ;
7833       else
7834         {
7835           clib_warning ("parse error '%U'", format_unformat_error, i);
7836           return -99;
7837         }
7838     }
7839
7840   if (~0 == table_id)
7841     {
7842       errmsg ("missing table-ID");
7843       return -99;
7844     }
7845
7846   /* Construct the API message */
7847   M (IP_TABLE_ADD_DEL, mp);
7848
7849   mp->table.table_id = ntohl (table_id);
7850   mp->table.is_ip6 = is_ipv6;
7851   mp->is_add = is_add;
7852
7853   /* send it... */
7854   S (mp);
7855
7856   /* Wait for a reply... */
7857   W (ret);
7858
7859   return ret;
7860 }
7861
7862 uword
7863 unformat_fib_path (unformat_input_t * input, va_list * args)
7864 {
7865   vat_main_t *vam = va_arg (*args, vat_main_t *);
7866   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7867   u32 weight, preference;
7868   mpls_label_t out_label;
7869
7870   clib_memset (path, 0, sizeof (*path));
7871   path->weight = 1;
7872   path->sw_if_index = ~0;
7873   path->rpf_id = ~0;
7874   path->n_labels = 0;
7875
7876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7877     {
7878       if (unformat (input, "%U %U",
7879                     unformat_vl_api_ip4_address,
7880                     &path->nh.address.ip4,
7881                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7882         {
7883           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7884         }
7885       else if (unformat (input, "%U %U",
7886                          unformat_vl_api_ip6_address,
7887                          &path->nh.address.ip6,
7888                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7889         {
7890           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7891         }
7892       else if (unformat (input, "weight %u", &weight))
7893         {
7894           path->weight = weight;
7895         }
7896       else if (unformat (input, "preference %u", &preference))
7897         {
7898           path->preference = preference;
7899         }
7900       else if (unformat (input, "%U next-hop-table %d",
7901                          unformat_vl_api_ip4_address,
7902                          &path->nh.address.ip4, &path->table_id))
7903         {
7904           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7905         }
7906       else if (unformat (input, "%U next-hop-table %d",
7907                          unformat_vl_api_ip6_address,
7908                          &path->nh.address.ip6, &path->table_id))
7909         {
7910           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7911         }
7912       else if (unformat (input, "%U",
7913                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7914         {
7915           /*
7916            * the recursive next-hops are by default in the default table
7917            */
7918           path->table_id = 0;
7919           path->sw_if_index = ~0;
7920           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7921         }
7922       else if (unformat (input, "%U",
7923                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7924         {
7925           /*
7926            * the recursive next-hops are by default in the default table
7927            */
7928           path->table_id = 0;
7929           path->sw_if_index = ~0;
7930           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7931         }
7932       else if (unformat (input, "resolve-via-host"))
7933         {
7934           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7935         }
7936       else if (unformat (input, "resolve-via-attached"))
7937         {
7938           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7939         }
7940       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7941         {
7942           path->type = FIB_API_PATH_TYPE_LOCAL;
7943           path->sw_if_index = ~0;
7944           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7945         }
7946       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7947         {
7948           path->type = FIB_API_PATH_TYPE_LOCAL;
7949           path->sw_if_index = ~0;
7950           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7951         }
7952       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7953         ;
7954       else if (unformat (input, "via-label %d", &path->nh.via_label))
7955         {
7956           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7957           path->sw_if_index = ~0;
7958         }
7959       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7960         {
7961           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7962           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7963         }
7964       else if (unformat (input, "local"))
7965         {
7966           path->type = FIB_API_PATH_TYPE_LOCAL;
7967         }
7968       else if (unformat (input, "out-labels"))
7969         {
7970           while (unformat (input, "%d", &out_label))
7971             {
7972               path->label_stack[path->n_labels].label = out_label;
7973               path->label_stack[path->n_labels].is_uniform = 0;
7974               path->label_stack[path->n_labels].ttl = 64;
7975               path->n_labels++;
7976             }
7977         }
7978       else if (unformat (input, "via"))
7979         {
7980           /* new path, back up and return */
7981           unformat_put_input (input);
7982           unformat_put_input (input);
7983           unformat_put_input (input);
7984           unformat_put_input (input);
7985           break;
7986         }
7987       else
7988         {
7989           return (0);
7990         }
7991     }
7992
7993   path->proto = ntohl (path->proto);
7994   path->type = ntohl (path->type);
7995   path->flags = ntohl (path->flags);
7996   path->table_id = ntohl (path->table_id);
7997   path->sw_if_index = ntohl (path->sw_if_index);
7998
7999   return (1);
8000 }
8001
8002 static int
8003 api_ip_route_add_del (vat_main_t * vam)
8004 {
8005   unformat_input_t *i = vam->input;
8006   vl_api_ip_route_add_del_t *mp;
8007   u32 vrf_id = 0;
8008   u8 is_add = 1;
8009   u8 is_multipath = 0;
8010   u8 prefix_set = 0;
8011   u8 path_count = 0;
8012   vl_api_prefix_t pfx = { };
8013   vl_api_fib_path_t paths[8];
8014   int count = 1;
8015   int j;
8016   f64 before = 0;
8017   u32 random_add_del = 0;
8018   u32 *random_vector = 0;
8019   u32 random_seed = 0xdeaddabe;
8020
8021   /* Parse args required to build the message */
8022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8023     {
8024       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8025         prefix_set = 1;
8026       else if (unformat (i, "del"))
8027         is_add = 0;
8028       else if (unformat (i, "add"))
8029         is_add = 1;
8030       else if (unformat (i, "vrf %d", &vrf_id))
8031         ;
8032       else if (unformat (i, "count %d", &count))
8033         ;
8034       else if (unformat (i, "random"))
8035         random_add_del = 1;
8036       else if (unformat (i, "multipath"))
8037         is_multipath = 1;
8038       else if (unformat (i, "seed %d", &random_seed))
8039         ;
8040       else
8041         if (unformat
8042             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8043         {
8044           path_count++;
8045           if (8 == path_count)
8046             {
8047               errmsg ("max 8 paths");
8048               return -99;
8049             }
8050         }
8051       else
8052         {
8053           clib_warning ("parse error '%U'", format_unformat_error, i);
8054           return -99;
8055         }
8056     }
8057
8058   if (!path_count)
8059     {
8060       errmsg ("specify a path; via ...");
8061       return -99;
8062     }
8063   if (prefix_set == 0)
8064     {
8065       errmsg ("missing prefix");
8066       return -99;
8067     }
8068
8069   /* Generate a pile of unique, random routes */
8070   if (random_add_del)
8071     {
8072       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8073       u32 this_random_address;
8074       uword *random_hash;
8075
8076       random_hash = hash_create (count, sizeof (uword));
8077
8078       hash_set (random_hash, i->as_u32, 1);
8079       for (j = 0; j <= count; j++)
8080         {
8081           do
8082             {
8083               this_random_address = random_u32 (&random_seed);
8084               this_random_address =
8085                 clib_host_to_net_u32 (this_random_address);
8086             }
8087           while (hash_get (random_hash, this_random_address));
8088           vec_add1 (random_vector, this_random_address);
8089           hash_set (random_hash, this_random_address, 1);
8090         }
8091       hash_free (random_hash);
8092       set_ip4_address (&pfx.address, random_vector[0]);
8093     }
8094
8095   if (count > 1)
8096     {
8097       /* Turn on async mode */
8098       vam->async_mode = 1;
8099       vam->async_errors = 0;
8100       before = vat_time_now (vam);
8101     }
8102
8103   for (j = 0; j < count; j++)
8104     {
8105       /* Construct the API message */
8106       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8107
8108       mp->is_add = is_add;
8109       mp->is_multipath = is_multipath;
8110
8111       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8112       mp->route.table_id = ntohl (vrf_id);
8113       mp->route.n_paths = path_count;
8114
8115       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8116
8117       if (random_add_del)
8118         set_ip4_address (&pfx.address, random_vector[j + 1]);
8119       else
8120         increment_address (&pfx.address);
8121       /* send it... */
8122       S (mp);
8123       /* If we receive SIGTERM, stop now... */
8124       if (vam->do_exit)
8125         break;
8126     }
8127
8128   /* When testing multiple add/del ops, use a control-ping to sync */
8129   if (count > 1)
8130     {
8131       vl_api_control_ping_t *mp_ping;
8132       f64 after;
8133       f64 timeout;
8134
8135       /* Shut off async mode */
8136       vam->async_mode = 0;
8137
8138       MPING (CONTROL_PING, mp_ping);
8139       S (mp_ping);
8140
8141       timeout = vat_time_now (vam) + 1.0;
8142       while (vat_time_now (vam) < timeout)
8143         if (vam->result_ready == 1)
8144           goto out;
8145       vam->retval = -99;
8146
8147     out:
8148       if (vam->retval == -99)
8149         errmsg ("timeout");
8150
8151       if (vam->async_errors > 0)
8152         {
8153           errmsg ("%d asynchronous errors", vam->async_errors);
8154           vam->retval = -98;
8155         }
8156       vam->async_errors = 0;
8157       after = vat_time_now (vam);
8158
8159       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8160       if (j > 0)
8161         count = j;
8162
8163       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8164              count, after - before, count / (after - before));
8165     }
8166   else
8167     {
8168       int ret;
8169
8170       /* Wait for a reply... */
8171       W (ret);
8172       return ret;
8173     }
8174
8175   /* Return the good/bad news */
8176   return (vam->retval);
8177 }
8178
8179 static int
8180 api_ip_mroute_add_del (vat_main_t * vam)
8181 {
8182   unformat_input_t *i = vam->input;
8183   u8 path_set = 0, prefix_set = 0, is_add = 1;
8184   vl_api_ip_mroute_add_del_t *mp;
8185   mfib_entry_flags_t eflags = 0;
8186   vl_api_mfib_path_t path;
8187   vl_api_mprefix_t pfx = { };
8188   u32 vrf_id = 0;
8189   int ret;
8190
8191   /* Parse args required to build the message */
8192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8193     {
8194       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8195         {
8196           prefix_set = 1;
8197           pfx.grp_address_length = htons (pfx.grp_address_length);
8198         }
8199       else if (unformat (i, "del"))
8200         is_add = 0;
8201       else if (unformat (i, "add"))
8202         is_add = 1;
8203       else if (unformat (i, "vrf %d", &vrf_id))
8204         ;
8205       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8206         path.itf_flags = htonl (path.itf_flags);
8207       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8208         ;
8209       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8210         path_set = 1;
8211       else
8212         {
8213           clib_warning ("parse error '%U'", format_unformat_error, i);
8214           return -99;
8215         }
8216     }
8217
8218   if (prefix_set == 0)
8219     {
8220       errmsg ("missing addresses\n");
8221       return -99;
8222     }
8223   if (path_set == 0)
8224     {
8225       errmsg ("missing path\n");
8226       return -99;
8227     }
8228
8229   /* Construct the API message */
8230   M (IP_MROUTE_ADD_DEL, mp);
8231
8232   mp->is_add = is_add;
8233   mp->is_multipath = 1;
8234
8235   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8236   mp->route.table_id = htonl (vrf_id);
8237   mp->route.n_paths = 1;
8238   mp->route.entry_flags = htonl (eflags);
8239
8240   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8241
8242   /* send it... */
8243   S (mp);
8244   /* Wait for a reply... */
8245   W (ret);
8246   return ret;
8247 }
8248
8249 static int
8250 api_mpls_table_add_del (vat_main_t * vam)
8251 {
8252   unformat_input_t *i = vam->input;
8253   vl_api_mpls_table_add_del_t *mp;
8254   u32 table_id = ~0;
8255   u8 is_add = 1;
8256   int ret = 0;
8257
8258   /* Parse args required to build the message */
8259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8260     {
8261       if (unformat (i, "table %d", &table_id))
8262         ;
8263       else if (unformat (i, "del"))
8264         is_add = 0;
8265       else if (unformat (i, "add"))
8266         is_add = 1;
8267       else
8268         {
8269           clib_warning ("parse error '%U'", format_unformat_error, i);
8270           return -99;
8271         }
8272     }
8273
8274   if (~0 == table_id)
8275     {
8276       errmsg ("missing table-ID");
8277       return -99;
8278     }
8279
8280   /* Construct the API message */
8281   M (MPLS_TABLE_ADD_DEL, mp);
8282
8283   mp->mt_table.mt_table_id = ntohl (table_id);
8284   mp->mt_is_add = is_add;
8285
8286   /* send it... */
8287   S (mp);
8288
8289   /* Wait for a reply... */
8290   W (ret);
8291
8292   return ret;
8293 }
8294
8295 static int
8296 api_mpls_route_add_del (vat_main_t * vam)
8297 {
8298   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8299   mpls_label_t local_label = MPLS_LABEL_INVALID;
8300   unformat_input_t *i = vam->input;
8301   vl_api_mpls_route_add_del_t *mp;
8302   vl_api_fib_path_t paths[8];
8303   int count = 1, j;
8304   f64 before = 0;
8305
8306   /* Parse args required to build the message */
8307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8308     {
8309       if (unformat (i, "%d", &local_label))
8310         ;
8311       else if (unformat (i, "eos"))
8312         is_eos = 1;
8313       else if (unformat (i, "non-eos"))
8314         is_eos = 0;
8315       else if (unformat (i, "del"))
8316         is_add = 0;
8317       else if (unformat (i, "add"))
8318         is_add = 1;
8319       else if (unformat (i, "multipath"))
8320         is_multipath = 1;
8321       else if (unformat (i, "count %d", &count))
8322         ;
8323       else
8324         if (unformat
8325             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8326         {
8327           path_count++;
8328           if (8 == path_count)
8329             {
8330               errmsg ("max 8 paths");
8331               return -99;
8332             }
8333         }
8334       else
8335         {
8336           clib_warning ("parse error '%U'", format_unformat_error, i);
8337           return -99;
8338         }
8339     }
8340
8341   if (!path_count)
8342     {
8343       errmsg ("specify a path; via ...");
8344       return -99;
8345     }
8346
8347   if (MPLS_LABEL_INVALID == local_label)
8348     {
8349       errmsg ("missing label");
8350       return -99;
8351     }
8352
8353   if (count > 1)
8354     {
8355       /* Turn on async mode */
8356       vam->async_mode = 1;
8357       vam->async_errors = 0;
8358       before = vat_time_now (vam);
8359     }
8360
8361   for (j = 0; j < count; j++)
8362     {
8363       /* Construct the API message */
8364       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8365
8366       mp->mr_is_add = is_add;
8367       mp->mr_is_multipath = is_multipath;
8368
8369       mp->mr_route.mr_label = local_label;
8370       mp->mr_route.mr_eos = is_eos;
8371       mp->mr_route.mr_table_id = 0;
8372       mp->mr_route.mr_n_paths = path_count;
8373
8374       clib_memcpy (&mp->mr_route.mr_paths, paths,
8375                    sizeof (paths[0]) * path_count);
8376
8377       local_label++;
8378
8379       /* send it... */
8380       S (mp);
8381       /* If we receive SIGTERM, stop now... */
8382       if (vam->do_exit)
8383         break;
8384     }
8385
8386   /* When testing multiple add/del ops, use a control-ping to sync */
8387   if (count > 1)
8388     {
8389       vl_api_control_ping_t *mp_ping;
8390       f64 after;
8391       f64 timeout;
8392
8393       /* Shut off async mode */
8394       vam->async_mode = 0;
8395
8396       MPING (CONTROL_PING, mp_ping);
8397       S (mp_ping);
8398
8399       timeout = vat_time_now (vam) + 1.0;
8400       while (vat_time_now (vam) < timeout)
8401         if (vam->result_ready == 1)
8402           goto out;
8403       vam->retval = -99;
8404
8405     out:
8406       if (vam->retval == -99)
8407         errmsg ("timeout");
8408
8409       if (vam->async_errors > 0)
8410         {
8411           errmsg ("%d asynchronous errors", vam->async_errors);
8412           vam->retval = -98;
8413         }
8414       vam->async_errors = 0;
8415       after = vat_time_now (vam);
8416
8417       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8418       if (j > 0)
8419         count = j;
8420
8421       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8422              count, after - before, count / (after - before));
8423     }
8424   else
8425     {
8426       int ret;
8427
8428       /* Wait for a reply... */
8429       W (ret);
8430       return ret;
8431     }
8432
8433   /* Return the good/bad news */
8434   return (vam->retval);
8435   return (0);
8436 }
8437
8438 static int
8439 api_mpls_ip_bind_unbind (vat_main_t * vam)
8440 {
8441   unformat_input_t *i = vam->input;
8442   vl_api_mpls_ip_bind_unbind_t *mp;
8443   u32 ip_table_id = 0;
8444   u8 is_bind = 1;
8445   vl_api_prefix_t pfx;
8446   u8 prefix_set = 0;
8447   mpls_label_t local_label = MPLS_LABEL_INVALID;
8448   int ret;
8449
8450   /* Parse args required to build the message */
8451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8454         prefix_set = 1;
8455       else if (unformat (i, "%d", &local_label))
8456         ;
8457       else if (unformat (i, "table-id %d", &ip_table_id))
8458         ;
8459       else if (unformat (i, "unbind"))
8460         is_bind = 0;
8461       else if (unformat (i, "bind"))
8462         is_bind = 1;
8463       else
8464         {
8465           clib_warning ("parse error '%U'", format_unformat_error, i);
8466           return -99;
8467         }
8468     }
8469
8470   if (!prefix_set)
8471     {
8472       errmsg ("IP prefix not set");
8473       return -99;
8474     }
8475
8476   if (MPLS_LABEL_INVALID == local_label)
8477     {
8478       errmsg ("missing label");
8479       return -99;
8480     }
8481
8482   /* Construct the API message */
8483   M (MPLS_IP_BIND_UNBIND, mp);
8484
8485   mp->mb_is_bind = is_bind;
8486   mp->mb_ip_table_id = ntohl (ip_table_id);
8487   mp->mb_mpls_table_id = 0;
8488   mp->mb_label = ntohl (local_label);
8489   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8490
8491   /* send it... */
8492   S (mp);
8493
8494   /* Wait for a reply... */
8495   W (ret);
8496   return ret;
8497   return (0);
8498 }
8499
8500 static int
8501 api_sr_mpls_policy_add (vat_main_t * vam)
8502 {
8503   unformat_input_t *i = vam->input;
8504   vl_api_sr_mpls_policy_add_t *mp;
8505   u32 bsid = 0;
8506   u32 weight = 1;
8507   u8 type = 0;
8508   u8 n_segments = 0;
8509   u32 sid;
8510   u32 *segments = NULL;
8511   int ret;
8512
8513   /* Parse args required to build the message */
8514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8515     {
8516       if (unformat (i, "bsid %d", &bsid))
8517         ;
8518       else if (unformat (i, "weight %d", &weight))
8519         ;
8520       else if (unformat (i, "spray"))
8521         type = 1;
8522       else if (unformat (i, "next %d", &sid))
8523         {
8524           n_segments += 1;
8525           vec_add1 (segments, htonl (sid));
8526         }
8527       else
8528         {
8529           clib_warning ("parse error '%U'", format_unformat_error, i);
8530           return -99;
8531         }
8532     }
8533
8534   if (bsid == 0)
8535     {
8536       errmsg ("bsid not set");
8537       return -99;
8538     }
8539
8540   if (n_segments == 0)
8541     {
8542       errmsg ("no sid in segment stack");
8543       return -99;
8544     }
8545
8546   /* Construct the API message */
8547   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8548
8549   mp->bsid = htonl (bsid);
8550   mp->weight = htonl (weight);
8551   mp->is_spray = type;
8552   mp->n_segments = n_segments;
8553   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8554   vec_free (segments);
8555
8556   /* send it... */
8557   S (mp);
8558
8559   /* Wait for a reply... */
8560   W (ret);
8561   return ret;
8562 }
8563
8564 static int
8565 api_sr_mpls_policy_del (vat_main_t * vam)
8566 {
8567   unformat_input_t *i = vam->input;
8568   vl_api_sr_mpls_policy_del_t *mp;
8569   u32 bsid = 0;
8570   int ret;
8571
8572   /* Parse args required to build the message */
8573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8574     {
8575       if (unformat (i, "bsid %d", &bsid))
8576         ;
8577       else
8578         {
8579           clib_warning ("parse error '%U'", format_unformat_error, i);
8580           return -99;
8581         }
8582     }
8583
8584   if (bsid == 0)
8585     {
8586       errmsg ("bsid not set");
8587       return -99;
8588     }
8589
8590   /* Construct the API message */
8591   M (SR_MPLS_POLICY_DEL, mp);
8592
8593   mp->bsid = htonl (bsid);
8594
8595   /* send it... */
8596   S (mp);
8597
8598   /* Wait for a reply... */
8599   W (ret);
8600   return ret;
8601 }
8602
8603 static int
8604 api_bier_table_add_del (vat_main_t * vam)
8605 {
8606   unformat_input_t *i = vam->input;
8607   vl_api_bier_table_add_del_t *mp;
8608   u8 is_add = 1;
8609   u32 set = 0, sub_domain = 0, hdr_len = 3;
8610   mpls_label_t local_label = MPLS_LABEL_INVALID;
8611   int ret;
8612
8613   /* Parse args required to build the message */
8614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8615     {
8616       if (unformat (i, "sub-domain %d", &sub_domain))
8617         ;
8618       else if (unformat (i, "set %d", &set))
8619         ;
8620       else if (unformat (i, "label %d", &local_label))
8621         ;
8622       else if (unformat (i, "hdr-len %d", &hdr_len))
8623         ;
8624       else if (unformat (i, "add"))
8625         is_add = 1;
8626       else if (unformat (i, "del"))
8627         is_add = 0;
8628       else
8629         {
8630           clib_warning ("parse error '%U'", format_unformat_error, i);
8631           return -99;
8632         }
8633     }
8634
8635   if (MPLS_LABEL_INVALID == local_label)
8636     {
8637       errmsg ("missing label\n");
8638       return -99;
8639     }
8640
8641   /* Construct the API message */
8642   M (BIER_TABLE_ADD_DEL, mp);
8643
8644   mp->bt_is_add = is_add;
8645   mp->bt_label = ntohl (local_label);
8646   mp->bt_tbl_id.bt_set = set;
8647   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8648   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8649
8650   /* send it... */
8651   S (mp);
8652
8653   /* Wait for a reply... */
8654   W (ret);
8655
8656   return (ret);
8657 }
8658
8659 static int
8660 api_bier_route_add_del (vat_main_t * vam)
8661 {
8662   unformat_input_t *i = vam->input;
8663   vl_api_bier_route_add_del_t *mp;
8664   u8 is_add = 1;
8665   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8666   ip4_address_t v4_next_hop_address;
8667   ip6_address_t v6_next_hop_address;
8668   u8 next_hop_set = 0;
8669   u8 next_hop_proto_is_ip4 = 1;
8670   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8671   int ret;
8672
8673   /* Parse args required to build the message */
8674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8675     {
8676       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8677         {
8678           next_hop_proto_is_ip4 = 1;
8679           next_hop_set = 1;
8680         }
8681       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8682         {
8683           next_hop_proto_is_ip4 = 0;
8684           next_hop_set = 1;
8685         }
8686       if (unformat (i, "sub-domain %d", &sub_domain))
8687         ;
8688       else if (unformat (i, "set %d", &set))
8689         ;
8690       else if (unformat (i, "hdr-len %d", &hdr_len))
8691         ;
8692       else if (unformat (i, "bp %d", &bp))
8693         ;
8694       else if (unformat (i, "add"))
8695         is_add = 1;
8696       else if (unformat (i, "del"))
8697         is_add = 0;
8698       else if (unformat (i, "out-label %d", &next_hop_out_label))
8699         ;
8700       else
8701         {
8702           clib_warning ("parse error '%U'", format_unformat_error, i);
8703           return -99;
8704         }
8705     }
8706
8707   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8708     {
8709       errmsg ("next hop / label set\n");
8710       return -99;
8711     }
8712   if (0 == bp)
8713     {
8714       errmsg ("bit=position not set\n");
8715       return -99;
8716     }
8717
8718   /* Construct the API message */
8719   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8720
8721   mp->br_is_add = is_add;
8722   mp->br_route.br_tbl_id.bt_set = set;
8723   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8724   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8725   mp->br_route.br_bp = ntohs (bp);
8726   mp->br_route.br_n_paths = 1;
8727   mp->br_route.br_paths[0].n_labels = 1;
8728   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8729   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8730                                     FIB_API_PATH_NH_PROTO_IP4 :
8731                                     FIB_API_PATH_NH_PROTO_IP6);
8732
8733   if (next_hop_proto_is_ip4)
8734     {
8735       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8736                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8737     }
8738   else
8739     {
8740       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8741                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8742     }
8743
8744   /* send it... */
8745   S (mp);
8746
8747   /* Wait for a reply... */
8748   W (ret);
8749
8750   return (ret);
8751 }
8752
8753 static int
8754 api_mpls_tunnel_add_del (vat_main_t * vam)
8755 {
8756   unformat_input_t *i = vam->input;
8757   vl_api_mpls_tunnel_add_del_t *mp;
8758
8759   vl_api_fib_path_t paths[8];
8760   u32 sw_if_index = ~0;
8761   u8 path_count = 0;
8762   u8 l2_only = 0;
8763   u8 is_add = 1;
8764   int ret;
8765
8766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8767     {
8768       if (unformat (i, "add"))
8769         is_add = 1;
8770       else
8771         if (unformat
8772             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8773         is_add = 0;
8774       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8775         is_add = 0;
8776       else if (unformat (i, "l2-only"))
8777         l2_only = 1;
8778       else
8779         if (unformat
8780             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8781         {
8782           path_count++;
8783           if (8 == path_count)
8784             {
8785               errmsg ("max 8 paths");
8786               return -99;
8787             }
8788         }
8789       else
8790         {
8791           clib_warning ("parse error '%U'", format_unformat_error, i);
8792           return -99;
8793         }
8794     }
8795
8796   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8797
8798   mp->mt_is_add = is_add;
8799   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8800   mp->mt_tunnel.mt_l2_only = l2_only;
8801   mp->mt_tunnel.mt_is_multicast = 0;
8802   mp->mt_tunnel.mt_n_paths = path_count;
8803
8804   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8805                sizeof (paths[0]) * path_count);
8806
8807   S (mp);
8808   W (ret);
8809   return ret;
8810 }
8811
8812 static int
8813 api_sw_interface_set_unnumbered (vat_main_t * vam)
8814 {
8815   unformat_input_t *i = vam->input;
8816   vl_api_sw_interface_set_unnumbered_t *mp;
8817   u32 sw_if_index;
8818   u32 unnum_sw_index = ~0;
8819   u8 is_add = 1;
8820   u8 sw_if_index_set = 0;
8821   int ret;
8822
8823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8824     {
8825       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8826         sw_if_index_set = 1;
8827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8828         sw_if_index_set = 1;
8829       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8830         ;
8831       else if (unformat (i, "del"))
8832         is_add = 0;
8833       else
8834         {
8835           clib_warning ("parse error '%U'", format_unformat_error, i);
8836           return -99;
8837         }
8838     }
8839
8840   if (sw_if_index_set == 0)
8841     {
8842       errmsg ("missing interface name or sw_if_index");
8843       return -99;
8844     }
8845
8846   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8847
8848   mp->sw_if_index = ntohl (sw_if_index);
8849   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8850   mp->is_add = is_add;
8851
8852   S (mp);
8853   W (ret);
8854   return ret;
8855 }
8856
8857
8858 static int
8859 api_create_vlan_subif (vat_main_t * vam)
8860 {
8861   unformat_input_t *i = vam->input;
8862   vl_api_create_vlan_subif_t *mp;
8863   u32 sw_if_index;
8864   u8 sw_if_index_set = 0;
8865   u32 vlan_id;
8866   u8 vlan_id_set = 0;
8867   int ret;
8868
8869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8870     {
8871       if (unformat (i, "sw_if_index %d", &sw_if_index))
8872         sw_if_index_set = 1;
8873       else
8874         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8875         sw_if_index_set = 1;
8876       else if (unformat (i, "vlan %d", &vlan_id))
8877         vlan_id_set = 1;
8878       else
8879         {
8880           clib_warning ("parse error '%U'", format_unformat_error, i);
8881           return -99;
8882         }
8883     }
8884
8885   if (sw_if_index_set == 0)
8886     {
8887       errmsg ("missing interface name or sw_if_index");
8888       return -99;
8889     }
8890
8891   if (vlan_id_set == 0)
8892     {
8893       errmsg ("missing vlan_id");
8894       return -99;
8895     }
8896   M (CREATE_VLAN_SUBIF, mp);
8897
8898   mp->sw_if_index = ntohl (sw_if_index);
8899   mp->vlan_id = ntohl (vlan_id);
8900
8901   S (mp);
8902   W (ret);
8903   return ret;
8904 }
8905
8906 #define foreach_create_subif_bit                \
8907 _(no_tags)                                      \
8908 _(one_tag)                                      \
8909 _(two_tags)                                     \
8910 _(dot1ad)                                       \
8911 _(exact_match)                                  \
8912 _(default_sub)                                  \
8913 _(outer_vlan_id_any)                            \
8914 _(inner_vlan_id_any)
8915
8916 #define foreach_create_subif_flag               \
8917 _(0, "no_tags")                                 \
8918 _(1, "one_tag")                                 \
8919 _(2, "two_tags")                                \
8920 _(3, "dot1ad")                                  \
8921 _(4, "exact_match")                             \
8922 _(5, "default_sub")                             \
8923 _(6, "outer_vlan_id_any")                       \
8924 _(7, "inner_vlan_id_any")
8925
8926 static int
8927 api_create_subif (vat_main_t * vam)
8928 {
8929   unformat_input_t *i = vam->input;
8930   vl_api_create_subif_t *mp;
8931   u32 sw_if_index;
8932   u8 sw_if_index_set = 0;
8933   u32 sub_id;
8934   u8 sub_id_set = 0;
8935   u32 __attribute__ ((unused)) no_tags = 0;
8936   u32 __attribute__ ((unused)) one_tag = 0;
8937   u32 __attribute__ ((unused)) two_tags = 0;
8938   u32 __attribute__ ((unused)) dot1ad = 0;
8939   u32 __attribute__ ((unused)) exact_match = 0;
8940   u32 __attribute__ ((unused)) default_sub = 0;
8941   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8942   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8943   u32 tmp;
8944   u16 outer_vlan_id = 0;
8945   u16 inner_vlan_id = 0;
8946   int ret;
8947
8948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8949     {
8950       if (unformat (i, "sw_if_index %d", &sw_if_index))
8951         sw_if_index_set = 1;
8952       else
8953         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8954         sw_if_index_set = 1;
8955       else if (unformat (i, "sub_id %d", &sub_id))
8956         sub_id_set = 1;
8957       else if (unformat (i, "outer_vlan_id %d", &tmp))
8958         outer_vlan_id = tmp;
8959       else if (unformat (i, "inner_vlan_id %d", &tmp))
8960         inner_vlan_id = tmp;
8961
8962 #define _(a) else if (unformat (i, #a)) a = 1 ;
8963       foreach_create_subif_bit
8964 #undef _
8965         else
8966         {
8967           clib_warning ("parse error '%U'", format_unformat_error, i);
8968           return -99;
8969         }
8970     }
8971
8972   if (sw_if_index_set == 0)
8973     {
8974       errmsg ("missing interface name or sw_if_index");
8975       return -99;
8976     }
8977
8978   if (sub_id_set == 0)
8979     {
8980       errmsg ("missing sub_id");
8981       return -99;
8982     }
8983   M (CREATE_SUBIF, mp);
8984
8985   mp->sw_if_index = ntohl (sw_if_index);
8986   mp->sub_id = ntohl (sub_id);
8987
8988 #define _(a,b) mp->sub_if_flags |= (1 << a);
8989   foreach_create_subif_flag;
8990 #undef _
8991
8992   mp->outer_vlan_id = ntohs (outer_vlan_id);
8993   mp->inner_vlan_id = ntohs (inner_vlan_id);
8994
8995   S (mp);
8996   W (ret);
8997   return ret;
8998 }
8999
9000 static int
9001 api_ip_table_replace_begin (vat_main_t * vam)
9002 {
9003   unformat_input_t *i = vam->input;
9004   vl_api_ip_table_replace_begin_t *mp;
9005   u32 table_id = 0;
9006   u8 is_ipv6 = 0;
9007
9008   int ret;
9009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9010     {
9011       if (unformat (i, "table %d", &table_id))
9012         ;
9013       else if (unformat (i, "ipv6"))
9014         is_ipv6 = 1;
9015       else
9016         {
9017           clib_warning ("parse error '%U'", format_unformat_error, i);
9018           return -99;
9019         }
9020     }
9021
9022   M (IP_TABLE_REPLACE_BEGIN, mp);
9023
9024   mp->table.table_id = ntohl (table_id);
9025   mp->table.is_ip6 = is_ipv6;
9026
9027   S (mp);
9028   W (ret);
9029   return ret;
9030 }
9031
9032 static int
9033 api_ip_table_flush (vat_main_t * vam)
9034 {
9035   unformat_input_t *i = vam->input;
9036   vl_api_ip_table_flush_t *mp;
9037   u32 table_id = 0;
9038   u8 is_ipv6 = 0;
9039
9040   int ret;
9041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9042     {
9043       if (unformat (i, "table %d", &table_id))
9044         ;
9045       else if (unformat (i, "ipv6"))
9046         is_ipv6 = 1;
9047       else
9048         {
9049           clib_warning ("parse error '%U'", format_unformat_error, i);
9050           return -99;
9051         }
9052     }
9053
9054   M (IP_TABLE_FLUSH, mp);
9055
9056   mp->table.table_id = ntohl (table_id);
9057   mp->table.is_ip6 = is_ipv6;
9058
9059   S (mp);
9060   W (ret);
9061   return ret;
9062 }
9063
9064 static int
9065 api_ip_table_replace_end (vat_main_t * vam)
9066 {
9067   unformat_input_t *i = vam->input;
9068   vl_api_ip_table_replace_end_t *mp;
9069   u32 table_id = 0;
9070   u8 is_ipv6 = 0;
9071
9072   int ret;
9073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9074     {
9075       if (unformat (i, "table %d", &table_id))
9076         ;
9077       else if (unformat (i, "ipv6"))
9078         is_ipv6 = 1;
9079       else
9080         {
9081           clib_warning ("parse error '%U'", format_unformat_error, i);
9082           return -99;
9083         }
9084     }
9085
9086   M (IP_TABLE_REPLACE_END, mp);
9087
9088   mp->table.table_id = ntohl (table_id);
9089   mp->table.is_ip6 = is_ipv6;
9090
9091   S (mp);
9092   W (ret);
9093   return ret;
9094 }
9095
9096 static int
9097 api_set_ip_flow_hash (vat_main_t * vam)
9098 {
9099   unformat_input_t *i = vam->input;
9100   vl_api_set_ip_flow_hash_t *mp;
9101   u32 vrf_id = 0;
9102   u8 is_ipv6 = 0;
9103   u8 vrf_id_set = 0;
9104   u8 src = 0;
9105   u8 dst = 0;
9106   u8 sport = 0;
9107   u8 dport = 0;
9108   u8 proto = 0;
9109   u8 reverse = 0;
9110   int ret;
9111
9112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9113     {
9114       if (unformat (i, "vrf %d", &vrf_id))
9115         vrf_id_set = 1;
9116       else if (unformat (i, "ipv6"))
9117         is_ipv6 = 1;
9118       else if (unformat (i, "src"))
9119         src = 1;
9120       else if (unformat (i, "dst"))
9121         dst = 1;
9122       else if (unformat (i, "sport"))
9123         sport = 1;
9124       else if (unformat (i, "dport"))
9125         dport = 1;
9126       else if (unformat (i, "proto"))
9127         proto = 1;
9128       else if (unformat (i, "reverse"))
9129         reverse = 1;
9130
9131       else
9132         {
9133           clib_warning ("parse error '%U'", format_unformat_error, i);
9134           return -99;
9135         }
9136     }
9137
9138   if (vrf_id_set == 0)
9139     {
9140       errmsg ("missing vrf id");
9141       return -99;
9142     }
9143
9144   M (SET_IP_FLOW_HASH, mp);
9145   mp->src = src;
9146   mp->dst = dst;
9147   mp->sport = sport;
9148   mp->dport = dport;
9149   mp->proto = proto;
9150   mp->reverse = reverse;
9151   mp->vrf_id = ntohl (vrf_id);
9152   mp->is_ipv6 = is_ipv6;
9153
9154   S (mp);
9155   W (ret);
9156   return ret;
9157 }
9158
9159 static int
9160 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9161 {
9162   unformat_input_t *i = vam->input;
9163   vl_api_sw_interface_ip6_enable_disable_t *mp;
9164   u32 sw_if_index;
9165   u8 sw_if_index_set = 0;
9166   u8 enable = 0;
9167   int ret;
9168
9169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9170     {
9171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9172         sw_if_index_set = 1;
9173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9174         sw_if_index_set = 1;
9175       else if (unformat (i, "enable"))
9176         enable = 1;
9177       else if (unformat (i, "disable"))
9178         enable = 0;
9179       else
9180         {
9181           clib_warning ("parse error '%U'", format_unformat_error, i);
9182           return -99;
9183         }
9184     }
9185
9186   if (sw_if_index_set == 0)
9187     {
9188       errmsg ("missing interface name or sw_if_index");
9189       return -99;
9190     }
9191
9192   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9193
9194   mp->sw_if_index = ntohl (sw_if_index);
9195   mp->enable = enable;
9196
9197   S (mp);
9198   W (ret);
9199   return ret;
9200 }
9201
9202
9203 static int
9204 api_l2_patch_add_del (vat_main_t * vam)
9205 {
9206   unformat_input_t *i = vam->input;
9207   vl_api_l2_patch_add_del_t *mp;
9208   u32 rx_sw_if_index;
9209   u8 rx_sw_if_index_set = 0;
9210   u32 tx_sw_if_index;
9211   u8 tx_sw_if_index_set = 0;
9212   u8 is_add = 1;
9213   int ret;
9214
9215   /* Parse args required to build the message */
9216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217     {
9218       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9219         rx_sw_if_index_set = 1;
9220       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9221         tx_sw_if_index_set = 1;
9222       else if (unformat (i, "rx"))
9223         {
9224           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9225             {
9226               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9227                             &rx_sw_if_index))
9228                 rx_sw_if_index_set = 1;
9229             }
9230           else
9231             break;
9232         }
9233       else if (unformat (i, "tx"))
9234         {
9235           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9236             {
9237               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9238                             &tx_sw_if_index))
9239                 tx_sw_if_index_set = 1;
9240             }
9241           else
9242             break;
9243         }
9244       else if (unformat (i, "del"))
9245         is_add = 0;
9246       else
9247         break;
9248     }
9249
9250   if (rx_sw_if_index_set == 0)
9251     {
9252       errmsg ("missing rx interface name or rx_sw_if_index");
9253       return -99;
9254     }
9255
9256   if (tx_sw_if_index_set == 0)
9257     {
9258       errmsg ("missing tx interface name or tx_sw_if_index");
9259       return -99;
9260     }
9261
9262   M (L2_PATCH_ADD_DEL, mp);
9263
9264   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9265   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9266   mp->is_add = is_add;
9267
9268   S (mp);
9269   W (ret);
9270   return ret;
9271 }
9272
9273 u8 is_del;
9274 u8 localsid_addr[16];
9275 u8 end_psp;
9276 u8 behavior;
9277 u32 sw_if_index;
9278 u32 vlan_index;
9279 u32 fib_table;
9280 u8 nh_addr[16];
9281
9282 static int
9283 api_sr_localsid_add_del (vat_main_t * vam)
9284 {
9285   unformat_input_t *i = vam->input;
9286   vl_api_sr_localsid_add_del_t *mp;
9287
9288   u8 is_del;
9289   ip6_address_t localsid;
9290   u8 end_psp = 0;
9291   u8 behavior = ~0;
9292   u32 sw_if_index;
9293   u32 fib_table = ~(u32) 0;
9294   ip6_address_t nh_addr6;
9295   ip4_address_t nh_addr4;
9296   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9297   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9298
9299   bool nexthop_set = 0;
9300
9301   int ret;
9302
9303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9304     {
9305       if (unformat (i, "del"))
9306         is_del = 1;
9307       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9308       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9309         nexthop_set = 1;
9310       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9311         nexthop_set = 1;
9312       else if (unformat (i, "behavior %u", &behavior));
9313       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9314       else if (unformat (i, "fib-table %u", &fib_table));
9315       else if (unformat (i, "end.psp %u", &behavior));
9316       else
9317         break;
9318     }
9319
9320   M (SR_LOCALSID_ADD_DEL, mp);
9321
9322   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9323
9324   if (nexthop_set)
9325     {
9326       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9327       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9328     }
9329   mp->behavior = behavior;
9330   mp->sw_if_index = ntohl (sw_if_index);
9331   mp->fib_table = ntohl (fib_table);
9332   mp->end_psp = end_psp;
9333   mp->is_del = is_del;
9334
9335   S (mp);
9336   W (ret);
9337   return ret;
9338 }
9339
9340 static int
9341 api_ioam_enable (vat_main_t * vam)
9342 {
9343   unformat_input_t *input = vam->input;
9344   vl_api_ioam_enable_t *mp;
9345   u32 id = 0;
9346   int has_trace_option = 0;
9347   int has_pot_option = 0;
9348   int has_seqno_option = 0;
9349   int has_analyse_option = 0;
9350   int ret;
9351
9352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9353     {
9354       if (unformat (input, "trace"))
9355         has_trace_option = 1;
9356       else if (unformat (input, "pot"))
9357         has_pot_option = 1;
9358       else if (unformat (input, "seqno"))
9359         has_seqno_option = 1;
9360       else if (unformat (input, "analyse"))
9361         has_analyse_option = 1;
9362       else
9363         break;
9364     }
9365   M (IOAM_ENABLE, mp);
9366   mp->id = htons (id);
9367   mp->seqno = has_seqno_option;
9368   mp->analyse = has_analyse_option;
9369   mp->pot_enable = has_pot_option;
9370   mp->trace_enable = has_trace_option;
9371
9372   S (mp);
9373   W (ret);
9374   return ret;
9375 }
9376
9377
9378 static int
9379 api_ioam_disable (vat_main_t * vam)
9380 {
9381   vl_api_ioam_disable_t *mp;
9382   int ret;
9383
9384   M (IOAM_DISABLE, mp);
9385   S (mp);
9386   W (ret);
9387   return ret;
9388 }
9389
9390 #define foreach_tcp_proto_field                 \
9391 _(src_port)                                     \
9392 _(dst_port)
9393
9394 #define foreach_udp_proto_field                 \
9395 _(src_port)                                     \
9396 _(dst_port)
9397
9398 #define foreach_ip4_proto_field                 \
9399 _(src_address)                                  \
9400 _(dst_address)                                  \
9401 _(tos)                                          \
9402 _(length)                                       \
9403 _(fragment_id)                                  \
9404 _(ttl)                                          \
9405 _(protocol)                                     \
9406 _(checksum)
9407
9408 typedef struct
9409 {
9410   u16 src_port, dst_port;
9411 } tcpudp_header_t;
9412
9413 #if VPP_API_TEST_BUILTIN == 0
9414 uword
9415 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9416 {
9417   u8 **maskp = va_arg (*args, u8 **);
9418   u8 *mask = 0;
9419   u8 found_something = 0;
9420   tcp_header_t *tcp;
9421
9422 #define _(a) u8 a=0;
9423   foreach_tcp_proto_field;
9424 #undef _
9425
9426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9427     {
9428       if (0);
9429 #define _(a) else if (unformat (input, #a)) a=1;
9430       foreach_tcp_proto_field
9431 #undef _
9432         else
9433         break;
9434     }
9435
9436 #define _(a) found_something += a;
9437   foreach_tcp_proto_field;
9438 #undef _
9439
9440   if (found_something == 0)
9441     return 0;
9442
9443   vec_validate (mask, sizeof (*tcp) - 1);
9444
9445   tcp = (tcp_header_t *) mask;
9446
9447 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9448   foreach_tcp_proto_field;
9449 #undef _
9450
9451   *maskp = mask;
9452   return 1;
9453 }
9454
9455 uword
9456 unformat_udp_mask (unformat_input_t * input, va_list * args)
9457 {
9458   u8 **maskp = va_arg (*args, u8 **);
9459   u8 *mask = 0;
9460   u8 found_something = 0;
9461   udp_header_t *udp;
9462
9463 #define _(a) u8 a=0;
9464   foreach_udp_proto_field;
9465 #undef _
9466
9467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9468     {
9469       if (0);
9470 #define _(a) else if (unformat (input, #a)) a=1;
9471       foreach_udp_proto_field
9472 #undef _
9473         else
9474         break;
9475     }
9476
9477 #define _(a) found_something += a;
9478   foreach_udp_proto_field;
9479 #undef _
9480
9481   if (found_something == 0)
9482     return 0;
9483
9484   vec_validate (mask, sizeof (*udp) - 1);
9485
9486   udp = (udp_header_t *) mask;
9487
9488 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9489   foreach_udp_proto_field;
9490 #undef _
9491
9492   *maskp = mask;
9493   return 1;
9494 }
9495
9496 uword
9497 unformat_l4_mask (unformat_input_t * input, va_list * args)
9498 {
9499   u8 **maskp = va_arg (*args, u8 **);
9500   u16 src_port = 0, dst_port = 0;
9501   tcpudp_header_t *tcpudp;
9502
9503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9504     {
9505       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9506         return 1;
9507       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9508         return 1;
9509       else if (unformat (input, "src_port"))
9510         src_port = 0xFFFF;
9511       else if (unformat (input, "dst_port"))
9512         dst_port = 0xFFFF;
9513       else
9514         return 0;
9515     }
9516
9517   if (!src_port && !dst_port)
9518     return 0;
9519
9520   u8 *mask = 0;
9521   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9522
9523   tcpudp = (tcpudp_header_t *) mask;
9524   tcpudp->src_port = src_port;
9525   tcpudp->dst_port = dst_port;
9526
9527   *maskp = mask;
9528
9529   return 1;
9530 }
9531
9532 uword
9533 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9534 {
9535   u8 **maskp = va_arg (*args, u8 **);
9536   u8 *mask = 0;
9537   u8 found_something = 0;
9538   ip4_header_t *ip;
9539
9540 #define _(a) u8 a=0;
9541   foreach_ip4_proto_field;
9542 #undef _
9543   u8 version = 0;
9544   u8 hdr_length = 0;
9545
9546
9547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9548     {
9549       if (unformat (input, "version"))
9550         version = 1;
9551       else if (unformat (input, "hdr_length"))
9552         hdr_length = 1;
9553       else if (unformat (input, "src"))
9554         src_address = 1;
9555       else if (unformat (input, "dst"))
9556         dst_address = 1;
9557       else if (unformat (input, "proto"))
9558         protocol = 1;
9559
9560 #define _(a) else if (unformat (input, #a)) a=1;
9561       foreach_ip4_proto_field
9562 #undef _
9563         else
9564         break;
9565     }
9566
9567 #define _(a) found_something += a;
9568   foreach_ip4_proto_field;
9569 #undef _
9570
9571   if (found_something == 0)
9572     return 0;
9573
9574   vec_validate (mask, sizeof (*ip) - 1);
9575
9576   ip = (ip4_header_t *) mask;
9577
9578 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9579   foreach_ip4_proto_field;
9580 #undef _
9581
9582   ip->ip_version_and_header_length = 0;
9583
9584   if (version)
9585     ip->ip_version_and_header_length |= 0xF0;
9586
9587   if (hdr_length)
9588     ip->ip_version_and_header_length |= 0x0F;
9589
9590   *maskp = mask;
9591   return 1;
9592 }
9593
9594 #define foreach_ip6_proto_field                 \
9595 _(src_address)                                  \
9596 _(dst_address)                                  \
9597 _(payload_length)                               \
9598 _(hop_limit)                                    \
9599 _(protocol)
9600
9601 uword
9602 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9603 {
9604   u8 **maskp = va_arg (*args, u8 **);
9605   u8 *mask = 0;
9606   u8 found_something = 0;
9607   ip6_header_t *ip;
9608   u32 ip_version_traffic_class_and_flow_label;
9609
9610 #define _(a) u8 a=0;
9611   foreach_ip6_proto_field;
9612 #undef _
9613   u8 version = 0;
9614   u8 traffic_class = 0;
9615   u8 flow_label = 0;
9616
9617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9618     {
9619       if (unformat (input, "version"))
9620         version = 1;
9621       else if (unformat (input, "traffic-class"))
9622         traffic_class = 1;
9623       else if (unformat (input, "flow-label"))
9624         flow_label = 1;
9625       else if (unformat (input, "src"))
9626         src_address = 1;
9627       else if (unformat (input, "dst"))
9628         dst_address = 1;
9629       else if (unformat (input, "proto"))
9630         protocol = 1;
9631
9632 #define _(a) else if (unformat (input, #a)) a=1;
9633       foreach_ip6_proto_field
9634 #undef _
9635         else
9636         break;
9637     }
9638
9639 #define _(a) found_something += a;
9640   foreach_ip6_proto_field;
9641 #undef _
9642
9643   if (found_something == 0)
9644     return 0;
9645
9646   vec_validate (mask, sizeof (*ip) - 1);
9647
9648   ip = (ip6_header_t *) mask;
9649
9650 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9651   foreach_ip6_proto_field;
9652 #undef _
9653
9654   ip_version_traffic_class_and_flow_label = 0;
9655
9656   if (version)
9657     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9658
9659   if (traffic_class)
9660     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9661
9662   if (flow_label)
9663     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9664
9665   ip->ip_version_traffic_class_and_flow_label =
9666     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9667
9668   *maskp = mask;
9669   return 1;
9670 }
9671
9672 uword
9673 unformat_l3_mask (unformat_input_t * input, va_list * args)
9674 {
9675   u8 **maskp = va_arg (*args, u8 **);
9676
9677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9678     {
9679       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9680         return 1;
9681       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9682         return 1;
9683       else
9684         break;
9685     }
9686   return 0;
9687 }
9688
9689 uword
9690 unformat_l2_mask (unformat_input_t * input, va_list * args)
9691 {
9692   u8 **maskp = va_arg (*args, u8 **);
9693   u8 *mask = 0;
9694   u8 src = 0;
9695   u8 dst = 0;
9696   u8 proto = 0;
9697   u8 tag1 = 0;
9698   u8 tag2 = 0;
9699   u8 ignore_tag1 = 0;
9700   u8 ignore_tag2 = 0;
9701   u8 cos1 = 0;
9702   u8 cos2 = 0;
9703   u8 dot1q = 0;
9704   u8 dot1ad = 0;
9705   int len = 14;
9706
9707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (input, "src"))
9710         src = 1;
9711       else if (unformat (input, "dst"))
9712         dst = 1;
9713       else if (unformat (input, "proto"))
9714         proto = 1;
9715       else if (unformat (input, "tag1"))
9716         tag1 = 1;
9717       else if (unformat (input, "tag2"))
9718         tag2 = 1;
9719       else if (unformat (input, "ignore-tag1"))
9720         ignore_tag1 = 1;
9721       else if (unformat (input, "ignore-tag2"))
9722         ignore_tag2 = 1;
9723       else if (unformat (input, "cos1"))
9724         cos1 = 1;
9725       else if (unformat (input, "cos2"))
9726         cos2 = 1;
9727       else if (unformat (input, "dot1q"))
9728         dot1q = 1;
9729       else if (unformat (input, "dot1ad"))
9730         dot1ad = 1;
9731       else
9732         break;
9733     }
9734   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9735        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9736     return 0;
9737
9738   if (tag1 || ignore_tag1 || cos1 || dot1q)
9739     len = 18;
9740   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9741     len = 22;
9742
9743   vec_validate (mask, len - 1);
9744
9745   if (dst)
9746     clib_memset (mask, 0xff, 6);
9747
9748   if (src)
9749     clib_memset (mask + 6, 0xff, 6);
9750
9751   if (tag2 || dot1ad)
9752     {
9753       /* inner vlan tag */
9754       if (tag2)
9755         {
9756           mask[19] = 0xff;
9757           mask[18] = 0x0f;
9758         }
9759       if (cos2)
9760         mask[18] |= 0xe0;
9761       if (proto)
9762         mask[21] = mask[20] = 0xff;
9763       if (tag1)
9764         {
9765           mask[15] = 0xff;
9766           mask[14] = 0x0f;
9767         }
9768       if (cos1)
9769         mask[14] |= 0xe0;
9770       *maskp = mask;
9771       return 1;
9772     }
9773   if (tag1 | dot1q)
9774     {
9775       if (tag1)
9776         {
9777           mask[15] = 0xff;
9778           mask[14] = 0x0f;
9779         }
9780       if (cos1)
9781         mask[14] |= 0xe0;
9782       if (proto)
9783         mask[16] = mask[17] = 0xff;
9784
9785       *maskp = mask;
9786       return 1;
9787     }
9788   if (cos2)
9789     mask[18] |= 0xe0;
9790   if (cos1)
9791     mask[14] |= 0xe0;
9792   if (proto)
9793     mask[12] = mask[13] = 0xff;
9794
9795   *maskp = mask;
9796   return 1;
9797 }
9798
9799 uword
9800 unformat_classify_mask (unformat_input_t * input, va_list * args)
9801 {
9802   u8 **maskp = va_arg (*args, u8 **);
9803   u32 *skipp = va_arg (*args, u32 *);
9804   u32 *matchp = va_arg (*args, u32 *);
9805   u32 match;
9806   u8 *mask = 0;
9807   u8 *l2 = 0;
9808   u8 *l3 = 0;
9809   u8 *l4 = 0;
9810   int i;
9811
9812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9813     {
9814       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9815         ;
9816       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9817         ;
9818       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9819         ;
9820       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9821         ;
9822       else
9823         break;
9824     }
9825
9826   if (l4 && !l3)
9827     {
9828       vec_free (mask);
9829       vec_free (l2);
9830       vec_free (l4);
9831       return 0;
9832     }
9833
9834   if (mask || l2 || l3 || l4)
9835     {
9836       if (l2 || l3 || l4)
9837         {
9838           /* "With a free Ethernet header in every package" */
9839           if (l2 == 0)
9840             vec_validate (l2, 13);
9841           mask = l2;
9842           if (vec_len (l3))
9843             {
9844               vec_append (mask, l3);
9845               vec_free (l3);
9846             }
9847           if (vec_len (l4))
9848             {
9849               vec_append (mask, l4);
9850               vec_free (l4);
9851             }
9852         }
9853
9854       /* Scan forward looking for the first significant mask octet */
9855       for (i = 0; i < vec_len (mask); i++)
9856         if (mask[i])
9857           break;
9858
9859       /* compute (skip, match) params */
9860       *skipp = i / sizeof (u32x4);
9861       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9862
9863       /* Pad mask to an even multiple of the vector size */
9864       while (vec_len (mask) % sizeof (u32x4))
9865         vec_add1 (mask, 0);
9866
9867       match = vec_len (mask) / sizeof (u32x4);
9868
9869       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9870         {
9871           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9872           if (*tmp || *(tmp + 1))
9873             break;
9874           match--;
9875         }
9876       if (match == 0)
9877         clib_warning ("BUG: match 0");
9878
9879       _vec_len (mask) = match * sizeof (u32x4);
9880
9881       *matchp = match;
9882       *maskp = mask;
9883
9884       return 1;
9885     }
9886
9887   return 0;
9888 }
9889 #endif /* VPP_API_TEST_BUILTIN */
9890
9891 #define foreach_l2_next                         \
9892 _(drop, DROP)                                   \
9893 _(ethernet, ETHERNET_INPUT)                     \
9894 _(ip4, IP4_INPUT)                               \
9895 _(ip6, IP6_INPUT)
9896
9897 uword
9898 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9899 {
9900   u32 *miss_next_indexp = va_arg (*args, u32 *);
9901   u32 next_index = 0;
9902   u32 tmp;
9903
9904 #define _(n,N) \
9905   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9906   foreach_l2_next;
9907 #undef _
9908
9909   if (unformat (input, "%d", &tmp))
9910     {
9911       next_index = tmp;
9912       goto out;
9913     }
9914
9915   return 0;
9916
9917 out:
9918   *miss_next_indexp = next_index;
9919   return 1;
9920 }
9921
9922 #define foreach_ip_next                         \
9923 _(drop, DROP)                                   \
9924 _(local, LOCAL)                                 \
9925 _(rewrite, REWRITE)
9926
9927 uword
9928 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9929 {
9930   u32 *miss_next_indexp = va_arg (*args, u32 *);
9931   u32 next_index = 0;
9932   u32 tmp;
9933
9934 #define _(n,N) \
9935   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9936   foreach_ip_next;
9937 #undef _
9938
9939   if (unformat (input, "%d", &tmp))
9940     {
9941       next_index = tmp;
9942       goto out;
9943     }
9944
9945   return 0;
9946
9947 out:
9948   *miss_next_indexp = next_index;
9949   return 1;
9950 }
9951
9952 #define foreach_acl_next                        \
9953 _(deny, DENY)
9954
9955 uword
9956 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9957 {
9958   u32 *miss_next_indexp = va_arg (*args, u32 *);
9959   u32 next_index = 0;
9960   u32 tmp;
9961
9962 #define _(n,N) \
9963   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9964   foreach_acl_next;
9965 #undef _
9966
9967   if (unformat (input, "permit"))
9968     {
9969       next_index = ~0;
9970       goto out;
9971     }
9972   else if (unformat (input, "%d", &tmp))
9973     {
9974       next_index = tmp;
9975       goto out;
9976     }
9977
9978   return 0;
9979
9980 out:
9981   *miss_next_indexp = next_index;
9982   return 1;
9983 }
9984
9985 uword
9986 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9987 {
9988   u32 *r = va_arg (*args, u32 *);
9989
9990   if (unformat (input, "conform-color"))
9991     *r = POLICE_CONFORM;
9992   else if (unformat (input, "exceed-color"))
9993     *r = POLICE_EXCEED;
9994   else
9995     return 0;
9996
9997   return 1;
9998 }
9999
10000 static int
10001 api_classify_add_del_table (vat_main_t * vam)
10002 {
10003   unformat_input_t *i = vam->input;
10004   vl_api_classify_add_del_table_t *mp;
10005
10006   u32 nbuckets = 2;
10007   u32 skip = ~0;
10008   u32 match = ~0;
10009   int is_add = 1;
10010   int del_chain = 0;
10011   u32 table_index = ~0;
10012   u32 next_table_index = ~0;
10013   u32 miss_next_index = ~0;
10014   u32 memory_size = 32 << 20;
10015   u8 *mask = 0;
10016   u32 current_data_flag = 0;
10017   int current_data_offset = 0;
10018   int ret;
10019
10020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10021     {
10022       if (unformat (i, "del"))
10023         is_add = 0;
10024       else if (unformat (i, "del-chain"))
10025         {
10026           is_add = 0;
10027           del_chain = 1;
10028         }
10029       else if (unformat (i, "buckets %d", &nbuckets))
10030         ;
10031       else if (unformat (i, "memory_size %d", &memory_size))
10032         ;
10033       else if (unformat (i, "skip %d", &skip))
10034         ;
10035       else if (unformat (i, "match %d", &match))
10036         ;
10037       else if (unformat (i, "table %d", &table_index))
10038         ;
10039       else if (unformat (i, "mask %U", unformat_classify_mask,
10040                          &mask, &skip, &match))
10041         ;
10042       else if (unformat (i, "next-table %d", &next_table_index))
10043         ;
10044       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10045                          &miss_next_index))
10046         ;
10047       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10048                          &miss_next_index))
10049         ;
10050       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10051                          &miss_next_index))
10052         ;
10053       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10054         ;
10055       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10056         ;
10057       else
10058         break;
10059     }
10060
10061   if (is_add && mask == 0)
10062     {
10063       errmsg ("Mask required");
10064       return -99;
10065     }
10066
10067   if (is_add && skip == ~0)
10068     {
10069       errmsg ("skip count required");
10070       return -99;
10071     }
10072
10073   if (is_add && match == ~0)
10074     {
10075       errmsg ("match count required");
10076       return -99;
10077     }
10078
10079   if (!is_add && table_index == ~0)
10080     {
10081       errmsg ("table index required for delete");
10082       return -99;
10083     }
10084
10085   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10086
10087   mp->is_add = is_add;
10088   mp->del_chain = del_chain;
10089   mp->table_index = ntohl (table_index);
10090   mp->nbuckets = ntohl (nbuckets);
10091   mp->memory_size = ntohl (memory_size);
10092   mp->skip_n_vectors = ntohl (skip);
10093   mp->match_n_vectors = ntohl (match);
10094   mp->next_table_index = ntohl (next_table_index);
10095   mp->miss_next_index = ntohl (miss_next_index);
10096   mp->current_data_flag = ntohl (current_data_flag);
10097   mp->current_data_offset = ntohl (current_data_offset);
10098   mp->mask_len = ntohl (vec_len (mask));
10099   clib_memcpy (mp->mask, mask, vec_len (mask));
10100
10101   vec_free (mask);
10102
10103   S (mp);
10104   W (ret);
10105   return ret;
10106 }
10107
10108 #if VPP_API_TEST_BUILTIN == 0
10109 uword
10110 unformat_l4_match (unformat_input_t * input, va_list * args)
10111 {
10112   u8 **matchp = va_arg (*args, u8 **);
10113
10114   u8 *proto_header = 0;
10115   int src_port = 0;
10116   int dst_port = 0;
10117
10118   tcpudp_header_t h;
10119
10120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10121     {
10122       if (unformat (input, "src_port %d", &src_port))
10123         ;
10124       else if (unformat (input, "dst_port %d", &dst_port))
10125         ;
10126       else
10127         return 0;
10128     }
10129
10130   h.src_port = clib_host_to_net_u16 (src_port);
10131   h.dst_port = clib_host_to_net_u16 (dst_port);
10132   vec_validate (proto_header, sizeof (h) - 1);
10133   memcpy (proto_header, &h, sizeof (h));
10134
10135   *matchp = proto_header;
10136
10137   return 1;
10138 }
10139
10140 uword
10141 unformat_ip4_match (unformat_input_t * input, va_list * args)
10142 {
10143   u8 **matchp = va_arg (*args, u8 **);
10144   u8 *match = 0;
10145   ip4_header_t *ip;
10146   int version = 0;
10147   u32 version_val;
10148   int hdr_length = 0;
10149   u32 hdr_length_val;
10150   int src = 0, dst = 0;
10151   ip4_address_t src_val, dst_val;
10152   int proto = 0;
10153   u32 proto_val;
10154   int tos = 0;
10155   u32 tos_val;
10156   int length = 0;
10157   u32 length_val;
10158   int fragment_id = 0;
10159   u32 fragment_id_val;
10160   int ttl = 0;
10161   int ttl_val;
10162   int checksum = 0;
10163   u32 checksum_val;
10164
10165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10166     {
10167       if (unformat (input, "version %d", &version_val))
10168         version = 1;
10169       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10170         hdr_length = 1;
10171       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10172         src = 1;
10173       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10174         dst = 1;
10175       else if (unformat (input, "proto %d", &proto_val))
10176         proto = 1;
10177       else if (unformat (input, "tos %d", &tos_val))
10178         tos = 1;
10179       else if (unformat (input, "length %d", &length_val))
10180         length = 1;
10181       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10182         fragment_id = 1;
10183       else if (unformat (input, "ttl %d", &ttl_val))
10184         ttl = 1;
10185       else if (unformat (input, "checksum %d", &checksum_val))
10186         checksum = 1;
10187       else
10188         break;
10189     }
10190
10191   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10192       + ttl + checksum == 0)
10193     return 0;
10194
10195   /*
10196    * Aligned because we use the real comparison functions
10197    */
10198   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10199
10200   ip = (ip4_header_t *) match;
10201
10202   /* These are realistically matched in practice */
10203   if (src)
10204     ip->src_address.as_u32 = src_val.as_u32;
10205
10206   if (dst)
10207     ip->dst_address.as_u32 = dst_val.as_u32;
10208
10209   if (proto)
10210     ip->protocol = proto_val;
10211
10212
10213   /* These are not, but they're included for completeness */
10214   if (version)
10215     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10216
10217   if (hdr_length)
10218     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10219
10220   if (tos)
10221     ip->tos = tos_val;
10222
10223   if (length)
10224     ip->length = clib_host_to_net_u16 (length_val);
10225
10226   if (ttl)
10227     ip->ttl = ttl_val;
10228
10229   if (checksum)
10230     ip->checksum = clib_host_to_net_u16 (checksum_val);
10231
10232   *matchp = match;
10233   return 1;
10234 }
10235
10236 uword
10237 unformat_ip6_match (unformat_input_t * input, va_list * args)
10238 {
10239   u8 **matchp = va_arg (*args, u8 **);
10240   u8 *match = 0;
10241   ip6_header_t *ip;
10242   int version = 0;
10243   u32 version_val;
10244   u8 traffic_class = 0;
10245   u32 traffic_class_val = 0;
10246   u8 flow_label = 0;
10247   u8 flow_label_val;
10248   int src = 0, dst = 0;
10249   ip6_address_t src_val, dst_val;
10250   int proto = 0;
10251   u32 proto_val;
10252   int payload_length = 0;
10253   u32 payload_length_val;
10254   int hop_limit = 0;
10255   int hop_limit_val;
10256   u32 ip_version_traffic_class_and_flow_label;
10257
10258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10259     {
10260       if (unformat (input, "version %d", &version_val))
10261         version = 1;
10262       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10263         traffic_class = 1;
10264       else if (unformat (input, "flow_label %d", &flow_label_val))
10265         flow_label = 1;
10266       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10267         src = 1;
10268       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10269         dst = 1;
10270       else if (unformat (input, "proto %d", &proto_val))
10271         proto = 1;
10272       else if (unformat (input, "payload_length %d", &payload_length_val))
10273         payload_length = 1;
10274       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10275         hop_limit = 1;
10276       else
10277         break;
10278     }
10279
10280   if (version + traffic_class + flow_label + src + dst + proto +
10281       payload_length + hop_limit == 0)
10282     return 0;
10283
10284   /*
10285    * Aligned because we use the real comparison functions
10286    */
10287   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10288
10289   ip = (ip6_header_t *) match;
10290
10291   if (src)
10292     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10293
10294   if (dst)
10295     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10296
10297   if (proto)
10298     ip->protocol = proto_val;
10299
10300   ip_version_traffic_class_and_flow_label = 0;
10301
10302   if (version)
10303     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10304
10305   if (traffic_class)
10306     ip_version_traffic_class_and_flow_label |=
10307       (traffic_class_val & 0xFF) << 20;
10308
10309   if (flow_label)
10310     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10311
10312   ip->ip_version_traffic_class_and_flow_label =
10313     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10314
10315   if (payload_length)
10316     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10317
10318   if (hop_limit)
10319     ip->hop_limit = hop_limit_val;
10320
10321   *matchp = match;
10322   return 1;
10323 }
10324
10325 uword
10326 unformat_l3_match (unformat_input_t * input, va_list * args)
10327 {
10328   u8 **matchp = va_arg (*args, u8 **);
10329
10330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10331     {
10332       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10333         return 1;
10334       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10335         return 1;
10336       else
10337         break;
10338     }
10339   return 0;
10340 }
10341
10342 uword
10343 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10344 {
10345   u8 *tagp = va_arg (*args, u8 *);
10346   u32 tag;
10347
10348   if (unformat (input, "%d", &tag))
10349     {
10350       tagp[0] = (tag >> 8) & 0x0F;
10351       tagp[1] = tag & 0xFF;
10352       return 1;
10353     }
10354
10355   return 0;
10356 }
10357
10358 uword
10359 unformat_l2_match (unformat_input_t * input, va_list * args)
10360 {
10361   u8 **matchp = va_arg (*args, u8 **);
10362   u8 *match = 0;
10363   u8 src = 0;
10364   u8 src_val[6];
10365   u8 dst = 0;
10366   u8 dst_val[6];
10367   u8 proto = 0;
10368   u16 proto_val;
10369   u8 tag1 = 0;
10370   u8 tag1_val[2];
10371   u8 tag2 = 0;
10372   u8 tag2_val[2];
10373   int len = 14;
10374   u8 ignore_tag1 = 0;
10375   u8 ignore_tag2 = 0;
10376   u8 cos1 = 0;
10377   u8 cos2 = 0;
10378   u32 cos1_val = 0;
10379   u32 cos2_val = 0;
10380
10381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10382     {
10383       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10384         src = 1;
10385       else
10386         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10387         dst = 1;
10388       else if (unformat (input, "proto %U",
10389                          unformat_ethernet_type_host_byte_order, &proto_val))
10390         proto = 1;
10391       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10392         tag1 = 1;
10393       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10394         tag2 = 1;
10395       else if (unformat (input, "ignore-tag1"))
10396         ignore_tag1 = 1;
10397       else if (unformat (input, "ignore-tag2"))
10398         ignore_tag2 = 1;
10399       else if (unformat (input, "cos1 %d", &cos1_val))
10400         cos1 = 1;
10401       else if (unformat (input, "cos2 %d", &cos2_val))
10402         cos2 = 1;
10403       else
10404         break;
10405     }
10406   if ((src + dst + proto + tag1 + tag2 +
10407        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10408     return 0;
10409
10410   if (tag1 || ignore_tag1 || cos1)
10411     len = 18;
10412   if (tag2 || ignore_tag2 || cos2)
10413     len = 22;
10414
10415   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10416
10417   if (dst)
10418     clib_memcpy (match, dst_val, 6);
10419
10420   if (src)
10421     clib_memcpy (match + 6, src_val, 6);
10422
10423   if (tag2)
10424     {
10425       /* inner vlan tag */
10426       match[19] = tag2_val[1];
10427       match[18] = tag2_val[0];
10428       if (cos2)
10429         match[18] |= (cos2_val & 0x7) << 5;
10430       if (proto)
10431         {
10432           match[21] = proto_val & 0xff;
10433           match[20] = proto_val >> 8;
10434         }
10435       if (tag1)
10436         {
10437           match[15] = tag1_val[1];
10438           match[14] = tag1_val[0];
10439         }
10440       if (cos1)
10441         match[14] |= (cos1_val & 0x7) << 5;
10442       *matchp = match;
10443       return 1;
10444     }
10445   if (tag1)
10446     {
10447       match[15] = tag1_val[1];
10448       match[14] = tag1_val[0];
10449       if (proto)
10450         {
10451           match[17] = proto_val & 0xff;
10452           match[16] = proto_val >> 8;
10453         }
10454       if (cos1)
10455         match[14] |= (cos1_val & 0x7) << 5;
10456
10457       *matchp = match;
10458       return 1;
10459     }
10460   if (cos2)
10461     match[18] |= (cos2_val & 0x7) << 5;
10462   if (cos1)
10463     match[14] |= (cos1_val & 0x7) << 5;
10464   if (proto)
10465     {
10466       match[13] = proto_val & 0xff;
10467       match[12] = proto_val >> 8;
10468     }
10469
10470   *matchp = match;
10471   return 1;
10472 }
10473
10474 uword
10475 unformat_qos_source (unformat_input_t * input, va_list * args)
10476 {
10477   int *qs = va_arg (*args, int *);
10478
10479   if (unformat (input, "ip"))
10480     *qs = QOS_SOURCE_IP;
10481   else if (unformat (input, "mpls"))
10482     *qs = QOS_SOURCE_MPLS;
10483   else if (unformat (input, "ext"))
10484     *qs = QOS_SOURCE_EXT;
10485   else if (unformat (input, "vlan"))
10486     *qs = QOS_SOURCE_VLAN;
10487   else
10488     return 0;
10489
10490   return 1;
10491 }
10492 #endif
10493
10494 uword
10495 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10496 {
10497   u8 **matchp = va_arg (*args, u8 **);
10498   u32 skip_n_vectors = va_arg (*args, u32);
10499   u32 match_n_vectors = va_arg (*args, u32);
10500
10501   u8 *match = 0;
10502   u8 *l2 = 0;
10503   u8 *l3 = 0;
10504   u8 *l4 = 0;
10505
10506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10507     {
10508       if (unformat (input, "hex %U", unformat_hex_string, &match))
10509         ;
10510       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10511         ;
10512       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10513         ;
10514       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10515         ;
10516       else
10517         break;
10518     }
10519
10520   if (l4 && !l3)
10521     {
10522       vec_free (match);
10523       vec_free (l2);
10524       vec_free (l4);
10525       return 0;
10526     }
10527
10528   if (match || l2 || l3 || l4)
10529     {
10530       if (l2 || l3 || l4)
10531         {
10532           /* "Win a free Ethernet header in every packet" */
10533           if (l2 == 0)
10534             vec_validate_aligned (l2, 13, sizeof (u32x4));
10535           match = l2;
10536           if (vec_len (l3))
10537             {
10538               vec_append_aligned (match, l3, sizeof (u32x4));
10539               vec_free (l3);
10540             }
10541           if (vec_len (l4))
10542             {
10543               vec_append_aligned (match, l4, sizeof (u32x4));
10544               vec_free (l4);
10545             }
10546         }
10547
10548       /* Make sure the vector is big enough even if key is all 0's */
10549       vec_validate_aligned
10550         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10551          sizeof (u32x4));
10552
10553       /* Set size, include skipped vectors */
10554       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10555
10556       *matchp = match;
10557
10558       return 1;
10559     }
10560
10561   return 0;
10562 }
10563
10564 static int
10565 api_classify_add_del_session (vat_main_t * vam)
10566 {
10567   unformat_input_t *i = vam->input;
10568   vl_api_classify_add_del_session_t *mp;
10569   int is_add = 1;
10570   u32 table_index = ~0;
10571   u32 hit_next_index = ~0;
10572   u32 opaque_index = ~0;
10573   u8 *match = 0;
10574   i32 advance = 0;
10575   u32 skip_n_vectors = 0;
10576   u32 match_n_vectors = 0;
10577   u32 action = 0;
10578   u32 metadata = 0;
10579   int ret;
10580
10581   /*
10582    * Warning: you have to supply skip_n and match_n
10583    * because the API client cant simply look at the classify
10584    * table object.
10585    */
10586
10587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10588     {
10589       if (unformat (i, "del"))
10590         is_add = 0;
10591       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10592                          &hit_next_index))
10593         ;
10594       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10595                          &hit_next_index))
10596         ;
10597       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10598                          &hit_next_index))
10599         ;
10600       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10601         ;
10602       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10603         ;
10604       else if (unformat (i, "opaque-index %d", &opaque_index))
10605         ;
10606       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10607         ;
10608       else if (unformat (i, "match_n %d", &match_n_vectors))
10609         ;
10610       else if (unformat (i, "match %U", api_unformat_classify_match,
10611                          &match, skip_n_vectors, match_n_vectors))
10612         ;
10613       else if (unformat (i, "advance %d", &advance))
10614         ;
10615       else if (unformat (i, "table-index %d", &table_index))
10616         ;
10617       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10618         action = 1;
10619       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10620         action = 2;
10621       else if (unformat (i, "action %d", &action))
10622         ;
10623       else if (unformat (i, "metadata %d", &metadata))
10624         ;
10625       else
10626         break;
10627     }
10628
10629   if (table_index == ~0)
10630     {
10631       errmsg ("Table index required");
10632       return -99;
10633     }
10634
10635   if (is_add && match == 0)
10636     {
10637       errmsg ("Match value required");
10638       return -99;
10639     }
10640
10641   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10642
10643   mp->is_add = is_add;
10644   mp->table_index = ntohl (table_index);
10645   mp->hit_next_index = ntohl (hit_next_index);
10646   mp->opaque_index = ntohl (opaque_index);
10647   mp->advance = ntohl (advance);
10648   mp->action = action;
10649   mp->metadata = ntohl (metadata);
10650   mp->match_len = ntohl (vec_len (match));
10651   clib_memcpy (mp->match, match, vec_len (match));
10652   vec_free (match);
10653
10654   S (mp);
10655   W (ret);
10656   return ret;
10657 }
10658
10659 static int
10660 api_classify_set_interface_ip_table (vat_main_t * vam)
10661 {
10662   unformat_input_t *i = vam->input;
10663   vl_api_classify_set_interface_ip_table_t *mp;
10664   u32 sw_if_index;
10665   int sw_if_index_set;
10666   u32 table_index = ~0;
10667   u8 is_ipv6 = 0;
10668   int ret;
10669
10670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10671     {
10672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10673         sw_if_index_set = 1;
10674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10675         sw_if_index_set = 1;
10676       else if (unformat (i, "table %d", &table_index))
10677         ;
10678       else
10679         {
10680           clib_warning ("parse error '%U'", format_unformat_error, i);
10681           return -99;
10682         }
10683     }
10684
10685   if (sw_if_index_set == 0)
10686     {
10687       errmsg ("missing interface name or sw_if_index");
10688       return -99;
10689     }
10690
10691
10692   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10693
10694   mp->sw_if_index = ntohl (sw_if_index);
10695   mp->table_index = ntohl (table_index);
10696   mp->is_ipv6 = is_ipv6;
10697
10698   S (mp);
10699   W (ret);
10700   return ret;
10701 }
10702
10703 static int
10704 api_classify_set_interface_l2_tables (vat_main_t * vam)
10705 {
10706   unformat_input_t *i = vam->input;
10707   vl_api_classify_set_interface_l2_tables_t *mp;
10708   u32 sw_if_index;
10709   int sw_if_index_set;
10710   u32 ip4_table_index = ~0;
10711   u32 ip6_table_index = ~0;
10712   u32 other_table_index = ~0;
10713   u32 is_input = 1;
10714   int ret;
10715
10716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10717     {
10718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10719         sw_if_index_set = 1;
10720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10721         sw_if_index_set = 1;
10722       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10723         ;
10724       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10725         ;
10726       else if (unformat (i, "other-table %d", &other_table_index))
10727         ;
10728       else if (unformat (i, "is-input %d", &is_input))
10729         ;
10730       else
10731         {
10732           clib_warning ("parse error '%U'", format_unformat_error, i);
10733           return -99;
10734         }
10735     }
10736
10737   if (sw_if_index_set == 0)
10738     {
10739       errmsg ("missing interface name or sw_if_index");
10740       return -99;
10741     }
10742
10743
10744   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10745
10746   mp->sw_if_index = ntohl (sw_if_index);
10747   mp->ip4_table_index = ntohl (ip4_table_index);
10748   mp->ip6_table_index = ntohl (ip6_table_index);
10749   mp->other_table_index = ntohl (other_table_index);
10750   mp->is_input = (u8) is_input;
10751
10752   S (mp);
10753   W (ret);
10754   return ret;
10755 }
10756
10757 static int
10758 api_set_ipfix_exporter (vat_main_t * vam)
10759 {
10760   unformat_input_t *i = vam->input;
10761   vl_api_set_ipfix_exporter_t *mp;
10762   ip4_address_t collector_address;
10763   u8 collector_address_set = 0;
10764   u32 collector_port = ~0;
10765   ip4_address_t src_address;
10766   u8 src_address_set = 0;
10767   u32 vrf_id = ~0;
10768   u32 path_mtu = ~0;
10769   u32 template_interval = ~0;
10770   u8 udp_checksum = 0;
10771   int ret;
10772
10773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10774     {
10775       if (unformat (i, "collector_address %U", unformat_ip4_address,
10776                     &collector_address))
10777         collector_address_set = 1;
10778       else if (unformat (i, "collector_port %d", &collector_port))
10779         ;
10780       else if (unformat (i, "src_address %U", unformat_ip4_address,
10781                          &src_address))
10782         src_address_set = 1;
10783       else if (unformat (i, "vrf_id %d", &vrf_id))
10784         ;
10785       else if (unformat (i, "path_mtu %d", &path_mtu))
10786         ;
10787       else if (unformat (i, "template_interval %d", &template_interval))
10788         ;
10789       else if (unformat (i, "udp_checksum"))
10790         udp_checksum = 1;
10791       else
10792         break;
10793     }
10794
10795   if (collector_address_set == 0)
10796     {
10797       errmsg ("collector_address required");
10798       return -99;
10799     }
10800
10801   if (src_address_set == 0)
10802     {
10803       errmsg ("src_address required");
10804       return -99;
10805     }
10806
10807   M (SET_IPFIX_EXPORTER, mp);
10808
10809   memcpy (mp->collector_address.un.ip4, collector_address.data,
10810           sizeof (collector_address.data));
10811   mp->collector_port = htons ((u16) collector_port);
10812   memcpy (mp->src_address.un.ip4, src_address.data,
10813           sizeof (src_address.data));
10814   mp->vrf_id = htonl (vrf_id);
10815   mp->path_mtu = htonl (path_mtu);
10816   mp->template_interval = htonl (template_interval);
10817   mp->udp_checksum = udp_checksum;
10818
10819   S (mp);
10820   W (ret);
10821   return ret;
10822 }
10823
10824 static int
10825 api_set_ipfix_classify_stream (vat_main_t * vam)
10826 {
10827   unformat_input_t *i = vam->input;
10828   vl_api_set_ipfix_classify_stream_t *mp;
10829   u32 domain_id = 0;
10830   u32 src_port = UDP_DST_PORT_ipfix;
10831   int ret;
10832
10833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10834     {
10835       if (unformat (i, "domain %d", &domain_id))
10836         ;
10837       else if (unformat (i, "src_port %d", &src_port))
10838         ;
10839       else
10840         {
10841           errmsg ("unknown input `%U'", format_unformat_error, i);
10842           return -99;
10843         }
10844     }
10845
10846   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10847
10848   mp->domain_id = htonl (domain_id);
10849   mp->src_port = htons ((u16) src_port);
10850
10851   S (mp);
10852   W (ret);
10853   return ret;
10854 }
10855
10856 static int
10857 api_ipfix_classify_table_add_del (vat_main_t * vam)
10858 {
10859   unformat_input_t *i = vam->input;
10860   vl_api_ipfix_classify_table_add_del_t *mp;
10861   int is_add = -1;
10862   u32 classify_table_index = ~0;
10863   u8 ip_version = 0;
10864   u8 transport_protocol = 255;
10865   int ret;
10866
10867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (i, "add"))
10870         is_add = 1;
10871       else if (unformat (i, "del"))
10872         is_add = 0;
10873       else if (unformat (i, "table %d", &classify_table_index))
10874         ;
10875       else if (unformat (i, "ip4"))
10876         ip_version = 4;
10877       else if (unformat (i, "ip6"))
10878         ip_version = 6;
10879       else if (unformat (i, "tcp"))
10880         transport_protocol = 6;
10881       else if (unformat (i, "udp"))
10882         transport_protocol = 17;
10883       else
10884         {
10885           errmsg ("unknown input `%U'", format_unformat_error, i);
10886           return -99;
10887         }
10888     }
10889
10890   if (is_add == -1)
10891     {
10892       errmsg ("expecting: add|del");
10893       return -99;
10894     }
10895   if (classify_table_index == ~0)
10896     {
10897       errmsg ("classifier table not specified");
10898       return -99;
10899     }
10900   if (ip_version == 0)
10901     {
10902       errmsg ("IP version not specified");
10903       return -99;
10904     }
10905
10906   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10907
10908   mp->is_add = is_add;
10909   mp->table_id = htonl (classify_table_index);
10910   mp->ip_version = ip_version;
10911   mp->transport_protocol = transport_protocol;
10912
10913   S (mp);
10914   W (ret);
10915   return ret;
10916 }
10917
10918 static int
10919 api_get_node_index (vat_main_t * vam)
10920 {
10921   unformat_input_t *i = vam->input;
10922   vl_api_get_node_index_t *mp;
10923   u8 *name = 0;
10924   int ret;
10925
10926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10927     {
10928       if (unformat (i, "node %s", &name))
10929         ;
10930       else
10931         break;
10932     }
10933   if (name == 0)
10934     {
10935       errmsg ("node name required");
10936       return -99;
10937     }
10938   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10939     {
10940       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10941       return -99;
10942     }
10943
10944   M (GET_NODE_INDEX, mp);
10945   clib_memcpy (mp->node_name, name, vec_len (name));
10946   vec_free (name);
10947
10948   S (mp);
10949   W (ret);
10950   return ret;
10951 }
10952
10953 static int
10954 api_get_next_index (vat_main_t * vam)
10955 {
10956   unformat_input_t *i = vam->input;
10957   vl_api_get_next_index_t *mp;
10958   u8 *node_name = 0, *next_node_name = 0;
10959   int ret;
10960
10961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10962     {
10963       if (unformat (i, "node-name %s", &node_name))
10964         ;
10965       else if (unformat (i, "next-node-name %s", &next_node_name))
10966         break;
10967     }
10968
10969   if (node_name == 0)
10970     {
10971       errmsg ("node name required");
10972       return -99;
10973     }
10974   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10975     {
10976       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10977       return -99;
10978     }
10979
10980   if (next_node_name == 0)
10981     {
10982       errmsg ("next node name required");
10983       return -99;
10984     }
10985   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10986     {
10987       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10988       return -99;
10989     }
10990
10991   M (GET_NEXT_INDEX, mp);
10992   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10993   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10994   vec_free (node_name);
10995   vec_free (next_node_name);
10996
10997   S (mp);
10998   W (ret);
10999   return ret;
11000 }
11001
11002 static int
11003 api_add_node_next (vat_main_t * vam)
11004 {
11005   unformat_input_t *i = vam->input;
11006   vl_api_add_node_next_t *mp;
11007   u8 *name = 0;
11008   u8 *next = 0;
11009   int ret;
11010
11011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11012     {
11013       if (unformat (i, "node %s", &name))
11014         ;
11015       else if (unformat (i, "next %s", &next))
11016         ;
11017       else
11018         break;
11019     }
11020   if (name == 0)
11021     {
11022       errmsg ("node name required");
11023       return -99;
11024     }
11025   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11026     {
11027       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11028       return -99;
11029     }
11030   if (next == 0)
11031     {
11032       errmsg ("next node required");
11033       return -99;
11034     }
11035   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11036     {
11037       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11038       return -99;
11039     }
11040
11041   M (ADD_NODE_NEXT, mp);
11042   clib_memcpy (mp->node_name, name, vec_len (name));
11043   clib_memcpy (mp->next_name, next, vec_len (next));
11044   vec_free (name);
11045   vec_free (next);
11046
11047   S (mp);
11048   W (ret);
11049   return ret;
11050 }
11051
11052 static int
11053 api_l2tpv3_create_tunnel (vat_main_t * vam)
11054 {
11055   unformat_input_t *i = vam->input;
11056   ip6_address_t client_address, our_address;
11057   int client_address_set = 0;
11058   int our_address_set = 0;
11059   u32 local_session_id = 0;
11060   u32 remote_session_id = 0;
11061   u64 local_cookie = 0;
11062   u64 remote_cookie = 0;
11063   u8 l2_sublayer_present = 0;
11064   vl_api_l2tpv3_create_tunnel_t *mp;
11065   int ret;
11066
11067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11068     {
11069       if (unformat (i, "client_address %U", unformat_ip6_address,
11070                     &client_address))
11071         client_address_set = 1;
11072       else if (unformat (i, "our_address %U", unformat_ip6_address,
11073                          &our_address))
11074         our_address_set = 1;
11075       else if (unformat (i, "local_session_id %d", &local_session_id))
11076         ;
11077       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11078         ;
11079       else if (unformat (i, "local_cookie %lld", &local_cookie))
11080         ;
11081       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11082         ;
11083       else if (unformat (i, "l2-sublayer-present"))
11084         l2_sublayer_present = 1;
11085       else
11086         break;
11087     }
11088
11089   if (client_address_set == 0)
11090     {
11091       errmsg ("client_address required");
11092       return -99;
11093     }
11094
11095   if (our_address_set == 0)
11096     {
11097       errmsg ("our_address required");
11098       return -99;
11099     }
11100
11101   M (L2TPV3_CREATE_TUNNEL, mp);
11102
11103   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11104                sizeof (ip6_address_t));
11105
11106   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11107                sizeof (ip6_address_t));
11108
11109   mp->local_session_id = ntohl (local_session_id);
11110   mp->remote_session_id = ntohl (remote_session_id);
11111   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11112   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11113   mp->l2_sublayer_present = l2_sublayer_present;
11114
11115   S (mp);
11116   W (ret);
11117   return ret;
11118 }
11119
11120 static int
11121 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11122 {
11123   unformat_input_t *i = vam->input;
11124   u32 sw_if_index;
11125   u8 sw_if_index_set = 0;
11126   u64 new_local_cookie = 0;
11127   u64 new_remote_cookie = 0;
11128   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11129   int ret;
11130
11131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11132     {
11133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11134         sw_if_index_set = 1;
11135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11136         sw_if_index_set = 1;
11137       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11138         ;
11139       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11140         ;
11141       else
11142         break;
11143     }
11144
11145   if (sw_if_index_set == 0)
11146     {
11147       errmsg ("missing interface name or sw_if_index");
11148       return -99;
11149     }
11150
11151   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11152
11153   mp->sw_if_index = ntohl (sw_if_index);
11154   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11155   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11156
11157   S (mp);
11158   W (ret);
11159   return ret;
11160 }
11161
11162 static int
11163 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11164 {
11165   unformat_input_t *i = vam->input;
11166   vl_api_l2tpv3_interface_enable_disable_t *mp;
11167   u32 sw_if_index;
11168   u8 sw_if_index_set = 0;
11169   u8 enable_disable = 1;
11170   int ret;
11171
11172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11173     {
11174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11175         sw_if_index_set = 1;
11176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11177         sw_if_index_set = 1;
11178       else if (unformat (i, "enable"))
11179         enable_disable = 1;
11180       else if (unformat (i, "disable"))
11181         enable_disable = 0;
11182       else
11183         break;
11184     }
11185
11186   if (sw_if_index_set == 0)
11187     {
11188       errmsg ("missing interface name or sw_if_index");
11189       return -99;
11190     }
11191
11192   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11193
11194   mp->sw_if_index = ntohl (sw_if_index);
11195   mp->enable_disable = enable_disable;
11196
11197   S (mp);
11198   W (ret);
11199   return ret;
11200 }
11201
11202 static int
11203 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11204 {
11205   unformat_input_t *i = vam->input;
11206   vl_api_l2tpv3_set_lookup_key_t *mp;
11207   u8 key = ~0;
11208   int ret;
11209
11210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11211     {
11212       if (unformat (i, "lookup_v6_src"))
11213         key = L2T_LOOKUP_SRC_ADDRESS;
11214       else if (unformat (i, "lookup_v6_dst"))
11215         key = L2T_LOOKUP_DST_ADDRESS;
11216       else if (unformat (i, "lookup_session_id"))
11217         key = L2T_LOOKUP_SESSION_ID;
11218       else
11219         break;
11220     }
11221
11222   if (key == (u8) ~ 0)
11223     {
11224       errmsg ("l2tp session lookup key unset");
11225       return -99;
11226     }
11227
11228   M (L2TPV3_SET_LOOKUP_KEY, mp);
11229
11230   mp->key = key;
11231
11232   S (mp);
11233   W (ret);
11234   return ret;
11235 }
11236
11237 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11238   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11239 {
11240   vat_main_t *vam = &vat_main;
11241
11242   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11243          format_ip6_address, mp->our_address,
11244          format_ip6_address, mp->client_address,
11245          clib_net_to_host_u32 (mp->sw_if_index));
11246
11247   print (vam->ofp,
11248          "   local cookies %016llx %016llx remote cookie %016llx",
11249          clib_net_to_host_u64 (mp->local_cookie[0]),
11250          clib_net_to_host_u64 (mp->local_cookie[1]),
11251          clib_net_to_host_u64 (mp->remote_cookie));
11252
11253   print (vam->ofp, "   local session-id %d remote session-id %d",
11254          clib_net_to_host_u32 (mp->local_session_id),
11255          clib_net_to_host_u32 (mp->remote_session_id));
11256
11257   print (vam->ofp, "   l2 specific sublayer %s\n",
11258          mp->l2_sublayer_present ? "preset" : "absent");
11259
11260 }
11261
11262 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11263   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11264 {
11265   vat_main_t *vam = &vat_main;
11266   vat_json_node_t *node = NULL;
11267   struct in6_addr addr;
11268
11269   if (VAT_JSON_ARRAY != vam->json_tree.type)
11270     {
11271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11272       vat_json_init_array (&vam->json_tree);
11273     }
11274   node = vat_json_array_add (&vam->json_tree);
11275
11276   vat_json_init_object (node);
11277
11278   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11279   vat_json_object_add_ip6 (node, "our_address", addr);
11280   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11281   vat_json_object_add_ip6 (node, "client_address", addr);
11282
11283   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11284   vat_json_init_array (lc);
11285   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11286   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11287   vat_json_object_add_uint (node, "remote_cookie",
11288                             clib_net_to_host_u64 (mp->remote_cookie));
11289
11290   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11291   vat_json_object_add_uint (node, "local_session_id",
11292                             clib_net_to_host_u32 (mp->local_session_id));
11293   vat_json_object_add_uint (node, "remote_session_id",
11294                             clib_net_to_host_u32 (mp->remote_session_id));
11295   vat_json_object_add_string_copy (node, "l2_sublayer",
11296                                    mp->l2_sublayer_present ? (u8 *) "present"
11297                                    : (u8 *) "absent");
11298 }
11299
11300 static int
11301 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11302 {
11303   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11304   vl_api_control_ping_t *mp_ping;
11305   int ret;
11306
11307   /* Get list of l2tpv3-tunnel interfaces */
11308   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11309   S (mp);
11310
11311   /* Use a control ping for synchronization */
11312   MPING (CONTROL_PING, mp_ping);
11313   S (mp_ping);
11314
11315   W (ret);
11316   return ret;
11317 }
11318
11319
11320 static void vl_api_sw_interface_tap_v2_details_t_handler
11321   (vl_api_sw_interface_tap_v2_details_t * mp)
11322 {
11323   vat_main_t *vam = &vat_main;
11324
11325   u8 *ip4 =
11326     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11327             mp->host_ip4_prefix.len);
11328   u8 *ip6 =
11329     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11330             mp->host_ip6_prefix.len);
11331
11332   print (vam->ofp,
11333          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11334          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11335          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11336          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11337          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11338
11339   vec_free (ip4);
11340   vec_free (ip6);
11341 }
11342
11343 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11344   (vl_api_sw_interface_tap_v2_details_t * mp)
11345 {
11346   vat_main_t *vam = &vat_main;
11347   vat_json_node_t *node = NULL;
11348
11349   if (VAT_JSON_ARRAY != vam->json_tree.type)
11350     {
11351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11352       vat_json_init_array (&vam->json_tree);
11353     }
11354   node = vat_json_array_add (&vam->json_tree);
11355
11356   vat_json_init_object (node);
11357   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11358   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11359   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11360   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11361   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11362   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11363   vat_json_object_add_string_copy (node, "host_mac_addr",
11364                                    format (0, "%U", format_ethernet_address,
11365                                            &mp->host_mac_addr));
11366   vat_json_object_add_string_copy (node, "host_namespace",
11367                                    mp->host_namespace);
11368   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11369   vat_json_object_add_string_copy (node, "host_ip4_addr",
11370                                    format (0, "%U/%d", format_ip4_address,
11371                                            mp->host_ip4_prefix.address,
11372                                            mp->host_ip4_prefix.len));
11373   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11374                                    format (0, "%U/%d", format_ip6_address,
11375                                            mp->host_ip6_prefix.address,
11376                                            mp->host_ip6_prefix.len));
11377
11378 }
11379
11380 static int
11381 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11382 {
11383   vl_api_sw_interface_tap_v2_dump_t *mp;
11384   vl_api_control_ping_t *mp_ping;
11385   int ret;
11386
11387   print (vam->ofp,
11388          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11389          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11390          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11391          "host_ip6_addr");
11392
11393   /* Get list of tap interfaces */
11394   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11395   S (mp);
11396
11397   /* Use a control ping for synchronization */
11398   MPING (CONTROL_PING, mp_ping);
11399   S (mp_ping);
11400
11401   W (ret);
11402   return ret;
11403 }
11404
11405 static void vl_api_sw_interface_virtio_pci_details_t_handler
11406   (vl_api_sw_interface_virtio_pci_details_t * mp)
11407 {
11408   vat_main_t *vam = &vat_main;
11409
11410   typedef union
11411   {
11412     struct
11413     {
11414       u16 domain;
11415       u8 bus;
11416       u8 slot:5;
11417       u8 function:3;
11418     };
11419     u32 as_u32;
11420   } pci_addr_t;
11421   pci_addr_t addr;
11422
11423   addr.domain = ntohs (mp->pci_addr.domain);
11424   addr.bus = mp->pci_addr.bus;
11425   addr.slot = mp->pci_addr.slot;
11426   addr.function = mp->pci_addr.function;
11427
11428   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11429                          addr.slot, addr.function);
11430
11431   print (vam->ofp,
11432          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11433          pci_addr, ntohl (mp->sw_if_index),
11434          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11435          format_ethernet_address, mp->mac_addr,
11436          clib_net_to_host_u64 (mp->features));
11437   vec_free (pci_addr);
11438 }
11439
11440 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11441   (vl_api_sw_interface_virtio_pci_details_t * mp)
11442 {
11443   vat_main_t *vam = &vat_main;
11444   vat_json_node_t *node = NULL;
11445   vlib_pci_addr_t pci_addr;
11446
11447   if (VAT_JSON_ARRAY != vam->json_tree.type)
11448     {
11449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11450       vat_json_init_array (&vam->json_tree);
11451     }
11452   node = vat_json_array_add (&vam->json_tree);
11453
11454   pci_addr.domain = ntohs (mp->pci_addr.domain);
11455   pci_addr.bus = mp->pci_addr.bus;
11456   pci_addr.slot = mp->pci_addr.slot;
11457   pci_addr.function = mp->pci_addr.function;
11458
11459   vat_json_init_object (node);
11460   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11461   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11462   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11463   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11464   vat_json_object_add_uint (node, "features",
11465                             clib_net_to_host_u64 (mp->features));
11466   vat_json_object_add_string_copy (node, "mac_addr",
11467                                    format (0, "%U", format_ethernet_address,
11468                                            &mp->mac_addr));
11469 }
11470
11471 static int
11472 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11473 {
11474   vl_api_sw_interface_virtio_pci_dump_t *mp;
11475   vl_api_control_ping_t *mp_ping;
11476   int ret;
11477
11478   print (vam->ofp,
11479          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11480          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11481          "mac_addr", "features");
11482
11483   /* Get list of tap interfaces */
11484   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11485   S (mp);
11486
11487   /* Use a control ping for synchronization */
11488   MPING (CONTROL_PING, mp_ping);
11489   S (mp_ping);
11490
11491   W (ret);
11492   return ret;
11493 }
11494
11495 static int
11496 api_vxlan_offload_rx (vat_main_t * vam)
11497 {
11498   unformat_input_t *line_input = vam->input;
11499   vl_api_vxlan_offload_rx_t *mp;
11500   u32 hw_if_index = ~0, rx_if_index = ~0;
11501   u8 is_add = 1;
11502   int ret;
11503
11504   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11505     {
11506       if (unformat (line_input, "del"))
11507         is_add = 0;
11508       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11509                          &hw_if_index))
11510         ;
11511       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11512         ;
11513       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11514                          &rx_if_index))
11515         ;
11516       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11517         ;
11518       else
11519         {
11520           errmsg ("parse error '%U'", format_unformat_error, line_input);
11521           return -99;
11522         }
11523     }
11524
11525   if (hw_if_index == ~0)
11526     {
11527       errmsg ("no hw interface");
11528       return -99;
11529     }
11530
11531   if (rx_if_index == ~0)
11532     {
11533       errmsg ("no rx tunnel");
11534       return -99;
11535     }
11536
11537   M (VXLAN_OFFLOAD_RX, mp);
11538
11539   mp->hw_if_index = ntohl (hw_if_index);
11540   mp->sw_if_index = ntohl (rx_if_index);
11541   mp->enable = is_add;
11542
11543   S (mp);
11544   W (ret);
11545   return ret;
11546 }
11547
11548 static uword unformat_vxlan_decap_next
11549   (unformat_input_t * input, va_list * args)
11550 {
11551   u32 *result = va_arg (*args, u32 *);
11552   u32 tmp;
11553
11554   if (unformat (input, "l2"))
11555     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11556   else if (unformat (input, "%d", &tmp))
11557     *result = tmp;
11558   else
11559     return 0;
11560   return 1;
11561 }
11562
11563 static int
11564 api_vxlan_add_del_tunnel (vat_main_t * vam)
11565 {
11566   unformat_input_t *line_input = vam->input;
11567   vl_api_vxlan_add_del_tunnel_t *mp;
11568   ip46_address_t src, dst;
11569   u8 is_add = 1;
11570   u8 ipv4_set = 0, ipv6_set = 0;
11571   u8 src_set = 0;
11572   u8 dst_set = 0;
11573   u8 grp_set = 0;
11574   u32 instance = ~0;
11575   u32 mcast_sw_if_index = ~0;
11576   u32 encap_vrf_id = 0;
11577   u32 decap_next_index = ~0;
11578   u32 vni = 0;
11579   int ret;
11580
11581   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11582   clib_memset (&src, 0, sizeof src);
11583   clib_memset (&dst, 0, sizeof dst);
11584
11585   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (line_input, "del"))
11588         is_add = 0;
11589       else if (unformat (line_input, "instance %d", &instance))
11590         ;
11591       else
11592         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11593         {
11594           ipv4_set = 1;
11595           src_set = 1;
11596         }
11597       else
11598         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11599         {
11600           ipv4_set = 1;
11601           dst_set = 1;
11602         }
11603       else
11604         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11605         {
11606           ipv6_set = 1;
11607           src_set = 1;
11608         }
11609       else
11610         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11611         {
11612           ipv6_set = 1;
11613           dst_set = 1;
11614         }
11615       else if (unformat (line_input, "group %U %U",
11616                          unformat_ip4_address, &dst.ip4,
11617                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11618         {
11619           grp_set = dst_set = 1;
11620           ipv4_set = 1;
11621         }
11622       else if (unformat (line_input, "group %U",
11623                          unformat_ip4_address, &dst.ip4))
11624         {
11625           grp_set = dst_set = 1;
11626           ipv4_set = 1;
11627         }
11628       else if (unformat (line_input, "group %U %U",
11629                          unformat_ip6_address, &dst.ip6,
11630                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11631         {
11632           grp_set = dst_set = 1;
11633           ipv6_set = 1;
11634         }
11635       else if (unformat (line_input, "group %U",
11636                          unformat_ip6_address, &dst.ip6))
11637         {
11638           grp_set = dst_set = 1;
11639           ipv6_set = 1;
11640         }
11641       else
11642         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11643         ;
11644       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11645         ;
11646       else if (unformat (line_input, "decap-next %U",
11647                          unformat_vxlan_decap_next, &decap_next_index))
11648         ;
11649       else if (unformat (line_input, "vni %d", &vni))
11650         ;
11651       else
11652         {
11653           errmsg ("parse error '%U'", format_unformat_error, line_input);
11654           return -99;
11655         }
11656     }
11657
11658   if (src_set == 0)
11659     {
11660       errmsg ("tunnel src address not specified");
11661       return -99;
11662     }
11663   if (dst_set == 0)
11664     {
11665       errmsg ("tunnel dst address not specified");
11666       return -99;
11667     }
11668
11669   if (grp_set && !ip46_address_is_multicast (&dst))
11670     {
11671       errmsg ("tunnel group address not multicast");
11672       return -99;
11673     }
11674   if (grp_set && mcast_sw_if_index == ~0)
11675     {
11676       errmsg ("tunnel nonexistent multicast device");
11677       return -99;
11678     }
11679   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11680     {
11681       errmsg ("tunnel dst address must be unicast");
11682       return -99;
11683     }
11684
11685
11686   if (ipv4_set && ipv6_set)
11687     {
11688       errmsg ("both IPv4 and IPv6 addresses specified");
11689       return -99;
11690     }
11691
11692   if ((vni == 0) || (vni >> 24))
11693     {
11694       errmsg ("vni not specified or out of range");
11695       return -99;
11696     }
11697
11698   M (VXLAN_ADD_DEL_TUNNEL, mp);
11699
11700   if (ipv6_set)
11701     {
11702       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11703       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11704     }
11705   else
11706     {
11707       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11708       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11709     }
11710
11711   mp->instance = htonl (instance);
11712   mp->encap_vrf_id = ntohl (encap_vrf_id);
11713   mp->decap_next_index = ntohl (decap_next_index);
11714   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11715   mp->vni = ntohl (vni);
11716   mp->is_add = is_add;
11717   mp->is_ipv6 = ipv6_set;
11718
11719   S (mp);
11720   W (ret);
11721   return ret;
11722 }
11723
11724 static void vl_api_vxlan_tunnel_details_t_handler
11725   (vl_api_vxlan_tunnel_details_t * mp)
11726 {
11727   vat_main_t *vam = &vat_main;
11728   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11729   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11730
11731   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11732          ntohl (mp->sw_if_index),
11733          ntohl (mp->instance),
11734          format_ip46_address, &src, IP46_TYPE_ANY,
11735          format_ip46_address, &dst, IP46_TYPE_ANY,
11736          ntohl (mp->encap_vrf_id),
11737          ntohl (mp->decap_next_index), ntohl (mp->vni),
11738          ntohl (mp->mcast_sw_if_index));
11739 }
11740
11741 static void vl_api_vxlan_tunnel_details_t_handler_json
11742   (vl_api_vxlan_tunnel_details_t * mp)
11743 {
11744   vat_main_t *vam = &vat_main;
11745   vat_json_node_t *node = NULL;
11746
11747   if (VAT_JSON_ARRAY != vam->json_tree.type)
11748     {
11749       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11750       vat_json_init_array (&vam->json_tree);
11751     }
11752   node = vat_json_array_add (&vam->json_tree);
11753
11754   vat_json_init_object (node);
11755   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11756
11757   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11758
11759   if (mp->is_ipv6)
11760     {
11761       struct in6_addr ip6;
11762
11763       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11764       vat_json_object_add_ip6 (node, "src_address", ip6);
11765       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11766       vat_json_object_add_ip6 (node, "dst_address", ip6);
11767     }
11768   else
11769     {
11770       struct in_addr ip4;
11771
11772       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11773       vat_json_object_add_ip4 (node, "src_address", ip4);
11774       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11775       vat_json_object_add_ip4 (node, "dst_address", ip4);
11776     }
11777   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11778   vat_json_object_add_uint (node, "decap_next_index",
11779                             ntohl (mp->decap_next_index));
11780   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11781   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11782   vat_json_object_add_uint (node, "mcast_sw_if_index",
11783                             ntohl (mp->mcast_sw_if_index));
11784 }
11785
11786 static int
11787 api_vxlan_tunnel_dump (vat_main_t * vam)
11788 {
11789   unformat_input_t *i = vam->input;
11790   vl_api_vxlan_tunnel_dump_t *mp;
11791   vl_api_control_ping_t *mp_ping;
11792   u32 sw_if_index;
11793   u8 sw_if_index_set = 0;
11794   int ret;
11795
11796   /* Parse args required to build the message */
11797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11798     {
11799       if (unformat (i, "sw_if_index %d", &sw_if_index))
11800         sw_if_index_set = 1;
11801       else
11802         break;
11803     }
11804
11805   if (sw_if_index_set == 0)
11806     {
11807       sw_if_index = ~0;
11808     }
11809
11810   if (!vam->json_output)
11811     {
11812       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11813              "sw_if_index", "instance", "src_address", "dst_address",
11814              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11815     }
11816
11817   /* Get list of vxlan-tunnel interfaces */
11818   M (VXLAN_TUNNEL_DUMP, mp);
11819
11820   mp->sw_if_index = htonl (sw_if_index);
11821
11822   S (mp);
11823
11824   /* Use a control ping for synchronization */
11825   MPING (CONTROL_PING, mp_ping);
11826   S (mp_ping);
11827
11828   W (ret);
11829   return ret;
11830 }
11831
11832 static uword unformat_geneve_decap_next
11833   (unformat_input_t * input, va_list * args)
11834 {
11835   u32 *result = va_arg (*args, u32 *);
11836   u32 tmp;
11837
11838   if (unformat (input, "l2"))
11839     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11840   else if (unformat (input, "%d", &tmp))
11841     *result = tmp;
11842   else
11843     return 0;
11844   return 1;
11845 }
11846
11847 static int
11848 api_geneve_add_del_tunnel (vat_main_t * vam)
11849 {
11850   unformat_input_t *line_input = vam->input;
11851   vl_api_geneve_add_del_tunnel_t *mp;
11852   ip46_address_t src, dst;
11853   u8 is_add = 1;
11854   u8 ipv4_set = 0, ipv6_set = 0;
11855   u8 src_set = 0;
11856   u8 dst_set = 0;
11857   u8 grp_set = 0;
11858   u32 mcast_sw_if_index = ~0;
11859   u32 encap_vrf_id = 0;
11860   u32 decap_next_index = ~0;
11861   u32 vni = 0;
11862   int ret;
11863
11864   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11865   clib_memset (&src, 0, sizeof src);
11866   clib_memset (&dst, 0, sizeof dst);
11867
11868   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11869     {
11870       if (unformat (line_input, "del"))
11871         is_add = 0;
11872       else
11873         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11874         {
11875           ipv4_set = 1;
11876           src_set = 1;
11877         }
11878       else
11879         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11880         {
11881           ipv4_set = 1;
11882           dst_set = 1;
11883         }
11884       else
11885         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11886         {
11887           ipv6_set = 1;
11888           src_set = 1;
11889         }
11890       else
11891         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11892         {
11893           ipv6_set = 1;
11894           dst_set = 1;
11895         }
11896       else if (unformat (line_input, "group %U %U",
11897                          unformat_ip4_address, &dst.ip4,
11898                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11899         {
11900           grp_set = dst_set = 1;
11901           ipv4_set = 1;
11902         }
11903       else if (unformat (line_input, "group %U",
11904                          unformat_ip4_address, &dst.ip4))
11905         {
11906           grp_set = dst_set = 1;
11907           ipv4_set = 1;
11908         }
11909       else if (unformat (line_input, "group %U %U",
11910                          unformat_ip6_address, &dst.ip6,
11911                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11912         {
11913           grp_set = dst_set = 1;
11914           ipv6_set = 1;
11915         }
11916       else if (unformat (line_input, "group %U",
11917                          unformat_ip6_address, &dst.ip6))
11918         {
11919           grp_set = dst_set = 1;
11920           ipv6_set = 1;
11921         }
11922       else
11923         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11924         ;
11925       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11926         ;
11927       else if (unformat (line_input, "decap-next %U",
11928                          unformat_geneve_decap_next, &decap_next_index))
11929         ;
11930       else if (unformat (line_input, "vni %d", &vni))
11931         ;
11932       else
11933         {
11934           errmsg ("parse error '%U'", format_unformat_error, line_input);
11935           return -99;
11936         }
11937     }
11938
11939   if (src_set == 0)
11940     {
11941       errmsg ("tunnel src address not specified");
11942       return -99;
11943     }
11944   if (dst_set == 0)
11945     {
11946       errmsg ("tunnel dst address not specified");
11947       return -99;
11948     }
11949
11950   if (grp_set && !ip46_address_is_multicast (&dst))
11951     {
11952       errmsg ("tunnel group address not multicast");
11953       return -99;
11954     }
11955   if (grp_set && mcast_sw_if_index == ~0)
11956     {
11957       errmsg ("tunnel nonexistent multicast device");
11958       return -99;
11959     }
11960   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11961     {
11962       errmsg ("tunnel dst address must be unicast");
11963       return -99;
11964     }
11965
11966
11967   if (ipv4_set && ipv6_set)
11968     {
11969       errmsg ("both IPv4 and IPv6 addresses specified");
11970       return -99;
11971     }
11972
11973   if ((vni == 0) || (vni >> 24))
11974     {
11975       errmsg ("vni not specified or out of range");
11976       return -99;
11977     }
11978
11979   M (GENEVE_ADD_DEL_TUNNEL, mp);
11980
11981   if (ipv6_set)
11982     {
11983       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11984       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11985     }
11986   else
11987     {
11988       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11989       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11990     }
11991   mp->encap_vrf_id = ntohl (encap_vrf_id);
11992   mp->decap_next_index = ntohl (decap_next_index);
11993   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11994   mp->vni = ntohl (vni);
11995   mp->is_add = is_add;
11996
11997   S (mp);
11998   W (ret);
11999   return ret;
12000 }
12001
12002 static void vl_api_geneve_tunnel_details_t_handler
12003   (vl_api_geneve_tunnel_details_t * mp)
12004 {
12005   vat_main_t *vam = &vat_main;
12006   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12007   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12008
12009   if (mp->src_address.af == ADDRESS_IP6)
12010     {
12011       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12012       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12013     }
12014   else
12015     {
12016       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12017       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12018     }
12019
12020   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12021          ntohl (mp->sw_if_index),
12022          format_ip46_address, &src, IP46_TYPE_ANY,
12023          format_ip46_address, &dst, IP46_TYPE_ANY,
12024          ntohl (mp->encap_vrf_id),
12025          ntohl (mp->decap_next_index), ntohl (mp->vni),
12026          ntohl (mp->mcast_sw_if_index));
12027 }
12028
12029 static void vl_api_geneve_tunnel_details_t_handler_json
12030   (vl_api_geneve_tunnel_details_t * mp)
12031 {
12032   vat_main_t *vam = &vat_main;
12033   vat_json_node_t *node = NULL;
12034   bool is_ipv6;
12035
12036   if (VAT_JSON_ARRAY != vam->json_tree.type)
12037     {
12038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12039       vat_json_init_array (&vam->json_tree);
12040     }
12041   node = vat_json_array_add (&vam->json_tree);
12042
12043   vat_json_init_object (node);
12044   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12045   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12046   if (is_ipv6)
12047     {
12048       struct in6_addr ip6;
12049
12050       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12051       vat_json_object_add_ip6 (node, "src_address", ip6);
12052       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12053       vat_json_object_add_ip6 (node, "dst_address", ip6);
12054     }
12055   else
12056     {
12057       struct in_addr ip4;
12058
12059       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12060       vat_json_object_add_ip4 (node, "src_address", ip4);
12061       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12062       vat_json_object_add_ip4 (node, "dst_address", ip4);
12063     }
12064   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12065   vat_json_object_add_uint (node, "decap_next_index",
12066                             ntohl (mp->decap_next_index));
12067   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12068   vat_json_object_add_uint (node, "mcast_sw_if_index",
12069                             ntohl (mp->mcast_sw_if_index));
12070 }
12071
12072 static int
12073 api_geneve_tunnel_dump (vat_main_t * vam)
12074 {
12075   unformat_input_t *i = vam->input;
12076   vl_api_geneve_tunnel_dump_t *mp;
12077   vl_api_control_ping_t *mp_ping;
12078   u32 sw_if_index;
12079   u8 sw_if_index_set = 0;
12080   int ret;
12081
12082   /* Parse args required to build the message */
12083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12084     {
12085       if (unformat (i, "sw_if_index %d", &sw_if_index))
12086         sw_if_index_set = 1;
12087       else
12088         break;
12089     }
12090
12091   if (sw_if_index_set == 0)
12092     {
12093       sw_if_index = ~0;
12094     }
12095
12096   if (!vam->json_output)
12097     {
12098       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12099              "sw_if_index", "local_address", "remote_address",
12100              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12101     }
12102
12103   /* Get list of geneve-tunnel interfaces */
12104   M (GENEVE_TUNNEL_DUMP, mp);
12105
12106   mp->sw_if_index = htonl (sw_if_index);
12107
12108   S (mp);
12109
12110   /* Use a control ping for synchronization */
12111   M (CONTROL_PING, mp_ping);
12112   S (mp_ping);
12113
12114   W (ret);
12115   return ret;
12116 }
12117
12118 static int
12119 api_gre_tunnel_add_del (vat_main_t * vam)
12120 {
12121   unformat_input_t *line_input = vam->input;
12122   vl_api_address_t src = { }, dst =
12123   {
12124   };
12125   vl_api_gre_tunnel_add_del_t *mp;
12126   vl_api_gre_tunnel_type_t t_type;
12127   u8 is_add = 1;
12128   u8 src_set = 0;
12129   u8 dst_set = 0;
12130   u32 outer_table_id = 0;
12131   u32 session_id = 0;
12132   u32 instance = ~0;
12133   int ret;
12134
12135   t_type = GRE_API_TUNNEL_TYPE_L3;
12136
12137   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12138     {
12139       if (unformat (line_input, "del"))
12140         is_add = 0;
12141       else if (unformat (line_input, "instance %d", &instance))
12142         ;
12143       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12144         {
12145           src_set = 1;
12146         }
12147       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12148         {
12149           dst_set = 1;
12150         }
12151       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12152         ;
12153       else if (unformat (line_input, "teb"))
12154         t_type = GRE_API_TUNNEL_TYPE_TEB;
12155       else if (unformat (line_input, "erspan %d", &session_id))
12156         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12157       else
12158         {
12159           errmsg ("parse error '%U'", format_unformat_error, line_input);
12160           return -99;
12161         }
12162     }
12163
12164   if (src_set == 0)
12165     {
12166       errmsg ("tunnel src address not specified");
12167       return -99;
12168     }
12169   if (dst_set == 0)
12170     {
12171       errmsg ("tunnel dst address not specified");
12172       return -99;
12173     }
12174
12175   M (GRE_TUNNEL_ADD_DEL, mp);
12176
12177   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12178   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12179
12180   mp->tunnel.instance = htonl (instance);
12181   mp->tunnel.outer_table_id = htonl (outer_table_id);
12182   mp->is_add = is_add;
12183   mp->tunnel.session_id = htons ((u16) session_id);
12184   mp->tunnel.type = htonl (t_type);
12185
12186   S (mp);
12187   W (ret);
12188   return ret;
12189 }
12190
12191 static void vl_api_gre_tunnel_details_t_handler
12192   (vl_api_gre_tunnel_details_t * mp)
12193 {
12194   vat_main_t *vam = &vat_main;
12195
12196   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12197          ntohl (mp->tunnel.sw_if_index),
12198          ntohl (mp->tunnel.instance),
12199          format_vl_api_address, &mp->tunnel.src,
12200          format_vl_api_address, &mp->tunnel.dst,
12201          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12202          ntohl (mp->tunnel.session_id));
12203 }
12204
12205 static void vl_api_gre_tunnel_details_t_handler_json
12206   (vl_api_gre_tunnel_details_t * mp)
12207 {
12208   vat_main_t *vam = &vat_main;
12209   vat_json_node_t *node = NULL;
12210
12211   if (VAT_JSON_ARRAY != vam->json_tree.type)
12212     {
12213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12214       vat_json_init_array (&vam->json_tree);
12215     }
12216   node = vat_json_array_add (&vam->json_tree);
12217
12218   vat_json_init_object (node);
12219   vat_json_object_add_uint (node, "sw_if_index",
12220                             ntohl (mp->tunnel.sw_if_index));
12221   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12222
12223   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12224   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12225   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12226   vat_json_object_add_uint (node, "outer_table_id",
12227                             ntohl (mp->tunnel.outer_table_id));
12228   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12229 }
12230
12231 static int
12232 api_gre_tunnel_dump (vat_main_t * vam)
12233 {
12234   unformat_input_t *i = vam->input;
12235   vl_api_gre_tunnel_dump_t *mp;
12236   vl_api_control_ping_t *mp_ping;
12237   u32 sw_if_index;
12238   u8 sw_if_index_set = 0;
12239   int ret;
12240
12241   /* Parse args required to build the message */
12242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12243     {
12244       if (unformat (i, "sw_if_index %d", &sw_if_index))
12245         sw_if_index_set = 1;
12246       else
12247         break;
12248     }
12249
12250   if (sw_if_index_set == 0)
12251     {
12252       sw_if_index = ~0;
12253     }
12254
12255   if (!vam->json_output)
12256     {
12257       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12258              "sw_if_index", "instance", "src_address", "dst_address",
12259              "tunnel_type", "outer_fib_id", "session_id");
12260     }
12261
12262   /* Get list of gre-tunnel interfaces */
12263   M (GRE_TUNNEL_DUMP, mp);
12264
12265   mp->sw_if_index = htonl (sw_if_index);
12266
12267   S (mp);
12268
12269   /* Use a control ping for synchronization */
12270   MPING (CONTROL_PING, mp_ping);
12271   S (mp_ping);
12272
12273   W (ret);
12274   return ret;
12275 }
12276
12277 static int
12278 api_l2_fib_clear_table (vat_main_t * vam)
12279 {
12280 //  unformat_input_t * i = vam->input;
12281   vl_api_l2_fib_clear_table_t *mp;
12282   int ret;
12283
12284   M (L2_FIB_CLEAR_TABLE, mp);
12285
12286   S (mp);
12287   W (ret);
12288   return ret;
12289 }
12290
12291 static int
12292 api_l2_interface_efp_filter (vat_main_t * vam)
12293 {
12294   unformat_input_t *i = vam->input;
12295   vl_api_l2_interface_efp_filter_t *mp;
12296   u32 sw_if_index;
12297   u8 enable = 1;
12298   u8 sw_if_index_set = 0;
12299   int ret;
12300
12301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12304         sw_if_index_set = 1;
12305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12306         sw_if_index_set = 1;
12307       else if (unformat (i, "enable"))
12308         enable = 1;
12309       else if (unformat (i, "disable"))
12310         enable = 0;
12311       else
12312         {
12313           clib_warning ("parse error '%U'", format_unformat_error, i);
12314           return -99;
12315         }
12316     }
12317
12318   if (sw_if_index_set == 0)
12319     {
12320       errmsg ("missing sw_if_index");
12321       return -99;
12322     }
12323
12324   M (L2_INTERFACE_EFP_FILTER, mp);
12325
12326   mp->sw_if_index = ntohl (sw_if_index);
12327   mp->enable_disable = enable;
12328
12329   S (mp);
12330   W (ret);
12331   return ret;
12332 }
12333
12334 #define foreach_vtr_op                          \
12335 _("disable",  L2_VTR_DISABLED)                  \
12336 _("push-1",  L2_VTR_PUSH_1)                     \
12337 _("push-2",  L2_VTR_PUSH_2)                     \
12338 _("pop-1",  L2_VTR_POP_1)                       \
12339 _("pop-2",  L2_VTR_POP_2)                       \
12340 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12341 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12342 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12343 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12344
12345 static int
12346 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12347 {
12348   unformat_input_t *i = vam->input;
12349   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12350   u32 sw_if_index;
12351   u8 sw_if_index_set = 0;
12352   u8 vtr_op_set = 0;
12353   u32 vtr_op = 0;
12354   u32 push_dot1q = 1;
12355   u32 tag1 = ~0;
12356   u32 tag2 = ~0;
12357   int ret;
12358
12359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12360     {
12361       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12362         sw_if_index_set = 1;
12363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12364         sw_if_index_set = 1;
12365       else if (unformat (i, "vtr_op %d", &vtr_op))
12366         vtr_op_set = 1;
12367 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12368       foreach_vtr_op
12369 #undef _
12370         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12371         ;
12372       else if (unformat (i, "tag1 %d", &tag1))
12373         ;
12374       else if (unformat (i, "tag2 %d", &tag2))
12375         ;
12376       else
12377         {
12378           clib_warning ("parse error '%U'", format_unformat_error, i);
12379           return -99;
12380         }
12381     }
12382
12383   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12384     {
12385       errmsg ("missing vtr operation or sw_if_index");
12386       return -99;
12387     }
12388
12389   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12390   mp->sw_if_index = ntohl (sw_if_index);
12391   mp->vtr_op = ntohl (vtr_op);
12392   mp->push_dot1q = ntohl (push_dot1q);
12393   mp->tag1 = ntohl (tag1);
12394   mp->tag2 = ntohl (tag2);
12395
12396   S (mp);
12397   W (ret);
12398   return ret;
12399 }
12400
12401 static int
12402 api_create_vhost_user_if (vat_main_t * vam)
12403 {
12404   unformat_input_t *i = vam->input;
12405   vl_api_create_vhost_user_if_t *mp;
12406   u8 *file_name;
12407   u8 is_server = 0;
12408   u8 file_name_set = 0;
12409   u32 custom_dev_instance = ~0;
12410   u8 hwaddr[6];
12411   u8 use_custom_mac = 0;
12412   u8 disable_mrg_rxbuf = 0;
12413   u8 disable_indirect_desc = 0;
12414   u8 *tag = 0;
12415   u8 enable_gso = 0;
12416   int ret;
12417
12418   /* Shut up coverity */
12419   clib_memset (hwaddr, 0, sizeof (hwaddr));
12420
12421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12422     {
12423       if (unformat (i, "socket %s", &file_name))
12424         {
12425           file_name_set = 1;
12426         }
12427       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12428         ;
12429       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12430         use_custom_mac = 1;
12431       else if (unformat (i, "server"))
12432         is_server = 1;
12433       else if (unformat (i, "disable_mrg_rxbuf"))
12434         disable_mrg_rxbuf = 1;
12435       else if (unformat (i, "disable_indirect_desc"))
12436         disable_indirect_desc = 1;
12437       else if (unformat (i, "gso"))
12438         enable_gso = 1;
12439       else if (unformat (i, "tag %s", &tag))
12440         ;
12441       else
12442         break;
12443     }
12444
12445   if (file_name_set == 0)
12446     {
12447       errmsg ("missing socket file name");
12448       return -99;
12449     }
12450
12451   if (vec_len (file_name) > 255)
12452     {
12453       errmsg ("socket file name too long");
12454       return -99;
12455     }
12456   vec_add1 (file_name, 0);
12457
12458   M (CREATE_VHOST_USER_IF, mp);
12459
12460   mp->is_server = is_server;
12461   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12462   mp->disable_indirect_desc = disable_indirect_desc;
12463   mp->enable_gso = enable_gso;
12464   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12465   vec_free (file_name);
12466   if (custom_dev_instance != ~0)
12467     {
12468       mp->renumber = 1;
12469       mp->custom_dev_instance = ntohl (custom_dev_instance);
12470     }
12471
12472   mp->use_custom_mac = use_custom_mac;
12473   clib_memcpy (mp->mac_address, hwaddr, 6);
12474   if (tag)
12475     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12476   vec_free (tag);
12477
12478   S (mp);
12479   W (ret);
12480   return ret;
12481 }
12482
12483 static int
12484 api_modify_vhost_user_if (vat_main_t * vam)
12485 {
12486   unformat_input_t *i = vam->input;
12487   vl_api_modify_vhost_user_if_t *mp;
12488   u8 *file_name;
12489   u8 is_server = 0;
12490   u8 file_name_set = 0;
12491   u32 custom_dev_instance = ~0;
12492   u8 sw_if_index_set = 0;
12493   u32 sw_if_index = (u32) ~ 0;
12494   u8 enable_gso = 0;
12495   int ret;
12496
12497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12498     {
12499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12500         sw_if_index_set = 1;
12501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12502         sw_if_index_set = 1;
12503       else if (unformat (i, "socket %s", &file_name))
12504         {
12505           file_name_set = 1;
12506         }
12507       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12508         ;
12509       else if (unformat (i, "server"))
12510         is_server = 1;
12511       else if (unformat (i, "gso"))
12512         enable_gso = 1;
12513       else
12514         break;
12515     }
12516
12517   if (sw_if_index_set == 0)
12518     {
12519       errmsg ("missing sw_if_index or interface name");
12520       return -99;
12521     }
12522
12523   if (file_name_set == 0)
12524     {
12525       errmsg ("missing socket file name");
12526       return -99;
12527     }
12528
12529   if (vec_len (file_name) > 255)
12530     {
12531       errmsg ("socket file name too long");
12532       return -99;
12533     }
12534   vec_add1 (file_name, 0);
12535
12536   M (MODIFY_VHOST_USER_IF, mp);
12537
12538   mp->sw_if_index = ntohl (sw_if_index);
12539   mp->is_server = is_server;
12540   mp->enable_gso = enable_gso;
12541   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12542   vec_free (file_name);
12543   if (custom_dev_instance != ~0)
12544     {
12545       mp->renumber = 1;
12546       mp->custom_dev_instance = ntohl (custom_dev_instance);
12547     }
12548
12549   S (mp);
12550   W (ret);
12551   return ret;
12552 }
12553
12554 static int
12555 api_delete_vhost_user_if (vat_main_t * vam)
12556 {
12557   unformat_input_t *i = vam->input;
12558   vl_api_delete_vhost_user_if_t *mp;
12559   u32 sw_if_index = ~0;
12560   u8 sw_if_index_set = 0;
12561   int ret;
12562
12563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12564     {
12565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12566         sw_if_index_set = 1;
12567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12568         sw_if_index_set = 1;
12569       else
12570         break;
12571     }
12572
12573   if (sw_if_index_set == 0)
12574     {
12575       errmsg ("missing sw_if_index or interface name");
12576       return -99;
12577     }
12578
12579
12580   M (DELETE_VHOST_USER_IF, mp);
12581
12582   mp->sw_if_index = ntohl (sw_if_index);
12583
12584   S (mp);
12585   W (ret);
12586   return ret;
12587 }
12588
12589 static void vl_api_sw_interface_vhost_user_details_t_handler
12590   (vl_api_sw_interface_vhost_user_details_t * mp)
12591 {
12592   vat_main_t *vam = &vat_main;
12593   u64 features;
12594
12595   features =
12596     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12597                                                     clib_net_to_host_u32
12598                                                     (mp->features_last_32) <<
12599                                                     32);
12600
12601   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12602          (char *) mp->interface_name,
12603          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12604          features, mp->is_server,
12605          ntohl (mp->num_regions), (char *) mp->sock_filename);
12606   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12607 }
12608
12609 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12610   (vl_api_sw_interface_vhost_user_details_t * mp)
12611 {
12612   vat_main_t *vam = &vat_main;
12613   vat_json_node_t *node = NULL;
12614
12615   if (VAT_JSON_ARRAY != vam->json_tree.type)
12616     {
12617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12618       vat_json_init_array (&vam->json_tree);
12619     }
12620   node = vat_json_array_add (&vam->json_tree);
12621
12622   vat_json_init_object (node);
12623   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12624   vat_json_object_add_string_copy (node, "interface_name",
12625                                    mp->interface_name);
12626   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12627                             ntohl (mp->virtio_net_hdr_sz));
12628   vat_json_object_add_uint (node, "features_first_32",
12629                             clib_net_to_host_u32 (mp->features_first_32));
12630   vat_json_object_add_uint (node, "features_last_32",
12631                             clib_net_to_host_u32 (mp->features_last_32));
12632   vat_json_object_add_uint (node, "is_server", mp->is_server);
12633   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12634   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12635   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12636 }
12637
12638 static int
12639 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12640 {
12641   vl_api_sw_interface_vhost_user_dump_t *mp;
12642   vl_api_control_ping_t *mp_ping;
12643   int ret;
12644   print (vam->ofp,
12645          "Interface name            idx hdr_sz features server regions filename");
12646
12647   /* Get list of vhost-user interfaces */
12648   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12649   mp->sw_if_index = ntohl (~0);
12650   S (mp);
12651
12652   /* Use a control ping for synchronization */
12653   MPING (CONTROL_PING, mp_ping);
12654   S (mp_ping);
12655
12656   W (ret);
12657   return ret;
12658 }
12659
12660 static int
12661 api_show_version (vat_main_t * vam)
12662 {
12663   vl_api_show_version_t *mp;
12664   int ret;
12665
12666   M (SHOW_VERSION, mp);
12667
12668   S (mp);
12669   W (ret);
12670   return ret;
12671 }
12672
12673
12674 static int
12675 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12676 {
12677   unformat_input_t *line_input = vam->input;
12678   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12679   ip4_address_t local4, remote4;
12680   ip6_address_t local6, remote6;
12681   u8 is_add = 1;
12682   u8 ipv4_set = 0, ipv6_set = 0;
12683   u8 local_set = 0;
12684   u8 remote_set = 0;
12685   u8 grp_set = 0;
12686   u32 mcast_sw_if_index = ~0;
12687   u32 encap_vrf_id = 0;
12688   u32 decap_vrf_id = 0;
12689   u8 protocol = ~0;
12690   u32 vni;
12691   u8 vni_set = 0;
12692   int ret;
12693
12694   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12695   clib_memset (&local4, 0, sizeof local4);
12696   clib_memset (&remote4, 0, sizeof remote4);
12697   clib_memset (&local6, 0, sizeof local6);
12698   clib_memset (&remote6, 0, sizeof remote6);
12699
12700   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12701     {
12702       if (unformat (line_input, "del"))
12703         is_add = 0;
12704       else if (unformat (line_input, "local %U",
12705                          unformat_ip4_address, &local4))
12706         {
12707           local_set = 1;
12708           ipv4_set = 1;
12709         }
12710       else if (unformat (line_input, "remote %U",
12711                          unformat_ip4_address, &remote4))
12712         {
12713           remote_set = 1;
12714           ipv4_set = 1;
12715         }
12716       else if (unformat (line_input, "local %U",
12717                          unformat_ip6_address, &local6))
12718         {
12719           local_set = 1;
12720           ipv6_set = 1;
12721         }
12722       else if (unformat (line_input, "remote %U",
12723                          unformat_ip6_address, &remote6))
12724         {
12725           remote_set = 1;
12726           ipv6_set = 1;
12727         }
12728       else if (unformat (line_input, "group %U %U",
12729                          unformat_ip4_address, &remote4,
12730                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12731         {
12732           grp_set = remote_set = 1;
12733           ipv4_set = 1;
12734         }
12735       else if (unformat (line_input, "group %U",
12736                          unformat_ip4_address, &remote4))
12737         {
12738           grp_set = remote_set = 1;
12739           ipv4_set = 1;
12740         }
12741       else if (unformat (line_input, "group %U %U",
12742                          unformat_ip6_address, &remote6,
12743                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12744         {
12745           grp_set = remote_set = 1;
12746           ipv6_set = 1;
12747         }
12748       else if (unformat (line_input, "group %U",
12749                          unformat_ip6_address, &remote6))
12750         {
12751           grp_set = remote_set = 1;
12752           ipv6_set = 1;
12753         }
12754       else
12755         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12756         ;
12757       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12758         ;
12759       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12760         ;
12761       else if (unformat (line_input, "vni %d", &vni))
12762         vni_set = 1;
12763       else if (unformat (line_input, "next-ip4"))
12764         protocol = 1;
12765       else if (unformat (line_input, "next-ip6"))
12766         protocol = 2;
12767       else if (unformat (line_input, "next-ethernet"))
12768         protocol = 3;
12769       else if (unformat (line_input, "next-nsh"))
12770         protocol = 4;
12771       else
12772         {
12773           errmsg ("parse error '%U'", format_unformat_error, line_input);
12774           return -99;
12775         }
12776     }
12777
12778   if (local_set == 0)
12779     {
12780       errmsg ("tunnel local address not specified");
12781       return -99;
12782     }
12783   if (remote_set == 0)
12784     {
12785       errmsg ("tunnel remote address not specified");
12786       return -99;
12787     }
12788   if (grp_set && mcast_sw_if_index == ~0)
12789     {
12790       errmsg ("tunnel nonexistent multicast device");
12791       return -99;
12792     }
12793   if (ipv4_set && ipv6_set)
12794     {
12795       errmsg ("both IPv4 and IPv6 addresses specified");
12796       return -99;
12797     }
12798
12799   if (vni_set == 0)
12800     {
12801       errmsg ("vni not specified");
12802       return -99;
12803     }
12804
12805   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12806
12807
12808   if (ipv6_set)
12809     {
12810       clib_memcpy (&mp->local, &local6, sizeof (local6));
12811       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12812     }
12813   else
12814     {
12815       clib_memcpy (&mp->local, &local4, sizeof (local4));
12816       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12817     }
12818
12819   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12820   mp->encap_vrf_id = ntohl (encap_vrf_id);
12821   mp->decap_vrf_id = ntohl (decap_vrf_id);
12822   mp->protocol = protocol;
12823   mp->vni = ntohl (vni);
12824   mp->is_add = is_add;
12825   mp->is_ipv6 = ipv6_set;
12826
12827   S (mp);
12828   W (ret);
12829   return ret;
12830 }
12831
12832 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12833   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12834 {
12835   vat_main_t *vam = &vat_main;
12836   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12837   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12838
12839   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12840          ntohl (mp->sw_if_index),
12841          format_ip46_address, &local, IP46_TYPE_ANY,
12842          format_ip46_address, &remote, IP46_TYPE_ANY,
12843          ntohl (mp->vni), mp->protocol,
12844          ntohl (mp->mcast_sw_if_index),
12845          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12846 }
12847
12848
12849 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12850   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12851 {
12852   vat_main_t *vam = &vat_main;
12853   vat_json_node_t *node = NULL;
12854   struct in_addr ip4;
12855   struct in6_addr ip6;
12856
12857   if (VAT_JSON_ARRAY != vam->json_tree.type)
12858     {
12859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12860       vat_json_init_array (&vam->json_tree);
12861     }
12862   node = vat_json_array_add (&vam->json_tree);
12863
12864   vat_json_init_object (node);
12865   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12866   if (mp->is_ipv6)
12867     {
12868       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12869       vat_json_object_add_ip6 (node, "local", ip6);
12870       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12871       vat_json_object_add_ip6 (node, "remote", ip6);
12872     }
12873   else
12874     {
12875       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12876       vat_json_object_add_ip4 (node, "local", ip4);
12877       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12878       vat_json_object_add_ip4 (node, "remote", ip4);
12879     }
12880   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12881   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12882   vat_json_object_add_uint (node, "mcast_sw_if_index",
12883                             ntohl (mp->mcast_sw_if_index));
12884   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12885   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12886   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12887 }
12888
12889 static int
12890 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12891 {
12892   unformat_input_t *i = vam->input;
12893   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12894   vl_api_control_ping_t *mp_ping;
12895   u32 sw_if_index;
12896   u8 sw_if_index_set = 0;
12897   int ret;
12898
12899   /* Parse args required to build the message */
12900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12901     {
12902       if (unformat (i, "sw_if_index %d", &sw_if_index))
12903         sw_if_index_set = 1;
12904       else
12905         break;
12906     }
12907
12908   if (sw_if_index_set == 0)
12909     {
12910       sw_if_index = ~0;
12911     }
12912
12913   if (!vam->json_output)
12914     {
12915       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12916              "sw_if_index", "local", "remote", "vni",
12917              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12918     }
12919
12920   /* Get list of vxlan-tunnel interfaces */
12921   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12922
12923   mp->sw_if_index = htonl (sw_if_index);
12924
12925   S (mp);
12926
12927   /* Use a control ping for synchronization */
12928   MPING (CONTROL_PING, mp_ping);
12929   S (mp_ping);
12930
12931   W (ret);
12932   return ret;
12933 }
12934
12935 static void vl_api_l2_fib_table_details_t_handler
12936   (vl_api_l2_fib_table_details_t * mp)
12937 {
12938   vat_main_t *vam = &vat_main;
12939
12940   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12941          "       %d       %d     %d",
12942          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12943          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12944          mp->bvi_mac);
12945 }
12946
12947 static void vl_api_l2_fib_table_details_t_handler_json
12948   (vl_api_l2_fib_table_details_t * mp)
12949 {
12950   vat_main_t *vam = &vat_main;
12951   vat_json_node_t *node = NULL;
12952
12953   if (VAT_JSON_ARRAY != vam->json_tree.type)
12954     {
12955       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12956       vat_json_init_array (&vam->json_tree);
12957     }
12958   node = vat_json_array_add (&vam->json_tree);
12959
12960   vat_json_init_object (node);
12961   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12962   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12963   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12964   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12965   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12966   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12967 }
12968
12969 static int
12970 api_l2_fib_table_dump (vat_main_t * vam)
12971 {
12972   unformat_input_t *i = vam->input;
12973   vl_api_l2_fib_table_dump_t *mp;
12974   vl_api_control_ping_t *mp_ping;
12975   u32 bd_id;
12976   u8 bd_id_set = 0;
12977   int ret;
12978
12979   /* Parse args required to build the message */
12980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12981     {
12982       if (unformat (i, "bd_id %d", &bd_id))
12983         bd_id_set = 1;
12984       else
12985         break;
12986     }
12987
12988   if (bd_id_set == 0)
12989     {
12990       errmsg ("missing bridge domain");
12991       return -99;
12992     }
12993
12994   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12995
12996   /* Get list of l2 fib entries */
12997   M (L2_FIB_TABLE_DUMP, mp);
12998
12999   mp->bd_id = ntohl (bd_id);
13000   S (mp);
13001
13002   /* Use a control ping for synchronization */
13003   MPING (CONTROL_PING, mp_ping);
13004   S (mp_ping);
13005
13006   W (ret);
13007   return ret;
13008 }
13009
13010
13011 static int
13012 api_interface_name_renumber (vat_main_t * vam)
13013 {
13014   unformat_input_t *line_input = vam->input;
13015   vl_api_interface_name_renumber_t *mp;
13016   u32 sw_if_index = ~0;
13017   u32 new_show_dev_instance = ~0;
13018   int ret;
13019
13020   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13021     {
13022       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13023                     &sw_if_index))
13024         ;
13025       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13026         ;
13027       else if (unformat (line_input, "new_show_dev_instance %d",
13028                          &new_show_dev_instance))
13029         ;
13030       else
13031         break;
13032     }
13033
13034   if (sw_if_index == ~0)
13035     {
13036       errmsg ("missing interface name or sw_if_index");
13037       return -99;
13038     }
13039
13040   if (new_show_dev_instance == ~0)
13041     {
13042       errmsg ("missing new_show_dev_instance");
13043       return -99;
13044     }
13045
13046   M (INTERFACE_NAME_RENUMBER, mp);
13047
13048   mp->sw_if_index = ntohl (sw_if_index);
13049   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13050
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_want_l2_macs_events (vat_main_t * vam)
13058 {
13059   unformat_input_t *line_input = vam->input;
13060   vl_api_want_l2_macs_events_t *mp;
13061   u8 enable_disable = 1;
13062   u32 scan_delay = 0;
13063   u32 max_macs_in_event = 0;
13064   u32 learn_limit = 0;
13065   int ret;
13066
13067   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (line_input, "learn-limit %d", &learn_limit))
13070         ;
13071       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13072         ;
13073       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13074         ;
13075       else if (unformat (line_input, "disable"))
13076         enable_disable = 0;
13077       else
13078         break;
13079     }
13080
13081   M (WANT_L2_MACS_EVENTS, mp);
13082   mp->enable_disable = enable_disable;
13083   mp->pid = htonl (getpid ());
13084   mp->learn_limit = htonl (learn_limit);
13085   mp->scan_delay = (u8) scan_delay;
13086   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13087   S (mp);
13088   W (ret);
13089   return ret;
13090 }
13091
13092 static int
13093 api_input_acl_set_interface (vat_main_t * vam)
13094 {
13095   unformat_input_t *i = vam->input;
13096   vl_api_input_acl_set_interface_t *mp;
13097   u32 sw_if_index;
13098   int sw_if_index_set;
13099   u32 ip4_table_index = ~0;
13100   u32 ip6_table_index = ~0;
13101   u32 l2_table_index = ~0;
13102   u8 is_add = 1;
13103   int ret;
13104
13105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13106     {
13107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13108         sw_if_index_set = 1;
13109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13110         sw_if_index_set = 1;
13111       else if (unformat (i, "del"))
13112         is_add = 0;
13113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13114         ;
13115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13116         ;
13117       else if (unformat (i, "l2-table %d", &l2_table_index))
13118         ;
13119       else
13120         {
13121           clib_warning ("parse error '%U'", format_unformat_error, i);
13122           return -99;
13123         }
13124     }
13125
13126   if (sw_if_index_set == 0)
13127     {
13128       errmsg ("missing interface name or sw_if_index");
13129       return -99;
13130     }
13131
13132   M (INPUT_ACL_SET_INTERFACE, mp);
13133
13134   mp->sw_if_index = ntohl (sw_if_index);
13135   mp->ip4_table_index = ntohl (ip4_table_index);
13136   mp->ip6_table_index = ntohl (ip6_table_index);
13137   mp->l2_table_index = ntohl (l2_table_index);
13138   mp->is_add = is_add;
13139
13140   S (mp);
13141   W (ret);
13142   return ret;
13143 }
13144
13145 static int
13146 api_output_acl_set_interface (vat_main_t * vam)
13147 {
13148   unformat_input_t *i = vam->input;
13149   vl_api_output_acl_set_interface_t *mp;
13150   u32 sw_if_index;
13151   int sw_if_index_set;
13152   u32 ip4_table_index = ~0;
13153   u32 ip6_table_index = ~0;
13154   u32 l2_table_index = ~0;
13155   u8 is_add = 1;
13156   int ret;
13157
13158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13159     {
13160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13161         sw_if_index_set = 1;
13162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13163         sw_if_index_set = 1;
13164       else if (unformat (i, "del"))
13165         is_add = 0;
13166       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13167         ;
13168       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13169         ;
13170       else if (unformat (i, "l2-table %d", &l2_table_index))
13171         ;
13172       else
13173         {
13174           clib_warning ("parse error '%U'", format_unformat_error, i);
13175           return -99;
13176         }
13177     }
13178
13179   if (sw_if_index_set == 0)
13180     {
13181       errmsg ("missing interface name or sw_if_index");
13182       return -99;
13183     }
13184
13185   M (OUTPUT_ACL_SET_INTERFACE, mp);
13186
13187   mp->sw_if_index = ntohl (sw_if_index);
13188   mp->ip4_table_index = ntohl (ip4_table_index);
13189   mp->ip6_table_index = ntohl (ip6_table_index);
13190   mp->l2_table_index = ntohl (l2_table_index);
13191   mp->is_add = is_add;
13192
13193   S (mp);
13194   W (ret);
13195   return ret;
13196 }
13197
13198 static int
13199 api_ip_address_dump (vat_main_t * vam)
13200 {
13201   unformat_input_t *i = vam->input;
13202   vl_api_ip_address_dump_t *mp;
13203   vl_api_control_ping_t *mp_ping;
13204   u32 sw_if_index = ~0;
13205   u8 sw_if_index_set = 0;
13206   u8 ipv4_set = 0;
13207   u8 ipv6_set = 0;
13208   int ret;
13209
13210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13211     {
13212       if (unformat (i, "sw_if_index %d", &sw_if_index))
13213         sw_if_index_set = 1;
13214       else
13215         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13216         sw_if_index_set = 1;
13217       else if (unformat (i, "ipv4"))
13218         ipv4_set = 1;
13219       else if (unformat (i, "ipv6"))
13220         ipv6_set = 1;
13221       else
13222         break;
13223     }
13224
13225   if (ipv4_set && ipv6_set)
13226     {
13227       errmsg ("ipv4 and ipv6 flags cannot be both set");
13228       return -99;
13229     }
13230
13231   if ((!ipv4_set) && (!ipv6_set))
13232     {
13233       errmsg ("no ipv4 nor ipv6 flag set");
13234       return -99;
13235     }
13236
13237   if (sw_if_index_set == 0)
13238     {
13239       errmsg ("missing interface name or sw_if_index");
13240       return -99;
13241     }
13242
13243   vam->current_sw_if_index = sw_if_index;
13244   vam->is_ipv6 = ipv6_set;
13245
13246   M (IP_ADDRESS_DUMP, mp);
13247   mp->sw_if_index = ntohl (sw_if_index);
13248   mp->is_ipv6 = ipv6_set;
13249   S (mp);
13250
13251   /* Use a control ping for synchronization */
13252   MPING (CONTROL_PING, mp_ping);
13253   S (mp_ping);
13254
13255   W (ret);
13256   return ret;
13257 }
13258
13259 static int
13260 api_ip_dump (vat_main_t * vam)
13261 {
13262   vl_api_ip_dump_t *mp;
13263   vl_api_control_ping_t *mp_ping;
13264   unformat_input_t *in = vam->input;
13265   int ipv4_set = 0;
13266   int ipv6_set = 0;
13267   int is_ipv6;
13268   int i;
13269   int ret;
13270
13271   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13272     {
13273       if (unformat (in, "ipv4"))
13274         ipv4_set = 1;
13275       else if (unformat (in, "ipv6"))
13276         ipv6_set = 1;
13277       else
13278         break;
13279     }
13280
13281   if (ipv4_set && ipv6_set)
13282     {
13283       errmsg ("ipv4 and ipv6 flags cannot be both set");
13284       return -99;
13285     }
13286
13287   if ((!ipv4_set) && (!ipv6_set))
13288     {
13289       errmsg ("no ipv4 nor ipv6 flag set");
13290       return -99;
13291     }
13292
13293   is_ipv6 = ipv6_set;
13294   vam->is_ipv6 = is_ipv6;
13295
13296   /* free old data */
13297   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13298     {
13299       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13300     }
13301   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13302
13303   M (IP_DUMP, mp);
13304   mp->is_ipv6 = ipv6_set;
13305   S (mp);
13306
13307   /* Use a control ping for synchronization */
13308   MPING (CONTROL_PING, mp_ping);
13309   S (mp_ping);
13310
13311   W (ret);
13312   return ret;
13313 }
13314
13315 static int
13316 api_ipsec_spd_add_del (vat_main_t * vam)
13317 {
13318   unformat_input_t *i = vam->input;
13319   vl_api_ipsec_spd_add_del_t *mp;
13320   u32 spd_id = ~0;
13321   u8 is_add = 1;
13322   int ret;
13323
13324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13325     {
13326       if (unformat (i, "spd_id %d", &spd_id))
13327         ;
13328       else if (unformat (i, "del"))
13329         is_add = 0;
13330       else
13331         {
13332           clib_warning ("parse error '%U'", format_unformat_error, i);
13333           return -99;
13334         }
13335     }
13336   if (spd_id == ~0)
13337     {
13338       errmsg ("spd_id must be set");
13339       return -99;
13340     }
13341
13342   M (IPSEC_SPD_ADD_DEL, mp);
13343
13344   mp->spd_id = ntohl (spd_id);
13345   mp->is_add = is_add;
13346
13347   S (mp);
13348   W (ret);
13349   return ret;
13350 }
13351
13352 static int
13353 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13354 {
13355   unformat_input_t *i = vam->input;
13356   vl_api_ipsec_interface_add_del_spd_t *mp;
13357   u32 sw_if_index;
13358   u8 sw_if_index_set = 0;
13359   u32 spd_id = (u32) ~ 0;
13360   u8 is_add = 1;
13361   int ret;
13362
13363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13364     {
13365       if (unformat (i, "del"))
13366         is_add = 0;
13367       else if (unformat (i, "spd_id %d", &spd_id))
13368         ;
13369       else
13370         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13371         sw_if_index_set = 1;
13372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13373         sw_if_index_set = 1;
13374       else
13375         {
13376           clib_warning ("parse error '%U'", format_unformat_error, i);
13377           return -99;
13378         }
13379
13380     }
13381
13382   if (spd_id == (u32) ~ 0)
13383     {
13384       errmsg ("spd_id must be set");
13385       return -99;
13386     }
13387
13388   if (sw_if_index_set == 0)
13389     {
13390       errmsg ("missing interface name or sw_if_index");
13391       return -99;
13392     }
13393
13394   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13395
13396   mp->spd_id = ntohl (spd_id);
13397   mp->sw_if_index = ntohl (sw_if_index);
13398   mp->is_add = is_add;
13399
13400   S (mp);
13401   W (ret);
13402   return ret;
13403 }
13404
13405 static int
13406 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13407 {
13408   unformat_input_t *i = vam->input;
13409   vl_api_ipsec_spd_entry_add_del_t *mp;
13410   u8 is_add = 1, is_outbound = 0;
13411   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13412   i32 priority = 0;
13413   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13414   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13415   vl_api_address_t laddr_start = { }, laddr_stop =
13416   {
13417   }, raddr_start =
13418   {
13419   }, raddr_stop =
13420   {
13421   };
13422   int ret;
13423
13424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13425     {
13426       if (unformat (i, "del"))
13427         is_add = 0;
13428       if (unformat (i, "outbound"))
13429         is_outbound = 1;
13430       if (unformat (i, "inbound"))
13431         is_outbound = 0;
13432       else if (unformat (i, "spd_id %d", &spd_id))
13433         ;
13434       else if (unformat (i, "sa_id %d", &sa_id))
13435         ;
13436       else if (unformat (i, "priority %d", &priority))
13437         ;
13438       else if (unformat (i, "protocol %d", &protocol))
13439         ;
13440       else if (unformat (i, "lport_start %d", &lport_start))
13441         ;
13442       else if (unformat (i, "lport_stop %d", &lport_stop))
13443         ;
13444       else if (unformat (i, "rport_start %d", &rport_start))
13445         ;
13446       else if (unformat (i, "rport_stop %d", &rport_stop))
13447         ;
13448       else if (unformat (i, "laddr_start %U",
13449                          unformat_vl_api_address, &laddr_start))
13450         ;
13451       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13452                          &laddr_stop))
13453         ;
13454       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13455                          &raddr_start))
13456         ;
13457       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13458                          &raddr_stop))
13459         ;
13460       else
13461         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13462         {
13463           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13464             {
13465               clib_warning ("unsupported action: 'resolve'");
13466               return -99;
13467             }
13468         }
13469       else
13470         {
13471           clib_warning ("parse error '%U'", format_unformat_error, i);
13472           return -99;
13473         }
13474
13475     }
13476
13477   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13478
13479   mp->is_add = is_add;
13480
13481   mp->entry.spd_id = ntohl (spd_id);
13482   mp->entry.priority = ntohl (priority);
13483   mp->entry.is_outbound = is_outbound;
13484
13485   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13486                sizeof (vl_api_address_t));
13487   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13488                sizeof (vl_api_address_t));
13489   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13490                sizeof (vl_api_address_t));
13491   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13492                sizeof (vl_api_address_t));
13493
13494   mp->entry.protocol = (u8) protocol;
13495   mp->entry.local_port_start = ntohs ((u16) lport_start);
13496   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13497   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13498   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13499   mp->entry.policy = (u8) policy;
13500   mp->entry.sa_id = ntohl (sa_id);
13501
13502   S (mp);
13503   W (ret);
13504   return ret;
13505 }
13506
13507 static int
13508 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13509 {
13510   unformat_input_t *i = vam->input;
13511   vl_api_ipsec_sad_entry_add_del_t *mp;
13512   u32 sad_id = 0, spi = 0;
13513   u8 *ck = 0, *ik = 0;
13514   u8 is_add = 1;
13515
13516   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13517   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13518   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13519   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13520   vl_api_address_t tun_src, tun_dst;
13521   int ret;
13522
13523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13524     {
13525       if (unformat (i, "del"))
13526         is_add = 0;
13527       else if (unformat (i, "sad_id %d", &sad_id))
13528         ;
13529       else if (unformat (i, "spi %d", &spi))
13530         ;
13531       else if (unformat (i, "esp"))
13532         protocol = IPSEC_API_PROTO_ESP;
13533       else
13534         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13535         {
13536           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13537           if (ADDRESS_IP6 == tun_src.af)
13538             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13539         }
13540       else
13541         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13542         {
13543           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13544           if (ADDRESS_IP6 == tun_src.af)
13545             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13546         }
13547       else
13548         if (unformat (i, "crypto_alg %U",
13549                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13550         ;
13551       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13552         ;
13553       else if (unformat (i, "integ_alg %U",
13554                          unformat_ipsec_api_integ_alg, &integ_alg))
13555         ;
13556       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13557         ;
13558       else
13559         {
13560           clib_warning ("parse error '%U'", format_unformat_error, i);
13561           return -99;
13562         }
13563
13564     }
13565
13566   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13567
13568   mp->is_add = is_add;
13569   mp->entry.sad_id = ntohl (sad_id);
13570   mp->entry.protocol = protocol;
13571   mp->entry.spi = ntohl (spi);
13572   mp->entry.flags = flags;
13573
13574   mp->entry.crypto_algorithm = crypto_alg;
13575   mp->entry.integrity_algorithm = integ_alg;
13576   mp->entry.crypto_key.length = vec_len (ck);
13577   mp->entry.integrity_key.length = vec_len (ik);
13578
13579   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13580     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13581
13582   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13583     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13584
13585   if (ck)
13586     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13587   if (ik)
13588     clib_memcpy (mp->entry.integrity_key.data, ik,
13589                  mp->entry.integrity_key.length);
13590
13591   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13592     {
13593       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13594                    sizeof (mp->entry.tunnel_src));
13595       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13596                    sizeof (mp->entry.tunnel_dst));
13597     }
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 static int
13605 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13606 {
13607   unformat_input_t *i = vam->input;
13608   vl_api_ipsec_tunnel_if_add_del_t *mp;
13609   u32 local_spi = 0, remote_spi = 0;
13610   u32 crypto_alg = 0, integ_alg = 0;
13611   u8 *lck = NULL, *rck = NULL;
13612   u8 *lik = NULL, *rik = NULL;
13613   vl_api_address_t local_ip = { 0 };
13614   vl_api_address_t remote_ip = { 0 };
13615   f64 before = 0;
13616   u8 is_add = 1;
13617   u8 esn = 0;
13618   u8 anti_replay = 0;
13619   u8 renumber = 0;
13620   u32 instance = ~0;
13621   u32 count = 1, jj;
13622   int ret = -1;
13623
13624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13625     {
13626       if (unformat (i, "del"))
13627         is_add = 0;
13628       else if (unformat (i, "esn"))
13629         esn = 1;
13630       else if (unformat (i, "anti-replay"))
13631         anti_replay = 1;
13632       else if (unformat (i, "count %d", &count))
13633         ;
13634       else if (unformat (i, "local_spi %d", &local_spi))
13635         ;
13636       else if (unformat (i, "remote_spi %d", &remote_spi))
13637         ;
13638       else
13639         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13640         ;
13641       else
13642         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13643         ;
13644       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13645         ;
13646       else
13647         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13648         ;
13649       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13650         ;
13651       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13652         ;
13653       else
13654         if (unformat
13655             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13656         {
13657           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13658             {
13659               errmsg ("unsupported crypto-alg: '%U'\n",
13660                       format_ipsec_crypto_alg, crypto_alg);
13661               return -99;
13662             }
13663         }
13664       else
13665         if (unformat
13666             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13667         {
13668           if (integ_alg >= IPSEC_INTEG_N_ALG)
13669             {
13670               errmsg ("unsupported integ-alg: '%U'\n",
13671                       format_ipsec_integ_alg, integ_alg);
13672               return -99;
13673             }
13674         }
13675       else if (unformat (i, "instance %u", &instance))
13676         renumber = 1;
13677       else
13678         {
13679           errmsg ("parse error '%U'\n", format_unformat_error, i);
13680           return -99;
13681         }
13682     }
13683
13684   if (count > 1)
13685     {
13686       /* Turn on async mode */
13687       vam->async_mode = 1;
13688       vam->async_errors = 0;
13689       before = vat_time_now (vam);
13690     }
13691
13692   for (jj = 0; jj < count; jj++)
13693     {
13694       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13695
13696       mp->is_add = is_add;
13697       mp->esn = esn;
13698       mp->anti_replay = anti_replay;
13699
13700       if (jj > 0)
13701         increment_address (&remote_ip);
13702
13703       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13704       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13705
13706       mp->local_spi = htonl (local_spi + jj);
13707       mp->remote_spi = htonl (remote_spi + jj);
13708       mp->crypto_alg = (u8) crypto_alg;
13709
13710       mp->local_crypto_key_len = 0;
13711       if (lck)
13712         {
13713           mp->local_crypto_key_len = vec_len (lck);
13714           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13715             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13716           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13717         }
13718
13719       mp->remote_crypto_key_len = 0;
13720       if (rck)
13721         {
13722           mp->remote_crypto_key_len = vec_len (rck);
13723           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13724             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13725           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13726         }
13727
13728       mp->integ_alg = (u8) integ_alg;
13729
13730       mp->local_integ_key_len = 0;
13731       if (lik)
13732         {
13733           mp->local_integ_key_len = vec_len (lik);
13734           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13735             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13736           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13737         }
13738
13739       mp->remote_integ_key_len = 0;
13740       if (rik)
13741         {
13742           mp->remote_integ_key_len = vec_len (rik);
13743           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13744             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13745           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13746         }
13747
13748       if (renumber)
13749         {
13750           mp->renumber = renumber;
13751           mp->show_instance = ntohl (instance);
13752         }
13753       S (mp);
13754     }
13755
13756   /* When testing multiple add/del ops, use a control-ping to sync */
13757   if (count > 1)
13758     {
13759       vl_api_control_ping_t *mp_ping;
13760       f64 after;
13761       f64 timeout;
13762
13763       /* Shut off async mode */
13764       vam->async_mode = 0;
13765
13766       MPING (CONTROL_PING, mp_ping);
13767       S (mp_ping);
13768
13769       timeout = vat_time_now (vam) + 1.0;
13770       while (vat_time_now (vam) < timeout)
13771         if (vam->result_ready == 1)
13772           goto out;
13773       vam->retval = -99;
13774
13775     out:
13776       if (vam->retval == -99)
13777         errmsg ("timeout");
13778
13779       if (vam->async_errors > 0)
13780         {
13781           errmsg ("%d asynchronous errors", vam->async_errors);
13782           vam->retval = -98;
13783         }
13784       vam->async_errors = 0;
13785       after = vat_time_now (vam);
13786
13787       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13788       if (jj > 0)
13789         count = jj;
13790
13791       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13792              count, after - before, count / (after - before));
13793     }
13794   else
13795     {
13796       /* Wait for a reply... */
13797       W (ret);
13798       return ret;
13799     }
13800
13801   return ret;
13802 }
13803
13804 static void
13805 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13806 {
13807   vat_main_t *vam = &vat_main;
13808
13809   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13810          "crypto_key %U integ_alg %u integ_key %U flags %x "
13811          "tunnel_src_addr %U tunnel_dst_addr %U "
13812          "salt %u seq_outbound %lu last_seq_inbound %lu "
13813          "replay_window %lu\n",
13814          ntohl (mp->entry.sad_id),
13815          ntohl (mp->sw_if_index),
13816          ntohl (mp->entry.spi),
13817          ntohl (mp->entry.protocol),
13818          ntohl (mp->entry.crypto_algorithm),
13819          format_hex_bytes, mp->entry.crypto_key.data,
13820          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13821          format_hex_bytes, mp->entry.integrity_key.data,
13822          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13823          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13824          &mp->entry.tunnel_dst, ntohl (mp->salt),
13825          clib_net_to_host_u64 (mp->seq_outbound),
13826          clib_net_to_host_u64 (mp->last_seq_inbound),
13827          clib_net_to_host_u64 (mp->replay_window));
13828 }
13829
13830 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13831 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13832
13833 static void vl_api_ipsec_sa_details_t_handler_json
13834   (vl_api_ipsec_sa_details_t * mp)
13835 {
13836   vat_main_t *vam = &vat_main;
13837   vat_json_node_t *node = NULL;
13838   vl_api_ipsec_sad_flags_t flags;
13839
13840   if (VAT_JSON_ARRAY != vam->json_tree.type)
13841     {
13842       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13843       vat_json_init_array (&vam->json_tree);
13844     }
13845   node = vat_json_array_add (&vam->json_tree);
13846
13847   vat_json_init_object (node);
13848   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13849   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13850   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13851   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13852   vat_json_object_add_uint (node, "crypto_alg",
13853                             ntohl (mp->entry.crypto_algorithm));
13854   vat_json_object_add_uint (node, "integ_alg",
13855                             ntohl (mp->entry.integrity_algorithm));
13856   flags = ntohl (mp->entry.flags);
13857   vat_json_object_add_uint (node, "use_esn",
13858                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13859   vat_json_object_add_uint (node, "use_anti_replay",
13860                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13861   vat_json_object_add_uint (node, "is_tunnel",
13862                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13863   vat_json_object_add_uint (node, "is_tunnel_ip6",
13864                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13865   vat_json_object_add_uint (node, "udp_encap",
13866                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13867   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13868                              mp->entry.crypto_key.length);
13869   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13870                              mp->entry.integrity_key.length);
13871   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13872   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13873   vat_json_object_add_uint (node, "replay_window",
13874                             clib_net_to_host_u64 (mp->replay_window));
13875 }
13876
13877 static int
13878 api_ipsec_sa_dump (vat_main_t * vam)
13879 {
13880   unformat_input_t *i = vam->input;
13881   vl_api_ipsec_sa_dump_t *mp;
13882   vl_api_control_ping_t *mp_ping;
13883   u32 sa_id = ~0;
13884   int ret;
13885
13886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (i, "sa_id %d", &sa_id))
13889         ;
13890       else
13891         {
13892           clib_warning ("parse error '%U'", format_unformat_error, i);
13893           return -99;
13894         }
13895     }
13896
13897   M (IPSEC_SA_DUMP, mp);
13898
13899   mp->sa_id = ntohl (sa_id);
13900
13901   S (mp);
13902
13903   /* Use a control ping for synchronization */
13904   M (CONTROL_PING, mp_ping);
13905   S (mp_ping);
13906
13907   W (ret);
13908   return ret;
13909 }
13910
13911 static int
13912 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13913 {
13914   unformat_input_t *i = vam->input;
13915   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13916   u32 sw_if_index = ~0;
13917   u32 sa_id = ~0;
13918   u8 is_outbound = (u8) ~ 0;
13919   int ret;
13920
13921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13924         ;
13925       else if (unformat (i, "sa_id %d", &sa_id))
13926         ;
13927       else if (unformat (i, "outbound"))
13928         is_outbound = 1;
13929       else if (unformat (i, "inbound"))
13930         is_outbound = 0;
13931       else
13932         {
13933           clib_warning ("parse error '%U'", format_unformat_error, i);
13934           return -99;
13935         }
13936     }
13937
13938   if (sw_if_index == ~0)
13939     {
13940       errmsg ("interface must be specified");
13941       return -99;
13942     }
13943
13944   if (sa_id == ~0)
13945     {
13946       errmsg ("SA ID must be specified");
13947       return -99;
13948     }
13949
13950   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13951
13952   mp->sw_if_index = htonl (sw_if_index);
13953   mp->sa_id = htonl (sa_id);
13954   mp->is_outbound = is_outbound;
13955
13956   S (mp);
13957   W (ret);
13958
13959   return ret;
13960 }
13961
13962 static int
13963 api_get_first_msg_id (vat_main_t * vam)
13964 {
13965   vl_api_get_first_msg_id_t *mp;
13966   unformat_input_t *i = vam->input;
13967   u8 *name;
13968   u8 name_set = 0;
13969   int ret;
13970
13971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13972     {
13973       if (unformat (i, "client %s", &name))
13974         name_set = 1;
13975       else
13976         break;
13977     }
13978
13979   if (name_set == 0)
13980     {
13981       errmsg ("missing client name");
13982       return -99;
13983     }
13984   vec_add1 (name, 0);
13985
13986   if (vec_len (name) > 63)
13987     {
13988       errmsg ("client name too long");
13989       return -99;
13990     }
13991
13992   M (GET_FIRST_MSG_ID, mp);
13993   clib_memcpy (mp->name, name, vec_len (name));
13994   S (mp);
13995   W (ret);
13996   return ret;
13997 }
13998
13999 static int
14000 api_cop_interface_enable_disable (vat_main_t * vam)
14001 {
14002   unformat_input_t *line_input = vam->input;
14003   vl_api_cop_interface_enable_disable_t *mp;
14004   u32 sw_if_index = ~0;
14005   u8 enable_disable = 1;
14006   int ret;
14007
14008   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14009     {
14010       if (unformat (line_input, "disable"))
14011         enable_disable = 0;
14012       if (unformat (line_input, "enable"))
14013         enable_disable = 1;
14014       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14015                          vam, &sw_if_index))
14016         ;
14017       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14018         ;
14019       else
14020         break;
14021     }
14022
14023   if (sw_if_index == ~0)
14024     {
14025       errmsg ("missing interface name or sw_if_index");
14026       return -99;
14027     }
14028
14029   /* Construct the API message */
14030   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14031   mp->sw_if_index = ntohl (sw_if_index);
14032   mp->enable_disable = enable_disable;
14033
14034   /* send it... */
14035   S (mp);
14036   /* Wait for the reply */
14037   W (ret);
14038   return ret;
14039 }
14040
14041 static int
14042 api_cop_whitelist_enable_disable (vat_main_t * vam)
14043 {
14044   unformat_input_t *line_input = vam->input;
14045   vl_api_cop_whitelist_enable_disable_t *mp;
14046   u32 sw_if_index = ~0;
14047   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14048   u32 fib_id = 0;
14049   int ret;
14050
14051   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14052     {
14053       if (unformat (line_input, "ip4"))
14054         ip4 = 1;
14055       else if (unformat (line_input, "ip6"))
14056         ip6 = 1;
14057       else if (unformat (line_input, "default"))
14058         default_cop = 1;
14059       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14060                          vam, &sw_if_index))
14061         ;
14062       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14063         ;
14064       else if (unformat (line_input, "fib-id %d", &fib_id))
14065         ;
14066       else
14067         break;
14068     }
14069
14070   if (sw_if_index == ~0)
14071     {
14072       errmsg ("missing interface name or sw_if_index");
14073       return -99;
14074     }
14075
14076   /* Construct the API message */
14077   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14078   mp->sw_if_index = ntohl (sw_if_index);
14079   mp->fib_id = ntohl (fib_id);
14080   mp->ip4 = ip4;
14081   mp->ip6 = ip6;
14082   mp->default_cop = default_cop;
14083
14084   /* send it... */
14085   S (mp);
14086   /* Wait for the reply */
14087   W (ret);
14088   return ret;
14089 }
14090
14091 static int
14092 api_get_node_graph (vat_main_t * vam)
14093 {
14094   vl_api_get_node_graph_t *mp;
14095   int ret;
14096
14097   M (GET_NODE_GRAPH, mp);
14098
14099   /* send it... */
14100   S (mp);
14101   /* Wait for the reply */
14102   W (ret);
14103   return ret;
14104 }
14105
14106 /* *INDENT-OFF* */
14107 /** Used for parsing LISP eids */
14108 typedef CLIB_PACKED(struct{
14109   u8 addr[16];   /**< eid address */
14110   u32 len;       /**< prefix length if IP */
14111   u8 type;      /**< type of eid */
14112 }) lisp_eid_vat_t;
14113 /* *INDENT-ON* */
14114
14115 static uword
14116 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14117 {
14118   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14119
14120   clib_memset (a, 0, sizeof (a[0]));
14121
14122   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14123     {
14124       a->type = 0;              /* ipv4 type */
14125     }
14126   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14127     {
14128       a->type = 1;              /* ipv6 type */
14129     }
14130   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14131     {
14132       a->type = 2;              /* mac type */
14133     }
14134   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14135     {
14136       a->type = 3;              /* NSH type */
14137       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14138       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14139     }
14140   else
14141     {
14142       return 0;
14143     }
14144
14145   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14146     {
14147       return 0;
14148     }
14149
14150   return 1;
14151 }
14152
14153 static int
14154 lisp_eid_size_vat (u8 type)
14155 {
14156   switch (type)
14157     {
14158     case 0:
14159       return 4;
14160     case 1:
14161       return 16;
14162     case 2:
14163       return 6;
14164     case 3:
14165       return 5;
14166     }
14167   return 0;
14168 }
14169
14170 static void
14171 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14172 {
14173   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14174 }
14175
14176 static int
14177 api_one_add_del_locator_set (vat_main_t * vam)
14178 {
14179   unformat_input_t *input = vam->input;
14180   vl_api_one_add_del_locator_set_t *mp;
14181   u8 is_add = 1;
14182   u8 *locator_set_name = NULL;
14183   u8 locator_set_name_set = 0;
14184   vl_api_local_locator_t locator, *locators = 0;
14185   u32 sw_if_index, priority, weight;
14186   u32 data_len = 0;
14187
14188   int ret;
14189   /* Parse args required to build the message */
14190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14191     {
14192       if (unformat (input, "del"))
14193         {
14194           is_add = 0;
14195         }
14196       else if (unformat (input, "locator-set %s", &locator_set_name))
14197         {
14198           locator_set_name_set = 1;
14199         }
14200       else if (unformat (input, "sw_if_index %u p %u w %u",
14201                          &sw_if_index, &priority, &weight))
14202         {
14203           locator.sw_if_index = htonl (sw_if_index);
14204           locator.priority = priority;
14205           locator.weight = weight;
14206           vec_add1 (locators, locator);
14207         }
14208       else
14209         if (unformat
14210             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14211              &sw_if_index, &priority, &weight))
14212         {
14213           locator.sw_if_index = htonl (sw_if_index);
14214           locator.priority = priority;
14215           locator.weight = weight;
14216           vec_add1 (locators, locator);
14217         }
14218       else
14219         break;
14220     }
14221
14222   if (locator_set_name_set == 0)
14223     {
14224       errmsg ("missing locator-set name");
14225       vec_free (locators);
14226       return -99;
14227     }
14228
14229   if (vec_len (locator_set_name) > 64)
14230     {
14231       errmsg ("locator-set name too long");
14232       vec_free (locator_set_name);
14233       vec_free (locators);
14234       return -99;
14235     }
14236   vec_add1 (locator_set_name, 0);
14237
14238   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14239
14240   /* Construct the API message */
14241   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14242
14243   mp->is_add = is_add;
14244   clib_memcpy (mp->locator_set_name, locator_set_name,
14245                vec_len (locator_set_name));
14246   vec_free (locator_set_name);
14247
14248   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14249   if (locators)
14250     clib_memcpy (mp->locators, locators, data_len);
14251   vec_free (locators);
14252
14253   /* send it... */
14254   S (mp);
14255
14256   /* Wait for a reply... */
14257   W (ret);
14258   return ret;
14259 }
14260
14261 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14262
14263 static int
14264 api_one_add_del_locator (vat_main_t * vam)
14265 {
14266   unformat_input_t *input = vam->input;
14267   vl_api_one_add_del_locator_t *mp;
14268   u32 tmp_if_index = ~0;
14269   u32 sw_if_index = ~0;
14270   u8 sw_if_index_set = 0;
14271   u8 sw_if_index_if_name_set = 0;
14272   u32 priority = ~0;
14273   u8 priority_set = 0;
14274   u32 weight = ~0;
14275   u8 weight_set = 0;
14276   u8 is_add = 1;
14277   u8 *locator_set_name = NULL;
14278   u8 locator_set_name_set = 0;
14279   int ret;
14280
14281   /* Parse args required to build the message */
14282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14283     {
14284       if (unformat (input, "del"))
14285         {
14286           is_add = 0;
14287         }
14288       else if (unformat (input, "locator-set %s", &locator_set_name))
14289         {
14290           locator_set_name_set = 1;
14291         }
14292       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14293                          &tmp_if_index))
14294         {
14295           sw_if_index_if_name_set = 1;
14296           sw_if_index = tmp_if_index;
14297         }
14298       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14299         {
14300           sw_if_index_set = 1;
14301           sw_if_index = tmp_if_index;
14302         }
14303       else if (unformat (input, "p %d", &priority))
14304         {
14305           priority_set = 1;
14306         }
14307       else if (unformat (input, "w %d", &weight))
14308         {
14309           weight_set = 1;
14310         }
14311       else
14312         break;
14313     }
14314
14315   if (locator_set_name_set == 0)
14316     {
14317       errmsg ("missing locator-set name");
14318       return -99;
14319     }
14320
14321   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14322     {
14323       errmsg ("missing sw_if_index");
14324       vec_free (locator_set_name);
14325       return -99;
14326     }
14327
14328   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14329     {
14330       errmsg ("cannot use both params interface name and sw_if_index");
14331       vec_free (locator_set_name);
14332       return -99;
14333     }
14334
14335   if (priority_set == 0)
14336     {
14337       errmsg ("missing locator-set priority");
14338       vec_free (locator_set_name);
14339       return -99;
14340     }
14341
14342   if (weight_set == 0)
14343     {
14344       errmsg ("missing locator-set weight");
14345       vec_free (locator_set_name);
14346       return -99;
14347     }
14348
14349   if (vec_len (locator_set_name) > 64)
14350     {
14351       errmsg ("locator-set name too long");
14352       vec_free (locator_set_name);
14353       return -99;
14354     }
14355   vec_add1 (locator_set_name, 0);
14356
14357   /* Construct the API message */
14358   M (ONE_ADD_DEL_LOCATOR, mp);
14359
14360   mp->is_add = is_add;
14361   mp->sw_if_index = ntohl (sw_if_index);
14362   mp->priority = priority;
14363   mp->weight = weight;
14364   clib_memcpy (mp->locator_set_name, locator_set_name,
14365                vec_len (locator_set_name));
14366   vec_free (locator_set_name);
14367
14368   /* send it... */
14369   S (mp);
14370
14371   /* Wait for a reply... */
14372   W (ret);
14373   return ret;
14374 }
14375
14376 #define api_lisp_add_del_locator api_one_add_del_locator
14377
14378 uword
14379 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14380 {
14381   u32 *key_id = va_arg (*args, u32 *);
14382   u8 *s = 0;
14383
14384   if (unformat (input, "%s", &s))
14385     {
14386       if (!strcmp ((char *) s, "sha1"))
14387         key_id[0] = HMAC_SHA_1_96;
14388       else if (!strcmp ((char *) s, "sha256"))
14389         key_id[0] = HMAC_SHA_256_128;
14390       else
14391         {
14392           clib_warning ("invalid key_id: '%s'", s);
14393           key_id[0] = HMAC_NO_KEY;
14394         }
14395     }
14396   else
14397     return 0;
14398
14399   vec_free (s);
14400   return 1;
14401 }
14402
14403 static int
14404 api_one_add_del_local_eid (vat_main_t * vam)
14405 {
14406   unformat_input_t *input = vam->input;
14407   vl_api_one_add_del_local_eid_t *mp;
14408   u8 is_add = 1;
14409   u8 eid_set = 0;
14410   lisp_eid_vat_t _eid, *eid = &_eid;
14411   u8 *locator_set_name = 0;
14412   u8 locator_set_name_set = 0;
14413   u32 vni = 0;
14414   u16 key_id = 0;
14415   u8 *key = 0;
14416   int ret;
14417
14418   /* Parse args required to build the message */
14419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14420     {
14421       if (unformat (input, "del"))
14422         {
14423           is_add = 0;
14424         }
14425       else if (unformat (input, "vni %d", &vni))
14426         {
14427           ;
14428         }
14429       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14430         {
14431           eid_set = 1;
14432         }
14433       else if (unformat (input, "locator-set %s", &locator_set_name))
14434         {
14435           locator_set_name_set = 1;
14436         }
14437       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14438         ;
14439       else if (unformat (input, "secret-key %_%v%_", &key))
14440         ;
14441       else
14442         break;
14443     }
14444
14445   if (locator_set_name_set == 0)
14446     {
14447       errmsg ("missing locator-set name");
14448       return -99;
14449     }
14450
14451   if (0 == eid_set)
14452     {
14453       errmsg ("EID address not set!");
14454       vec_free (locator_set_name);
14455       return -99;
14456     }
14457
14458   if (key && (0 == key_id))
14459     {
14460       errmsg ("invalid key_id!");
14461       return -99;
14462     }
14463
14464   if (vec_len (key) > 64)
14465     {
14466       errmsg ("key too long");
14467       vec_free (key);
14468       return -99;
14469     }
14470
14471   if (vec_len (locator_set_name) > 64)
14472     {
14473       errmsg ("locator-set name too long");
14474       vec_free (locator_set_name);
14475       return -99;
14476     }
14477   vec_add1 (locator_set_name, 0);
14478
14479   /* Construct the API message */
14480   M (ONE_ADD_DEL_LOCAL_EID, mp);
14481
14482   mp->is_add = is_add;
14483   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14484   mp->eid_type = eid->type;
14485   mp->prefix_len = eid->len;
14486   mp->vni = clib_host_to_net_u32 (vni);
14487   mp->key_id = clib_host_to_net_u16 (key_id);
14488   clib_memcpy (mp->locator_set_name, locator_set_name,
14489                vec_len (locator_set_name));
14490   clib_memcpy (mp->key, key, vec_len (key));
14491
14492   vec_free (locator_set_name);
14493   vec_free (key);
14494
14495   /* send it... */
14496   S (mp);
14497
14498   /* Wait for a reply... */
14499   W (ret);
14500   return ret;
14501 }
14502
14503 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14504
14505 static int
14506 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14507 {
14508   u32 dp_table = 0, vni = 0;;
14509   unformat_input_t *input = vam->input;
14510   vl_api_gpe_add_del_fwd_entry_t *mp;
14511   u8 is_add = 1;
14512   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14513   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14514   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14515   u32 action = ~0, w;
14516   ip4_address_t rmt_rloc4, lcl_rloc4;
14517   ip6_address_t rmt_rloc6, lcl_rloc6;
14518   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14519   int ret;
14520
14521   clib_memset (&rloc, 0, sizeof (rloc));
14522
14523   /* Parse args required to build the message */
14524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14525     {
14526       if (unformat (input, "del"))
14527         is_add = 0;
14528       else if (unformat (input, "add"))
14529         is_add = 1;
14530       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14531         {
14532           rmt_eid_set = 1;
14533         }
14534       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14535         {
14536           lcl_eid_set = 1;
14537         }
14538       else if (unformat (input, "vrf %d", &dp_table))
14539         ;
14540       else if (unformat (input, "bd %d", &dp_table))
14541         ;
14542       else if (unformat (input, "vni %d", &vni))
14543         ;
14544       else if (unformat (input, "w %d", &w))
14545         {
14546           if (!curr_rloc)
14547             {
14548               errmsg ("No RLOC configured for setting priority/weight!");
14549               return -99;
14550             }
14551           curr_rloc->weight = w;
14552         }
14553       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14554                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14555         {
14556           rloc.is_ip4 = 1;
14557
14558           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14559           rloc.weight = 0;
14560           vec_add1 (lcl_locs, rloc);
14561
14562           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14563           vec_add1 (rmt_locs, rloc);
14564           /* weight saved in rmt loc */
14565           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14566         }
14567       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14568                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14569         {
14570           rloc.is_ip4 = 0;
14571           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14572           rloc.weight = 0;
14573           vec_add1 (lcl_locs, rloc);
14574
14575           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14576           vec_add1 (rmt_locs, rloc);
14577           /* weight saved in rmt loc */
14578           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14579         }
14580       else if (unformat (input, "action %d", &action))
14581         {
14582           ;
14583         }
14584       else
14585         {
14586           clib_warning ("parse error '%U'", format_unformat_error, input);
14587           return -99;
14588         }
14589     }
14590
14591   if (!rmt_eid_set)
14592     {
14593       errmsg ("remote eid addresses not set");
14594       return -99;
14595     }
14596
14597   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14598     {
14599       errmsg ("eid types don't match");
14600       return -99;
14601     }
14602
14603   if (0 == rmt_locs && (u32) ~ 0 == action)
14604     {
14605       errmsg ("action not set for negative mapping");
14606       return -99;
14607     }
14608
14609   /* Construct the API message */
14610   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14611       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14612
14613   mp->is_add = is_add;
14614   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14615   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14616   mp->eid_type = rmt_eid->type;
14617   mp->dp_table = clib_host_to_net_u32 (dp_table);
14618   mp->vni = clib_host_to_net_u32 (vni);
14619   mp->rmt_len = rmt_eid->len;
14620   mp->lcl_len = lcl_eid->len;
14621   mp->action = action;
14622
14623   if (0 != rmt_locs && 0 != lcl_locs)
14624     {
14625       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14626       clib_memcpy (mp->locs, lcl_locs,
14627                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14628
14629       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14630       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14631                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14632     }
14633   vec_free (lcl_locs);
14634   vec_free (rmt_locs);
14635
14636   /* send it... */
14637   S (mp);
14638
14639   /* Wait for a reply... */
14640   W (ret);
14641   return ret;
14642 }
14643
14644 static int
14645 api_one_add_del_map_server (vat_main_t * vam)
14646 {
14647   unformat_input_t *input = vam->input;
14648   vl_api_one_add_del_map_server_t *mp;
14649   u8 is_add = 1;
14650   u8 ipv4_set = 0;
14651   u8 ipv6_set = 0;
14652   ip4_address_t ipv4;
14653   ip6_address_t ipv6;
14654   int ret;
14655
14656   /* Parse args required to build the message */
14657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14658     {
14659       if (unformat (input, "del"))
14660         {
14661           is_add = 0;
14662         }
14663       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14664         {
14665           ipv4_set = 1;
14666         }
14667       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14668         {
14669           ipv6_set = 1;
14670         }
14671       else
14672         break;
14673     }
14674
14675   if (ipv4_set && ipv6_set)
14676     {
14677       errmsg ("both eid v4 and v6 addresses set");
14678       return -99;
14679     }
14680
14681   if (!ipv4_set && !ipv6_set)
14682     {
14683       errmsg ("eid addresses not set");
14684       return -99;
14685     }
14686
14687   /* Construct the API message */
14688   M (ONE_ADD_DEL_MAP_SERVER, mp);
14689
14690   mp->is_add = is_add;
14691   if (ipv6_set)
14692     {
14693       mp->is_ipv6 = 1;
14694       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14695     }
14696   else
14697     {
14698       mp->is_ipv6 = 0;
14699       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14700     }
14701
14702   /* send it... */
14703   S (mp);
14704
14705   /* Wait for a reply... */
14706   W (ret);
14707   return ret;
14708 }
14709
14710 #define api_lisp_add_del_map_server api_one_add_del_map_server
14711
14712 static int
14713 api_one_add_del_map_resolver (vat_main_t * vam)
14714 {
14715   unformat_input_t *input = vam->input;
14716   vl_api_one_add_del_map_resolver_t *mp;
14717   u8 is_add = 1;
14718   u8 ipv4_set = 0;
14719   u8 ipv6_set = 0;
14720   ip4_address_t ipv4;
14721   ip6_address_t ipv6;
14722   int ret;
14723
14724   /* Parse args required to build the message */
14725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14726     {
14727       if (unformat (input, "del"))
14728         {
14729           is_add = 0;
14730         }
14731       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14732         {
14733           ipv4_set = 1;
14734         }
14735       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14736         {
14737           ipv6_set = 1;
14738         }
14739       else
14740         break;
14741     }
14742
14743   if (ipv4_set && ipv6_set)
14744     {
14745       errmsg ("both eid v4 and v6 addresses set");
14746       return -99;
14747     }
14748
14749   if (!ipv4_set && !ipv6_set)
14750     {
14751       errmsg ("eid addresses not set");
14752       return -99;
14753     }
14754
14755   /* Construct the API message */
14756   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14757
14758   mp->is_add = is_add;
14759   if (ipv6_set)
14760     {
14761       mp->is_ipv6 = 1;
14762       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14763     }
14764   else
14765     {
14766       mp->is_ipv6 = 0;
14767       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14768     }
14769
14770   /* send it... */
14771   S (mp);
14772
14773   /* Wait for a reply... */
14774   W (ret);
14775   return ret;
14776 }
14777
14778 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14779
14780 static int
14781 api_lisp_gpe_enable_disable (vat_main_t * vam)
14782 {
14783   unformat_input_t *input = vam->input;
14784   vl_api_gpe_enable_disable_t *mp;
14785   u8 is_set = 0;
14786   u8 is_en = 1;
14787   int ret;
14788
14789   /* Parse args required to build the message */
14790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14791     {
14792       if (unformat (input, "enable"))
14793         {
14794           is_set = 1;
14795           is_en = 1;
14796         }
14797       else if (unformat (input, "disable"))
14798         {
14799           is_set = 1;
14800           is_en = 0;
14801         }
14802       else
14803         break;
14804     }
14805
14806   if (is_set == 0)
14807     {
14808       errmsg ("Value not set");
14809       return -99;
14810     }
14811
14812   /* Construct the API message */
14813   M (GPE_ENABLE_DISABLE, mp);
14814
14815   mp->is_en = is_en;
14816
14817   /* send it... */
14818   S (mp);
14819
14820   /* Wait for a reply... */
14821   W (ret);
14822   return ret;
14823 }
14824
14825 static int
14826 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14827 {
14828   unformat_input_t *input = vam->input;
14829   vl_api_one_rloc_probe_enable_disable_t *mp;
14830   u8 is_set = 0;
14831   u8 is_en = 0;
14832   int ret;
14833
14834   /* Parse args required to build the message */
14835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14836     {
14837       if (unformat (input, "enable"))
14838         {
14839           is_set = 1;
14840           is_en = 1;
14841         }
14842       else if (unformat (input, "disable"))
14843         is_set = 1;
14844       else
14845         break;
14846     }
14847
14848   if (!is_set)
14849     {
14850       errmsg ("Value not set");
14851       return -99;
14852     }
14853
14854   /* Construct the API message */
14855   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14856
14857   mp->is_enabled = is_en;
14858
14859   /* send it... */
14860   S (mp);
14861
14862   /* Wait for a reply... */
14863   W (ret);
14864   return ret;
14865 }
14866
14867 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14868
14869 static int
14870 api_one_map_register_enable_disable (vat_main_t * vam)
14871 {
14872   unformat_input_t *input = vam->input;
14873   vl_api_one_map_register_enable_disable_t *mp;
14874   u8 is_set = 0;
14875   u8 is_en = 0;
14876   int ret;
14877
14878   /* Parse args required to build the message */
14879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14880     {
14881       if (unformat (input, "enable"))
14882         {
14883           is_set = 1;
14884           is_en = 1;
14885         }
14886       else if (unformat (input, "disable"))
14887         is_set = 1;
14888       else
14889         break;
14890     }
14891
14892   if (!is_set)
14893     {
14894       errmsg ("Value not set");
14895       return -99;
14896     }
14897
14898   /* Construct the API message */
14899   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14900
14901   mp->is_enabled = is_en;
14902
14903   /* send it... */
14904   S (mp);
14905
14906   /* Wait for a reply... */
14907   W (ret);
14908   return ret;
14909 }
14910
14911 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14912
14913 static int
14914 api_one_enable_disable (vat_main_t * vam)
14915 {
14916   unformat_input_t *input = vam->input;
14917   vl_api_one_enable_disable_t *mp;
14918   u8 is_set = 0;
14919   u8 is_en = 0;
14920   int ret;
14921
14922   /* Parse args required to build the message */
14923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (input, "enable"))
14926         {
14927           is_set = 1;
14928           is_en = 1;
14929         }
14930       else if (unformat (input, "disable"))
14931         {
14932           is_set = 1;
14933         }
14934       else
14935         break;
14936     }
14937
14938   if (!is_set)
14939     {
14940       errmsg ("Value not set");
14941       return -99;
14942     }
14943
14944   /* Construct the API message */
14945   M (ONE_ENABLE_DISABLE, mp);
14946
14947   mp->is_en = is_en;
14948
14949   /* send it... */
14950   S (mp);
14951
14952   /* Wait for a reply... */
14953   W (ret);
14954   return ret;
14955 }
14956
14957 #define api_lisp_enable_disable api_one_enable_disable
14958
14959 static int
14960 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14961 {
14962   unformat_input_t *input = vam->input;
14963   vl_api_one_enable_disable_xtr_mode_t *mp;
14964   u8 is_set = 0;
14965   u8 is_en = 0;
14966   int ret;
14967
14968   /* Parse args required to build the message */
14969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14970     {
14971       if (unformat (input, "enable"))
14972         {
14973           is_set = 1;
14974           is_en = 1;
14975         }
14976       else if (unformat (input, "disable"))
14977         {
14978           is_set = 1;
14979         }
14980       else
14981         break;
14982     }
14983
14984   if (!is_set)
14985     {
14986       errmsg ("Value not set");
14987       return -99;
14988     }
14989
14990   /* Construct the API message */
14991   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14992
14993   mp->is_en = is_en;
14994
14995   /* send it... */
14996   S (mp);
14997
14998   /* Wait for a reply... */
14999   W (ret);
15000   return ret;
15001 }
15002
15003 static int
15004 api_one_show_xtr_mode (vat_main_t * vam)
15005 {
15006   vl_api_one_show_xtr_mode_t *mp;
15007   int ret;
15008
15009   /* Construct the API message */
15010   M (ONE_SHOW_XTR_MODE, mp);
15011
15012   /* send it... */
15013   S (mp);
15014
15015   /* Wait for a reply... */
15016   W (ret);
15017   return ret;
15018 }
15019
15020 static int
15021 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15022 {
15023   unformat_input_t *input = vam->input;
15024   vl_api_one_enable_disable_pitr_mode_t *mp;
15025   u8 is_set = 0;
15026   u8 is_en = 0;
15027   int ret;
15028
15029   /* Parse args required to build the message */
15030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15031     {
15032       if (unformat (input, "enable"))
15033         {
15034           is_set = 1;
15035           is_en = 1;
15036         }
15037       else if (unformat (input, "disable"))
15038         {
15039           is_set = 1;
15040         }
15041       else
15042         break;
15043     }
15044
15045   if (!is_set)
15046     {
15047       errmsg ("Value not set");
15048       return -99;
15049     }
15050
15051   /* Construct the API message */
15052   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15053
15054   mp->is_en = is_en;
15055
15056   /* send it... */
15057   S (mp);
15058
15059   /* Wait for a reply... */
15060   W (ret);
15061   return ret;
15062 }
15063
15064 static int
15065 api_one_show_pitr_mode (vat_main_t * vam)
15066 {
15067   vl_api_one_show_pitr_mode_t *mp;
15068   int ret;
15069
15070   /* Construct the API message */
15071   M (ONE_SHOW_PITR_MODE, mp);
15072
15073   /* send it... */
15074   S (mp);
15075
15076   /* Wait for a reply... */
15077   W (ret);
15078   return ret;
15079 }
15080
15081 static int
15082 api_one_enable_disable_petr_mode (vat_main_t * vam)
15083 {
15084   unformat_input_t *input = vam->input;
15085   vl_api_one_enable_disable_petr_mode_t *mp;
15086   u8 is_set = 0;
15087   u8 is_en = 0;
15088   int ret;
15089
15090   /* Parse args required to build the message */
15091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15092     {
15093       if (unformat (input, "enable"))
15094         {
15095           is_set = 1;
15096           is_en = 1;
15097         }
15098       else if (unformat (input, "disable"))
15099         {
15100           is_set = 1;
15101         }
15102       else
15103         break;
15104     }
15105
15106   if (!is_set)
15107     {
15108       errmsg ("Value not set");
15109       return -99;
15110     }
15111
15112   /* Construct the API message */
15113   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15114
15115   mp->is_en = is_en;
15116
15117   /* send it... */
15118   S (mp);
15119
15120   /* Wait for a reply... */
15121   W (ret);
15122   return ret;
15123 }
15124
15125 static int
15126 api_one_show_petr_mode (vat_main_t * vam)
15127 {
15128   vl_api_one_show_petr_mode_t *mp;
15129   int ret;
15130
15131   /* Construct the API message */
15132   M (ONE_SHOW_PETR_MODE, mp);
15133
15134   /* send it... */
15135   S (mp);
15136
15137   /* Wait for a reply... */
15138   W (ret);
15139   return ret;
15140 }
15141
15142 static int
15143 api_show_one_map_register_state (vat_main_t * vam)
15144 {
15145   vl_api_show_one_map_register_state_t *mp;
15146   int ret;
15147
15148   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15149
15150   /* send */
15151   S (mp);
15152
15153   /* wait for reply */
15154   W (ret);
15155   return ret;
15156 }
15157
15158 #define api_show_lisp_map_register_state api_show_one_map_register_state
15159
15160 static int
15161 api_show_one_rloc_probe_state (vat_main_t * vam)
15162 {
15163   vl_api_show_one_rloc_probe_state_t *mp;
15164   int ret;
15165
15166   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15167
15168   /* send */
15169   S (mp);
15170
15171   /* wait for reply */
15172   W (ret);
15173   return ret;
15174 }
15175
15176 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15177
15178 static int
15179 api_one_add_del_ndp_entry (vat_main_t * vam)
15180 {
15181   vl_api_one_add_del_ndp_entry_t *mp;
15182   unformat_input_t *input = vam->input;
15183   u8 is_add = 1;
15184   u8 mac_set = 0;
15185   u8 bd_set = 0;
15186   u8 ip_set = 0;
15187   u8 mac[6] = { 0, };
15188   u8 ip6[16] = { 0, };
15189   u32 bd = ~0;
15190   int ret;
15191
15192   /* Parse args required to build the message */
15193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15194     {
15195       if (unformat (input, "del"))
15196         is_add = 0;
15197       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15198         mac_set = 1;
15199       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15200         ip_set = 1;
15201       else if (unformat (input, "bd %d", &bd))
15202         bd_set = 1;
15203       else
15204         {
15205           errmsg ("parse error '%U'", format_unformat_error, input);
15206           return -99;
15207         }
15208     }
15209
15210   if (!bd_set || !ip_set || (!mac_set && is_add))
15211     {
15212       errmsg ("Missing BD, IP or MAC!");
15213       return -99;
15214     }
15215
15216   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15217   mp->is_add = is_add;
15218   clib_memcpy (mp->mac, mac, 6);
15219   mp->bd = clib_host_to_net_u32 (bd);
15220   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15221
15222   /* send */
15223   S (mp);
15224
15225   /* wait for reply */
15226   W (ret);
15227   return ret;
15228 }
15229
15230 static int
15231 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15232 {
15233   vl_api_one_add_del_l2_arp_entry_t *mp;
15234   unformat_input_t *input = vam->input;
15235   u8 is_add = 1;
15236   u8 mac_set = 0;
15237   u8 bd_set = 0;
15238   u8 ip_set = 0;
15239   u8 mac[6] = { 0, };
15240   u32 ip4 = 0, bd = ~0;
15241   int ret;
15242
15243   /* Parse args required to build the message */
15244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15245     {
15246       if (unformat (input, "del"))
15247         is_add = 0;
15248       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15249         mac_set = 1;
15250       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15251         ip_set = 1;
15252       else if (unformat (input, "bd %d", &bd))
15253         bd_set = 1;
15254       else
15255         {
15256           errmsg ("parse error '%U'", format_unformat_error, input);
15257           return -99;
15258         }
15259     }
15260
15261   if (!bd_set || !ip_set || (!mac_set && is_add))
15262     {
15263       errmsg ("Missing BD, IP or MAC!");
15264       return -99;
15265     }
15266
15267   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15268   mp->is_add = is_add;
15269   clib_memcpy (mp->mac, mac, 6);
15270   mp->bd = clib_host_to_net_u32 (bd);
15271   mp->ip4 = ip4;
15272
15273   /* send */
15274   S (mp);
15275
15276   /* wait for reply */
15277   W (ret);
15278   return ret;
15279 }
15280
15281 static int
15282 api_one_ndp_bd_get (vat_main_t * vam)
15283 {
15284   vl_api_one_ndp_bd_get_t *mp;
15285   int ret;
15286
15287   M (ONE_NDP_BD_GET, mp);
15288
15289   /* send */
15290   S (mp);
15291
15292   /* wait for reply */
15293   W (ret);
15294   return ret;
15295 }
15296
15297 static int
15298 api_one_ndp_entries_get (vat_main_t * vam)
15299 {
15300   vl_api_one_ndp_entries_get_t *mp;
15301   unformat_input_t *input = vam->input;
15302   u8 bd_set = 0;
15303   u32 bd = ~0;
15304   int ret;
15305
15306   /* Parse args required to build the message */
15307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15308     {
15309       if (unformat (input, "bd %d", &bd))
15310         bd_set = 1;
15311       else
15312         {
15313           errmsg ("parse error '%U'", format_unformat_error, input);
15314           return -99;
15315         }
15316     }
15317
15318   if (!bd_set)
15319     {
15320       errmsg ("Expected bridge domain!");
15321       return -99;
15322     }
15323
15324   M (ONE_NDP_ENTRIES_GET, mp);
15325   mp->bd = clib_host_to_net_u32 (bd);
15326
15327   /* send */
15328   S (mp);
15329
15330   /* wait for reply */
15331   W (ret);
15332   return ret;
15333 }
15334
15335 static int
15336 api_one_l2_arp_bd_get (vat_main_t * vam)
15337 {
15338   vl_api_one_l2_arp_bd_get_t *mp;
15339   int ret;
15340
15341   M (ONE_L2_ARP_BD_GET, mp);
15342
15343   /* send */
15344   S (mp);
15345
15346   /* wait for reply */
15347   W (ret);
15348   return ret;
15349 }
15350
15351 static int
15352 api_one_l2_arp_entries_get (vat_main_t * vam)
15353 {
15354   vl_api_one_l2_arp_entries_get_t *mp;
15355   unformat_input_t *input = vam->input;
15356   u8 bd_set = 0;
15357   u32 bd = ~0;
15358   int ret;
15359
15360   /* Parse args required to build the message */
15361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15362     {
15363       if (unformat (input, "bd %d", &bd))
15364         bd_set = 1;
15365       else
15366         {
15367           errmsg ("parse error '%U'", format_unformat_error, input);
15368           return -99;
15369         }
15370     }
15371
15372   if (!bd_set)
15373     {
15374       errmsg ("Expected bridge domain!");
15375       return -99;
15376     }
15377
15378   M (ONE_L2_ARP_ENTRIES_GET, mp);
15379   mp->bd = clib_host_to_net_u32 (bd);
15380
15381   /* send */
15382   S (mp);
15383
15384   /* wait for reply */
15385   W (ret);
15386   return ret;
15387 }
15388
15389 static int
15390 api_one_stats_enable_disable (vat_main_t * vam)
15391 {
15392   vl_api_one_stats_enable_disable_t *mp;
15393   unformat_input_t *input = vam->input;
15394   u8 is_set = 0;
15395   u8 is_en = 0;
15396   int ret;
15397
15398   /* Parse args required to build the message */
15399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15400     {
15401       if (unformat (input, "enable"))
15402         {
15403           is_set = 1;
15404           is_en = 1;
15405         }
15406       else if (unformat (input, "disable"))
15407         {
15408           is_set = 1;
15409         }
15410       else
15411         break;
15412     }
15413
15414   if (!is_set)
15415     {
15416       errmsg ("Value not set");
15417       return -99;
15418     }
15419
15420   M (ONE_STATS_ENABLE_DISABLE, mp);
15421   mp->is_en = is_en;
15422
15423   /* send */
15424   S (mp);
15425
15426   /* wait for reply */
15427   W (ret);
15428   return ret;
15429 }
15430
15431 static int
15432 api_show_one_stats_enable_disable (vat_main_t * vam)
15433 {
15434   vl_api_show_one_stats_enable_disable_t *mp;
15435   int ret;
15436
15437   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15438
15439   /* send */
15440   S (mp);
15441
15442   /* wait for reply */
15443   W (ret);
15444   return ret;
15445 }
15446
15447 static int
15448 api_show_one_map_request_mode (vat_main_t * vam)
15449 {
15450   vl_api_show_one_map_request_mode_t *mp;
15451   int ret;
15452
15453   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15454
15455   /* send */
15456   S (mp);
15457
15458   /* wait for reply */
15459   W (ret);
15460   return ret;
15461 }
15462
15463 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15464
15465 static int
15466 api_one_map_request_mode (vat_main_t * vam)
15467 {
15468   unformat_input_t *input = vam->input;
15469   vl_api_one_map_request_mode_t *mp;
15470   u8 mode = 0;
15471   int ret;
15472
15473   /* Parse args required to build the message */
15474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (input, "dst-only"))
15477         mode = 0;
15478       else if (unformat (input, "src-dst"))
15479         mode = 1;
15480       else
15481         {
15482           errmsg ("parse error '%U'", format_unformat_error, input);
15483           return -99;
15484         }
15485     }
15486
15487   M (ONE_MAP_REQUEST_MODE, mp);
15488
15489   mp->mode = mode;
15490
15491   /* send */
15492   S (mp);
15493
15494   /* wait for reply */
15495   W (ret);
15496   return ret;
15497 }
15498
15499 #define api_lisp_map_request_mode api_one_map_request_mode
15500
15501 /**
15502  * Enable/disable ONE proxy ITR.
15503  *
15504  * @param vam vpp API test context
15505  * @return return code
15506  */
15507 static int
15508 api_one_pitr_set_locator_set (vat_main_t * vam)
15509 {
15510   u8 ls_name_set = 0;
15511   unformat_input_t *input = vam->input;
15512   vl_api_one_pitr_set_locator_set_t *mp;
15513   u8 is_add = 1;
15514   u8 *ls_name = 0;
15515   int ret;
15516
15517   /* Parse args required to build the message */
15518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15519     {
15520       if (unformat (input, "del"))
15521         is_add = 0;
15522       else if (unformat (input, "locator-set %s", &ls_name))
15523         ls_name_set = 1;
15524       else
15525         {
15526           errmsg ("parse error '%U'", format_unformat_error, input);
15527           return -99;
15528         }
15529     }
15530
15531   if (!ls_name_set)
15532     {
15533       errmsg ("locator-set name not set!");
15534       return -99;
15535     }
15536
15537   M (ONE_PITR_SET_LOCATOR_SET, mp);
15538
15539   mp->is_add = is_add;
15540   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15541   vec_free (ls_name);
15542
15543   /* send */
15544   S (mp);
15545
15546   /* wait for reply */
15547   W (ret);
15548   return ret;
15549 }
15550
15551 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15552
15553 static int
15554 api_one_nsh_set_locator_set (vat_main_t * vam)
15555 {
15556   u8 ls_name_set = 0;
15557   unformat_input_t *input = vam->input;
15558   vl_api_one_nsh_set_locator_set_t *mp;
15559   u8 is_add = 1;
15560   u8 *ls_name = 0;
15561   int ret;
15562
15563   /* Parse args required to build the message */
15564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15565     {
15566       if (unformat (input, "del"))
15567         is_add = 0;
15568       else if (unformat (input, "ls %s", &ls_name))
15569         ls_name_set = 1;
15570       else
15571         {
15572           errmsg ("parse error '%U'", format_unformat_error, input);
15573           return -99;
15574         }
15575     }
15576
15577   if (!ls_name_set && is_add)
15578     {
15579       errmsg ("locator-set name not set!");
15580       return -99;
15581     }
15582
15583   M (ONE_NSH_SET_LOCATOR_SET, mp);
15584
15585   mp->is_add = is_add;
15586   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15587   vec_free (ls_name);
15588
15589   /* send */
15590   S (mp);
15591
15592   /* wait for reply */
15593   W (ret);
15594   return ret;
15595 }
15596
15597 static int
15598 api_show_one_pitr (vat_main_t * vam)
15599 {
15600   vl_api_show_one_pitr_t *mp;
15601   int ret;
15602
15603   if (!vam->json_output)
15604     {
15605       print (vam->ofp, "%=20s", "lisp status:");
15606     }
15607
15608   M (SHOW_ONE_PITR, mp);
15609   /* send it... */
15610   S (mp);
15611
15612   /* Wait for a reply... */
15613   W (ret);
15614   return ret;
15615 }
15616
15617 #define api_show_lisp_pitr api_show_one_pitr
15618
15619 static int
15620 api_one_use_petr (vat_main_t * vam)
15621 {
15622   unformat_input_t *input = vam->input;
15623   vl_api_one_use_petr_t *mp;
15624   u8 is_add = 0;
15625   ip_address_t ip;
15626   int ret;
15627
15628   clib_memset (&ip, 0, sizeof (ip));
15629
15630   /* Parse args required to build the message */
15631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15632     {
15633       if (unformat (input, "disable"))
15634         is_add = 0;
15635       else
15636         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15637         {
15638           is_add = 1;
15639           ip_addr_version (&ip) = AF_IP4;
15640         }
15641       else
15642         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15643         {
15644           is_add = 1;
15645           ip_addr_version (&ip) = AF_IP6;
15646         }
15647       else
15648         {
15649           errmsg ("parse error '%U'", format_unformat_error, input);
15650           return -99;
15651         }
15652     }
15653
15654   M (ONE_USE_PETR, mp);
15655
15656   mp->is_add = is_add;
15657   if (is_add)
15658     {
15659       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15660       if (mp->is_ip4)
15661         clib_memcpy (mp->address, &ip, 4);
15662       else
15663         clib_memcpy (mp->address, &ip, 16);
15664     }
15665
15666   /* send */
15667   S (mp);
15668
15669   /* wait for reply */
15670   W (ret);
15671   return ret;
15672 }
15673
15674 #define api_lisp_use_petr api_one_use_petr
15675
15676 static int
15677 api_show_one_nsh_mapping (vat_main_t * vam)
15678 {
15679   vl_api_show_one_use_petr_t *mp;
15680   int ret;
15681
15682   if (!vam->json_output)
15683     {
15684       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15685     }
15686
15687   M (SHOW_ONE_NSH_MAPPING, mp);
15688   /* send it... */
15689   S (mp);
15690
15691   /* Wait for a reply... */
15692   W (ret);
15693   return ret;
15694 }
15695
15696 static int
15697 api_show_one_use_petr (vat_main_t * vam)
15698 {
15699   vl_api_show_one_use_petr_t *mp;
15700   int ret;
15701
15702   if (!vam->json_output)
15703     {
15704       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15705     }
15706
15707   M (SHOW_ONE_USE_PETR, mp);
15708   /* send it... */
15709   S (mp);
15710
15711   /* Wait for a reply... */
15712   W (ret);
15713   return ret;
15714 }
15715
15716 #define api_show_lisp_use_petr api_show_one_use_petr
15717
15718 /**
15719  * Add/delete mapping between vni and vrf
15720  */
15721 static int
15722 api_one_eid_table_add_del_map (vat_main_t * vam)
15723 {
15724   unformat_input_t *input = vam->input;
15725   vl_api_one_eid_table_add_del_map_t *mp;
15726   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15727   u32 vni, vrf, bd_index;
15728   int ret;
15729
15730   /* Parse args required to build the message */
15731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15732     {
15733       if (unformat (input, "del"))
15734         is_add = 0;
15735       else if (unformat (input, "vrf %d", &vrf))
15736         vrf_set = 1;
15737       else if (unformat (input, "bd_index %d", &bd_index))
15738         bd_index_set = 1;
15739       else if (unformat (input, "vni %d", &vni))
15740         vni_set = 1;
15741       else
15742         break;
15743     }
15744
15745   if (!vni_set || (!vrf_set && !bd_index_set))
15746     {
15747       errmsg ("missing arguments!");
15748       return -99;
15749     }
15750
15751   if (vrf_set && bd_index_set)
15752     {
15753       errmsg ("error: both vrf and bd entered!");
15754       return -99;
15755     }
15756
15757   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15758
15759   mp->is_add = is_add;
15760   mp->vni = htonl (vni);
15761   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15762   mp->is_l2 = bd_index_set;
15763
15764   /* send */
15765   S (mp);
15766
15767   /* wait for reply */
15768   W (ret);
15769   return ret;
15770 }
15771
15772 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15773
15774 uword
15775 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15776 {
15777   u32 *action = va_arg (*args, u32 *);
15778   u8 *s = 0;
15779
15780   if (unformat (input, "%s", &s))
15781     {
15782       if (!strcmp ((char *) s, "no-action"))
15783         action[0] = 0;
15784       else if (!strcmp ((char *) s, "natively-forward"))
15785         action[0] = 1;
15786       else if (!strcmp ((char *) s, "send-map-request"))
15787         action[0] = 2;
15788       else if (!strcmp ((char *) s, "drop"))
15789         action[0] = 3;
15790       else
15791         {
15792           clib_warning ("invalid action: '%s'", s);
15793           action[0] = 3;
15794         }
15795     }
15796   else
15797     return 0;
15798
15799   vec_free (s);
15800   return 1;
15801 }
15802
15803 /**
15804  * Add/del remote mapping to/from ONE control plane
15805  *
15806  * @param vam vpp API test context
15807  * @return return code
15808  */
15809 static int
15810 api_one_add_del_remote_mapping (vat_main_t * vam)
15811 {
15812   unformat_input_t *input = vam->input;
15813   vl_api_one_add_del_remote_mapping_t *mp;
15814   u32 vni = 0;
15815   lisp_eid_vat_t _eid, *eid = &_eid;
15816   lisp_eid_vat_t _seid, *seid = &_seid;
15817   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15818   u32 action = ~0, p, w, data_len;
15819   ip4_address_t rloc4;
15820   ip6_address_t rloc6;
15821   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15822   int ret;
15823
15824   clib_memset (&rloc, 0, sizeof (rloc));
15825
15826   /* Parse args required to build the message */
15827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15828     {
15829       if (unformat (input, "del-all"))
15830         {
15831           del_all = 1;
15832         }
15833       else if (unformat (input, "del"))
15834         {
15835           is_add = 0;
15836         }
15837       else if (unformat (input, "add"))
15838         {
15839           is_add = 1;
15840         }
15841       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15842         {
15843           eid_set = 1;
15844         }
15845       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15846         {
15847           seid_set = 1;
15848         }
15849       else if (unformat (input, "vni %d", &vni))
15850         {
15851           ;
15852         }
15853       else if (unformat (input, "p %d w %d", &p, &w))
15854         {
15855           if (!curr_rloc)
15856             {
15857               errmsg ("No RLOC configured for setting priority/weight!");
15858               return -99;
15859             }
15860           curr_rloc->priority = p;
15861           curr_rloc->weight = w;
15862         }
15863       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15864         {
15865           rloc.is_ip4 = 1;
15866           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15867           vec_add1 (rlocs, rloc);
15868           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15869         }
15870       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15871         {
15872           rloc.is_ip4 = 0;
15873           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15874           vec_add1 (rlocs, rloc);
15875           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15876         }
15877       else if (unformat (input, "action %U",
15878                          unformat_negative_mapping_action, &action))
15879         {
15880           ;
15881         }
15882       else
15883         {
15884           clib_warning ("parse error '%U'", format_unformat_error, input);
15885           return -99;
15886         }
15887     }
15888
15889   if (0 == eid_set)
15890     {
15891       errmsg ("missing params!");
15892       return -99;
15893     }
15894
15895   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15896     {
15897       errmsg ("no action set for negative map-reply!");
15898       return -99;
15899     }
15900
15901   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15902
15903   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15904   mp->is_add = is_add;
15905   mp->vni = htonl (vni);
15906   mp->action = (u8) action;
15907   mp->is_src_dst = seid_set;
15908   mp->eid_len = eid->len;
15909   mp->seid_len = seid->len;
15910   mp->del_all = del_all;
15911   mp->eid_type = eid->type;
15912   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15913   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15914
15915   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15916   clib_memcpy (mp->rlocs, rlocs, data_len);
15917   vec_free (rlocs);
15918
15919   /* send it... */
15920   S (mp);
15921
15922   /* Wait for a reply... */
15923   W (ret);
15924   return ret;
15925 }
15926
15927 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15928
15929 /**
15930  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15931  * forwarding entries in data-plane accordingly.
15932  *
15933  * @param vam vpp API test context
15934  * @return return code
15935  */
15936 static int
15937 api_one_add_del_adjacency (vat_main_t * vam)
15938 {
15939   unformat_input_t *input = vam->input;
15940   vl_api_one_add_del_adjacency_t *mp;
15941   u32 vni = 0;
15942   ip4_address_t leid4, reid4;
15943   ip6_address_t leid6, reid6;
15944   u8 reid_mac[6] = { 0 };
15945   u8 leid_mac[6] = { 0 };
15946   u8 reid_type, leid_type;
15947   u32 leid_len = 0, reid_len = 0, len;
15948   u8 is_add = 1;
15949   int ret;
15950
15951   leid_type = reid_type = (u8) ~ 0;
15952
15953   /* Parse args required to build the message */
15954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15955     {
15956       if (unformat (input, "del"))
15957         {
15958           is_add = 0;
15959         }
15960       else if (unformat (input, "add"))
15961         {
15962           is_add = 1;
15963         }
15964       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15965                          &reid4, &len))
15966         {
15967           reid_type = 0;        /* ipv4 */
15968           reid_len = len;
15969         }
15970       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15971                          &reid6, &len))
15972         {
15973           reid_type = 1;        /* ipv6 */
15974           reid_len = len;
15975         }
15976       else if (unformat (input, "reid %U", unformat_ethernet_address,
15977                          reid_mac))
15978         {
15979           reid_type = 2;        /* mac */
15980         }
15981       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15982                          &leid4, &len))
15983         {
15984           leid_type = 0;        /* ipv4 */
15985           leid_len = len;
15986         }
15987       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15988                          &leid6, &len))
15989         {
15990           leid_type = 1;        /* ipv6 */
15991           leid_len = len;
15992         }
15993       else if (unformat (input, "leid %U", unformat_ethernet_address,
15994                          leid_mac))
15995         {
15996           leid_type = 2;        /* mac */
15997         }
15998       else if (unformat (input, "vni %d", &vni))
15999         {
16000           ;
16001         }
16002       else
16003         {
16004           errmsg ("parse error '%U'", format_unformat_error, input);
16005           return -99;
16006         }
16007     }
16008
16009   if ((u8) ~ 0 == reid_type)
16010     {
16011       errmsg ("missing params!");
16012       return -99;
16013     }
16014
16015   if (leid_type != reid_type)
16016     {
16017       errmsg ("remote and local EIDs are of different types!");
16018       return -99;
16019     }
16020
16021   M (ONE_ADD_DEL_ADJACENCY, mp);
16022   mp->is_add = is_add;
16023   mp->vni = htonl (vni);
16024   mp->leid_len = leid_len;
16025   mp->reid_len = reid_len;
16026   mp->eid_type = reid_type;
16027
16028   switch (mp->eid_type)
16029     {
16030     case 0:
16031       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16032       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16033       break;
16034     case 1:
16035       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16036       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16037       break;
16038     case 2:
16039       clib_memcpy (mp->leid, leid_mac, 6);
16040       clib_memcpy (mp->reid, reid_mac, 6);
16041       break;
16042     default:
16043       errmsg ("unknown EID type %d!", mp->eid_type);
16044       return 0;
16045     }
16046
16047   /* send it... */
16048   S (mp);
16049
16050   /* Wait for a reply... */
16051   W (ret);
16052   return ret;
16053 }
16054
16055 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16056
16057 uword
16058 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16059 {
16060   u32 *mode = va_arg (*args, u32 *);
16061
16062   if (unformat (input, "lisp"))
16063     *mode = 0;
16064   else if (unformat (input, "vxlan"))
16065     *mode = 1;
16066   else
16067     return 0;
16068
16069   return 1;
16070 }
16071
16072 static int
16073 api_gpe_get_encap_mode (vat_main_t * vam)
16074 {
16075   vl_api_gpe_get_encap_mode_t *mp;
16076   int ret;
16077
16078   /* Construct the API message */
16079   M (GPE_GET_ENCAP_MODE, mp);
16080
16081   /* send it... */
16082   S (mp);
16083
16084   /* Wait for a reply... */
16085   W (ret);
16086   return ret;
16087 }
16088
16089 static int
16090 api_gpe_set_encap_mode (vat_main_t * vam)
16091 {
16092   unformat_input_t *input = vam->input;
16093   vl_api_gpe_set_encap_mode_t *mp;
16094   int ret;
16095   u32 mode = 0;
16096
16097   /* Parse args required to build the message */
16098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16101         ;
16102       else
16103         break;
16104     }
16105
16106   /* Construct the API message */
16107   M (GPE_SET_ENCAP_MODE, mp);
16108
16109   mp->mode = mode;
16110
16111   /* send it... */
16112   S (mp);
16113
16114   /* Wait for a reply... */
16115   W (ret);
16116   return ret;
16117 }
16118
16119 static int
16120 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16121 {
16122   unformat_input_t *input = vam->input;
16123   vl_api_gpe_add_del_iface_t *mp;
16124   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16125   u32 dp_table = 0, vni = 0;
16126   int ret;
16127
16128   /* Parse args required to build the message */
16129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16130     {
16131       if (unformat (input, "up"))
16132         {
16133           action_set = 1;
16134           is_add = 1;
16135         }
16136       else if (unformat (input, "down"))
16137         {
16138           action_set = 1;
16139           is_add = 0;
16140         }
16141       else if (unformat (input, "table_id %d", &dp_table))
16142         {
16143           dp_table_set = 1;
16144         }
16145       else if (unformat (input, "bd_id %d", &dp_table))
16146         {
16147           dp_table_set = 1;
16148           is_l2 = 1;
16149         }
16150       else if (unformat (input, "vni %d", &vni))
16151         {
16152           vni_set = 1;
16153         }
16154       else
16155         break;
16156     }
16157
16158   if (action_set == 0)
16159     {
16160       errmsg ("Action not set");
16161       return -99;
16162     }
16163   if (dp_table_set == 0 || vni_set == 0)
16164     {
16165       errmsg ("vni and dp_table must be set");
16166       return -99;
16167     }
16168
16169   /* Construct the API message */
16170   M (GPE_ADD_DEL_IFACE, mp);
16171
16172   mp->is_add = is_add;
16173   mp->dp_table = clib_host_to_net_u32 (dp_table);
16174   mp->is_l2 = is_l2;
16175   mp->vni = clib_host_to_net_u32 (vni);
16176
16177   /* send it... */
16178   S (mp);
16179
16180   /* Wait for a reply... */
16181   W (ret);
16182   return ret;
16183 }
16184
16185 static int
16186 api_one_map_register_fallback_threshold (vat_main_t * vam)
16187 {
16188   unformat_input_t *input = vam->input;
16189   vl_api_one_map_register_fallback_threshold_t *mp;
16190   u32 value = 0;
16191   u8 is_set = 0;
16192   int ret;
16193
16194   /* Parse args required to build the message */
16195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16196     {
16197       if (unformat (input, "%u", &value))
16198         is_set = 1;
16199       else
16200         {
16201           clib_warning ("parse error '%U'", format_unformat_error, input);
16202           return -99;
16203         }
16204     }
16205
16206   if (!is_set)
16207     {
16208       errmsg ("fallback threshold value is missing!");
16209       return -99;
16210     }
16211
16212   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16213   mp->value = clib_host_to_net_u32 (value);
16214
16215   /* send it... */
16216   S (mp);
16217
16218   /* Wait for a reply... */
16219   W (ret);
16220   return ret;
16221 }
16222
16223 static int
16224 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16225 {
16226   vl_api_show_one_map_register_fallback_threshold_t *mp;
16227   int ret;
16228
16229   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16230
16231   /* send it... */
16232   S (mp);
16233
16234   /* Wait for a reply... */
16235   W (ret);
16236   return ret;
16237 }
16238
16239 uword
16240 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16241 {
16242   u32 *proto = va_arg (*args, u32 *);
16243
16244   if (unformat (input, "udp"))
16245     *proto = 1;
16246   else if (unformat (input, "api"))
16247     *proto = 2;
16248   else
16249     return 0;
16250
16251   return 1;
16252 }
16253
16254 static int
16255 api_one_set_transport_protocol (vat_main_t * vam)
16256 {
16257   unformat_input_t *input = vam->input;
16258   vl_api_one_set_transport_protocol_t *mp;
16259   u8 is_set = 0;
16260   u32 protocol = 0;
16261   int ret;
16262
16263   /* Parse args required to build the message */
16264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16265     {
16266       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16267         is_set = 1;
16268       else
16269         {
16270           clib_warning ("parse error '%U'", format_unformat_error, input);
16271           return -99;
16272         }
16273     }
16274
16275   if (!is_set)
16276     {
16277       errmsg ("Transport protocol missing!");
16278       return -99;
16279     }
16280
16281   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16282   mp->protocol = (u8) protocol;
16283
16284   /* send it... */
16285   S (mp);
16286
16287   /* Wait for a reply... */
16288   W (ret);
16289   return ret;
16290 }
16291
16292 static int
16293 api_one_get_transport_protocol (vat_main_t * vam)
16294 {
16295   vl_api_one_get_transport_protocol_t *mp;
16296   int ret;
16297
16298   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16299
16300   /* send it... */
16301   S (mp);
16302
16303   /* Wait for a reply... */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 static int
16309 api_one_map_register_set_ttl (vat_main_t * vam)
16310 {
16311   unformat_input_t *input = vam->input;
16312   vl_api_one_map_register_set_ttl_t *mp;
16313   u32 ttl = 0;
16314   u8 is_set = 0;
16315   int ret;
16316
16317   /* Parse args required to build the message */
16318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16319     {
16320       if (unformat (input, "%u", &ttl))
16321         is_set = 1;
16322       else
16323         {
16324           clib_warning ("parse error '%U'", format_unformat_error, input);
16325           return -99;
16326         }
16327     }
16328
16329   if (!is_set)
16330     {
16331       errmsg ("TTL value missing!");
16332       return -99;
16333     }
16334
16335   M (ONE_MAP_REGISTER_SET_TTL, mp);
16336   mp->ttl = clib_host_to_net_u32 (ttl);
16337
16338   /* send it... */
16339   S (mp);
16340
16341   /* Wait for a reply... */
16342   W (ret);
16343   return ret;
16344 }
16345
16346 static int
16347 api_show_one_map_register_ttl (vat_main_t * vam)
16348 {
16349   vl_api_show_one_map_register_ttl_t *mp;
16350   int ret;
16351
16352   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16353
16354   /* send it... */
16355   S (mp);
16356
16357   /* Wait for a reply... */
16358   W (ret);
16359   return ret;
16360 }
16361
16362 /**
16363  * Add/del map request itr rlocs from ONE control plane and updates
16364  *
16365  * @param vam vpp API test context
16366  * @return return code
16367  */
16368 static int
16369 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16370 {
16371   unformat_input_t *input = vam->input;
16372   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16373   u8 *locator_set_name = 0;
16374   u8 locator_set_name_set = 0;
16375   u8 is_add = 1;
16376   int ret;
16377
16378   /* Parse args required to build the message */
16379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16380     {
16381       if (unformat (input, "del"))
16382         {
16383           is_add = 0;
16384         }
16385       else if (unformat (input, "%_%v%_", &locator_set_name))
16386         {
16387           locator_set_name_set = 1;
16388         }
16389       else
16390         {
16391           clib_warning ("parse error '%U'", format_unformat_error, input);
16392           return -99;
16393         }
16394     }
16395
16396   if (is_add && !locator_set_name_set)
16397     {
16398       errmsg ("itr-rloc is not set!");
16399       return -99;
16400     }
16401
16402   if (is_add && vec_len (locator_set_name) > 64)
16403     {
16404       errmsg ("itr-rloc locator-set name too long");
16405       vec_free (locator_set_name);
16406       return -99;
16407     }
16408
16409   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16410   mp->is_add = is_add;
16411   if (is_add)
16412     {
16413       clib_memcpy (mp->locator_set_name, locator_set_name,
16414                    vec_len (locator_set_name));
16415     }
16416   else
16417     {
16418       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16419     }
16420   vec_free (locator_set_name);
16421
16422   /* send it... */
16423   S (mp);
16424
16425   /* Wait for a reply... */
16426   W (ret);
16427   return ret;
16428 }
16429
16430 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16431
16432 static int
16433 api_one_locator_dump (vat_main_t * vam)
16434 {
16435   unformat_input_t *input = vam->input;
16436   vl_api_one_locator_dump_t *mp;
16437   vl_api_control_ping_t *mp_ping;
16438   u8 is_index_set = 0, is_name_set = 0;
16439   u8 *ls_name = 0;
16440   u32 ls_index = ~0;
16441   int ret;
16442
16443   /* Parse args required to build the message */
16444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16445     {
16446       if (unformat (input, "ls_name %_%v%_", &ls_name))
16447         {
16448           is_name_set = 1;
16449         }
16450       else if (unformat (input, "ls_index %d", &ls_index))
16451         {
16452           is_index_set = 1;
16453         }
16454       else
16455         {
16456           errmsg ("parse error '%U'", format_unformat_error, input);
16457           return -99;
16458         }
16459     }
16460
16461   if (!is_index_set && !is_name_set)
16462     {
16463       errmsg ("error: expected one of index or name!");
16464       return -99;
16465     }
16466
16467   if (is_index_set && is_name_set)
16468     {
16469       errmsg ("error: only one param expected!");
16470       return -99;
16471     }
16472
16473   if (vec_len (ls_name) > 62)
16474     {
16475       errmsg ("error: locator set name too long!");
16476       return -99;
16477     }
16478
16479   if (!vam->json_output)
16480     {
16481       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16482     }
16483
16484   M (ONE_LOCATOR_DUMP, mp);
16485   mp->is_index_set = is_index_set;
16486
16487   if (is_index_set)
16488     mp->ls_index = clib_host_to_net_u32 (ls_index);
16489   else
16490     {
16491       vec_add1 (ls_name, 0);
16492       strncpy ((char *) mp->ls_name, (char *) ls_name,
16493                sizeof (mp->ls_name) - 1);
16494     }
16495
16496   /* send it... */
16497   S (mp);
16498
16499   /* Use a control ping for synchronization */
16500   MPING (CONTROL_PING, mp_ping);
16501   S (mp_ping);
16502
16503   /* Wait for a reply... */
16504   W (ret);
16505   return ret;
16506 }
16507
16508 #define api_lisp_locator_dump api_one_locator_dump
16509
16510 static int
16511 api_one_locator_set_dump (vat_main_t * vam)
16512 {
16513   vl_api_one_locator_set_dump_t *mp;
16514   vl_api_control_ping_t *mp_ping;
16515   unformat_input_t *input = vam->input;
16516   u8 filter = 0;
16517   int ret;
16518
16519   /* Parse args required to build the message */
16520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16521     {
16522       if (unformat (input, "local"))
16523         {
16524           filter = 1;
16525         }
16526       else if (unformat (input, "remote"))
16527         {
16528           filter = 2;
16529         }
16530       else
16531         {
16532           errmsg ("parse error '%U'", format_unformat_error, input);
16533           return -99;
16534         }
16535     }
16536
16537   if (!vam->json_output)
16538     {
16539       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16540     }
16541
16542   M (ONE_LOCATOR_SET_DUMP, mp);
16543
16544   mp->filter = filter;
16545
16546   /* send it... */
16547   S (mp);
16548
16549   /* Use a control ping for synchronization */
16550   MPING (CONTROL_PING, mp_ping);
16551   S (mp_ping);
16552
16553   /* Wait for a reply... */
16554   W (ret);
16555   return ret;
16556 }
16557
16558 #define api_lisp_locator_set_dump api_one_locator_set_dump
16559
16560 static int
16561 api_one_eid_table_map_dump (vat_main_t * vam)
16562 {
16563   u8 is_l2 = 0;
16564   u8 mode_set = 0;
16565   unformat_input_t *input = vam->input;
16566   vl_api_one_eid_table_map_dump_t *mp;
16567   vl_api_control_ping_t *mp_ping;
16568   int ret;
16569
16570   /* Parse args required to build the message */
16571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (input, "l2"))
16574         {
16575           is_l2 = 1;
16576           mode_set = 1;
16577         }
16578       else if (unformat (input, "l3"))
16579         {
16580           is_l2 = 0;
16581           mode_set = 1;
16582         }
16583       else
16584         {
16585           errmsg ("parse error '%U'", format_unformat_error, input);
16586           return -99;
16587         }
16588     }
16589
16590   if (!mode_set)
16591     {
16592       errmsg ("expected one of 'l2' or 'l3' parameter!");
16593       return -99;
16594     }
16595
16596   if (!vam->json_output)
16597     {
16598       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16599     }
16600
16601   M (ONE_EID_TABLE_MAP_DUMP, mp);
16602   mp->is_l2 = is_l2;
16603
16604   /* send it... */
16605   S (mp);
16606
16607   /* Use a control ping for synchronization */
16608   MPING (CONTROL_PING, mp_ping);
16609   S (mp_ping);
16610
16611   /* Wait for a reply... */
16612   W (ret);
16613   return ret;
16614 }
16615
16616 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16617
16618 static int
16619 api_one_eid_table_vni_dump (vat_main_t * vam)
16620 {
16621   vl_api_one_eid_table_vni_dump_t *mp;
16622   vl_api_control_ping_t *mp_ping;
16623   int ret;
16624
16625   if (!vam->json_output)
16626     {
16627       print (vam->ofp, "VNI");
16628     }
16629
16630   M (ONE_EID_TABLE_VNI_DUMP, mp);
16631
16632   /* send it... */
16633   S (mp);
16634
16635   /* Use a control ping for synchronization */
16636   MPING (CONTROL_PING, mp_ping);
16637   S (mp_ping);
16638
16639   /* Wait for a reply... */
16640   W (ret);
16641   return ret;
16642 }
16643
16644 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16645
16646 static int
16647 api_one_eid_table_dump (vat_main_t * vam)
16648 {
16649   unformat_input_t *i = vam->input;
16650   vl_api_one_eid_table_dump_t *mp;
16651   vl_api_control_ping_t *mp_ping;
16652   struct in_addr ip4;
16653   struct in6_addr ip6;
16654   u8 mac[6];
16655   u8 eid_type = ~0, eid_set = 0;
16656   u32 prefix_length = ~0, t, vni = 0;
16657   u8 filter = 0;
16658   int ret;
16659   lisp_nsh_api_t nsh;
16660
16661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16662     {
16663       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16664         {
16665           eid_set = 1;
16666           eid_type = 0;
16667           prefix_length = t;
16668         }
16669       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16670         {
16671           eid_set = 1;
16672           eid_type = 1;
16673           prefix_length = t;
16674         }
16675       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16676         {
16677           eid_set = 1;
16678           eid_type = 2;
16679         }
16680       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16681         {
16682           eid_set = 1;
16683           eid_type = 3;
16684         }
16685       else if (unformat (i, "vni %d", &t))
16686         {
16687           vni = t;
16688         }
16689       else if (unformat (i, "local"))
16690         {
16691           filter = 1;
16692         }
16693       else if (unformat (i, "remote"))
16694         {
16695           filter = 2;
16696         }
16697       else
16698         {
16699           errmsg ("parse error '%U'", format_unformat_error, i);
16700           return -99;
16701         }
16702     }
16703
16704   if (!vam->json_output)
16705     {
16706       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16707              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16708     }
16709
16710   M (ONE_EID_TABLE_DUMP, mp);
16711
16712   mp->filter = filter;
16713   if (eid_set)
16714     {
16715       mp->eid_set = 1;
16716       mp->vni = htonl (vni);
16717       mp->eid_type = eid_type;
16718       switch (eid_type)
16719         {
16720         case 0:
16721           mp->prefix_length = prefix_length;
16722           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16723           break;
16724         case 1:
16725           mp->prefix_length = prefix_length;
16726           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16727           break;
16728         case 2:
16729           clib_memcpy (mp->eid, mac, sizeof (mac));
16730           break;
16731         case 3:
16732           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16733           break;
16734         default:
16735           errmsg ("unknown EID type %d!", eid_type);
16736           return -99;
16737         }
16738     }
16739
16740   /* send it... */
16741   S (mp);
16742
16743   /* Use a control ping for synchronization */
16744   MPING (CONTROL_PING, mp_ping);
16745   S (mp_ping);
16746
16747   /* Wait for a reply... */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 #define api_lisp_eid_table_dump api_one_eid_table_dump
16753
16754 static int
16755 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16756 {
16757   unformat_input_t *i = vam->input;
16758   vl_api_gpe_fwd_entries_get_t *mp;
16759   u8 vni_set = 0;
16760   u32 vni = ~0;
16761   int ret;
16762
16763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16764     {
16765       if (unformat (i, "vni %d", &vni))
16766         {
16767           vni_set = 1;
16768         }
16769       else
16770         {
16771           errmsg ("parse error '%U'", format_unformat_error, i);
16772           return -99;
16773         }
16774     }
16775
16776   if (!vni_set)
16777     {
16778       errmsg ("vni not set!");
16779       return -99;
16780     }
16781
16782   if (!vam->json_output)
16783     {
16784       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16785              "leid", "reid");
16786     }
16787
16788   M (GPE_FWD_ENTRIES_GET, mp);
16789   mp->vni = clib_host_to_net_u32 (vni);
16790
16791   /* send it... */
16792   S (mp);
16793
16794   /* Wait for a reply... */
16795   W (ret);
16796   return ret;
16797 }
16798
16799 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16800 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16801 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16802 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16803 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16804 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16805 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16806 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16807
16808 static int
16809 api_one_adjacencies_get (vat_main_t * vam)
16810 {
16811   unformat_input_t *i = vam->input;
16812   vl_api_one_adjacencies_get_t *mp;
16813   u8 vni_set = 0;
16814   u32 vni = ~0;
16815   int ret;
16816
16817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16818     {
16819       if (unformat (i, "vni %d", &vni))
16820         {
16821           vni_set = 1;
16822         }
16823       else
16824         {
16825           errmsg ("parse error '%U'", format_unformat_error, i);
16826           return -99;
16827         }
16828     }
16829
16830   if (!vni_set)
16831     {
16832       errmsg ("vni not set!");
16833       return -99;
16834     }
16835
16836   if (!vam->json_output)
16837     {
16838       print (vam->ofp, "%s %40s", "leid", "reid");
16839     }
16840
16841   M (ONE_ADJACENCIES_GET, mp);
16842   mp->vni = clib_host_to_net_u32 (vni);
16843
16844   /* send it... */
16845   S (mp);
16846
16847   /* Wait for a reply... */
16848   W (ret);
16849   return ret;
16850 }
16851
16852 #define api_lisp_adjacencies_get api_one_adjacencies_get
16853
16854 static int
16855 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16856 {
16857   unformat_input_t *i = vam->input;
16858   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16859   int ret;
16860   u8 ip_family_set = 0, is_ip4 = 1;
16861
16862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16863     {
16864       if (unformat (i, "ip4"))
16865         {
16866           ip_family_set = 1;
16867           is_ip4 = 1;
16868         }
16869       else if (unformat (i, "ip6"))
16870         {
16871           ip_family_set = 1;
16872           is_ip4 = 0;
16873         }
16874       else
16875         {
16876           errmsg ("parse error '%U'", format_unformat_error, i);
16877           return -99;
16878         }
16879     }
16880
16881   if (!ip_family_set)
16882     {
16883       errmsg ("ip family not set!");
16884       return -99;
16885     }
16886
16887   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16888   mp->is_ip4 = is_ip4;
16889
16890   /* send it... */
16891   S (mp);
16892
16893   /* Wait for a reply... */
16894   W (ret);
16895   return ret;
16896 }
16897
16898 static int
16899 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16900 {
16901   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16902   int ret;
16903
16904   if (!vam->json_output)
16905     {
16906       print (vam->ofp, "VNIs");
16907     }
16908
16909   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16910
16911   /* send it... */
16912   S (mp);
16913
16914   /* Wait for a reply... */
16915   W (ret);
16916   return ret;
16917 }
16918
16919 static int
16920 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16921 {
16922   unformat_input_t *i = vam->input;
16923   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16924   int ret = 0;
16925   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16926   struct in_addr ip4;
16927   struct in6_addr ip6;
16928   u32 table_id = 0, nh_sw_if_index = ~0;
16929
16930   clib_memset (&ip4, 0, sizeof (ip4));
16931   clib_memset (&ip6, 0, sizeof (ip6));
16932
16933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16934     {
16935       if (unformat (i, "del"))
16936         is_add = 0;
16937       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16938                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16939         {
16940           ip_set = 1;
16941           is_ip4 = 1;
16942         }
16943       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16944                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16945         {
16946           ip_set = 1;
16947           is_ip4 = 0;
16948         }
16949       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16950         {
16951           ip_set = 1;
16952           is_ip4 = 1;
16953           nh_sw_if_index = ~0;
16954         }
16955       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16956         {
16957           ip_set = 1;
16958           is_ip4 = 0;
16959           nh_sw_if_index = ~0;
16960         }
16961       else if (unformat (i, "table %d", &table_id))
16962         ;
16963       else
16964         {
16965           errmsg ("parse error '%U'", format_unformat_error, i);
16966           return -99;
16967         }
16968     }
16969
16970   if (!ip_set)
16971     {
16972       errmsg ("nh addr not set!");
16973       return -99;
16974     }
16975
16976   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16977   mp->is_add = is_add;
16978   mp->table_id = clib_host_to_net_u32 (table_id);
16979   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16980   mp->is_ip4 = is_ip4;
16981   if (is_ip4)
16982     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16983   else
16984     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16985
16986   /* send it... */
16987   S (mp);
16988
16989   /* Wait for a reply... */
16990   W (ret);
16991   return ret;
16992 }
16993
16994 static int
16995 api_one_map_server_dump (vat_main_t * vam)
16996 {
16997   vl_api_one_map_server_dump_t *mp;
16998   vl_api_control_ping_t *mp_ping;
16999   int ret;
17000
17001   if (!vam->json_output)
17002     {
17003       print (vam->ofp, "%=20s", "Map server");
17004     }
17005
17006   M (ONE_MAP_SERVER_DUMP, mp);
17007   /* send it... */
17008   S (mp);
17009
17010   /* Use a control ping for synchronization */
17011   MPING (CONTROL_PING, mp_ping);
17012   S (mp_ping);
17013
17014   /* Wait for a reply... */
17015   W (ret);
17016   return ret;
17017 }
17018
17019 #define api_lisp_map_server_dump api_one_map_server_dump
17020
17021 static int
17022 api_one_map_resolver_dump (vat_main_t * vam)
17023 {
17024   vl_api_one_map_resolver_dump_t *mp;
17025   vl_api_control_ping_t *mp_ping;
17026   int ret;
17027
17028   if (!vam->json_output)
17029     {
17030       print (vam->ofp, "%=20s", "Map resolver");
17031     }
17032
17033   M (ONE_MAP_RESOLVER_DUMP, mp);
17034   /* send it... */
17035   S (mp);
17036
17037   /* Use a control ping for synchronization */
17038   MPING (CONTROL_PING, mp_ping);
17039   S (mp_ping);
17040
17041   /* Wait for a reply... */
17042   W (ret);
17043   return ret;
17044 }
17045
17046 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17047
17048 static int
17049 api_one_stats_flush (vat_main_t * vam)
17050 {
17051   vl_api_one_stats_flush_t *mp;
17052   int ret = 0;
17053
17054   M (ONE_STATS_FLUSH, mp);
17055   S (mp);
17056   W (ret);
17057   return ret;
17058 }
17059
17060 static int
17061 api_one_stats_dump (vat_main_t * vam)
17062 {
17063   vl_api_one_stats_dump_t *mp;
17064   vl_api_control_ping_t *mp_ping;
17065   int ret;
17066
17067   M (ONE_STATS_DUMP, mp);
17068   /* send it... */
17069   S (mp);
17070
17071   /* Use a control ping for synchronization */
17072   MPING (CONTROL_PING, mp_ping);
17073   S (mp_ping);
17074
17075   /* Wait for a reply... */
17076   W (ret);
17077   return ret;
17078 }
17079
17080 static int
17081 api_show_one_status (vat_main_t * vam)
17082 {
17083   vl_api_show_one_status_t *mp;
17084   int ret;
17085
17086   if (!vam->json_output)
17087     {
17088       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17089     }
17090
17091   M (SHOW_ONE_STATUS, mp);
17092   /* send it... */
17093   S (mp);
17094   /* Wait for a reply... */
17095   W (ret);
17096   return ret;
17097 }
17098
17099 #define api_show_lisp_status api_show_one_status
17100
17101 static int
17102 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17103 {
17104   vl_api_gpe_fwd_entry_path_dump_t *mp;
17105   vl_api_control_ping_t *mp_ping;
17106   unformat_input_t *i = vam->input;
17107   u32 fwd_entry_index = ~0;
17108   int ret;
17109
17110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17111     {
17112       if (unformat (i, "index %d", &fwd_entry_index))
17113         ;
17114       else
17115         break;
17116     }
17117
17118   if (~0 == fwd_entry_index)
17119     {
17120       errmsg ("no index specified!");
17121       return -99;
17122     }
17123
17124   if (!vam->json_output)
17125     {
17126       print (vam->ofp, "first line");
17127     }
17128
17129   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17130
17131   /* send it... */
17132   S (mp);
17133   /* Use a control ping for synchronization */
17134   MPING (CONTROL_PING, mp_ping);
17135   S (mp_ping);
17136
17137   /* Wait for a reply... */
17138   W (ret);
17139   return ret;
17140 }
17141
17142 static int
17143 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17144 {
17145   vl_api_one_get_map_request_itr_rlocs_t *mp;
17146   int ret;
17147
17148   if (!vam->json_output)
17149     {
17150       print (vam->ofp, "%=20s", "itr-rlocs:");
17151     }
17152
17153   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17154   /* send it... */
17155   S (mp);
17156   /* Wait for a reply... */
17157   W (ret);
17158   return ret;
17159 }
17160
17161 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17162
17163 static int
17164 api_af_packet_create (vat_main_t * vam)
17165 {
17166   unformat_input_t *i = vam->input;
17167   vl_api_af_packet_create_t *mp;
17168   u8 *host_if_name = 0;
17169   u8 hw_addr[6];
17170   u8 random_hw_addr = 1;
17171   int ret;
17172
17173   clib_memset (hw_addr, 0, sizeof (hw_addr));
17174
17175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17176     {
17177       if (unformat (i, "name %s", &host_if_name))
17178         vec_add1 (host_if_name, 0);
17179       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17180         random_hw_addr = 0;
17181       else
17182         break;
17183     }
17184
17185   if (!vec_len (host_if_name))
17186     {
17187       errmsg ("host-interface name must be specified");
17188       return -99;
17189     }
17190
17191   if (vec_len (host_if_name) > 64)
17192     {
17193       errmsg ("host-interface name too long");
17194       return -99;
17195     }
17196
17197   M (AF_PACKET_CREATE, mp);
17198
17199   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17200   clib_memcpy (mp->hw_addr, hw_addr, 6);
17201   mp->use_random_hw_addr = random_hw_addr;
17202   vec_free (host_if_name);
17203
17204   S (mp);
17205
17206   /* *INDENT-OFF* */
17207   W2 (ret,
17208       ({
17209         if (ret == 0)
17210           fprintf (vam->ofp ? vam->ofp : stderr,
17211                    " new sw_if_index = %d\n", vam->sw_if_index);
17212       }));
17213   /* *INDENT-ON* */
17214   return ret;
17215 }
17216
17217 static int
17218 api_af_packet_delete (vat_main_t * vam)
17219 {
17220   unformat_input_t *i = vam->input;
17221   vl_api_af_packet_delete_t *mp;
17222   u8 *host_if_name = 0;
17223   int ret;
17224
17225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17226     {
17227       if (unformat (i, "name %s", &host_if_name))
17228         vec_add1 (host_if_name, 0);
17229       else
17230         break;
17231     }
17232
17233   if (!vec_len (host_if_name))
17234     {
17235       errmsg ("host-interface name must be specified");
17236       return -99;
17237     }
17238
17239   if (vec_len (host_if_name) > 64)
17240     {
17241       errmsg ("host-interface name too long");
17242       return -99;
17243     }
17244
17245   M (AF_PACKET_DELETE, mp);
17246
17247   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17248   vec_free (host_if_name);
17249
17250   S (mp);
17251   W (ret);
17252   return ret;
17253 }
17254
17255 static void vl_api_af_packet_details_t_handler
17256   (vl_api_af_packet_details_t * mp)
17257 {
17258   vat_main_t *vam = &vat_main;
17259
17260   print (vam->ofp, "%-16s %d",
17261          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17262 }
17263
17264 static void vl_api_af_packet_details_t_handler_json
17265   (vl_api_af_packet_details_t * mp)
17266 {
17267   vat_main_t *vam = &vat_main;
17268   vat_json_node_t *node = NULL;
17269
17270   if (VAT_JSON_ARRAY != vam->json_tree.type)
17271     {
17272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17273       vat_json_init_array (&vam->json_tree);
17274     }
17275   node = vat_json_array_add (&vam->json_tree);
17276
17277   vat_json_init_object (node);
17278   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17279   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17280 }
17281
17282 static int
17283 api_af_packet_dump (vat_main_t * vam)
17284 {
17285   vl_api_af_packet_dump_t *mp;
17286   vl_api_control_ping_t *mp_ping;
17287   int ret;
17288
17289   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17290   /* Get list of tap interfaces */
17291   M (AF_PACKET_DUMP, mp);
17292   S (mp);
17293
17294   /* Use a control ping for synchronization */
17295   MPING (CONTROL_PING, mp_ping);
17296   S (mp_ping);
17297
17298   W (ret);
17299   return ret;
17300 }
17301
17302 static int
17303 api_policer_add_del (vat_main_t * vam)
17304 {
17305   unformat_input_t *i = vam->input;
17306   vl_api_policer_add_del_t *mp;
17307   u8 is_add = 1;
17308   u8 *name = 0;
17309   u32 cir = 0;
17310   u32 eir = 0;
17311   u64 cb = 0;
17312   u64 eb = 0;
17313   u8 rate_type = 0;
17314   u8 round_type = 0;
17315   u8 type = 0;
17316   u8 color_aware = 0;
17317   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17318   int ret;
17319
17320   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17321   conform_action.dscp = 0;
17322   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17323   exceed_action.dscp = 0;
17324   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17325   violate_action.dscp = 0;
17326
17327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17328     {
17329       if (unformat (i, "del"))
17330         is_add = 0;
17331       else if (unformat (i, "name %s", &name))
17332         vec_add1 (name, 0);
17333       else if (unformat (i, "cir %u", &cir))
17334         ;
17335       else if (unformat (i, "eir %u", &eir))
17336         ;
17337       else if (unformat (i, "cb %u", &cb))
17338         ;
17339       else if (unformat (i, "eb %u", &eb))
17340         ;
17341       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17342                          &rate_type))
17343         ;
17344       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17345                          &round_type))
17346         ;
17347       else if (unformat (i, "type %U", unformat_policer_type, &type))
17348         ;
17349       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17350                          &conform_action))
17351         ;
17352       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17353                          &exceed_action))
17354         ;
17355       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17356                          &violate_action))
17357         ;
17358       else if (unformat (i, "color-aware"))
17359         color_aware = 1;
17360       else
17361         break;
17362     }
17363
17364   if (!vec_len (name))
17365     {
17366       errmsg ("policer name must be specified");
17367       return -99;
17368     }
17369
17370   if (vec_len (name) > 64)
17371     {
17372       errmsg ("policer name too long");
17373       return -99;
17374     }
17375
17376   M (POLICER_ADD_DEL, mp);
17377
17378   clib_memcpy (mp->name, name, vec_len (name));
17379   vec_free (name);
17380   mp->is_add = is_add;
17381   mp->cir = ntohl (cir);
17382   mp->eir = ntohl (eir);
17383   mp->cb = clib_net_to_host_u64 (cb);
17384   mp->eb = clib_net_to_host_u64 (eb);
17385   mp->rate_type = rate_type;
17386   mp->round_type = round_type;
17387   mp->type = type;
17388   mp->conform_action_type = conform_action.action_type;
17389   mp->conform_dscp = conform_action.dscp;
17390   mp->exceed_action_type = exceed_action.action_type;
17391   mp->exceed_dscp = exceed_action.dscp;
17392   mp->violate_action_type = violate_action.action_type;
17393   mp->violate_dscp = violate_action.dscp;
17394   mp->color_aware = color_aware;
17395
17396   S (mp);
17397   W (ret);
17398   return ret;
17399 }
17400
17401 static int
17402 api_policer_dump (vat_main_t * vam)
17403 {
17404   unformat_input_t *i = vam->input;
17405   vl_api_policer_dump_t *mp;
17406   vl_api_control_ping_t *mp_ping;
17407   u8 *match_name = 0;
17408   u8 match_name_valid = 0;
17409   int ret;
17410
17411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17412     {
17413       if (unformat (i, "name %s", &match_name))
17414         {
17415           vec_add1 (match_name, 0);
17416           match_name_valid = 1;
17417         }
17418       else
17419         break;
17420     }
17421
17422   M (POLICER_DUMP, mp);
17423   mp->match_name_valid = match_name_valid;
17424   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17425   vec_free (match_name);
17426   /* send it... */
17427   S (mp);
17428
17429   /* Use a control ping for synchronization */
17430   MPING (CONTROL_PING, mp_ping);
17431   S (mp_ping);
17432
17433   /* Wait for a reply... */
17434   W (ret);
17435   return ret;
17436 }
17437
17438 static int
17439 api_policer_classify_set_interface (vat_main_t * vam)
17440 {
17441   unformat_input_t *i = vam->input;
17442   vl_api_policer_classify_set_interface_t *mp;
17443   u32 sw_if_index;
17444   int sw_if_index_set;
17445   u32 ip4_table_index = ~0;
17446   u32 ip6_table_index = ~0;
17447   u32 l2_table_index = ~0;
17448   u8 is_add = 1;
17449   int ret;
17450
17451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17452     {
17453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17454         sw_if_index_set = 1;
17455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17456         sw_if_index_set = 1;
17457       else if (unformat (i, "del"))
17458         is_add = 0;
17459       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17460         ;
17461       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17462         ;
17463       else if (unformat (i, "l2-table %d", &l2_table_index))
17464         ;
17465       else
17466         {
17467           clib_warning ("parse error '%U'", format_unformat_error, i);
17468           return -99;
17469         }
17470     }
17471
17472   if (sw_if_index_set == 0)
17473     {
17474       errmsg ("missing interface name or sw_if_index");
17475       return -99;
17476     }
17477
17478   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17479
17480   mp->sw_if_index = ntohl (sw_if_index);
17481   mp->ip4_table_index = ntohl (ip4_table_index);
17482   mp->ip6_table_index = ntohl (ip6_table_index);
17483   mp->l2_table_index = ntohl (l2_table_index);
17484   mp->is_add = is_add;
17485
17486   S (mp);
17487   W (ret);
17488   return ret;
17489 }
17490
17491 static int
17492 api_policer_classify_dump (vat_main_t * vam)
17493 {
17494   unformat_input_t *i = vam->input;
17495   vl_api_policer_classify_dump_t *mp;
17496   vl_api_control_ping_t *mp_ping;
17497   u8 type = POLICER_CLASSIFY_N_TABLES;
17498   int ret;
17499
17500   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17501     ;
17502   else
17503     {
17504       errmsg ("classify table type must be specified");
17505       return -99;
17506     }
17507
17508   if (!vam->json_output)
17509     {
17510       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17511     }
17512
17513   M (POLICER_CLASSIFY_DUMP, mp);
17514   mp->type = type;
17515   /* send it... */
17516   S (mp);
17517
17518   /* Use a control ping for synchronization */
17519   MPING (CONTROL_PING, mp_ping);
17520   S (mp_ping);
17521
17522   /* Wait for a reply... */
17523   W (ret);
17524   return ret;
17525 }
17526
17527 static u8 *
17528 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17529 {
17530   vl_api_fib_path_nh_proto_t proto =
17531     va_arg (*args, vl_api_fib_path_nh_proto_t);
17532
17533   switch (proto)
17534     {
17535     case FIB_API_PATH_NH_PROTO_IP4:
17536       s = format (s, "ip4");
17537       break;
17538     case FIB_API_PATH_NH_PROTO_IP6:
17539       s = format (s, "ip6");
17540       break;
17541     case FIB_API_PATH_NH_PROTO_MPLS:
17542       s = format (s, "mpls");
17543       break;
17544     case FIB_API_PATH_NH_PROTO_BIER:
17545       s = format (s, "bier");
17546       break;
17547     case FIB_API_PATH_NH_PROTO_ETHERNET:
17548       s = format (s, "ethernet");
17549       break;
17550     }
17551
17552   return (s);
17553 }
17554
17555 static u8 *
17556 format_vl_api_ip_address_union (u8 * s, va_list * args)
17557 {
17558   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17559   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17560
17561   switch (af)
17562     {
17563     case ADDRESS_IP4:
17564       s = format (s, "%U", format_ip4_address, u->ip4);
17565       break;
17566     case ADDRESS_IP6:
17567       s = format (s, "%U", format_ip6_address, u->ip6);
17568       break;
17569     }
17570   return (s);
17571 }
17572
17573 static u8 *
17574 format_vl_api_fib_path_type (u8 * s, va_list * args)
17575 {
17576   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17577
17578   switch (t)
17579     {
17580     case FIB_API_PATH_TYPE_NORMAL:
17581       s = format (s, "normal");
17582       break;
17583     case FIB_API_PATH_TYPE_LOCAL:
17584       s = format (s, "local");
17585       break;
17586     case FIB_API_PATH_TYPE_DROP:
17587       s = format (s, "drop");
17588       break;
17589     case FIB_API_PATH_TYPE_UDP_ENCAP:
17590       s = format (s, "udp-encap");
17591       break;
17592     case FIB_API_PATH_TYPE_BIER_IMP:
17593       s = format (s, "bier-imp");
17594       break;
17595     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17596       s = format (s, "unreach");
17597       break;
17598     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17599       s = format (s, "prohibit");
17600       break;
17601     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17602       s = format (s, "src-lookup");
17603       break;
17604     case FIB_API_PATH_TYPE_DVR:
17605       s = format (s, "dvr");
17606       break;
17607     case FIB_API_PATH_TYPE_INTERFACE_RX:
17608       s = format (s, "interface-rx");
17609       break;
17610     case FIB_API_PATH_TYPE_CLASSIFY:
17611       s = format (s, "classify");
17612       break;
17613     }
17614
17615   return (s);
17616 }
17617
17618 static void
17619 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17620 {
17621   print (vam->ofp,
17622          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17623          ntohl (fp->weight), ntohl (fp->sw_if_index),
17624          format_vl_api_fib_path_type, fp->type,
17625          format_fib_api_path_nh_proto, fp->proto,
17626          format_vl_api_ip_address_union, &fp->nh.address);
17627 }
17628
17629 static void
17630 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17631                                  vl_api_fib_path_t * fp)
17632 {
17633   struct in_addr ip4;
17634   struct in6_addr ip6;
17635
17636   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17637   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17638   vat_json_object_add_uint (node, "type", fp->type);
17639   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17640   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17641     {
17642       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17643       vat_json_object_add_ip4 (node, "next_hop", ip4);
17644     }
17645   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17646     {
17647       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17648       vat_json_object_add_ip6 (node, "next_hop", ip6);
17649     }
17650 }
17651
17652 static void
17653 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17654 {
17655   vat_main_t *vam = &vat_main;
17656   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17657   vl_api_fib_path_t *fp;
17658   i32 i;
17659
17660   print (vam->ofp, "sw_if_index %d via:",
17661          ntohl (mp->mt_tunnel.mt_sw_if_index));
17662   fp = mp->mt_tunnel.mt_paths;
17663   for (i = 0; i < count; i++)
17664     {
17665       vl_api_fib_path_print (vam, fp);
17666       fp++;
17667     }
17668
17669   print (vam->ofp, "");
17670 }
17671
17672 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17673 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17674
17675 static void
17676 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17677 {
17678   vat_main_t *vam = &vat_main;
17679   vat_json_node_t *node = NULL;
17680   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17681   vl_api_fib_path_t *fp;
17682   i32 i;
17683
17684   if (VAT_JSON_ARRAY != vam->json_tree.type)
17685     {
17686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17687       vat_json_init_array (&vam->json_tree);
17688     }
17689   node = vat_json_array_add (&vam->json_tree);
17690
17691   vat_json_init_object (node);
17692   vat_json_object_add_uint (node, "sw_if_index",
17693                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17694
17695   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17696
17697   fp = mp->mt_tunnel.mt_paths;
17698   for (i = 0; i < count; i++)
17699     {
17700       vl_api_mpls_fib_path_json_print (node, fp);
17701       fp++;
17702     }
17703 }
17704
17705 static int
17706 api_mpls_tunnel_dump (vat_main_t * vam)
17707 {
17708   vl_api_mpls_tunnel_dump_t *mp;
17709   vl_api_control_ping_t *mp_ping;
17710   int ret;
17711
17712   M (MPLS_TUNNEL_DUMP, mp);
17713
17714   S (mp);
17715
17716   /* Use a control ping for synchronization */
17717   MPING (CONTROL_PING, mp_ping);
17718   S (mp_ping);
17719
17720   W (ret);
17721   return ret;
17722 }
17723
17724 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17725 #define vl_api_mpls_table_details_t_print vl_noop_handler
17726
17727
17728 static void
17729 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17730 {
17731   vat_main_t *vam = &vat_main;
17732
17733   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17734 }
17735
17736 static void vl_api_mpls_table_details_t_handler_json
17737   (vl_api_mpls_table_details_t * mp)
17738 {
17739   vat_main_t *vam = &vat_main;
17740   vat_json_node_t *node = NULL;
17741
17742   if (VAT_JSON_ARRAY != vam->json_tree.type)
17743     {
17744       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17745       vat_json_init_array (&vam->json_tree);
17746     }
17747   node = vat_json_array_add (&vam->json_tree);
17748
17749   vat_json_init_object (node);
17750   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17751 }
17752
17753 static int
17754 api_mpls_table_dump (vat_main_t * vam)
17755 {
17756   vl_api_mpls_table_dump_t *mp;
17757   vl_api_control_ping_t *mp_ping;
17758   int ret;
17759
17760   M (MPLS_TABLE_DUMP, mp);
17761   S (mp);
17762
17763   /* Use a control ping for synchronization */
17764   MPING (CONTROL_PING, mp_ping);
17765   S (mp_ping);
17766
17767   W (ret);
17768   return ret;
17769 }
17770
17771 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17772 #define vl_api_mpls_route_details_t_print vl_noop_handler
17773
17774 static void
17775 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17776 {
17777   vat_main_t *vam = &vat_main;
17778   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17779   vl_api_fib_path_t *fp;
17780   int i;
17781
17782   print (vam->ofp,
17783          "table-id %d, label %u, ess_bit %u",
17784          ntohl (mp->mr_route.mr_table_id),
17785          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17786   fp = mp->mr_route.mr_paths;
17787   for (i = 0; i < count; i++)
17788     {
17789       vl_api_fib_path_print (vam, fp);
17790       fp++;
17791     }
17792 }
17793
17794 static void vl_api_mpls_route_details_t_handler_json
17795   (vl_api_mpls_route_details_t * mp)
17796 {
17797   vat_main_t *vam = &vat_main;
17798   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17799   vat_json_node_t *node = NULL;
17800   vl_api_fib_path_t *fp;
17801   int i;
17802
17803   if (VAT_JSON_ARRAY != vam->json_tree.type)
17804     {
17805       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17806       vat_json_init_array (&vam->json_tree);
17807     }
17808   node = vat_json_array_add (&vam->json_tree);
17809
17810   vat_json_init_object (node);
17811   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17812   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17813   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17814   vat_json_object_add_uint (node, "path_count", count);
17815   fp = mp->mr_route.mr_paths;
17816   for (i = 0; i < count; i++)
17817     {
17818       vl_api_mpls_fib_path_json_print (node, fp);
17819       fp++;
17820     }
17821 }
17822
17823 static int
17824 api_mpls_route_dump (vat_main_t * vam)
17825 {
17826   unformat_input_t *input = vam->input;
17827   vl_api_mpls_route_dump_t *mp;
17828   vl_api_control_ping_t *mp_ping;
17829   u32 table_id;
17830   int ret;
17831
17832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17833     {
17834       if (unformat (input, "table_id %d", &table_id))
17835         ;
17836       else
17837         break;
17838     }
17839   if (table_id == ~0)
17840     {
17841       errmsg ("missing table id");
17842       return -99;
17843     }
17844
17845   M (MPLS_ROUTE_DUMP, mp);
17846
17847   mp->table.mt_table_id = ntohl (table_id);
17848   S (mp);
17849
17850   /* Use a control ping for synchronization */
17851   MPING (CONTROL_PING, mp_ping);
17852   S (mp_ping);
17853
17854   W (ret);
17855   return ret;
17856 }
17857
17858 #define vl_api_ip_table_details_t_endian vl_noop_handler
17859 #define vl_api_ip_table_details_t_print vl_noop_handler
17860
17861 static void
17862 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17863 {
17864   vat_main_t *vam = &vat_main;
17865
17866   print (vam->ofp,
17867          "%s; table-id %d, prefix %U/%d",
17868          mp->table.name, ntohl (mp->table.table_id));
17869 }
17870
17871
17872 static void vl_api_ip_table_details_t_handler_json
17873   (vl_api_ip_table_details_t * mp)
17874 {
17875   vat_main_t *vam = &vat_main;
17876   vat_json_node_t *node = NULL;
17877
17878   if (VAT_JSON_ARRAY != vam->json_tree.type)
17879     {
17880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17881       vat_json_init_array (&vam->json_tree);
17882     }
17883   node = vat_json_array_add (&vam->json_tree);
17884
17885   vat_json_init_object (node);
17886   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17887 }
17888
17889 static int
17890 api_ip_table_dump (vat_main_t * vam)
17891 {
17892   vl_api_ip_table_dump_t *mp;
17893   vl_api_control_ping_t *mp_ping;
17894   int ret;
17895
17896   M (IP_TABLE_DUMP, mp);
17897   S (mp);
17898
17899   /* Use a control ping for synchronization */
17900   MPING (CONTROL_PING, mp_ping);
17901   S (mp_ping);
17902
17903   W (ret);
17904   return ret;
17905 }
17906
17907 static int
17908 api_ip_mtable_dump (vat_main_t * vam)
17909 {
17910   vl_api_ip_mtable_dump_t *mp;
17911   vl_api_control_ping_t *mp_ping;
17912   int ret;
17913
17914   M (IP_MTABLE_DUMP, mp);
17915   S (mp);
17916
17917   /* Use a control ping for synchronization */
17918   MPING (CONTROL_PING, mp_ping);
17919   S (mp_ping);
17920
17921   W (ret);
17922   return ret;
17923 }
17924
17925 static int
17926 api_ip_mroute_dump (vat_main_t * vam)
17927 {
17928   unformat_input_t *input = vam->input;
17929   vl_api_control_ping_t *mp_ping;
17930   vl_api_ip_mroute_dump_t *mp;
17931   int ret, is_ip6;
17932   u32 table_id;
17933
17934   is_ip6 = 0;
17935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17936     {
17937       if (unformat (input, "table_id %d", &table_id))
17938         ;
17939       else if (unformat (input, "ip6"))
17940         is_ip6 = 1;
17941       else if (unformat (input, "ip4"))
17942         is_ip6 = 0;
17943       else
17944         break;
17945     }
17946   if (table_id == ~0)
17947     {
17948       errmsg ("missing table id");
17949       return -99;
17950     }
17951
17952   M (IP_MROUTE_DUMP, mp);
17953   mp->table.table_id = table_id;
17954   mp->table.is_ip6 = is_ip6;
17955   S (mp);
17956
17957   /* Use a control ping for synchronization */
17958   MPING (CONTROL_PING, mp_ping);
17959   S (mp_ping);
17960
17961   W (ret);
17962   return ret;
17963 }
17964
17965 #define vl_api_ip_route_details_t_endian vl_noop_handler
17966 #define vl_api_ip_route_details_t_print vl_noop_handler
17967
17968 static void
17969 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17970 {
17971   vat_main_t *vam = &vat_main;
17972   u8 count = mp->route.n_paths;
17973   vl_api_fib_path_t *fp;
17974   int i;
17975
17976   print (vam->ofp,
17977          "table-id %d, prefix %U/%d",
17978          ntohl (mp->route.table_id),
17979          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17980   for (i = 0; i < count; i++)
17981     {
17982       fp = &mp->route.paths[i];
17983
17984       vl_api_fib_path_print (vam, fp);
17985       fp++;
17986     }
17987 }
17988
17989 static void vl_api_ip_route_details_t_handler_json
17990   (vl_api_ip_route_details_t * mp)
17991 {
17992   vat_main_t *vam = &vat_main;
17993   u8 count = mp->route.n_paths;
17994   vat_json_node_t *node = NULL;
17995   struct in_addr ip4;
17996   struct in6_addr ip6;
17997   vl_api_fib_path_t *fp;
17998   int i;
17999
18000   if (VAT_JSON_ARRAY != vam->json_tree.type)
18001     {
18002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18003       vat_json_init_array (&vam->json_tree);
18004     }
18005   node = vat_json_array_add (&vam->json_tree);
18006
18007   vat_json_init_object (node);
18008   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18009   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18010     {
18011       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18012       vat_json_object_add_ip6 (node, "prefix", ip6);
18013     }
18014   else
18015     {
18016       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18017       vat_json_object_add_ip4 (node, "prefix", ip4);
18018     }
18019   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18020   vat_json_object_add_uint (node, "path_count", count);
18021   for (i = 0; i < count; i++)
18022     {
18023       fp = &mp->route.paths[i];
18024       vl_api_mpls_fib_path_json_print (node, fp);
18025     }
18026 }
18027
18028 static int
18029 api_ip_route_dump (vat_main_t * vam)
18030 {
18031   unformat_input_t *input = vam->input;
18032   vl_api_ip_route_dump_t *mp;
18033   vl_api_control_ping_t *mp_ping;
18034   u32 table_id;
18035   u8 is_ip6;
18036   int ret;
18037
18038   is_ip6 = 0;
18039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18040     {
18041       if (unformat (input, "table_id %d", &table_id))
18042         ;
18043       else if (unformat (input, "ip6"))
18044         is_ip6 = 1;
18045       else if (unformat (input, "ip4"))
18046         is_ip6 = 0;
18047       else
18048         break;
18049     }
18050   if (table_id == ~0)
18051     {
18052       errmsg ("missing table id");
18053       return -99;
18054     }
18055
18056   M (IP_ROUTE_DUMP, mp);
18057
18058   mp->table.table_id = table_id;
18059   mp->table.is_ip6 = is_ip6;
18060
18061   S (mp);
18062
18063   /* Use a control ping for synchronization */
18064   MPING (CONTROL_PING, mp_ping);
18065   S (mp_ping);
18066
18067   W (ret);
18068   return ret;
18069 }
18070
18071 int
18072 api_classify_table_ids (vat_main_t * vam)
18073 {
18074   vl_api_classify_table_ids_t *mp;
18075   int ret;
18076
18077   /* Construct the API message */
18078   M (CLASSIFY_TABLE_IDS, mp);
18079   mp->context = 0;
18080
18081   S (mp);
18082   W (ret);
18083   return ret;
18084 }
18085
18086 int
18087 api_classify_table_by_interface (vat_main_t * vam)
18088 {
18089   unformat_input_t *input = vam->input;
18090   vl_api_classify_table_by_interface_t *mp;
18091
18092   u32 sw_if_index = ~0;
18093   int ret;
18094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18095     {
18096       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18097         ;
18098       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18099         ;
18100       else
18101         break;
18102     }
18103   if (sw_if_index == ~0)
18104     {
18105       errmsg ("missing interface name or sw_if_index");
18106       return -99;
18107     }
18108
18109   /* Construct the API message */
18110   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18111   mp->context = 0;
18112   mp->sw_if_index = ntohl (sw_if_index);
18113
18114   S (mp);
18115   W (ret);
18116   return ret;
18117 }
18118
18119 int
18120 api_classify_table_info (vat_main_t * vam)
18121 {
18122   unformat_input_t *input = vam->input;
18123   vl_api_classify_table_info_t *mp;
18124
18125   u32 table_id = ~0;
18126   int ret;
18127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18128     {
18129       if (unformat (input, "table_id %d", &table_id))
18130         ;
18131       else
18132         break;
18133     }
18134   if (table_id == ~0)
18135     {
18136       errmsg ("missing table id");
18137       return -99;
18138     }
18139
18140   /* Construct the API message */
18141   M (CLASSIFY_TABLE_INFO, mp);
18142   mp->context = 0;
18143   mp->table_id = ntohl (table_id);
18144
18145   S (mp);
18146   W (ret);
18147   return ret;
18148 }
18149
18150 int
18151 api_classify_session_dump (vat_main_t * vam)
18152 {
18153   unformat_input_t *input = vam->input;
18154   vl_api_classify_session_dump_t *mp;
18155   vl_api_control_ping_t *mp_ping;
18156
18157   u32 table_id = ~0;
18158   int ret;
18159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18160     {
18161       if (unformat (input, "table_id %d", &table_id))
18162         ;
18163       else
18164         break;
18165     }
18166   if (table_id == ~0)
18167     {
18168       errmsg ("missing table id");
18169       return -99;
18170     }
18171
18172   /* Construct the API message */
18173   M (CLASSIFY_SESSION_DUMP, mp);
18174   mp->context = 0;
18175   mp->table_id = ntohl (table_id);
18176   S (mp);
18177
18178   /* Use a control ping for synchronization */
18179   MPING (CONTROL_PING, mp_ping);
18180   S (mp_ping);
18181
18182   W (ret);
18183   return ret;
18184 }
18185
18186 static void
18187 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18188 {
18189   vat_main_t *vam = &vat_main;
18190
18191   print (vam->ofp, "collector_address %U, collector_port %d, "
18192          "src_address %U, vrf_id %d, path_mtu %u, "
18193          "template_interval %u, udp_checksum %d",
18194          format_ip4_address, mp->collector_address,
18195          ntohs (mp->collector_port),
18196          format_ip4_address, mp->src_address,
18197          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18198          ntohl (mp->template_interval), mp->udp_checksum);
18199
18200   vam->retval = 0;
18201   vam->result_ready = 1;
18202 }
18203
18204 static void
18205   vl_api_ipfix_exporter_details_t_handler_json
18206   (vl_api_ipfix_exporter_details_t * mp)
18207 {
18208   vat_main_t *vam = &vat_main;
18209   vat_json_node_t node;
18210   struct in_addr collector_address;
18211   struct in_addr src_address;
18212
18213   vat_json_init_object (&node);
18214   clib_memcpy (&collector_address, &mp->collector_address,
18215                sizeof (collector_address));
18216   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18217   vat_json_object_add_uint (&node, "collector_port",
18218                             ntohs (mp->collector_port));
18219   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18220   vat_json_object_add_ip4 (&node, "src_address", src_address);
18221   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18222   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18223   vat_json_object_add_uint (&node, "template_interval",
18224                             ntohl (mp->template_interval));
18225   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18226
18227   vat_json_print (vam->ofp, &node);
18228   vat_json_free (&node);
18229   vam->retval = 0;
18230   vam->result_ready = 1;
18231 }
18232
18233 int
18234 api_ipfix_exporter_dump (vat_main_t * vam)
18235 {
18236   vl_api_ipfix_exporter_dump_t *mp;
18237   int ret;
18238
18239   /* Construct the API message */
18240   M (IPFIX_EXPORTER_DUMP, mp);
18241   mp->context = 0;
18242
18243   S (mp);
18244   W (ret);
18245   return ret;
18246 }
18247
18248 static int
18249 api_ipfix_classify_stream_dump (vat_main_t * vam)
18250 {
18251   vl_api_ipfix_classify_stream_dump_t *mp;
18252   int ret;
18253
18254   /* Construct the API message */
18255   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18256   mp->context = 0;
18257
18258   S (mp);
18259   W (ret);
18260   return ret;
18261   /* NOTREACHED */
18262   return 0;
18263 }
18264
18265 static void
18266   vl_api_ipfix_classify_stream_details_t_handler
18267   (vl_api_ipfix_classify_stream_details_t * mp)
18268 {
18269   vat_main_t *vam = &vat_main;
18270   print (vam->ofp, "domain_id %d, src_port %d",
18271          ntohl (mp->domain_id), ntohs (mp->src_port));
18272   vam->retval = 0;
18273   vam->result_ready = 1;
18274 }
18275
18276 static void
18277   vl_api_ipfix_classify_stream_details_t_handler_json
18278   (vl_api_ipfix_classify_stream_details_t * mp)
18279 {
18280   vat_main_t *vam = &vat_main;
18281   vat_json_node_t node;
18282
18283   vat_json_init_object (&node);
18284   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18285   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18286
18287   vat_json_print (vam->ofp, &node);
18288   vat_json_free (&node);
18289   vam->retval = 0;
18290   vam->result_ready = 1;
18291 }
18292
18293 static int
18294 api_ipfix_classify_table_dump (vat_main_t * vam)
18295 {
18296   vl_api_ipfix_classify_table_dump_t *mp;
18297   vl_api_control_ping_t *mp_ping;
18298   int ret;
18299
18300   if (!vam->json_output)
18301     {
18302       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18303              "transport_protocol");
18304     }
18305
18306   /* Construct the API message */
18307   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18308
18309   /* send it... */
18310   S (mp);
18311
18312   /* Use a control ping for synchronization */
18313   MPING (CONTROL_PING, mp_ping);
18314   S (mp_ping);
18315
18316   W (ret);
18317   return ret;
18318 }
18319
18320 static void
18321   vl_api_ipfix_classify_table_details_t_handler
18322   (vl_api_ipfix_classify_table_details_t * mp)
18323 {
18324   vat_main_t *vam = &vat_main;
18325   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18326          mp->transport_protocol);
18327 }
18328
18329 static void
18330   vl_api_ipfix_classify_table_details_t_handler_json
18331   (vl_api_ipfix_classify_table_details_t * mp)
18332 {
18333   vat_json_node_t *node = NULL;
18334   vat_main_t *vam = &vat_main;
18335
18336   if (VAT_JSON_ARRAY != vam->json_tree.type)
18337     {
18338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18339       vat_json_init_array (&vam->json_tree);
18340     }
18341
18342   node = vat_json_array_add (&vam->json_tree);
18343   vat_json_init_object (node);
18344
18345   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18346   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18347   vat_json_object_add_uint (node, "transport_protocol",
18348                             mp->transport_protocol);
18349 }
18350
18351 static int
18352 api_sw_interface_span_enable_disable (vat_main_t * vam)
18353 {
18354   unformat_input_t *i = vam->input;
18355   vl_api_sw_interface_span_enable_disable_t *mp;
18356   u32 src_sw_if_index = ~0;
18357   u32 dst_sw_if_index = ~0;
18358   u8 state = 3;
18359   int ret;
18360   u8 is_l2 = 0;
18361
18362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18363     {
18364       if (unformat
18365           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18366         ;
18367       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18368         ;
18369       else
18370         if (unformat
18371             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18372         ;
18373       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18374         ;
18375       else if (unformat (i, "disable"))
18376         state = 0;
18377       else if (unformat (i, "rx"))
18378         state = 1;
18379       else if (unformat (i, "tx"))
18380         state = 2;
18381       else if (unformat (i, "both"))
18382         state = 3;
18383       else if (unformat (i, "l2"))
18384         is_l2 = 1;
18385       else
18386         break;
18387     }
18388
18389   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18390
18391   mp->sw_if_index_from = htonl (src_sw_if_index);
18392   mp->sw_if_index_to = htonl (dst_sw_if_index);
18393   mp->state = state;
18394   mp->is_l2 = is_l2;
18395
18396   S (mp);
18397   W (ret);
18398   return ret;
18399 }
18400
18401 static void
18402 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18403                                             * mp)
18404 {
18405   vat_main_t *vam = &vat_main;
18406   u8 *sw_if_from_name = 0;
18407   u8 *sw_if_to_name = 0;
18408   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18409   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18410   char *states[] = { "none", "rx", "tx", "both" };
18411   hash_pair_t *p;
18412
18413   /* *INDENT-OFF* */
18414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18415   ({
18416     if ((u32) p->value[0] == sw_if_index_from)
18417       {
18418         sw_if_from_name = (u8 *)(p->key);
18419         if (sw_if_to_name)
18420           break;
18421       }
18422     if ((u32) p->value[0] == sw_if_index_to)
18423       {
18424         sw_if_to_name = (u8 *)(p->key);
18425         if (sw_if_from_name)
18426           break;
18427       }
18428   }));
18429   /* *INDENT-ON* */
18430   print (vam->ofp, "%20s => %20s (%s) %s",
18431          sw_if_from_name, sw_if_to_name, states[mp->state],
18432          mp->is_l2 ? "l2" : "device");
18433 }
18434
18435 static void
18436   vl_api_sw_interface_span_details_t_handler_json
18437   (vl_api_sw_interface_span_details_t * mp)
18438 {
18439   vat_main_t *vam = &vat_main;
18440   vat_json_node_t *node = NULL;
18441   u8 *sw_if_from_name = 0;
18442   u8 *sw_if_to_name = 0;
18443   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18444   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18445   hash_pair_t *p;
18446
18447   /* *INDENT-OFF* */
18448   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18449   ({
18450     if ((u32) p->value[0] == sw_if_index_from)
18451       {
18452         sw_if_from_name = (u8 *)(p->key);
18453         if (sw_if_to_name)
18454           break;
18455       }
18456     if ((u32) p->value[0] == sw_if_index_to)
18457       {
18458         sw_if_to_name = (u8 *)(p->key);
18459         if (sw_if_from_name)
18460           break;
18461       }
18462   }));
18463   /* *INDENT-ON* */
18464
18465   if (VAT_JSON_ARRAY != vam->json_tree.type)
18466     {
18467       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18468       vat_json_init_array (&vam->json_tree);
18469     }
18470   node = vat_json_array_add (&vam->json_tree);
18471
18472   vat_json_init_object (node);
18473   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18474   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18475   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18476   if (0 != sw_if_to_name)
18477     {
18478       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18479     }
18480   vat_json_object_add_uint (node, "state", mp->state);
18481   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18482 }
18483
18484 static int
18485 api_sw_interface_span_dump (vat_main_t * vam)
18486 {
18487   unformat_input_t *input = vam->input;
18488   vl_api_sw_interface_span_dump_t *mp;
18489   vl_api_control_ping_t *mp_ping;
18490   u8 is_l2 = 0;
18491   int ret;
18492
18493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18494     {
18495       if (unformat (input, "l2"))
18496         is_l2 = 1;
18497       else
18498         break;
18499     }
18500
18501   M (SW_INTERFACE_SPAN_DUMP, mp);
18502   mp->is_l2 = is_l2;
18503   S (mp);
18504
18505   /* Use a control ping for synchronization */
18506   MPING (CONTROL_PING, mp_ping);
18507   S (mp_ping);
18508
18509   W (ret);
18510   return ret;
18511 }
18512
18513 int
18514 api_pg_create_interface (vat_main_t * vam)
18515 {
18516   unformat_input_t *input = vam->input;
18517   vl_api_pg_create_interface_t *mp;
18518
18519   u32 if_id = ~0, gso_size = 0;
18520   u8 gso_enabled = 0;
18521   int ret;
18522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18523     {
18524       if (unformat (input, "if_id %d", &if_id))
18525         ;
18526       else if (unformat (input, "gso-enabled"))
18527         {
18528           gso_enabled = 1;
18529           if (unformat (input, "gso-size %u", &gso_size))
18530             ;
18531           else
18532             {
18533               errmsg ("missing gso-size");
18534               return -99;
18535             }
18536         }
18537       else
18538         break;
18539     }
18540   if (if_id == ~0)
18541     {
18542       errmsg ("missing pg interface index");
18543       return -99;
18544     }
18545
18546   /* Construct the API message */
18547   M (PG_CREATE_INTERFACE, mp);
18548   mp->context = 0;
18549   mp->interface_id = ntohl (if_id);
18550   mp->gso_enabled = gso_enabled;
18551
18552   S (mp);
18553   W (ret);
18554   return ret;
18555 }
18556
18557 int
18558 api_pg_capture (vat_main_t * vam)
18559 {
18560   unformat_input_t *input = vam->input;
18561   vl_api_pg_capture_t *mp;
18562
18563   u32 if_id = ~0;
18564   u8 enable = 1;
18565   u32 count = 1;
18566   u8 pcap_file_set = 0;
18567   u8 *pcap_file = 0;
18568   int ret;
18569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18570     {
18571       if (unformat (input, "if_id %d", &if_id))
18572         ;
18573       else if (unformat (input, "pcap %s", &pcap_file))
18574         pcap_file_set = 1;
18575       else if (unformat (input, "count %d", &count))
18576         ;
18577       else if (unformat (input, "disable"))
18578         enable = 0;
18579       else
18580         break;
18581     }
18582   if (if_id == ~0)
18583     {
18584       errmsg ("missing pg interface index");
18585       return -99;
18586     }
18587   if (pcap_file_set > 0)
18588     {
18589       if (vec_len (pcap_file) > 255)
18590         {
18591           errmsg ("pcap file name is too long");
18592           return -99;
18593         }
18594     }
18595
18596   /* Construct the API message */
18597   M (PG_CAPTURE, mp);
18598   mp->context = 0;
18599   mp->interface_id = ntohl (if_id);
18600   mp->is_enabled = enable;
18601   mp->count = ntohl (count);
18602   if (pcap_file_set != 0)
18603     {
18604       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18605     }
18606   vec_free (pcap_file);
18607
18608   S (mp);
18609   W (ret);
18610   return ret;
18611 }
18612
18613 int
18614 api_pg_enable_disable (vat_main_t * vam)
18615 {
18616   unformat_input_t *input = vam->input;
18617   vl_api_pg_enable_disable_t *mp;
18618
18619   u8 enable = 1;
18620   u8 stream_name_set = 0;
18621   u8 *stream_name = 0;
18622   int ret;
18623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18624     {
18625       if (unformat (input, "stream %s", &stream_name))
18626         stream_name_set = 1;
18627       else if (unformat (input, "disable"))
18628         enable = 0;
18629       else
18630         break;
18631     }
18632
18633   if (stream_name_set > 0)
18634     {
18635       if (vec_len (stream_name) > 255)
18636         {
18637           errmsg ("stream name too long");
18638           return -99;
18639         }
18640     }
18641
18642   /* Construct the API message */
18643   M (PG_ENABLE_DISABLE, mp);
18644   mp->context = 0;
18645   mp->is_enabled = enable;
18646   if (stream_name_set != 0)
18647     {
18648       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18649     }
18650   vec_free (stream_name);
18651
18652   S (mp);
18653   W (ret);
18654   return ret;
18655 }
18656
18657 int
18658 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18659 {
18660   unformat_input_t *input = vam->input;
18661   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18662
18663   u16 *low_ports = 0;
18664   u16 *high_ports = 0;
18665   u16 this_low;
18666   u16 this_hi;
18667   vl_api_prefix_t prefix;
18668   u32 tmp, tmp2;
18669   u8 prefix_set = 0;
18670   u32 vrf_id = ~0;
18671   u8 is_add = 1;
18672   int ret;
18673
18674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18675     {
18676       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18677         prefix_set = 1;
18678       else if (unformat (input, "vrf %d", &vrf_id))
18679         ;
18680       else if (unformat (input, "del"))
18681         is_add = 0;
18682       else if (unformat (input, "port %d", &tmp))
18683         {
18684           if (tmp == 0 || tmp > 65535)
18685             {
18686               errmsg ("port %d out of range", tmp);
18687               return -99;
18688             }
18689           this_low = tmp;
18690           this_hi = this_low + 1;
18691           vec_add1 (low_ports, this_low);
18692           vec_add1 (high_ports, this_hi);
18693         }
18694       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18695         {
18696           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18697             {
18698               errmsg ("incorrect range parameters");
18699               return -99;
18700             }
18701           this_low = tmp;
18702           /* Note: in debug CLI +1 is added to high before
18703              passing to real fn that does "the work"
18704              (ip_source_and_port_range_check_add_del).
18705              This fn is a wrapper around the binary API fn a
18706              control plane will call, which expects this increment
18707              to have occurred. Hence letting the binary API control
18708              plane fn do the increment for consistency between VAT
18709              and other control planes.
18710            */
18711           this_hi = tmp2;
18712           vec_add1 (low_ports, this_low);
18713           vec_add1 (high_ports, this_hi);
18714         }
18715       else
18716         break;
18717     }
18718
18719   if (prefix_set == 0)
18720     {
18721       errmsg ("<address>/<mask> not specified");
18722       return -99;
18723     }
18724
18725   if (vrf_id == ~0)
18726     {
18727       errmsg ("VRF ID required, not specified");
18728       return -99;
18729     }
18730
18731   if (vrf_id == 0)
18732     {
18733       errmsg
18734         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18735       return -99;
18736     }
18737
18738   if (vec_len (low_ports) == 0)
18739     {
18740       errmsg ("At least one port or port range required");
18741       return -99;
18742     }
18743
18744   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18745
18746   mp->is_add = is_add;
18747
18748   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18749
18750   mp->number_of_ranges = vec_len (low_ports);
18751
18752   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18753   vec_free (low_ports);
18754
18755   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18756   vec_free (high_ports);
18757
18758   mp->vrf_id = ntohl (vrf_id);
18759
18760   S (mp);
18761   W (ret);
18762   return ret;
18763 }
18764
18765 int
18766 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18767 {
18768   unformat_input_t *input = vam->input;
18769   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18770   u32 sw_if_index = ~0;
18771   int vrf_set = 0;
18772   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18773   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18774   u8 is_add = 1;
18775   int ret;
18776
18777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18778     {
18779       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18780         ;
18781       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18782         ;
18783       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18784         vrf_set = 1;
18785       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18786         vrf_set = 1;
18787       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18788         vrf_set = 1;
18789       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18790         vrf_set = 1;
18791       else if (unformat (input, "del"))
18792         is_add = 0;
18793       else
18794         break;
18795     }
18796
18797   if (sw_if_index == ~0)
18798     {
18799       errmsg ("Interface required but not specified");
18800       return -99;
18801     }
18802
18803   if (vrf_set == 0)
18804     {
18805       errmsg ("VRF ID required but not specified");
18806       return -99;
18807     }
18808
18809   if (tcp_out_vrf_id == 0
18810       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18811     {
18812       errmsg
18813         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18814       return -99;
18815     }
18816
18817   /* Construct the API message */
18818   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18819
18820   mp->sw_if_index = ntohl (sw_if_index);
18821   mp->is_add = is_add;
18822   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18823   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18824   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18825   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18826
18827   /* send it... */
18828   S (mp);
18829
18830   /* Wait for a reply... */
18831   W (ret);
18832   return ret;
18833 }
18834
18835 static int
18836 api_set_punt (vat_main_t * vam)
18837 {
18838   unformat_input_t *i = vam->input;
18839   vl_api_address_family_t af;
18840   vl_api_set_punt_t *mp;
18841   u32 protocol = ~0;
18842   u32 port = ~0;
18843   int is_add = 1;
18844   int ret;
18845
18846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18847     {
18848       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18849         ;
18850       else if (unformat (i, "protocol %d", &protocol))
18851         ;
18852       else if (unformat (i, "port %d", &port))
18853         ;
18854       else if (unformat (i, "del"))
18855         is_add = 0;
18856       else
18857         {
18858           clib_warning ("parse error '%U'", format_unformat_error, i);
18859           return -99;
18860         }
18861     }
18862
18863   M (SET_PUNT, mp);
18864
18865   mp->is_add = (u8) is_add;
18866   mp->punt.type = PUNT_API_TYPE_L4;
18867   mp->punt.punt.l4.af = af;
18868   mp->punt.punt.l4.protocol = (u8) protocol;
18869   mp->punt.punt.l4.port = htons ((u16) port);
18870
18871   S (mp);
18872   W (ret);
18873   return ret;
18874 }
18875
18876 static int
18877 api_delete_subif (vat_main_t * vam)
18878 {
18879   unformat_input_t *i = vam->input;
18880   vl_api_delete_subif_t *mp;
18881   u32 sw_if_index = ~0;
18882   int ret;
18883
18884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18885     {
18886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18887         ;
18888       if (unformat (i, "sw_if_index %d", &sw_if_index))
18889         ;
18890       else
18891         break;
18892     }
18893
18894   if (sw_if_index == ~0)
18895     {
18896       errmsg ("missing sw_if_index");
18897       return -99;
18898     }
18899
18900   /* Construct the API message */
18901   M (DELETE_SUBIF, mp);
18902   mp->sw_if_index = ntohl (sw_if_index);
18903
18904   S (mp);
18905   W (ret);
18906   return ret;
18907 }
18908
18909 #define foreach_pbb_vtr_op      \
18910 _("disable",  L2_VTR_DISABLED)  \
18911 _("pop",  L2_VTR_POP_2)         \
18912 _("push",  L2_VTR_PUSH_2)
18913
18914 static int
18915 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18916 {
18917   unformat_input_t *i = vam->input;
18918   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18919   u32 sw_if_index = ~0, vtr_op = ~0;
18920   u16 outer_tag = ~0;
18921   u8 dmac[6], smac[6];
18922   u8 dmac_set = 0, smac_set = 0;
18923   u16 vlanid = 0;
18924   u32 sid = ~0;
18925   u32 tmp;
18926   int ret;
18927
18928   /* Shut up coverity */
18929   clib_memset (dmac, 0, sizeof (dmac));
18930   clib_memset (smac, 0, sizeof (smac));
18931
18932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18933     {
18934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18935         ;
18936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18937         ;
18938       else if (unformat (i, "vtr_op %d", &vtr_op))
18939         ;
18940 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18941       foreach_pbb_vtr_op
18942 #undef _
18943         else if (unformat (i, "translate_pbb_stag"))
18944         {
18945           if (unformat (i, "%d", &tmp))
18946             {
18947               vtr_op = L2_VTR_TRANSLATE_2_1;
18948               outer_tag = tmp;
18949             }
18950           else
18951             {
18952               errmsg
18953                 ("translate_pbb_stag operation requires outer tag definition");
18954               return -99;
18955             }
18956         }
18957       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18958         dmac_set++;
18959       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18960         smac_set++;
18961       else if (unformat (i, "sid %d", &sid))
18962         ;
18963       else if (unformat (i, "vlanid %d", &tmp))
18964         vlanid = tmp;
18965       else
18966         {
18967           clib_warning ("parse error '%U'", format_unformat_error, i);
18968           return -99;
18969         }
18970     }
18971
18972   if ((sw_if_index == ~0) || (vtr_op == ~0))
18973     {
18974       errmsg ("missing sw_if_index or vtr operation");
18975       return -99;
18976     }
18977   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18978       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18979     {
18980       errmsg
18981         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18982       return -99;
18983     }
18984
18985   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18986   mp->sw_if_index = ntohl (sw_if_index);
18987   mp->vtr_op = ntohl (vtr_op);
18988   mp->outer_tag = ntohs (outer_tag);
18989   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18990   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18991   mp->b_vlanid = ntohs (vlanid);
18992   mp->i_sid = ntohl (sid);
18993
18994   S (mp);
18995   W (ret);
18996   return ret;
18997 }
18998
18999 static int
19000 api_flow_classify_set_interface (vat_main_t * vam)
19001 {
19002   unformat_input_t *i = vam->input;
19003   vl_api_flow_classify_set_interface_t *mp;
19004   u32 sw_if_index;
19005   int sw_if_index_set;
19006   u32 ip4_table_index = ~0;
19007   u32 ip6_table_index = ~0;
19008   u8 is_add = 1;
19009   int ret;
19010
19011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19012     {
19013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19014         sw_if_index_set = 1;
19015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19016         sw_if_index_set = 1;
19017       else if (unformat (i, "del"))
19018         is_add = 0;
19019       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19020         ;
19021       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19022         ;
19023       else
19024         {
19025           clib_warning ("parse error '%U'", format_unformat_error, i);
19026           return -99;
19027         }
19028     }
19029
19030   if (sw_if_index_set == 0)
19031     {
19032       errmsg ("missing interface name or sw_if_index");
19033       return -99;
19034     }
19035
19036   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19037
19038   mp->sw_if_index = ntohl (sw_if_index);
19039   mp->ip4_table_index = ntohl (ip4_table_index);
19040   mp->ip6_table_index = ntohl (ip6_table_index);
19041   mp->is_add = is_add;
19042
19043   S (mp);
19044   W (ret);
19045   return ret;
19046 }
19047
19048 static int
19049 api_flow_classify_dump (vat_main_t * vam)
19050 {
19051   unformat_input_t *i = vam->input;
19052   vl_api_flow_classify_dump_t *mp;
19053   vl_api_control_ping_t *mp_ping;
19054   u8 type = FLOW_CLASSIFY_N_TABLES;
19055   int ret;
19056
19057   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19058     ;
19059   else
19060     {
19061       errmsg ("classify table type must be specified");
19062       return -99;
19063     }
19064
19065   if (!vam->json_output)
19066     {
19067       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19068     }
19069
19070   M (FLOW_CLASSIFY_DUMP, mp);
19071   mp->type = type;
19072   /* send it... */
19073   S (mp);
19074
19075   /* Use a control ping for synchronization */
19076   MPING (CONTROL_PING, mp_ping);
19077   S (mp_ping);
19078
19079   /* Wait for a reply... */
19080   W (ret);
19081   return ret;
19082 }
19083
19084 static int
19085 api_feature_enable_disable (vat_main_t * vam)
19086 {
19087   unformat_input_t *i = vam->input;
19088   vl_api_feature_enable_disable_t *mp;
19089   u8 *arc_name = 0;
19090   u8 *feature_name = 0;
19091   u32 sw_if_index = ~0;
19092   u8 enable = 1;
19093   int ret;
19094
19095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19096     {
19097       if (unformat (i, "arc_name %s", &arc_name))
19098         ;
19099       else if (unformat (i, "feature_name %s", &feature_name))
19100         ;
19101       else
19102         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19103         ;
19104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19105         ;
19106       else if (unformat (i, "disable"))
19107         enable = 0;
19108       else
19109         break;
19110     }
19111
19112   if (arc_name == 0)
19113     {
19114       errmsg ("missing arc name");
19115       return -99;
19116     }
19117   if (vec_len (arc_name) > 63)
19118     {
19119       errmsg ("arc name too long");
19120     }
19121
19122   if (feature_name == 0)
19123     {
19124       errmsg ("missing feature name");
19125       return -99;
19126     }
19127   if (vec_len (feature_name) > 63)
19128     {
19129       errmsg ("feature name too long");
19130     }
19131
19132   if (sw_if_index == ~0)
19133     {
19134       errmsg ("missing interface name or sw_if_index");
19135       return -99;
19136     }
19137
19138   /* Construct the API message */
19139   M (FEATURE_ENABLE_DISABLE, mp);
19140   mp->sw_if_index = ntohl (sw_if_index);
19141   mp->enable = enable;
19142   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19143   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19144   vec_free (arc_name);
19145   vec_free (feature_name);
19146
19147   S (mp);
19148   W (ret);
19149   return ret;
19150 }
19151
19152 static int
19153 api_feature_gso_enable_disable (vat_main_t * vam)
19154 {
19155   unformat_input_t *i = vam->input;
19156   vl_api_feature_gso_enable_disable_t *mp;
19157   u32 sw_if_index = ~0;
19158   u8 enable = 1;
19159   int ret;
19160
19161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19162     {
19163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19164         ;
19165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19166         ;
19167       else if (unformat (i, "enable"))
19168         enable = 1;
19169       else if (unformat (i, "disable"))
19170         enable = 0;
19171       else
19172         break;
19173     }
19174
19175   if (sw_if_index == ~0)
19176     {
19177       errmsg ("missing interface name or sw_if_index");
19178       return -99;
19179     }
19180
19181   /* Construct the API message */
19182   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19183   mp->sw_if_index = ntohl (sw_if_index);
19184   mp->enable_disable = enable;
19185
19186   S (mp);
19187   W (ret);
19188   return ret;
19189 }
19190
19191 static int
19192 api_sw_interface_tag_add_del (vat_main_t * vam)
19193 {
19194   unformat_input_t *i = vam->input;
19195   vl_api_sw_interface_tag_add_del_t *mp;
19196   u32 sw_if_index = ~0;
19197   u8 *tag = 0;
19198   u8 enable = 1;
19199   int ret;
19200
19201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19202     {
19203       if (unformat (i, "tag %s", &tag))
19204         ;
19205       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19206         ;
19207       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19208         ;
19209       else if (unformat (i, "del"))
19210         enable = 0;
19211       else
19212         break;
19213     }
19214
19215   if (sw_if_index == ~0)
19216     {
19217       errmsg ("missing interface name or sw_if_index");
19218       return -99;
19219     }
19220
19221   if (enable && (tag == 0))
19222     {
19223       errmsg ("no tag specified");
19224       return -99;
19225     }
19226
19227   /* Construct the API message */
19228   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19229   mp->sw_if_index = ntohl (sw_if_index);
19230   mp->is_add = enable;
19231   if (enable)
19232     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19233   vec_free (tag);
19234
19235   S (mp);
19236   W (ret);
19237   return ret;
19238 }
19239
19240 static int
19241 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19242 {
19243   unformat_input_t *i = vam->input;
19244   vl_api_mac_address_t mac = { 0 };
19245   vl_api_sw_interface_add_del_mac_address_t *mp;
19246   u32 sw_if_index = ~0;
19247   u8 is_add = 1;
19248   u8 mac_set = 0;
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, "%U", unformat_vl_api_mac_address, &mac))
19258         mac_set++;
19259       else if (unformat (i, "del"))
19260         is_add = 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   if (!mac_set)
19272     {
19273       errmsg ("missing MAC address");
19274       return -99;
19275     }
19276
19277   /* Construct the API message */
19278   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19279   mp->sw_if_index = ntohl (sw_if_index);
19280   mp->is_add = is_add;
19281   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19282
19283   S (mp);
19284   W (ret);
19285   return ret;
19286 }
19287
19288 static void vl_api_l2_xconnect_details_t_handler
19289   (vl_api_l2_xconnect_details_t * mp)
19290 {
19291   vat_main_t *vam = &vat_main;
19292
19293   print (vam->ofp, "%15d%15d",
19294          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19295 }
19296
19297 static void vl_api_l2_xconnect_details_t_handler_json
19298   (vl_api_l2_xconnect_details_t * mp)
19299 {
19300   vat_main_t *vam = &vat_main;
19301   vat_json_node_t *node = NULL;
19302
19303   if (VAT_JSON_ARRAY != vam->json_tree.type)
19304     {
19305       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19306       vat_json_init_array (&vam->json_tree);
19307     }
19308   node = vat_json_array_add (&vam->json_tree);
19309
19310   vat_json_init_object (node);
19311   vat_json_object_add_uint (node, "rx_sw_if_index",
19312                             ntohl (mp->rx_sw_if_index));
19313   vat_json_object_add_uint (node, "tx_sw_if_index",
19314                             ntohl (mp->tx_sw_if_index));
19315 }
19316
19317 static int
19318 api_l2_xconnect_dump (vat_main_t * vam)
19319 {
19320   vl_api_l2_xconnect_dump_t *mp;
19321   vl_api_control_ping_t *mp_ping;
19322   int ret;
19323
19324   if (!vam->json_output)
19325     {
19326       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19327     }
19328
19329   M (L2_XCONNECT_DUMP, mp);
19330
19331   S (mp);
19332
19333   /* Use a control ping for synchronization */
19334   MPING (CONTROL_PING, mp_ping);
19335   S (mp_ping);
19336
19337   W (ret);
19338   return ret;
19339 }
19340
19341 static int
19342 api_hw_interface_set_mtu (vat_main_t * vam)
19343 {
19344   unformat_input_t *i = vam->input;
19345   vl_api_hw_interface_set_mtu_t *mp;
19346   u32 sw_if_index = ~0;
19347   u32 mtu = 0;
19348   int ret;
19349
19350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19351     {
19352       if (unformat (i, "mtu %d", &mtu))
19353         ;
19354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19355         ;
19356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19357         ;
19358       else
19359         break;
19360     }
19361
19362   if (sw_if_index == ~0)
19363     {
19364       errmsg ("missing interface name or sw_if_index");
19365       return -99;
19366     }
19367
19368   if (mtu == 0)
19369     {
19370       errmsg ("no mtu specified");
19371       return -99;
19372     }
19373
19374   /* Construct the API message */
19375   M (HW_INTERFACE_SET_MTU, mp);
19376   mp->sw_if_index = ntohl (sw_if_index);
19377   mp->mtu = ntohs ((u16) mtu);
19378
19379   S (mp);
19380   W (ret);
19381   return ret;
19382 }
19383
19384 static int
19385 api_p2p_ethernet_add (vat_main_t * vam)
19386 {
19387   unformat_input_t *i = vam->input;
19388   vl_api_p2p_ethernet_add_t *mp;
19389   u32 parent_if_index = ~0;
19390   u32 sub_id = ~0;
19391   u8 remote_mac[6];
19392   u8 mac_set = 0;
19393   int ret;
19394
19395   clib_memset (remote_mac, 0, sizeof (remote_mac));
19396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19397     {
19398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19399         ;
19400       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19401         ;
19402       else
19403         if (unformat
19404             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19405         mac_set++;
19406       else if (unformat (i, "sub_id %d", &sub_id))
19407         ;
19408       else
19409         {
19410           clib_warning ("parse error '%U'", format_unformat_error, i);
19411           return -99;
19412         }
19413     }
19414
19415   if (parent_if_index == ~0)
19416     {
19417       errmsg ("missing interface name or sw_if_index");
19418       return -99;
19419     }
19420   if (mac_set == 0)
19421     {
19422       errmsg ("missing remote mac address");
19423       return -99;
19424     }
19425   if (sub_id == ~0)
19426     {
19427       errmsg ("missing sub-interface id");
19428       return -99;
19429     }
19430
19431   M (P2P_ETHERNET_ADD, mp);
19432   mp->parent_if_index = ntohl (parent_if_index);
19433   mp->subif_id = ntohl (sub_id);
19434   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19435
19436   S (mp);
19437   W (ret);
19438   return ret;
19439 }
19440
19441 static int
19442 api_p2p_ethernet_del (vat_main_t * vam)
19443 {
19444   unformat_input_t *i = vam->input;
19445   vl_api_p2p_ethernet_del_t *mp;
19446   u32 parent_if_index = ~0;
19447   u8 remote_mac[6];
19448   u8 mac_set = 0;
19449   int ret;
19450
19451   clib_memset (remote_mac, 0, sizeof (remote_mac));
19452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19453     {
19454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19455         ;
19456       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19457         ;
19458       else
19459         if (unformat
19460             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19461         mac_set++;
19462       else
19463         {
19464           clib_warning ("parse error '%U'", format_unformat_error, i);
19465           return -99;
19466         }
19467     }
19468
19469   if (parent_if_index == ~0)
19470     {
19471       errmsg ("missing interface name or sw_if_index");
19472       return -99;
19473     }
19474   if (mac_set == 0)
19475     {
19476       errmsg ("missing remote mac address");
19477       return -99;
19478     }
19479
19480   M (P2P_ETHERNET_DEL, mp);
19481   mp->parent_if_index = ntohl (parent_if_index);
19482   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19483
19484   S (mp);
19485   W (ret);
19486   return ret;
19487 }
19488
19489 static int
19490 api_lldp_config (vat_main_t * vam)
19491 {
19492   unformat_input_t *i = vam->input;
19493   vl_api_lldp_config_t *mp;
19494   int tx_hold = 0;
19495   int tx_interval = 0;
19496   u8 *sys_name = NULL;
19497   int ret;
19498
19499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19500     {
19501       if (unformat (i, "system-name %s", &sys_name))
19502         ;
19503       else if (unformat (i, "tx-hold %d", &tx_hold))
19504         ;
19505       else if (unformat (i, "tx-interval %d", &tx_interval))
19506         ;
19507       else
19508         {
19509           clib_warning ("parse error '%U'", format_unformat_error, i);
19510           return -99;
19511         }
19512     }
19513
19514   vec_add1 (sys_name, 0);
19515
19516   M (LLDP_CONFIG, mp);
19517   mp->tx_hold = htonl (tx_hold);
19518   mp->tx_interval = htonl (tx_interval);
19519   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19520   vec_free (sys_name);
19521
19522   S (mp);
19523   W (ret);
19524   return ret;
19525 }
19526
19527 static int
19528 api_sw_interface_set_lldp (vat_main_t * vam)
19529 {
19530   unformat_input_t *i = vam->input;
19531   vl_api_sw_interface_set_lldp_t *mp;
19532   u32 sw_if_index = ~0;
19533   u32 enable = 1;
19534   u8 *port_desc = NULL, *mgmt_oid = NULL;
19535   ip4_address_t ip4_addr;
19536   ip6_address_t ip6_addr;
19537   int ret;
19538
19539   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19540   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19541
19542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19543     {
19544       if (unformat (i, "disable"))
19545         enable = 0;
19546       else
19547         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19548         ;
19549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19550         ;
19551       else if (unformat (i, "port-desc %s", &port_desc))
19552         ;
19553       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19554         ;
19555       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19556         ;
19557       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19558         ;
19559       else
19560         break;
19561     }
19562
19563   if (sw_if_index == ~0)
19564     {
19565       errmsg ("missing interface name or sw_if_index");
19566       return -99;
19567     }
19568
19569   /* Construct the API message */
19570   vec_add1 (port_desc, 0);
19571   vec_add1 (mgmt_oid, 0);
19572   M (SW_INTERFACE_SET_LLDP, mp);
19573   mp->sw_if_index = ntohl (sw_if_index);
19574   mp->enable = enable;
19575   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19576   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19577   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19578   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19579   vec_free (port_desc);
19580   vec_free (mgmt_oid);
19581
19582   S (mp);
19583   W (ret);
19584   return ret;
19585 }
19586
19587 static int
19588 api_tcp_configure_src_addresses (vat_main_t * vam)
19589 {
19590   vl_api_tcp_configure_src_addresses_t *mp;
19591   unformat_input_t *i = vam->input;
19592   vl_api_address_t first, last;
19593   u8 range_set = 0;
19594   u32 vrf_id = 0;
19595   int ret;
19596
19597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19598     {
19599       if (unformat (i, "%U - %U",
19600                     unformat_vl_api_address, &first,
19601                     unformat_vl_api_address, &last))
19602         {
19603           if (range_set)
19604             {
19605               errmsg ("one range per message (range already set)");
19606               return -99;
19607             }
19608           range_set = 1;
19609         }
19610       else if (unformat (i, "vrf %d", &vrf_id))
19611         ;
19612       else
19613         break;
19614     }
19615
19616   if (range_set == 0)
19617     {
19618       errmsg ("address range not set");
19619       return -99;
19620     }
19621
19622   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19623
19624   mp->vrf_id = ntohl (vrf_id);
19625   clib_memcpy (&mp->first_address, &first, sizeof (first));
19626   clib_memcpy (&mp->last_address, &last, sizeof (last));
19627
19628   S (mp);
19629   W (ret);
19630   return ret;
19631 }
19632
19633 static void vl_api_app_namespace_add_del_reply_t_handler
19634   (vl_api_app_namespace_add_del_reply_t * mp)
19635 {
19636   vat_main_t *vam = &vat_main;
19637   i32 retval = ntohl (mp->retval);
19638   if (vam->async_mode)
19639     {
19640       vam->async_errors += (retval < 0);
19641     }
19642   else
19643     {
19644       vam->retval = retval;
19645       if (retval == 0)
19646         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19647       vam->result_ready = 1;
19648     }
19649 }
19650
19651 static void vl_api_app_namespace_add_del_reply_t_handler_json
19652   (vl_api_app_namespace_add_del_reply_t * mp)
19653 {
19654   vat_main_t *vam = &vat_main;
19655   vat_json_node_t node;
19656
19657   vat_json_init_object (&node);
19658   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19659   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19660
19661   vat_json_print (vam->ofp, &node);
19662   vat_json_free (&node);
19663
19664   vam->retval = ntohl (mp->retval);
19665   vam->result_ready = 1;
19666 }
19667
19668 static int
19669 api_app_namespace_add_del (vat_main_t * vam)
19670 {
19671   vl_api_app_namespace_add_del_t *mp;
19672   unformat_input_t *i = vam->input;
19673   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19674   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19675   u64 secret;
19676   int ret;
19677
19678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19679     {
19680       if (unformat (i, "id %_%v%_", &ns_id))
19681         ;
19682       else if (unformat (i, "secret %lu", &secret))
19683         secret_set = 1;
19684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19685         sw_if_index_set = 1;
19686       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19687         ;
19688       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19689         ;
19690       else
19691         break;
19692     }
19693   if (!ns_id || !secret_set || !sw_if_index_set)
19694     {
19695       errmsg ("namespace id, secret and sw_if_index must be set");
19696       return -99;
19697     }
19698   if (vec_len (ns_id) > 64)
19699     {
19700       errmsg ("namespace id too long");
19701       return -99;
19702     }
19703   M (APP_NAMESPACE_ADD_DEL, mp);
19704
19705   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19706   mp->namespace_id_len = vec_len (ns_id);
19707   mp->secret = clib_host_to_net_u64 (secret);
19708   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19709   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19710   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19711   vec_free (ns_id);
19712   S (mp);
19713   W (ret);
19714   return ret;
19715 }
19716
19717 static int
19718 api_sock_init_shm (vat_main_t * vam)
19719 {
19720 #if VPP_API_TEST_BUILTIN == 0
19721   unformat_input_t *i = vam->input;
19722   vl_api_shm_elem_config_t *config = 0;
19723   u64 size = 64 << 20;
19724   int rv;
19725
19726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19727     {
19728       if (unformat (i, "size %U", unformat_memory_size, &size))
19729         ;
19730       else
19731         break;
19732     }
19733
19734   /*
19735    * Canned custom ring allocator config.
19736    * Should probably parse all of this
19737    */
19738   vec_validate (config, 6);
19739   config[0].type = VL_API_VLIB_RING;
19740   config[0].size = 256;
19741   config[0].count = 32;
19742
19743   config[1].type = VL_API_VLIB_RING;
19744   config[1].size = 1024;
19745   config[1].count = 16;
19746
19747   config[2].type = VL_API_VLIB_RING;
19748   config[2].size = 4096;
19749   config[2].count = 2;
19750
19751   config[3].type = VL_API_CLIENT_RING;
19752   config[3].size = 256;
19753   config[3].count = 32;
19754
19755   config[4].type = VL_API_CLIENT_RING;
19756   config[4].size = 1024;
19757   config[4].count = 16;
19758
19759   config[5].type = VL_API_CLIENT_RING;
19760   config[5].size = 4096;
19761   config[5].count = 2;
19762
19763   config[6].type = VL_API_QUEUE;
19764   config[6].count = 128;
19765   config[6].size = sizeof (uword);
19766
19767   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19768   if (!rv)
19769     vam->client_index_invalid = 1;
19770   return rv;
19771 #else
19772   return -99;
19773 #endif
19774 }
19775
19776 static void
19777 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19778 {
19779   vat_main_t *vam = &vat_main;
19780
19781   if (mp->is_ip4)
19782     {
19783       print (vam->ofp,
19784              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19785              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19786              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19787              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19788              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19789              clib_net_to_host_u32 (mp->action_index), mp->tag);
19790     }
19791   else
19792     {
19793       print (vam->ofp,
19794              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19795              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19796              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19797              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19798              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19799              clib_net_to_host_u32 (mp->action_index), mp->tag);
19800     }
19801 }
19802
19803 static void
19804 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19805                                              mp)
19806 {
19807   vat_main_t *vam = &vat_main;
19808   vat_json_node_t *node = NULL;
19809   struct in6_addr ip6;
19810   struct in_addr ip4;
19811
19812   if (VAT_JSON_ARRAY != vam->json_tree.type)
19813     {
19814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19815       vat_json_init_array (&vam->json_tree);
19816     }
19817   node = vat_json_array_add (&vam->json_tree);
19818   vat_json_init_object (node);
19819
19820   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19821   vat_json_object_add_uint (node, "appns_index",
19822                             clib_net_to_host_u32 (mp->appns_index));
19823   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19824   vat_json_object_add_uint (node, "scope", mp->scope);
19825   vat_json_object_add_uint (node, "action_index",
19826                             clib_net_to_host_u32 (mp->action_index));
19827   vat_json_object_add_uint (node, "lcl_port",
19828                             clib_net_to_host_u16 (mp->lcl_port));
19829   vat_json_object_add_uint (node, "rmt_port",
19830                             clib_net_to_host_u16 (mp->rmt_port));
19831   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19832   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19833   vat_json_object_add_string_copy (node, "tag", mp->tag);
19834   if (mp->is_ip4)
19835     {
19836       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19837       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19838       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19839       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19840     }
19841   else
19842     {
19843       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19844       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19845       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19846       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19847     }
19848 }
19849
19850 static int
19851 api_session_rule_add_del (vat_main_t * vam)
19852 {
19853   vl_api_session_rule_add_del_t *mp;
19854   unformat_input_t *i = vam->input;
19855   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19856   u32 appns_index = 0, scope = 0;
19857   ip4_address_t lcl_ip4, rmt_ip4;
19858   ip6_address_t lcl_ip6, rmt_ip6;
19859   u8 is_ip4 = 1, conn_set = 0;
19860   u8 is_add = 1, *tag = 0;
19861   int ret;
19862
19863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19864     {
19865       if (unformat (i, "del"))
19866         is_add = 0;
19867       else if (unformat (i, "add"))
19868         ;
19869       else if (unformat (i, "proto tcp"))
19870         proto = 0;
19871       else if (unformat (i, "proto udp"))
19872         proto = 1;
19873       else if (unformat (i, "appns %d", &appns_index))
19874         ;
19875       else if (unformat (i, "scope %d", &scope))
19876         ;
19877       else if (unformat (i, "tag %_%v%_", &tag))
19878         ;
19879       else
19880         if (unformat
19881             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19882              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19883              &rmt_port))
19884         {
19885           is_ip4 = 1;
19886           conn_set = 1;
19887         }
19888       else
19889         if (unformat
19890             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19891              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19892              &rmt_port))
19893         {
19894           is_ip4 = 0;
19895           conn_set = 1;
19896         }
19897       else if (unformat (i, "action %d", &action))
19898         ;
19899       else
19900         break;
19901     }
19902   if (proto == ~0 || !conn_set || action == ~0)
19903     {
19904       errmsg ("transport proto, connection and action must be set");
19905       return -99;
19906     }
19907
19908   if (scope > 3)
19909     {
19910       errmsg ("scope should be 0-3");
19911       return -99;
19912     }
19913
19914   M (SESSION_RULE_ADD_DEL, mp);
19915
19916   mp->is_ip4 = is_ip4;
19917   mp->transport_proto = proto;
19918   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19919   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19920   mp->lcl_plen = lcl_plen;
19921   mp->rmt_plen = rmt_plen;
19922   mp->action_index = clib_host_to_net_u32 (action);
19923   mp->appns_index = clib_host_to_net_u32 (appns_index);
19924   mp->scope = scope;
19925   mp->is_add = is_add;
19926   if (is_ip4)
19927     {
19928       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
19929       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
19930     }
19931   else
19932     {
19933       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
19934       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
19935     }
19936   if (tag)
19937     {
19938       clib_memcpy (mp->tag, tag, vec_len (tag));
19939       vec_free (tag);
19940     }
19941
19942   S (mp);
19943   W (ret);
19944   return ret;
19945 }
19946
19947 static int
19948 api_session_rules_dump (vat_main_t * vam)
19949 {
19950   vl_api_session_rules_dump_t *mp;
19951   vl_api_control_ping_t *mp_ping;
19952   int ret;
19953
19954   if (!vam->json_output)
19955     {
19956       print (vam->ofp, "%=20s", "Session Rules");
19957     }
19958
19959   M (SESSION_RULES_DUMP, mp);
19960   /* send it... */
19961   S (mp);
19962
19963   /* Use a control ping for synchronization */
19964   MPING (CONTROL_PING, mp_ping);
19965   S (mp_ping);
19966
19967   /* Wait for a reply... */
19968   W (ret);
19969   return ret;
19970 }
19971
19972 static int
19973 api_ip_container_proxy_add_del (vat_main_t * vam)
19974 {
19975   vl_api_ip_container_proxy_add_del_t *mp;
19976   unformat_input_t *i = vam->input;
19977   u32 sw_if_index = ~0;
19978   vl_api_prefix_t pfx = { };
19979   u8 is_add = 1;
19980   int ret;
19981
19982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19983     {
19984       if (unformat (i, "del"))
19985         is_add = 0;
19986       else if (unformat (i, "add"))
19987         ;
19988       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19989         ;
19990       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19991         ;
19992       else
19993         break;
19994     }
19995   if (sw_if_index == ~0 || pfx.len == 0)
19996     {
19997       errmsg ("address and sw_if_index must be set");
19998       return -99;
19999     }
20000
20001   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20002
20003   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20004   mp->is_add = is_add;
20005   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20006
20007   S (mp);
20008   W (ret);
20009   return ret;
20010 }
20011
20012 static int
20013 api_qos_record_enable_disable (vat_main_t * vam)
20014 {
20015   unformat_input_t *i = vam->input;
20016   vl_api_qos_record_enable_disable_t *mp;
20017   u32 sw_if_index, qs = 0xff;
20018   u8 sw_if_index_set = 0;
20019   u8 enable = 1;
20020   int ret;
20021
20022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20023     {
20024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20025         sw_if_index_set = 1;
20026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20027         sw_if_index_set = 1;
20028       else if (unformat (i, "%U", unformat_qos_source, &qs))
20029         ;
20030       else if (unformat (i, "disable"))
20031         enable = 0;
20032       else
20033         {
20034           clib_warning ("parse error '%U'", format_unformat_error, i);
20035           return -99;
20036         }
20037     }
20038
20039   if (sw_if_index_set == 0)
20040     {
20041       errmsg ("missing interface name or sw_if_index");
20042       return -99;
20043     }
20044   if (qs == 0xff)
20045     {
20046       errmsg ("input location must be specified");
20047       return -99;
20048     }
20049
20050   M (QOS_RECORD_ENABLE_DISABLE, mp);
20051
20052   mp->record.sw_if_index = ntohl (sw_if_index);
20053   mp->record.input_source = qs;
20054   mp->enable = enable;
20055
20056   S (mp);
20057   W (ret);
20058   return ret;
20059 }
20060
20061
20062 static int
20063 q_or_quit (vat_main_t * vam)
20064 {
20065 #if VPP_API_TEST_BUILTIN == 0
20066   longjmp (vam->jump_buf, 1);
20067 #endif
20068   return 0;                     /* not so much */
20069 }
20070
20071 static int
20072 q (vat_main_t * vam)
20073 {
20074   return q_or_quit (vam);
20075 }
20076
20077 static int
20078 quit (vat_main_t * vam)
20079 {
20080   return q_or_quit (vam);
20081 }
20082
20083 static int
20084 comment (vat_main_t * vam)
20085 {
20086   return 0;
20087 }
20088
20089 static int
20090 elog_save (vat_main_t * vam)
20091 {
20092 #if VPP_API_TEST_BUILTIN == 0
20093   elog_main_t *em = &vam->elog_main;
20094   unformat_input_t *i = vam->input;
20095   char *file, *chroot_file;
20096   clib_error_t *error;
20097
20098   if (!unformat (i, "%s", &file))
20099     {
20100       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20101       return 0;
20102     }
20103
20104   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20105   if (strstr (file, "..") || index (file, '/'))
20106     {
20107       errmsg ("illegal characters in filename '%s'", file);
20108       return 0;
20109     }
20110
20111   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20112
20113   vec_free (file);
20114
20115   errmsg ("Saving %wd of %wd events to %s",
20116           elog_n_events_in_buffer (em),
20117           elog_buffer_capacity (em), chroot_file);
20118
20119   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20120   vec_free (chroot_file);
20121
20122   if (error)
20123     clib_error_report (error);
20124 #else
20125   errmsg ("Use the vpp event loger...");
20126 #endif
20127
20128   return 0;
20129 }
20130
20131 static int
20132 elog_setup (vat_main_t * vam)
20133 {
20134 #if VPP_API_TEST_BUILTIN == 0
20135   elog_main_t *em = &vam->elog_main;
20136   unformat_input_t *i = vam->input;
20137   u32 nevents = 128 << 10;
20138
20139   (void) unformat (i, "nevents %d", &nevents);
20140
20141   elog_init (em, nevents);
20142   vl_api_set_elog_main (em);
20143   vl_api_set_elog_trace_api_messages (1);
20144   errmsg ("Event logger initialized with %u events", nevents);
20145 #else
20146   errmsg ("Use the vpp event loger...");
20147 #endif
20148   return 0;
20149 }
20150
20151 static int
20152 elog_enable (vat_main_t * vam)
20153 {
20154 #if VPP_API_TEST_BUILTIN == 0
20155   elog_main_t *em = &vam->elog_main;
20156
20157   elog_enable_disable (em, 1 /* enable */ );
20158   vl_api_set_elog_trace_api_messages (1);
20159   errmsg ("Event logger enabled...");
20160 #else
20161   errmsg ("Use the vpp event loger...");
20162 #endif
20163   return 0;
20164 }
20165
20166 static int
20167 elog_disable (vat_main_t * vam)
20168 {
20169 #if VPP_API_TEST_BUILTIN == 0
20170   elog_main_t *em = &vam->elog_main;
20171
20172   elog_enable_disable (em, 0 /* enable */ );
20173   vl_api_set_elog_trace_api_messages (1);
20174   errmsg ("Event logger disabled...");
20175 #else
20176   errmsg ("Use the vpp event loger...");
20177 #endif
20178   return 0;
20179 }
20180
20181 static int
20182 statseg (vat_main_t * vam)
20183 {
20184   ssvm_private_t *ssvmp = &vam->stat_segment;
20185   ssvm_shared_header_t *shared_header = ssvmp->sh;
20186   vlib_counter_t **counters;
20187   u64 thread0_index1_packets;
20188   u64 thread0_index1_bytes;
20189   f64 vector_rate, input_rate;
20190   uword *p;
20191
20192   uword *counter_vector_by_name;
20193   if (vam->stat_segment_lockp == 0)
20194     {
20195       errmsg ("Stat segment not mapped...");
20196       return -99;
20197     }
20198
20199   /* look up "/if/rx for sw_if_index 1 as a test */
20200
20201   clib_spinlock_lock (vam->stat_segment_lockp);
20202
20203   counter_vector_by_name = (uword *) shared_header->opaque[1];
20204
20205   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20206   if (p == 0)
20207     {
20208       clib_spinlock_unlock (vam->stat_segment_lockp);
20209       errmsg ("/if/tx not found?");
20210       return -99;
20211     }
20212
20213   /* Fish per-thread vector of combined counters from shared memory */
20214   counters = (vlib_counter_t **) p[0];
20215
20216   if (vec_len (counters[0]) < 2)
20217     {
20218       clib_spinlock_unlock (vam->stat_segment_lockp);
20219       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20220       return -99;
20221     }
20222
20223   /* Read thread 0 sw_if_index 1 counter */
20224   thread0_index1_packets = counters[0][1].packets;
20225   thread0_index1_bytes = counters[0][1].bytes;
20226
20227   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20228   if (p == 0)
20229     {
20230       clib_spinlock_unlock (vam->stat_segment_lockp);
20231       errmsg ("vector_rate not found?");
20232       return -99;
20233     }
20234
20235   vector_rate = *(f64 *) (p[0]);
20236   p = hash_get_mem (counter_vector_by_name, "input_rate");
20237   if (p == 0)
20238     {
20239       clib_spinlock_unlock (vam->stat_segment_lockp);
20240       errmsg ("input_rate not found?");
20241       return -99;
20242     }
20243   input_rate = *(f64 *) (p[0]);
20244
20245   clib_spinlock_unlock (vam->stat_segment_lockp);
20246
20247   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20248          vector_rate, input_rate);
20249   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20250          thread0_index1_packets, thread0_index1_bytes);
20251
20252   return 0;
20253 }
20254
20255 static int
20256 cmd_cmp (void *a1, void *a2)
20257 {
20258   u8 **c1 = a1;
20259   u8 **c2 = a2;
20260
20261   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20262 }
20263
20264 static int
20265 help (vat_main_t * vam)
20266 {
20267   u8 **cmds = 0;
20268   u8 *name = 0;
20269   hash_pair_t *p;
20270   unformat_input_t *i = vam->input;
20271   int j;
20272
20273   if (unformat (i, "%s", &name))
20274     {
20275       uword *hs;
20276
20277       vec_add1 (name, 0);
20278
20279       hs = hash_get_mem (vam->help_by_name, name);
20280       if (hs)
20281         print (vam->ofp, "usage: %s %s", name, hs[0]);
20282       else
20283         print (vam->ofp, "No such msg / command '%s'", name);
20284       vec_free (name);
20285       return 0;
20286     }
20287
20288   print (vam->ofp, "Help is available for the following:");
20289
20290     /* *INDENT-OFF* */
20291     hash_foreach_pair (p, vam->function_by_name,
20292     ({
20293       vec_add1 (cmds, (u8 *)(p->key));
20294     }));
20295     /* *INDENT-ON* */
20296
20297   vec_sort_with_function (cmds, cmd_cmp);
20298
20299   for (j = 0; j < vec_len (cmds); j++)
20300     print (vam->ofp, "%s", cmds[j]);
20301
20302   vec_free (cmds);
20303   return 0;
20304 }
20305
20306 static int
20307 set (vat_main_t * vam)
20308 {
20309   u8 *name = 0, *value = 0;
20310   unformat_input_t *i = vam->input;
20311
20312   if (unformat (i, "%s", &name))
20313     {
20314       /* The input buffer is a vector, not a string. */
20315       value = vec_dup (i->buffer);
20316       vec_delete (value, i->index, 0);
20317       /* Almost certainly has a trailing newline */
20318       if (value[vec_len (value) - 1] == '\n')
20319         value[vec_len (value) - 1] = 0;
20320       /* Make sure it's a proper string, one way or the other */
20321       vec_add1 (value, 0);
20322       (void) clib_macro_set_value (&vam->macro_main,
20323                                    (char *) name, (char *) value);
20324     }
20325   else
20326     errmsg ("usage: set <name> <value>");
20327
20328   vec_free (name);
20329   vec_free (value);
20330   return 0;
20331 }
20332
20333 static int
20334 unset (vat_main_t * vam)
20335 {
20336   u8 *name = 0;
20337
20338   if (unformat (vam->input, "%s", &name))
20339     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20340       errmsg ("unset: %s wasn't set", name);
20341   vec_free (name);
20342   return 0;
20343 }
20344
20345 typedef struct
20346 {
20347   u8 *name;
20348   u8 *value;
20349 } macro_sort_t;
20350
20351
20352 static int
20353 macro_sort_cmp (void *a1, void *a2)
20354 {
20355   macro_sort_t *s1 = a1;
20356   macro_sort_t *s2 = a2;
20357
20358   return strcmp ((char *) (s1->name), (char *) (s2->name));
20359 }
20360
20361 static int
20362 dump_macro_table (vat_main_t * vam)
20363 {
20364   macro_sort_t *sort_me = 0, *sm;
20365   int i;
20366   hash_pair_t *p;
20367
20368     /* *INDENT-OFF* */
20369     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20370     ({
20371       vec_add2 (sort_me, sm, 1);
20372       sm->name = (u8 *)(p->key);
20373       sm->value = (u8 *) (p->value[0]);
20374     }));
20375     /* *INDENT-ON* */
20376
20377   vec_sort_with_function (sort_me, macro_sort_cmp);
20378
20379   if (vec_len (sort_me))
20380     print (vam->ofp, "%-15s%s", "Name", "Value");
20381   else
20382     print (vam->ofp, "The macro table is empty...");
20383
20384   for (i = 0; i < vec_len (sort_me); i++)
20385     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20386   return 0;
20387 }
20388
20389 static int
20390 dump_node_table (vat_main_t * vam)
20391 {
20392   int i, j;
20393   vlib_node_t *node, *next_node;
20394
20395   if (vec_len (vam->graph_nodes) == 0)
20396     {
20397       print (vam->ofp, "Node table empty, issue get_node_graph...");
20398       return 0;
20399     }
20400
20401   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20402     {
20403       node = vam->graph_nodes[0][i];
20404       print (vam->ofp, "[%d] %s", i, node->name);
20405       for (j = 0; j < vec_len (node->next_nodes); j++)
20406         {
20407           if (node->next_nodes[j] != ~0)
20408             {
20409               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20410               print (vam->ofp, "  [%d] %s", j, next_node->name);
20411             }
20412         }
20413     }
20414   return 0;
20415 }
20416
20417 static int
20418 value_sort_cmp (void *a1, void *a2)
20419 {
20420   name_sort_t *n1 = a1;
20421   name_sort_t *n2 = a2;
20422
20423   if (n1->value < n2->value)
20424     return -1;
20425   if (n1->value > n2->value)
20426     return 1;
20427   return 0;
20428 }
20429
20430
20431 static int
20432 dump_msg_api_table (vat_main_t * vam)
20433 {
20434   api_main_t *am = vlibapi_get_main ();
20435   name_sort_t *nses = 0, *ns;
20436   hash_pair_t *hp;
20437   int i;
20438
20439   /* *INDENT-OFF* */
20440   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20441   ({
20442     vec_add2 (nses, ns, 1);
20443     ns->name = (u8 *)(hp->key);
20444     ns->value = (u32) hp->value[0];
20445   }));
20446   /* *INDENT-ON* */
20447
20448   vec_sort_with_function (nses, value_sort_cmp);
20449
20450   for (i = 0; i < vec_len (nses); i++)
20451     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20452   vec_free (nses);
20453   return 0;
20454 }
20455
20456 static int
20457 get_msg_id (vat_main_t * vam)
20458 {
20459   u8 *name_and_crc;
20460   u32 message_index;
20461
20462   if (unformat (vam->input, "%s", &name_and_crc))
20463     {
20464       message_index = vl_msg_api_get_msg_index (name_and_crc);
20465       if (message_index == ~0)
20466         {
20467           print (vam->ofp, " '%s' not found", name_and_crc);
20468           return 0;
20469         }
20470       print (vam->ofp, " '%s' has message index %d",
20471              name_and_crc, message_index);
20472       return 0;
20473     }
20474   errmsg ("name_and_crc required...");
20475   return 0;
20476 }
20477
20478 static int
20479 search_node_table (vat_main_t * vam)
20480 {
20481   unformat_input_t *line_input = vam->input;
20482   u8 *node_to_find;
20483   int j;
20484   vlib_node_t *node, *next_node;
20485   uword *p;
20486
20487   if (vam->graph_node_index_by_name == 0)
20488     {
20489       print (vam->ofp, "Node table empty, issue get_node_graph...");
20490       return 0;
20491     }
20492
20493   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20494     {
20495       if (unformat (line_input, "%s", &node_to_find))
20496         {
20497           vec_add1 (node_to_find, 0);
20498           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20499           if (p == 0)
20500             {
20501               print (vam->ofp, "%s not found...", node_to_find);
20502               goto out;
20503             }
20504           node = vam->graph_nodes[0][p[0]];
20505           print (vam->ofp, "[%d] %s", p[0], node->name);
20506           for (j = 0; j < vec_len (node->next_nodes); j++)
20507             {
20508               if (node->next_nodes[j] != ~0)
20509                 {
20510                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20511                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20512                 }
20513             }
20514         }
20515
20516       else
20517         {
20518           clib_warning ("parse error '%U'", format_unformat_error,
20519                         line_input);
20520           return -99;
20521         }
20522
20523     out:
20524       vec_free (node_to_find);
20525
20526     }
20527
20528   return 0;
20529 }
20530
20531
20532 static int
20533 script (vat_main_t * vam)
20534 {
20535 #if (VPP_API_TEST_BUILTIN==0)
20536   u8 *s = 0;
20537   char *save_current_file;
20538   unformat_input_t save_input;
20539   jmp_buf save_jump_buf;
20540   u32 save_line_number;
20541
20542   FILE *new_fp, *save_ifp;
20543
20544   if (unformat (vam->input, "%s", &s))
20545     {
20546       new_fp = fopen ((char *) s, "r");
20547       if (new_fp == 0)
20548         {
20549           errmsg ("Couldn't open script file %s", s);
20550           vec_free (s);
20551           return -99;
20552         }
20553     }
20554   else
20555     {
20556       errmsg ("Missing script name");
20557       return -99;
20558     }
20559
20560   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20561   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20562   save_ifp = vam->ifp;
20563   save_line_number = vam->input_line_number;
20564   save_current_file = (char *) vam->current_file;
20565
20566   vam->input_line_number = 0;
20567   vam->ifp = new_fp;
20568   vam->current_file = s;
20569   do_one_file (vam);
20570
20571   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20572   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20573   vam->ifp = save_ifp;
20574   vam->input_line_number = save_line_number;
20575   vam->current_file = (u8 *) save_current_file;
20576   vec_free (s);
20577
20578   return 0;
20579 #else
20580   clib_warning ("use the exec command...");
20581   return -99;
20582 #endif
20583 }
20584
20585 static int
20586 echo (vat_main_t * vam)
20587 {
20588   print (vam->ofp, "%v", vam->input->buffer);
20589   return 0;
20590 }
20591
20592 /* List of API message constructors, CLI names map to api_xxx */
20593 #define foreach_vpe_api_msg                                             \
20594 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20595 _(sw_interface_dump,"")                                                 \
20596 _(sw_interface_set_flags,                                               \
20597   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20598 _(sw_interface_add_del_address,                                         \
20599   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20600 _(sw_interface_set_rx_mode,                                             \
20601   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20602 _(sw_interface_set_rx_placement,                                        \
20603   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20604 _(sw_interface_rx_placement_dump,                                       \
20605   "[<intfc> | sw_if_index <id>]")                                         \
20606 _(sw_interface_set_table,                                               \
20607   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20608 _(sw_interface_set_mpls_enable,                                         \
20609   "<intfc> | sw_if_index [disable | dis]")                              \
20610 _(sw_interface_set_vpath,                                               \
20611   "<intfc> | sw_if_index <id> enable | disable")                        \
20612 _(sw_interface_set_vxlan_bypass,                                        \
20613   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20614 _(sw_interface_set_geneve_bypass,                                       \
20615   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20616 _(sw_interface_set_l2_xconnect,                                         \
20617   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20618   "enable | disable")                                                   \
20619 _(sw_interface_set_l2_bridge,                                           \
20620   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20621   "[shg <split-horizon-group>] [bvi]\n"                                 \
20622   "enable | disable")                                                   \
20623 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20624 _(bridge_domain_add_del,                                                \
20625   "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") \
20626 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20627 _(l2fib_add_del,                                                        \
20628   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20629 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20630 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20631 _(l2_flags,                                                             \
20632   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20633 _(bridge_flags,                                                         \
20634   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20635 _(tap_create_v2,                                                        \
20636   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload]") \
20637 _(tap_delete_v2,                                                        \
20638   "<vpp-if-name> | sw_if_index <id>")                                   \
20639 _(sw_interface_tap_v2_dump, "")                                         \
20640 _(virtio_pci_create,                                                    \
20641   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20642 _(virtio_pci_delete,                                                    \
20643   "<vpp-if-name> | sw_if_index <id>")                                   \
20644 _(sw_interface_virtio_pci_dump, "")                                     \
20645 _(bond_create,                                                          \
20646   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20647   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20648   "[id <if-id>]")                                                       \
20649 _(bond_delete,                                                          \
20650   "<vpp-if-name> | sw_if_index <id>")                                   \
20651 _(bond_enslave,                                                         \
20652   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20653 _(bond_detach_slave,                                                    \
20654   "sw_if_index <n>")                                                    \
20655  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20656 _(sw_interface_bond_dump, "")                                           \
20657 _(sw_interface_slave_dump,                                              \
20658   "<vpp-if-name> | sw_if_index <id>")                                   \
20659 _(ip_table_add_del,                                                     \
20660   "table <n> [ipv6] [add | del]\n")                                     \
20661 _(ip_route_add_del,                                                     \
20662   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20663   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20664   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20665   "[multipath] [count <n>] [del]")                                      \
20666 _(ip_mroute_add_del,                                                    \
20667   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20668   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20669 _(mpls_table_add_del,                                                   \
20670   "table <n> [add | del]\n")                                            \
20671 _(mpls_route_add_del,                                                   \
20672   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20673   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20674   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20675   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20676   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20677   "[count <n>] [del]")                                                  \
20678 _(mpls_ip_bind_unbind,                                                  \
20679   "<label> <addr/len>")                                                 \
20680 _(mpls_tunnel_add_del,                                                  \
20681   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20682   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20683   "[l2-only]  [out-label <n>]")                                         \
20684 _(sr_mpls_policy_add,                                                   \
20685   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20686 _(sr_mpls_policy_del,                                                   \
20687   "bsid <id>")                                                          \
20688 _(bier_table_add_del,                                                   \
20689   "<label> <sub-domain> <set> <bsl> [del]")                             \
20690 _(bier_route_add_del,                                                   \
20691   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20692   "[<intfc> | sw_if_index <id>]"                                        \
20693   "[weight <n>] [del] [multipath]")                                     \
20694 _(sw_interface_set_unnumbered,                                          \
20695   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20696 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20697 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20698   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20699   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20700   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20701 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20702 _(ip_table_flush, "table <n> [ipv6]")                                   \
20703 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20704 _(set_ip_flow_hash,                                                     \
20705   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20706 _(sw_interface_ip6_enable_disable,                                      \
20707   "<intfc> | sw_if_index <id> enable | disable")                        \
20708 _(l2_patch_add_del,                                                     \
20709   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20710   "enable | disable")                                                   \
20711 _(sr_localsid_add_del,                                                  \
20712   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20713   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20714 _(classify_add_del_table,                                               \
20715   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20716   " [del] [del-chain] mask <mask-value>\n"                              \
20717   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20718   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20719 _(classify_add_del_session,                                             \
20720   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20721   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20722   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20723   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20724 _(classify_set_interface_ip_table,                                      \
20725   "<intfc> | sw_if_index <nn> table <nn>")                              \
20726 _(classify_set_interface_l2_tables,                                     \
20727   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20728   "  [other-table <nn>]")                                               \
20729 _(get_node_index, "node <node-name")                                    \
20730 _(add_node_next, "node <node-name> next <next-node-name>")              \
20731 _(l2tpv3_create_tunnel,                                                 \
20732   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20733   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20734   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20735 _(l2tpv3_set_tunnel_cookies,                                            \
20736   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20737   "[new_remote_cookie <nn>]\n")                                         \
20738 _(l2tpv3_interface_enable_disable,                                      \
20739   "<intfc> | sw_if_index <nn> enable | disable")                        \
20740 _(l2tpv3_set_lookup_key,                                                \
20741   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20742 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20743 _(vxlan_offload_rx,                                                     \
20744   "hw { <interface name> | hw_if_index <nn>} "                          \
20745   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20746 _(vxlan_add_del_tunnel,                                                 \
20747   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20748   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20749   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20750 _(geneve_add_del_tunnel,                                                \
20751   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20752   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20753   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20754 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20755 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20756 _(gre_tunnel_add_del,                                                   \
20757   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20758   "[teb | erspan <session-id>] [del]")                                  \
20759 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20760 _(l2_fib_clear_table, "")                                               \
20761 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20762 _(l2_interface_vlan_tag_rewrite,                                        \
20763   "<intfc> | sw_if_index <nn> \n"                                       \
20764   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20765   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20766 _(create_vhost_user_if,                                                 \
20767         "socket <filename> [server] [renumber <dev_instance>] "         \
20768         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20769         "[mac <mac_address>]")                                          \
20770 _(modify_vhost_user_if,                                                 \
20771         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20772         "[server] [renumber <dev_instance>] [gso]")                     \
20773 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20774 _(sw_interface_vhost_user_dump, "")                                     \
20775 _(show_version, "")                                                     \
20776 _(show_threads, "")                                                     \
20777 _(vxlan_gpe_add_del_tunnel,                                             \
20778   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20779   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20780   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20781   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20782 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20783 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20784 _(interface_name_renumber,                                              \
20785   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20786 _(input_acl_set_interface,                                              \
20787   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20788   "  [l2-table <nn>] [del]")                                            \
20789 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20790 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20791 _(ip_dump, "ipv4 | ipv6")                                               \
20792 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20793 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20794   "  spid_id <n> ")                                                     \
20795 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20796   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20797   "  integ_alg <alg> integ_key <hex>")                                  \
20798 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20799   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20800   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20801   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20802 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20803   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20804   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20805   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20806   "  [instance <n>]")     \
20807 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20808 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20809 _(delete_loopback,"sw_if_index <nn>")                                   \
20810 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20811 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20812 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20813 _(want_interface_events,  "enable|disable")                             \
20814 _(get_first_msg_id, "client <name>")                                    \
20815 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20816 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20817   "fib-id <nn> [ip4][ip6][default]")                                    \
20818 _(get_node_graph, " ")                                                  \
20819 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20820 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20821 _(ioam_disable, "")                                                     \
20822 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20823                             " sw_if_index <sw_if_index> p <priority> "  \
20824                             "w <weight>] [del]")                        \
20825 _(one_add_del_locator, "locator-set <locator_name> "                    \
20826                         "iface <intf> | sw_if_index <sw_if_index> "     \
20827                         "p <priority> w <weight> [del]")                \
20828 _(one_add_del_local_eid,"vni <vni> eid "                                \
20829                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20830                          "locator-set <locator_name> [del]"             \
20831                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20832 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20833 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20834 _(one_enable_disable, "enable|disable")                                 \
20835 _(one_map_register_enable_disable, "enable|disable")                    \
20836 _(one_map_register_fallback_threshold, "<value>")                       \
20837 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20838 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20839                                "[seid <seid>] "                         \
20840                                "rloc <locator> p <prio> "               \
20841                                "w <weight> [rloc <loc> ... ] "          \
20842                                "action <action> [del-all]")             \
20843 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20844                           "<local-eid>")                                \
20845 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20846 _(one_use_petr, "ip-address> | disable")                                \
20847 _(one_map_request_mode, "src-dst|dst-only")                             \
20848 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20849 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20850 _(one_locator_set_dump, "[local | remote]")                             \
20851 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20852 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20853                        "[local] | [remote]")                            \
20854 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20855 _(one_ndp_bd_get, "")                                                   \
20856 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20857 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20858 _(one_l2_arp_bd_get, "")                                                \
20859 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20860 _(one_stats_enable_disable, "enable|disable")                           \
20861 _(show_one_stats_enable_disable, "")                                    \
20862 _(one_eid_table_vni_dump, "")                                           \
20863 _(one_eid_table_map_dump, "l2|l3")                                      \
20864 _(one_map_resolver_dump, "")                                            \
20865 _(one_map_server_dump, "")                                              \
20866 _(one_adjacencies_get, "vni <vni>")                                     \
20867 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20868 _(show_one_rloc_probe_state, "")                                        \
20869 _(show_one_map_register_state, "")                                      \
20870 _(show_one_status, "")                                                  \
20871 _(one_stats_dump, "")                                                   \
20872 _(one_stats_flush, "")                                                  \
20873 _(one_get_map_request_itr_rlocs, "")                                    \
20874 _(one_map_register_set_ttl, "<ttl>")                                    \
20875 _(one_set_transport_protocol, "udp|api")                                \
20876 _(one_get_transport_protocol, "")                                       \
20877 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20878 _(one_show_xtr_mode, "")                                                \
20879 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20880 _(one_show_pitr_mode, "")                                               \
20881 _(one_enable_disable_petr_mode, "enable|disable")                       \
20882 _(one_show_petr_mode, "")                                               \
20883 _(show_one_nsh_mapping, "")                                             \
20884 _(show_one_pitr, "")                                                    \
20885 _(show_one_use_petr, "")                                                \
20886 _(show_one_map_request_mode, "")                                        \
20887 _(show_one_map_register_ttl, "")                                        \
20888 _(show_one_map_register_fallback_threshold, "")                         \
20889 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20890                             " sw_if_index <sw_if_index> p <priority> "  \
20891                             "w <weight>] [del]")                        \
20892 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20893                         "iface <intf> | sw_if_index <sw_if_index> "     \
20894                         "p <priority> w <weight> [del]")                \
20895 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20896                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20897                          "locator-set <locator_name> [del]"             \
20898                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20899 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20900 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20901 _(lisp_enable_disable, "enable|disable")                                \
20902 _(lisp_map_register_enable_disable, "enable|disable")                   \
20903 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20904 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20905                                "[seid <seid>] "                         \
20906                                "rloc <locator> p <prio> "               \
20907                                "w <weight> [rloc <loc> ... ] "          \
20908                                "action <action> [del-all]")             \
20909 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20910                           "<local-eid>")                                \
20911 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20912 _(lisp_use_petr, "<ip-address> | disable")                              \
20913 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20914 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20915 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20916 _(lisp_locator_set_dump, "[local | remote]")                            \
20917 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20918 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20919                        "[local] | [remote]")                            \
20920 _(lisp_eid_table_vni_dump, "")                                          \
20921 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20922 _(lisp_map_resolver_dump, "")                                           \
20923 _(lisp_map_server_dump, "")                                             \
20924 _(lisp_adjacencies_get, "vni <vni>")                                    \
20925 _(gpe_fwd_entry_vnis_get, "")                                           \
20926 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20927 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20928                                 "[table <table-id>]")                   \
20929 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20930 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20931 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20932 _(gpe_get_encap_mode, "")                                               \
20933 _(lisp_gpe_add_del_iface, "up|down")                                    \
20934 _(lisp_gpe_enable_disable, "enable|disable")                            \
20935 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20936   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20937 _(show_lisp_rloc_probe_state, "")                                       \
20938 _(show_lisp_map_register_state, "")                                     \
20939 _(show_lisp_status, "")                                                 \
20940 _(lisp_get_map_request_itr_rlocs, "")                                   \
20941 _(show_lisp_pitr, "")                                                   \
20942 _(show_lisp_use_petr, "")                                               \
20943 _(show_lisp_map_request_mode, "")                                       \
20944 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20945 _(af_packet_delete, "name <host interface name>")                       \
20946 _(af_packet_dump, "")                                                   \
20947 _(policer_add_del, "name <policer name> <params> [del]")                \
20948 _(policer_dump, "[name <policer name>]")                                \
20949 _(policer_classify_set_interface,                                       \
20950   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20951   "  [l2-table <nn>] [del]")                                            \
20952 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20953 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20954 _(mpls_table_dump, "")                                                  \
20955 _(mpls_route_dump, "table-id <ID>")                                     \
20956 _(classify_table_ids, "")                                               \
20957 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20958 _(classify_table_info, "table_id <nn>")                                 \
20959 _(classify_session_dump, "table_id <nn>")                               \
20960 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20961     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20962     "[template_interval <nn>] [udp_checksum]")                          \
20963 _(ipfix_exporter_dump, "")                                              \
20964 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20965 _(ipfix_classify_stream_dump, "")                                       \
20966 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20967 _(ipfix_classify_table_dump, "")                                        \
20968 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20969 _(sw_interface_span_dump, "[l2]")                                           \
20970 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20971 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20972 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20973 _(pg_enable_disable, "[stream <id>] disable")                           \
20974 _(ip_source_and_port_range_check_add_del,                               \
20975   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20976 _(ip_source_and_port_range_check_interface_add_del,                     \
20977   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20978   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20979 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20980 _(l2_interface_pbb_tag_rewrite,                                         \
20981   "<intfc> | sw_if_index <nn> \n"                                       \
20982   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20983   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20984 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20985 _(flow_classify_set_interface,                                          \
20986   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20987 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20988 _(ip_table_dump, "")                                                    \
20989 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20990 _(ip_mtable_dump, "")                                                   \
20991 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20992 _(feature_enable_disable, "arc_name <arc_name> "                        \
20993   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20994 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20995   "[enable | disable] ")                                                \
20996 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20997 "[disable]")                                                            \
20998 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20999   "mac <mac-address> [del]")                                            \
21000 _(l2_xconnect_dump, "")                                                 \
21001 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21002 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21003 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21004 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21005 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21006 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21007   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21008 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21009 _(sock_init_shm, "size <nnn>")                                          \
21010 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21011 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21012   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21013 _(session_rules_dump, "")                                               \
21014 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21015 _(output_acl_set_interface,                                             \
21016   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21017   "  [l2-table <nn>] [del]")                                            \
21018 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21019
21020 /* List of command functions, CLI names map directly to functions */
21021 #define foreach_cli_function                                    \
21022 _(comment, "usage: comment <ignore-rest-of-line>")              \
21023 _(dump_interface_table, "usage: dump_interface_table")          \
21024 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21025 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21026 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21027 _(dump_macro_table, "usage: dump_macro_table ")                 \
21028 _(dump_node_table, "usage: dump_node_table")                    \
21029 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21030 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21031 _(elog_disable, "usage: elog_disable")                          \
21032 _(elog_enable, "usage: elog_enable")                            \
21033 _(elog_save, "usage: elog_save <filename>")                     \
21034 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21035 _(echo, "usage: echo <message>")                                \
21036 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21037 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21038 _(help, "usage: help")                                          \
21039 _(q, "usage: quit")                                             \
21040 _(quit, "usage: quit")                                          \
21041 _(search_node_table, "usage: search_node_table <name>...")      \
21042 _(set, "usage: set <variable-name> <value>")                    \
21043 _(script, "usage: script <file-name>")                          \
21044 _(statseg, "usage: statseg")                                    \
21045 _(unset, "usage: unset <variable-name>")
21046
21047 #define _(N,n)                                  \
21048     static void vl_api_##n##_t_handler_uni      \
21049     (vl_api_##n##_t * mp)                       \
21050     {                                           \
21051         vat_main_t * vam = &vat_main;           \
21052         if (vam->json_output) {                 \
21053             vl_api_##n##_t_handler_json(mp);    \
21054         } else {                                \
21055             vl_api_##n##_t_handler(mp);         \
21056         }                                       \
21057     }
21058 foreach_vpe_api_reply_msg;
21059 #if VPP_API_TEST_BUILTIN == 0
21060 foreach_standalone_reply_msg;
21061 #endif
21062 #undef _
21063
21064 void
21065 vat_api_hookup (vat_main_t * vam)
21066 {
21067 #define _(N,n)                                                  \
21068     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21069                            vl_api_##n##_t_handler_uni,          \
21070                            vl_noop_handler,                     \
21071                            vl_api_##n##_t_endian,               \
21072                            vl_api_##n##_t_print,                \
21073                            sizeof(vl_api_##n##_t), 1);
21074   foreach_vpe_api_reply_msg;
21075 #if VPP_API_TEST_BUILTIN == 0
21076   foreach_standalone_reply_msg;
21077 #endif
21078 #undef _
21079
21080 #if (VPP_API_TEST_BUILTIN==0)
21081   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21082
21083   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21084
21085   vam->function_by_name = hash_create_string (0, sizeof (uword));
21086
21087   vam->help_by_name = hash_create_string (0, sizeof (uword));
21088 #endif
21089
21090   /* API messages we can send */
21091 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21092   foreach_vpe_api_msg;
21093 #undef _
21094
21095   /* Help strings */
21096 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21097   foreach_vpe_api_msg;
21098 #undef _
21099
21100   /* CLI functions */
21101 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21102   foreach_cli_function;
21103 #undef _
21104
21105   /* Help strings */
21106 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21107   foreach_cli_function;
21108 #undef _
21109 }
21110
21111 #if VPP_API_TEST_BUILTIN
21112 static clib_error_t *
21113 vat_api_hookup_shim (vlib_main_t * vm)
21114 {
21115   vat_api_hookup (&vat_main);
21116   return 0;
21117 }
21118
21119 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21120 #endif
21121
21122 /*
21123  * fd.io coding-style-patch-verification: ON
21124  *
21125  * Local Variables:
21126  * eval: (c-set-style "gnu")
21127  * End:
21128  */