ip: Protocol Independent IP Neighbors
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   return 0;
114 }
115 #else /* vpp built-in case, we don't do sockets... */
116 int
117 vat_socket_connect (vat_main_t * vam)
118 {
119   return 0;
120 }
121
122 int
123 vl_socket_client_read (int wait)
124 {
125   return -1;
126 };
127
128 int
129 vl_socket_client_write ()
130 {
131   return -1;
132 };
133
134 void *
135 vl_socket_client_msg_alloc (int nbytes)
136 {
137   return 0;
138 }
139 #endif
140
141
142 f64
143 vat_time_now (vat_main_t * vam)
144 {
145 #if VPP_API_TEST_BUILTIN
146   return vlib_time_now (vam->vlib_main);
147 #else
148   return clib_time_now (&vam->clib_time);
149 #endif
150 }
151
152 void
153 errmsg (char *fmt, ...)
154 {
155   vat_main_t *vam = &vat_main;
156   va_list va;
157   u8 *s;
158
159   va_start (va, fmt);
160   s = va_format (0, fmt, &va);
161   va_end (va);
162
163   vec_add1 (s, 0);
164
165 #if VPP_API_TEST_BUILTIN
166   vlib_cli_output (vam->vlib_main, (char *) s);
167 #else
168   {
169     if (vam->ifp != stdin)
170       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171                vam->input_line_number);
172     else
173       fformat (vam->ofp, "%s\n", (char *) s);
174     fflush (vam->ofp);
175   }
176 #endif
177
178   vec_free (s);
179 }
180
181 #if VPP_API_TEST_BUILTIN == 0
182 static uword
183 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184 {
185   vat_main_t *vam = va_arg (*args, vat_main_t *);
186   u32 *result = va_arg (*args, u32 *);
187   u8 *if_name;
188   uword *p;
189
190   if (!unformat (input, "%s", &if_name))
191     return 0;
192
193   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194   if (p == 0)
195     return 0;
196   *result = p[0];
197   return 1;
198 }
199
200 static uword
201 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202 {
203   return 0;
204 }
205
206 /* Parse an IP4 address %d.%d.%d.%d. */
207 uword
208 unformat_ip4_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   unsigned a[4];
212
213   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214     return 0;
215
216   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217     return 0;
218
219   result[0] = a[0];
220   result[1] = a[1];
221   result[2] = a[2];
222   result[3] = a[3];
223
224   return 1;
225 }
226
227 uword
228 unformat_ethernet_address (unformat_input_t * input, va_list * args)
229 {
230   u8 *result = va_arg (*args, u8 *);
231   u32 i, a[6];
232
233   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235     return 0;
236
237   /* Check range. */
238   for (i = 0; i < 6; i++)
239     if (a[i] >= (1 << 8))
240       return 0;
241
242   for (i = 0; i < 6; i++)
243     result[i] = a[i];
244
245   return 1;
246 }
247
248 /* Returns ethernet type as an int in host byte order. */
249 uword
250 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251                                         va_list * args)
252 {
253   u16 *result = va_arg (*args, u16 *);
254   int type;
255
256   /* Numeric type. */
257   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258     {
259       if (type >= (1 << 16))
260         return 0;
261       *result = type;
262       return 1;
263     }
264   return 0;
265 }
266
267 /* Parse an IP6 address. */
268 uword
269 unformat_ip6_address (unformat_input_t * input, va_list * args)
270 {
271   ip6_address_t *result = va_arg (*args, ip6_address_t *);
272   u16 hex_quads[8];
273   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
274   uword c, n_colon, double_colon_index;
275
276   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
277   double_colon_index = ARRAY_LEN (hex_quads);
278   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
279     {
280       hex_digit = 16;
281       if (c >= '0' && c <= '9')
282         hex_digit = c - '0';
283       else if (c >= 'a' && c <= 'f')
284         hex_digit = c + 10 - 'a';
285       else if (c >= 'A' && c <= 'F')
286         hex_digit = c + 10 - 'A';
287       else if (c == ':' && n_colon < 2)
288         n_colon++;
289       else
290         {
291           unformat_put_input (input);
292           break;
293         }
294
295       /* Too many hex quads. */
296       if (n_hex_quads >= ARRAY_LEN (hex_quads))
297         return 0;
298
299       if (hex_digit < 16)
300         {
301           hex_quad = (hex_quad << 4) | hex_digit;
302
303           /* Hex quad must fit in 16 bits. */
304           if (n_hex_digits >= 4)
305             return 0;
306
307           n_colon = 0;
308           n_hex_digits++;
309         }
310
311       /* Save position of :: */
312       if (n_colon == 2)
313         {
314           /* More than one :: ? */
315           if (double_colon_index < ARRAY_LEN (hex_quads))
316             return 0;
317           double_colon_index = n_hex_quads;
318         }
319
320       if (n_colon > 0 && n_hex_digits > 0)
321         {
322           hex_quads[n_hex_quads++] = hex_quad;
323           hex_quad = 0;
324           n_hex_digits = 0;
325         }
326     }
327
328   if (n_hex_digits > 0)
329     hex_quads[n_hex_quads++] = hex_quad;
330
331   {
332     word i;
333
334     /* Expand :: to appropriate number of zero hex quads. */
335     if (double_colon_index < ARRAY_LEN (hex_quads))
336       {
337         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
338
339         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
340           hex_quads[n_zero + i] = hex_quads[i];
341
342         for (i = 0; i < n_zero; i++)
343           hex_quads[double_colon_index + i] = 0;
344
345         n_hex_quads = ARRAY_LEN (hex_quads);
346       }
347
348     /* Too few hex quads given. */
349     if (n_hex_quads < ARRAY_LEN (hex_quads))
350       return 0;
351
352     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
353       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
354
355     return 1;
356   }
357 }
358
359 uword
360 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
361 {
362   u32 *r = va_arg (*args, u32 *);
363
364   if (0);
365 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
366   foreach_ipsec_policy_action
367 #undef _
368     else
369     return 0;
370   return 1;
371 }
372
373 u8 *
374 format_ipsec_crypto_alg (u8 * s, va_list * args)
375 {
376   u32 i = va_arg (*args, u32);
377   u8 *t = 0;
378
379   switch (i)
380     {
381 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
382       foreach_ipsec_crypto_alg
383 #undef _
384     default:
385       return format (s, "unknown");
386     }
387   return format (s, "%s", t);
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 #else /* VPP_API_TEST_BUILTIN == 1 */
408 static uword
409 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
416 }
417
418 static uword
419 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
420 {
421   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
422   vnet_main_t *vnm = vnet_get_main ();
423   u32 *result = va_arg (*args, u32 *);
424
425   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
426 }
427
428 #endif /* VPP_API_TEST_BUILTIN */
429
430 uword
431 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
432 {
433   u32 *r = va_arg (*args, u32 *);
434
435   if (0);
436 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
437   foreach_ipsec_crypto_alg
438 #undef _
439     else
440     return 0;
441   return 1;
442 }
443
444 uword
445 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
446 {
447   u32 *r = va_arg (*args, u32 *);
448
449   if (0);
450 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
451   foreach_ipsec_integ_alg
452 #undef _
453     else
454     return 0;
455   return 1;
456 }
457
458 static uword
459 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
460 {
461   u8 *r = va_arg (*args, u8 *);
462
463   if (unformat (input, "kbps"))
464     *r = SSE2_QOS_RATE_KBPS;
465   else if (unformat (input, "pps"))
466     *r = SSE2_QOS_RATE_PPS;
467   else
468     return 0;
469   return 1;
470 }
471
472 static uword
473 unformat_policer_round_type (unformat_input_t * input, va_list * args)
474 {
475   u8 *r = va_arg (*args, u8 *);
476
477   if (unformat (input, "closest"))
478     *r = SSE2_QOS_ROUND_TO_CLOSEST;
479   else if (unformat (input, "up"))
480     *r = SSE2_QOS_ROUND_TO_UP;
481   else if (unformat (input, "down"))
482     *r = SSE2_QOS_ROUND_TO_DOWN;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_type (unformat_input_t * input, va_list * args)
490 {
491   u8 *r = va_arg (*args, u8 *);
492
493   if (unformat (input, "1r2c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R2C;
495   else if (unformat (input, "1r3c"))
496     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
497   else if (unformat (input, "2r3c-2698"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
499   else if (unformat (input, "2r3c-4115"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
501   else if (unformat (input, "2r3c-mef5cf1"))
502     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
503   else
504     return 0;
505   return 1;
506 }
507
508 static uword
509 unformat_dscp (unformat_input_t * input, va_list * va)
510 {
511   u8 *r = va_arg (*va, u8 *);
512
513   if (0);
514 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
515   foreach_vnet_dscp
516 #undef _
517     else
518     return 0;
519   return 1;
520 }
521
522 static uword
523 unformat_policer_action_type (unformat_input_t * input, va_list * va)
524 {
525   sse2_qos_pol_action_params_st *a
526     = va_arg (*va, sse2_qos_pol_action_params_st *);
527
528   if (unformat (input, "drop"))
529     a->action_type = SSE2_QOS_ACTION_DROP;
530   else if (unformat (input, "transmit"))
531     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
532   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
533     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
534   else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = POLICER_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = POLICER_CLASSIFY_TABLE_IP6;
549   else if (unformat (input, "l2"))
550     tid = POLICER_CLASSIFY_TABLE_L2;
551   else
552     return 0;
553
554   *r = tid;
555   return 1;
556 }
557
558 static uword
559 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = FLOW_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = FLOW_CLASSIFY_TABLE_IP6;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 #if (VPP_API_TEST_BUILTIN==0)
576
577 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
578 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
579 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
580 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
581
582 uword
583 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
586   mfib_itf_attribute_t attr;
587
588   old = *iflags;
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_long_names[attr]))
592       *iflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_names[attr]))
597       *iflags |= (1 << attr);
598   }
599
600   return (old == *iflags ? 0 : 1);
601 }
602
603 uword
604 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
607   mfib_entry_attribute_t attr;
608
609   old = *eflags;
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_long_names[attr]))
613       *eflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_names[attr]))
618       *eflags |= (1 << attr);
619   }
620
621   return (old == *eflags ? 0 : 1);
622 }
623
624 u8 *
625 format_ip4_address (u8 * s, va_list * args)
626 {
627   u8 *a = va_arg (*args, u8 *);
628   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
629 }
630
631 u8 *
632 format_ip6_address (u8 * s, va_list * args)
633 {
634   ip6_address_t *a = va_arg (*args, ip6_address_t *);
635   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
636
637   i_max_n_zero = ARRAY_LEN (a->as_u16);
638   max_n_zeros = 0;
639   i_first_zero = i_max_n_zero;
640   n_zeros = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       u32 is_zero = a->as_u16[i] == 0;
644       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
645         {
646           i_first_zero = i;
647           n_zeros = 0;
648         }
649       n_zeros += is_zero;
650       if ((!is_zero && n_zeros > max_n_zeros)
651           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
652         {
653           i_max_n_zero = i_first_zero;
654           max_n_zeros = n_zeros;
655           i_first_zero = ARRAY_LEN (a->as_u16);
656           n_zeros = 0;
657         }
658     }
659
660   last_double_colon = 0;
661   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662     {
663       if (i == i_max_n_zero && max_n_zeros > 1)
664         {
665           s = format (s, "::");
666           i += max_n_zeros - 1;
667           last_double_colon = 1;
668         }
669       else
670         {
671           s = format (s, "%s%x",
672                       (last_double_colon || i == 0) ? "" : ":",
673                       clib_net_to_host_u16 (a->as_u16[i]));
674           last_double_colon = 0;
675         }
676     }
677
678   return s;
679 }
680
681 /* Format an IP46 address. */
682 u8 *
683 format_ip46_address (u8 * s, va_list * args)
684 {
685   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
686   ip46_type_t type = va_arg (*args, ip46_type_t);
687   int is_ip4 = 1;
688
689   switch (type)
690     {
691     case IP46_TYPE_ANY:
692       is_ip4 = ip46_address_is_ip4 (ip46);
693       break;
694     case IP46_TYPE_IP4:
695       is_ip4 = 1;
696       break;
697     case IP46_TYPE_IP6:
698       is_ip4 = 0;
699       break;
700     }
701
702   return is_ip4 ?
703     format (s, "%U", format_ip4_address, &ip46->ip4) :
704     format (s, "%U", format_ip6_address, &ip46->ip6);
705 }
706
707 u8 *
708 format_ethernet_address (u8 * s, va_list * args)
709 {
710   u8 *a = va_arg (*args, u8 *);
711
712   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
713                  a[0], a[1], a[2], a[3], a[4], a[5]);
714 }
715 #endif
716
717 static void
718 increment_v4_address (vl_api_ip4_address_t * i)
719 {
720   ip4_address_t *a = (ip4_address_t *) i;
721   u32 v;
722
723   v = ntohl (a->as_u32) + 1;
724   a->as_u32 = ntohl (v);
725 }
726
727 static void
728 increment_v6_address (vl_api_ip6_address_t * i)
729 {
730   ip6_address_t *a = (ip6_address_t *) i;
731   u64 v0, v1;
732
733   v0 = clib_net_to_host_u64 (a->as_u64[0]);
734   v1 = clib_net_to_host_u64 (a->as_u64[1]);
735
736   v1 += 1;
737   if (v1 == 0)
738     v0 += 1;
739   a->as_u64[0] = clib_net_to_host_u64 (v0);
740   a->as_u64[1] = clib_net_to_host_u64 (v1);
741 }
742
743 static void
744 increment_address (vl_api_address_t * a)
745 {
746   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
747     increment_v4_address (&a->un.ip4);
748   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
749     increment_v6_address (&a->un.ip6);
750 }
751
752 static void
753 set_ip4_address (vl_api_address_t * a, u32 v)
754 {
755   if (a->af == ADDRESS_IP4)
756     {
757       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
758       i->as_u32 = v;
759     }
760 }
761
762 static void
763 increment_mac_address (u8 * mac)
764 {
765   u64 tmp = *((u64 *) mac);
766   tmp = clib_net_to_host_u64 (tmp);
767   tmp += 1 << 16;               /* skip unused (least significant) octets */
768   tmp = clib_host_to_net_u64 (tmp);
769
770   clib_memcpy (mac, &tmp, 6);
771 }
772
773 static void
774 vat_json_object_add_address (vat_json_node_t * node,
775                              const char *str, const vl_api_address_t * addr)
776 {
777   if (ADDRESS_IP6 == addr->af)
778     {
779       struct in6_addr ip6;
780
781       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
782       vat_json_object_add_ip6 (node, str, ip6);
783     }
784   else
785     {
786       struct in_addr ip4;
787
788       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
789       vat_json_object_add_ip4 (node, str, ip4);
790     }
791 }
792
793 static void
794 vat_json_object_add_prefix (vat_json_node_t * node,
795                             const vl_api_prefix_t * prefix)
796 {
797   vat_json_object_add_uint (node, "len", prefix->len);
798   vat_json_object_add_address (node, "address", &prefix->address);
799 }
800
801 static void vl_api_create_loopback_reply_t_handler
802   (vl_api_create_loopback_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_loopback_reply_t_handler_json
814   (vl_api_create_loopback_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_loopback_instance_reply_t_handler
830   (vl_api_create_loopback_instance_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_loopback_instance_reply_t_handler_json
842   (vl_api_create_loopback_instance_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853   vam->retval = ntohl (mp->retval);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_af_packet_create_reply_t_handler
858   (vl_api_af_packet_create_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   i32 retval = ntohl (mp->retval);
862
863   vam->retval = retval;
864   vam->regenerate_interface_table = 1;
865   vam->sw_if_index = ntohl (mp->sw_if_index);
866   vam->result_ready = 1;
867 }
868
869 static void vl_api_af_packet_create_reply_t_handler_json
870   (vl_api_af_packet_create_reply_t * mp)
871 {
872   vat_main_t *vam = &vat_main;
873   vat_json_node_t node;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
878
879   vat_json_print (vam->ofp, &node);
880   vat_json_free (&node);
881
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_vlan_subif_reply_t_handler
887   (vl_api_create_vlan_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_create_vlan_subif_reply_t_handler_json
899   (vl_api_create_vlan_subif_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_subif_reply_t_handler
916   (vl_api_create_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_subif_reply_t_handler_json
928   (vl_api_create_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_interface_name_renumber_reply_t_handler
945   (vl_api_interface_name_renumber_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->result_ready = 1;
953 }
954
955 static void vl_api_interface_name_renumber_reply_t_handler_json
956   (vl_api_interface_name_renumber_reply_t * mp)
957 {
958   vat_main_t *vam = &vat_main;
959   vat_json_node_t node;
960
961   vat_json_init_object (&node);
962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
963
964   vat_json_print (vam->ofp, &node);
965   vat_json_free (&node);
966
967   vam->retval = ntohl (mp->retval);
968   vam->result_ready = 1;
969 }
970
971 /*
972  * Special-case: build the interface table, maintain
973  * the next loopback sw_if_index vbl.
974  */
975 static void vl_api_sw_interface_details_t_handler
976   (vl_api_sw_interface_details_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   u8 *s = format (0, "%s%c", mp->interface_name, 0);
980
981   hash_set_mem (vam->sw_if_index_by_interface_name, s,
982                 ntohl (mp->sw_if_index));
983
984   /* In sub interface case, fill the sub interface table entry */
985   if (mp->sw_if_index != mp->sup_sw_if_index)
986     {
987       sw_interface_subif_t *sub = NULL;
988
989       vec_add2 (vam->sw_if_subif_table, sub, 1);
990
991       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
992       strncpy ((char *) sub->interface_name, (char *) s,
993                vec_len (sub->interface_name));
994       sub->sw_if_index = ntohl (mp->sw_if_index);
995       sub->sub_id = ntohl (mp->sub_id);
996
997       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
998
999       sub->sub_number_of_tags = mp->sub_number_of_tags;
1000       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1001       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1002
1003       /* vlan tag rewrite */
1004       sub->vtr_op = ntohl (mp->vtr_op);
1005       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1006       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1007       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1008     }
1009 }
1010
1011 static void vl_api_sw_interface_details_t_handler_json
1012   (vl_api_sw_interface_details_t * mp)
1013 {
1014   vat_main_t *vam = &vat_main;
1015   vat_json_node_t *node = NULL;
1016
1017   if (VAT_JSON_ARRAY != vam->json_tree.type)
1018     {
1019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1020       vat_json_init_array (&vam->json_tree);
1021     }
1022   node = vat_json_array_add (&vam->json_tree);
1023
1024   vat_json_init_object (node);
1025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1026   vat_json_object_add_uint (node, "sup_sw_if_index",
1027                             ntohl (mp->sup_sw_if_index));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_string_copy (node, "interface_dev_type",
1033                                    mp->interface_dev_type);
1034   vat_json_object_add_uint (node, "flags", mp->flags);
1035   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1036   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1037   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1038   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1046   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1047   vat_json_object_add_uint (node, "vtr_push_dot1q",
1048                             ntohl (mp->vtr_push_dot1q));
1049   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1050   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1051   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1052     {
1053       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_dmac));
1057       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1058                                        format (0, "%U",
1059                                                format_ethernet_address,
1060                                                &mp->b_smac));
1061       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1062       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1063     }
1064 }
1065
1066 #if VPP_API_TEST_BUILTIN == 0
1067 static void vl_api_sw_interface_event_t_handler
1068   (vl_api_sw_interface_event_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   if (vam->interface_event_display)
1072     errmsg ("interface flags: sw_if_index %d %s %s",
1073             ntohl (mp->sw_if_index),
1074             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1075             "admin-up" : "admin-down",
1076             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1077             "link-up" : "link-down");
1078 }
1079 #endif
1080
1081 __clib_unused static void
1082 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1083 {
1084   /* JSON output not supported */
1085 }
1086
1087 static void
1088 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1089 {
1090   vat_main_t *vam = &vat_main;
1091   i32 retval = ntohl (mp->retval);
1092
1093   vam->retval = retval;
1094   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103   void *oldheap;
1104   u8 *reply;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "reply_in_shmem",
1109                             ntohl (mp->reply_in_shmem));
1110   /* Toss the shared-memory original... */
1111   oldheap = vl_msg_push_heap ();
1112
1113   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1114   vec_free (reply);
1115
1116   vl_msg_pop_heap (oldheap);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       errmsg ("        program: %s", mp->program);
1328       errmsg ("        version: %s", mp->version);
1329       errmsg ("     build date: %s", mp->build_date);
1330       errmsg ("build directory: %s", mp->build_directory);
1331     }
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_show_version_reply_t_handler_json
1337   (vl_api_show_version_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_string_copy (&node, "program", mp->program);
1345   vat_json_object_add_string_copy (&node, "version", mp->version);
1346   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    mp->build_directory);
1349
1350   vat_json_print (vam->ofp, &node);
1351   vat_json_free (&node);
1352
1353   vam->retval = ntohl (mp->retval);
1354   vam->result_ready = 1;
1355 }
1356
1357 static void vl_api_show_threads_reply_t_handler
1358   (vl_api_show_threads_reply_t * mp)
1359 {
1360   vat_main_t *vam = &vat_main;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   for (i = 0; i < count; i++)
1368     print (vam->ofp,
1369            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1370            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1371            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1372            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1373            ntohl (mp->thread_data[i].cpu_socket));
1374
1375   vam->retval = retval;
1376   vam->result_ready = 1;
1377 }
1378
1379 static void vl_api_show_threads_reply_t_handler_json
1380   (vl_api_show_threads_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   vat_json_node_t node;
1384   vl_api_thread_data_t *td;
1385   i32 retval = ntohl (mp->retval);
1386   int i, count = 0;
1387
1388   if (retval >= 0)
1389     count = ntohl (mp->count);
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", retval);
1393   vat_json_object_add_uint (&node, "count", count);
1394
1395   for (i = 0; i < count; i++)
1396     {
1397       td = &mp->thread_data[i];
1398       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1399       vat_json_object_add_string_copy (&node, "name", td->name);
1400       vat_json_object_add_string_copy (&node, "type", td->type);
1401       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1402       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1403       vat_json_object_add_int (&node, "core", ntohl (td->id));
1404       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1405     }
1406
1407   vat_json_print (vam->ofp, &node);
1408   vat_json_free (&node);
1409
1410   vam->retval = retval;
1411   vam->result_ready = 1;
1412 }
1413
1414 static int
1415 api_show_threads (vat_main_t * vam)
1416 {
1417   vl_api_show_threads_t *mp;
1418   int ret;
1419
1420   print (vam->ofp,
1421          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1422          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1423
1424   M (SHOW_THREADS, mp);
1425
1426   S (mp);
1427   W (ret);
1428   return ret;
1429 }
1430
1431 static void
1432 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1433 {
1434   u32 n_macs = ntohl (mp->n_macs);
1435   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1436           ntohl (mp->pid), mp->client_index, n_macs);
1437   int i;
1438   for (i = 0; i < n_macs; i++)
1439     {
1440       vl_api_mac_entry_t *mac = &mp->mac[i];
1441       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1442               i + 1, ntohl (mac->sw_if_index),
1443               format_ethernet_address, mac->mac_addr, mac->action);
1444       if (i == 1000)
1445         break;
1446     }
1447 }
1448
1449 static void
1450 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1451 {
1452   /* JSON output not supported */
1453 }
1454
1455 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1456 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1457
1458 /*
1459  * Special-case: build the bridge domain table, maintain
1460  * the next bd id vbl.
1461  */
1462 static void vl_api_bridge_domain_details_t_handler
1463   (vl_api_bridge_domain_details_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1467   int i;
1468
1469   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1470          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1471
1472   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1473          ntohl (mp->bd_id), mp->learn, mp->forward,
1474          mp->flood, ntohl (mp->bvi_sw_if_index),
1475          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1476
1477   if (n_sw_ifs)
1478     {
1479       vl_api_bridge_domain_sw_if_t *sw_ifs;
1480       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1481              "Interface Name");
1482
1483       sw_ifs = mp->sw_if_details;
1484       for (i = 0; i < n_sw_ifs; i++)
1485         {
1486           u8 *sw_if_name = 0;
1487           u32 sw_if_index;
1488           hash_pair_t *p;
1489
1490           sw_if_index = ntohl (sw_ifs->sw_if_index);
1491
1492           /* *INDENT-OFF* */
1493           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1494                              ({
1495                                if ((u32) p->value[0] == sw_if_index)
1496                                  {
1497                                    sw_if_name = (u8 *)(p->key);
1498                                    break;
1499                                  }
1500                              }));
1501           /* *INDENT-ON* */
1502           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1503                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1504                  "sw_if_index not found!");
1505
1506           sw_ifs++;
1507         }
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_details_t_handler_json
1512   (vl_api_bridge_domain_details_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t *node, *array = NULL;
1516   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1517
1518   if (VAT_JSON_ARRAY != vam->json_tree.type)
1519     {
1520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1521       vat_json_init_array (&vam->json_tree);
1522     }
1523   node = vat_json_array_add (&vam->json_tree);
1524
1525   vat_json_init_object (node);
1526   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1527   vat_json_object_add_uint (node, "flood", mp->flood);
1528   vat_json_object_add_uint (node, "forward", mp->forward);
1529   vat_json_object_add_uint (node, "learn", mp->learn);
1530   vat_json_object_add_uint (node, "bvi_sw_if_index",
1531                             ntohl (mp->bvi_sw_if_index));
1532   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1533   array = vat_json_object_add (node, "sw_if");
1534   vat_json_init_array (array);
1535
1536
1537
1538   if (n_sw_ifs)
1539     {
1540       vl_api_bridge_domain_sw_if_t *sw_ifs;
1541       int i;
1542
1543       sw_ifs = mp->sw_if_details;
1544       for (i = 0; i < n_sw_ifs; i++)
1545         {
1546           node = vat_json_array_add (array);
1547           vat_json_init_object (node);
1548           vat_json_object_add_uint (node, "sw_if_index",
1549                                     ntohl (sw_ifs->sw_if_index));
1550           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1551           sw_ifs++;
1552         }
1553     }
1554 }
1555
1556 static void vl_api_control_ping_reply_t_handler
1557   (vl_api_control_ping_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   i32 retval = ntohl (mp->retval);
1561   if (vam->async_mode)
1562     {
1563       vam->async_errors += (retval < 0);
1564     }
1565   else
1566     {
1567       vam->retval = retval;
1568       vam->result_ready = 1;
1569     }
1570   if (vam->socket_client_main)
1571     vam->socket_client_main->control_pings_outstanding--;
1572 }
1573
1574 static void vl_api_control_ping_reply_t_handler_json
1575   (vl_api_control_ping_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579
1580   if (VAT_JSON_NONE != vam->json_tree.type)
1581     {
1582       vat_json_print (vam->ofp, &vam->json_tree);
1583       vat_json_free (&vam->json_tree);
1584       vam->json_tree.type = VAT_JSON_NONE;
1585     }
1586   else
1587     {
1588       /* just print [] */
1589       vat_json_init_array (&vam->json_tree);
1590       vat_json_print (vam->ofp, &vam->json_tree);
1591       vam->json_tree.type = VAT_JSON_NONE;
1592     }
1593
1594   vam->retval = retval;
1595   vam->result_ready = 1;
1596 }
1597
1598 static void
1599   vl_api_bridge_domain_set_mac_age_reply_t_handler
1600   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604   if (vam->async_mode)
1605     {
1606       vam->async_errors += (retval < 0);
1607     }
1608   else
1609     {
1610       vam->retval = retval;
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1616   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623
1624   vat_json_print (vam->ofp, &node);
1625   vat_json_free (&node);
1626
1627   vam->retval = ntohl (mp->retval);
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_l2_flags_reply_t_handler_json
1648   (vl_api_l2_flags_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1656                             ntohl (mp->resulting_feature_bitmap));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void vl_api_bridge_flags_reply_t_handler
1666   (vl_api_bridge_flags_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_bridge_flags_reply_t_handler_json
1682   (vl_api_bridge_flags_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1690                             ntohl (mp->resulting_feature_bitmap));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void
1700 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->sw_if_index = ntohl (mp->sw_if_index);
1712       vam->result_ready = 1;
1713     }
1714
1715 }
1716
1717 static void vl_api_tap_create_v2_reply_t_handler_json
1718   (vl_api_tap_create_v2_reply_t * mp)
1719 {
1720   vat_main_t *vam = &vat_main;
1721   vat_json_node_t node;
1722
1723   vat_json_init_object (&node);
1724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1725   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1726
1727   vat_json_print (vam->ofp, &node);
1728   vat_json_free (&node);
1729
1730   vam->retval = ntohl (mp->retval);
1731   vam->result_ready = 1;
1732
1733 }
1734
1735 static void
1736 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1737 {
1738   vat_main_t *vam = &vat_main;
1739   i32 retval = ntohl (mp->retval);
1740   if (vam->async_mode)
1741     {
1742       vam->async_errors += (retval < 0);
1743     }
1744   else
1745     {
1746       vam->retval = retval;
1747       vam->result_ready = 1;
1748     }
1749 }
1750
1751 static void vl_api_tap_delete_v2_reply_t_handler_json
1752   (vl_api_tap_delete_v2_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765 }
1766
1767 static void
1768 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1769                                           mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->sw_if_index = ntohl (mp->sw_if_index);
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_virtio_pci_create_reply_t_handler_json
1786   (vl_api_virtio_pci_create_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800
1801 }
1802
1803 static void
1804 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1805                                           mp)
1806 {
1807   vat_main_t *vam = &vat_main;
1808   i32 retval = ntohl (mp->retval);
1809   if (vam->async_mode)
1810     {
1811       vam->async_errors += (retval < 0);
1812     }
1813   else
1814     {
1815       vam->retval = retval;
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_delete_reply_t_handler_json
1821   (vl_api_virtio_pci_delete_reply_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824   vat_json_node_t node;
1825
1826   vat_json_init_object (&node);
1827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1828
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834 }
1835
1836 static void
1837 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->sw_if_index = ntohl (mp->sw_if_index);
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_bond_create_reply_t_handler_json
1855   (vl_api_bond_create_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1863
1864   vat_json_print (vam->ofp, &node);
1865   vat_json_free (&node);
1866
1867   vam->retval = ntohl (mp->retval);
1868   vam->result_ready = 1;
1869 }
1870
1871 static void
1872 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1873 {
1874   vat_main_t *vam = &vat_main;
1875   i32 retval = ntohl (mp->retval);
1876
1877   if (vam->async_mode)
1878     {
1879       vam->async_errors += (retval < 0);
1880     }
1881   else
1882     {
1883       vam->retval = retval;
1884       vam->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_bond_delete_reply_t_handler_json
1889   (vl_api_bond_delete_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_enslave_reply_t_handler_json
1922   (vl_api_bond_enslave_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1939                                           mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_bond_detach_slave_reply_t_handler_json
1956   (vl_api_bond_detach_slave_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static int
1972 api_sw_interface_set_bond_weight (vat_main_t * vam)
1973 {
1974   unformat_input_t *i = vam->input;
1975   vl_api_sw_interface_set_bond_weight_t *mp;
1976   u32 sw_if_index = ~0;
1977   u32 weight = 0;
1978   u8 weight_enter = 0;
1979   int ret;
1980
1981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1982     {
1983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1984         ;
1985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
1986         ;
1987       else if (unformat (i, "weight %u", &weight))
1988         weight_enter = 1;
1989       else
1990         break;
1991     }
1992
1993   if (sw_if_index == ~0)
1994     {
1995       errmsg ("missing interface name or sw_if_index");
1996       return -99;
1997     }
1998   if (weight_enter == 0)
1999     {
2000       errmsg ("missing valid weight");
2001       return -99;
2002     }
2003
2004   /* Construct the API message */
2005   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2006   mp->sw_if_index = ntohl (sw_if_index);
2007   mp->weight = ntohl (weight);
2008
2009   S (mp);
2010   W (ret);
2011   return ret;
2012 }
2013
2014 static void vl_api_sw_interface_bond_details_t_handler
2015   (vl_api_sw_interface_bond_details_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018
2019   print (vam->ofp,
2020          "%-16s %-12d %-12U %-13U %-14u %-14u",
2021          mp->interface_name, ntohl (mp->sw_if_index),
2022          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2023          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2024 }
2025
2026 static void vl_api_sw_interface_bond_details_t_handler_json
2027   (vl_api_sw_interface_bond_details_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   vat_json_node_t *node = NULL;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037   node = vat_json_array_add (&vam->json_tree);
2038
2039   vat_json_init_object (node);
2040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2041   vat_json_object_add_string_copy (node, "interface_name",
2042                                    mp->interface_name);
2043   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2044   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2045   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2046   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2047 }
2048
2049 static int
2050 api_sw_interface_bond_dump (vat_main_t * vam)
2051 {
2052   vl_api_sw_interface_bond_dump_t *mp;
2053   vl_api_control_ping_t *mp_ping;
2054   int ret;
2055
2056   print (vam->ofp,
2057          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2058          "interface name", "sw_if_index", "mode", "load balance",
2059          "active slaves", "slaves");
2060
2061   /* Get list of bond interfaces */
2062   M (SW_INTERFACE_BOND_DUMP, mp);
2063   S (mp);
2064
2065   /* Use a control ping for synchronization */
2066   MPING (CONTROL_PING, mp_ping);
2067   S (mp_ping);
2068
2069   W (ret);
2070   return ret;
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077
2078   print (vam->ofp,
2079          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2080          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2081          ntohl (mp->weight), mp->is_local_numa);
2082 }
2083
2084 static void vl_api_sw_interface_slave_details_t_handler_json
2085   (vl_api_sw_interface_slave_details_t * mp)
2086 {
2087   vat_main_t *vam = &vat_main;
2088   vat_json_node_t *node = NULL;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095   node = vat_json_array_add (&vam->json_tree);
2096
2097   vat_json_init_object (node);
2098   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2099   vat_json_object_add_string_copy (node, "interface_name",
2100                                    mp->interface_name);
2101   vat_json_object_add_uint (node, "passive", mp->is_passive);
2102   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2103   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2104   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2105 }
2106
2107 static int
2108 api_sw_interface_slave_dump (vat_main_t * vam)
2109 {
2110   unformat_input_t *i = vam->input;
2111   vl_api_sw_interface_slave_dump_t *mp;
2112   vl_api_control_ping_t *mp_ping;
2113   u32 sw_if_index = ~0;
2114   u8 sw_if_index_set = 0;
2115   int ret;
2116
2117   /* Parse args required to build the message */
2118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2119     {
2120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2121         sw_if_index_set = 1;
2122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2123         sw_if_index_set = 1;
2124       else
2125         break;
2126     }
2127
2128   if (sw_if_index_set == 0)
2129     {
2130       errmsg ("missing vpp interface name. ");
2131       return -99;
2132     }
2133
2134   print (vam->ofp,
2135          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2136          "slave interface name", "sw_if_index", "passive", "long_timeout",
2137          "weight", "local numa");
2138
2139   /* Get list of bond interfaces */
2140   M (SW_INTERFACE_SLAVE_DUMP, mp);
2141   mp->sw_if_index = ntohl (sw_if_index);
2142   S (mp);
2143
2144   /* Use a control ping for synchronization */
2145   MPING (CONTROL_PING, mp_ping);
2146   S (mp_ping);
2147
2148   W (ret);
2149   return ret;
2150 }
2151
2152 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2153   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   i32 retval = ntohl (mp->retval);
2157   if (vam->async_mode)
2158     {
2159       vam->async_errors += (retval < 0);
2160     }
2161   else
2162     {
2163       vam->retval = retval;
2164       vam->sw_if_index = ntohl (mp->sw_if_index);
2165       vam->result_ready = 1;
2166     }
2167   vam->regenerate_interface_table = 1;
2168 }
2169
2170 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2171   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2172 {
2173   vat_main_t *vam = &vat_main;
2174   vat_json_node_t node;
2175
2176   vat_json_init_object (&node);
2177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2178   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2179                             ntohl (mp->sw_if_index));
2180
2181   vat_json_print (vam->ofp, &node);
2182   vat_json_free (&node);
2183
2184   vam->retval = ntohl (mp->retval);
2185   vam->result_ready = 1;
2186 }
2187
2188 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2189   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2190 {
2191   vat_main_t *vam = &vat_main;
2192   i32 retval = ntohl (mp->retval);
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->sw_if_index = ntohl (mp->sw_if_index);
2201       vam->result_ready = 1;
2202     }
2203 }
2204
2205 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2206   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   vat_json_node_t node;
2210
2211   vat_json_init_object (&node);
2212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2213   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2214
2215   vat_json_print (vam->ofp, &node);
2216   vat_json_free (&node);
2217
2218   vam->retval = ntohl (mp->retval);
2219   vam->result_ready = 1;
2220 }
2221
2222 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2223   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2224 {
2225   vat_main_t *vam = &vat_main;
2226   i32 retval = ntohl (mp->retval);
2227   if (vam->async_mode)
2228     {
2229       vam->async_errors += (retval < 0);
2230     }
2231   else
2232     {
2233       vam->retval = retval;
2234       vam->result_ready = 1;
2235     }
2236 }
2237
2238 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2239   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t node;
2243
2244   vat_json_init_object (&node);
2245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2246   vat_json_object_add_uint (&node, "fwd_entry_index",
2247                             clib_net_to_host_u32 (mp->fwd_entry_index));
2248
2249   vat_json_print (vam->ofp, &node);
2250   vat_json_free (&node);
2251
2252   vam->retval = ntohl (mp->retval);
2253   vam->result_ready = 1;
2254 }
2255
2256 u8 *
2257 format_lisp_transport_protocol (u8 * s, va_list * args)
2258 {
2259   u32 proto = va_arg (*args, u32);
2260
2261   switch (proto)
2262     {
2263     case 1:
2264       return format (s, "udp");
2265     case 2:
2266       return format (s, "api");
2267     default:
2268       return 0;
2269     }
2270   return 0;
2271 }
2272
2273 static void vl_api_one_get_transport_protocol_reply_t_handler
2274   (vl_api_one_get_transport_protocol_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   i32 retval = ntohl (mp->retval);
2278   if (vam->async_mode)
2279     {
2280       vam->async_errors += (retval < 0);
2281     }
2282   else
2283     {
2284       u32 proto = mp->protocol;
2285       print (vam->ofp, "Transport protocol: %U",
2286              format_lisp_transport_protocol, proto);
2287       vam->retval = retval;
2288       vam->result_ready = 1;
2289     }
2290 }
2291
2292 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2293   (vl_api_one_get_transport_protocol_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297   u8 *s;
2298
2299   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2300   vec_add1 (s, 0);
2301
2302   vat_json_init_object (&node);
2303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2304   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2305
2306   vec_free (s);
2307   vat_json_print (vam->ofp, &node);
2308   vat_json_free (&node);
2309
2310   vam->retval = ntohl (mp->retval);
2311   vam->result_ready = 1;
2312 }
2313
2314 static void vl_api_one_add_del_locator_set_reply_t_handler
2315   (vl_api_one_add_del_locator_set_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   i32 retval = ntohl (mp->retval);
2319   if (vam->async_mode)
2320     {
2321       vam->async_errors += (retval < 0);
2322     }
2323   else
2324     {
2325       vam->retval = retval;
2326       vam->result_ready = 1;
2327     }
2328 }
2329
2330 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2331   (vl_api_one_add_del_locator_set_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   vat_json_node_t node;
2335
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2339
2340   vat_json_print (vam->ofp, &node);
2341   vat_json_free (&node);
2342
2343   vam->retval = ntohl (mp->retval);
2344   vam->result_ready = 1;
2345 }
2346
2347 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2348   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   i32 retval = ntohl (mp->retval);
2352   if (vam->async_mode)
2353     {
2354       vam->async_errors += (retval < 0);
2355     }
2356   else
2357     {
2358       vam->retval = retval;
2359       vam->sw_if_index = ntohl (mp->sw_if_index);
2360       vam->result_ready = 1;
2361     }
2362   vam->regenerate_interface_table = 1;
2363 }
2364
2365 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2366   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2374
2375   vat_json_print (vam->ofp, &node);
2376   vat_json_free (&node);
2377
2378   vam->retval = ntohl (mp->retval);
2379   vam->result_ready = 1;
2380 }
2381
2382 static void vl_api_vxlan_offload_rx_reply_t_handler
2383   (vl_api_vxlan_offload_rx_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   i32 retval = ntohl (mp->retval);
2387   if (vam->async_mode)
2388     {
2389       vam->async_errors += (retval < 0);
2390     }
2391   else
2392     {
2393       vam->retval = retval;
2394       vam->result_ready = 1;
2395     }
2396 }
2397
2398 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2399   (vl_api_vxlan_offload_rx_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2415   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   i32 retval = ntohl (mp->retval);
2419   if (vam->async_mode)
2420     {
2421       vam->async_errors += (retval < 0);
2422     }
2423   else
2424     {
2425       vam->retval = retval;
2426       vam->sw_if_index = ntohl (mp->sw_if_index);
2427       vam->result_ready = 1;
2428     }
2429 }
2430
2431 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2432   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435   vat_json_node_t node;
2436
2437   vat_json_init_object (&node);
2438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2439   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2440
2441   vat_json_print (vam->ofp, &node);
2442   vat_json_free (&node);
2443
2444   vam->retval = ntohl (mp->retval);
2445   vam->result_ready = 1;
2446 }
2447
2448 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2449   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   i32 retval = ntohl (mp->retval);
2453   if (vam->async_mode)
2454     {
2455       vam->async_errors += (retval < 0);
2456     }
2457   else
2458     {
2459       vam->retval = retval;
2460       vam->sw_if_index = ntohl (mp->sw_if_index);
2461       vam->result_ready = 1;
2462     }
2463   vam->regenerate_interface_table = 1;
2464 }
2465
2466 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2467   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   vat_json_node_t node;
2471
2472   vat_json_init_object (&node);
2473   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2474   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2475
2476   vat_json_print (vam->ofp, &node);
2477   vat_json_free (&node);
2478
2479   vam->retval = ntohl (mp->retval);
2480   vam->result_ready = 1;
2481 }
2482
2483 static void vl_api_gre_tunnel_add_del_reply_t_handler
2484   (vl_api_gre_tunnel_add_del_reply_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   i32 retval = ntohl (mp->retval);
2488   if (vam->async_mode)
2489     {
2490       vam->async_errors += (retval < 0);
2491     }
2492   else
2493     {
2494       vam->retval = retval;
2495       vam->sw_if_index = ntohl (mp->sw_if_index);
2496       vam->result_ready = 1;
2497     }
2498 }
2499
2500 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2501   (vl_api_gre_tunnel_add_del_reply_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t node;
2505
2506   vat_json_init_object (&node);
2507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2508   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2509
2510   vat_json_print (vam->ofp, &node);
2511   vat_json_free (&node);
2512
2513   vam->retval = ntohl (mp->retval);
2514   vam->result_ready = 1;
2515 }
2516
2517 static void vl_api_create_vhost_user_if_reply_t_handler
2518   (vl_api_create_vhost_user_if_reply_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   i32 retval = ntohl (mp->retval);
2522   if (vam->async_mode)
2523     {
2524       vam->async_errors += (retval < 0);
2525     }
2526   else
2527     {
2528       vam->retval = retval;
2529       vam->sw_if_index = ntohl (mp->sw_if_index);
2530       vam->result_ready = 1;
2531     }
2532   vam->regenerate_interface_table = 1;
2533 }
2534
2535 static void vl_api_create_vhost_user_if_reply_t_handler_json
2536   (vl_api_create_vhost_user_if_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   vat_json_node_t node;
2540
2541   vat_json_init_object (&node);
2542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2543   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2544
2545   vat_json_print (vam->ofp, &node);
2546   vat_json_free (&node);
2547
2548   vam->retval = ntohl (mp->retval);
2549   vam->result_ready = 1;
2550 }
2551
2552 static void vl_api_ip_address_details_t_handler
2553   (vl_api_ip_address_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   static ip_address_details_t empty_ip_address_details = { {0} };
2557   ip_address_details_t *address = NULL;
2558   ip_details_t *current_ip_details = NULL;
2559   ip_details_t *details = NULL;
2560
2561   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2562
2563   if (!details || vam->current_sw_if_index >= vec_len (details)
2564       || !details[vam->current_sw_if_index].present)
2565     {
2566       errmsg ("ip address details arrived but not stored");
2567       errmsg ("ip_dump should be called first");
2568       return;
2569     }
2570
2571   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2572
2573 #define addresses (current_ip_details->addr)
2574
2575   vec_validate_init_empty (addresses, vec_len (addresses),
2576                            empty_ip_address_details);
2577
2578   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2579
2580   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2581   address->prefix_length = mp->prefix.len;
2582 #undef addresses
2583 }
2584
2585 static void vl_api_ip_address_details_t_handler_json
2586   (vl_api_ip_address_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   vat_json_node_t *node = NULL;
2590
2591   if (VAT_JSON_ARRAY != vam->json_tree.type)
2592     {
2593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2594       vat_json_init_array (&vam->json_tree);
2595     }
2596   node = vat_json_array_add (&vam->json_tree);
2597
2598   vat_json_init_object (node);
2599   vat_json_object_add_prefix (node, &mp->prefix);
2600 }
2601
2602 static void
2603 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_details_t empty_ip_details = { 0 };
2607   ip_details_t *ip = NULL;
2608   u32 sw_if_index = ~0;
2609
2610   sw_if_index = ntohl (mp->sw_if_index);
2611
2612   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2613                            sw_if_index, empty_ip_details);
2614
2615   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2616                          sw_if_index);
2617
2618   ip->present = 1;
2619 }
2620
2621 static void
2622 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2623 {
2624   vat_main_t *vam = &vat_main;
2625
2626   if (VAT_JSON_ARRAY != vam->json_tree.type)
2627     {
2628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2629       vat_json_init_array (&vam->json_tree);
2630     }
2631   vat_json_array_add_uint (&vam->json_tree,
2632                            clib_net_to_host_u32 (mp->sw_if_index));
2633 }
2634
2635 static void vl_api_get_first_msg_id_reply_t_handler
2636   (vl_api_get_first_msg_id_reply_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   i32 retval = ntohl (mp->retval);
2640
2641   if (vam->async_mode)
2642     {
2643       vam->async_errors += (retval < 0);
2644     }
2645   else
2646     {
2647       vam->retval = retval;
2648       vam->result_ready = 1;
2649     }
2650   if (retval >= 0)
2651     {
2652       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2653     }
2654 }
2655
2656 static void vl_api_get_first_msg_id_reply_t_handler_json
2657   (vl_api_get_first_msg_id_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t node;
2661
2662   vat_json_init_object (&node);
2663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2664   vat_json_object_add_uint (&node, "first_msg_id",
2665                             (uint) ntohs (mp->first_msg_id));
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void vl_api_get_node_graph_reply_t_handler
2675   (vl_api_get_node_graph_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   i32 retval = ntohl (mp->retval);
2679   u8 *pvt_copy, *reply;
2680   void *oldheap;
2681   vlib_node_t *node;
2682   int i;
2683
2684   if (vam->async_mode)
2685     {
2686       vam->async_errors += (retval < 0);
2687     }
2688   else
2689     {
2690       vam->retval = retval;
2691       vam->result_ready = 1;
2692     }
2693
2694   /* "Should never happen..." */
2695   if (retval != 0)
2696     return;
2697
2698   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2699   pvt_copy = vec_dup (reply);
2700
2701   /* Toss the shared-memory original... */
2702   oldheap = vl_msg_push_heap ();
2703
2704   vec_free (reply);
2705
2706   vl_msg_pop_heap (oldheap);
2707
2708   if (vam->graph_nodes)
2709     {
2710       hash_free (vam->graph_node_index_by_name);
2711
2712       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2713         {
2714           node = vam->graph_nodes[0][i];
2715           vec_free (node->name);
2716           vec_free (node->next_nodes);
2717           vec_free (node);
2718         }
2719       vec_free (vam->graph_nodes[0]);
2720       vec_free (vam->graph_nodes);
2721     }
2722
2723   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2724   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2725   vec_free (pvt_copy);
2726
2727   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2728     {
2729       node = vam->graph_nodes[0][i];
2730       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2731     }
2732 }
2733
2734 static void vl_api_get_node_graph_reply_t_handler_json
2735   (vl_api_get_node_graph_reply_t * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738   void *oldheap;
2739   vat_json_node_t node;
2740   u8 *reply;
2741
2742   /* $$$$ make this real? */
2743   vat_json_init_object (&node);
2744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2745   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2746
2747   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2748
2749   /* Toss the shared-memory original... */
2750   oldheap = vl_msg_push_heap ();
2751
2752   vec_free (reply);
2753
2754   vl_msg_pop_heap (oldheap);
2755
2756   vat_json_print (vam->ofp, &node);
2757   vat_json_free (&node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static void
2764 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *s = 0;
2768
2769   if (mp->local)
2770     {
2771       s = format (s, "%=16d%=16d%=16d",
2772                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2773     }
2774   else
2775     {
2776       s = format (s, "%=16U%=16d%=16d",
2777                   mp->is_ipv6 ? format_ip6_address :
2778                   format_ip4_address,
2779                   mp->ip_address, mp->priority, mp->weight);
2780     }
2781
2782   print (vam->ofp, "%v", s);
2783   vec_free (s);
2784 }
2785
2786 static void
2787 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791   struct in6_addr ip6;
2792   struct in_addr ip4;
2793
2794   if (VAT_JSON_ARRAY != vam->json_tree.type)
2795     {
2796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2797       vat_json_init_array (&vam->json_tree);
2798     }
2799   node = vat_json_array_add (&vam->json_tree);
2800   vat_json_init_object (node);
2801
2802   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2803   vat_json_object_add_uint (node, "priority", mp->priority);
2804   vat_json_object_add_uint (node, "weight", mp->weight);
2805
2806   if (mp->local)
2807     vat_json_object_add_uint (node, "sw_if_index",
2808                               clib_net_to_host_u32 (mp->sw_if_index));
2809   else
2810     {
2811       if (mp->is_ipv6)
2812         {
2813           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2814           vat_json_object_add_ip6 (node, "address", ip6);
2815         }
2816       else
2817         {
2818           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2819           vat_json_object_add_ip4 (node, "address", ip4);
2820         }
2821     }
2822 }
2823
2824 static void
2825 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2826                                           mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   u8 *ls_name = 0;
2830
2831   ls_name = format (0, "%s", mp->ls_name);
2832
2833   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2834          ls_name);
2835   vec_free (ls_name);
2836 }
2837
2838 static void
2839   vl_api_one_locator_set_details_t_handler_json
2840   (vl_api_one_locator_set_details_t * mp)
2841 {
2842   vat_main_t *vam = &vat_main;
2843   vat_json_node_t *node = 0;
2844   u8 *ls_name = 0;
2845
2846   ls_name = format (0, "%s", mp->ls_name);
2847   vec_add1 (ls_name, 0);
2848
2849   if (VAT_JSON_ARRAY != vam->json_tree.type)
2850     {
2851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2852       vat_json_init_array (&vam->json_tree);
2853     }
2854   node = vat_json_array_add (&vam->json_tree);
2855
2856   vat_json_init_object (node);
2857   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2858   vat_json_object_add_uint (node, "ls_index",
2859                             clib_net_to_host_u32 (mp->ls_index));
2860   vec_free (ls_name);
2861 }
2862
2863 typedef struct
2864 {
2865   u32 spi;
2866   u8 si;
2867 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2868
2869 uword
2870 unformat_nsh_address (unformat_input_t * input, va_list * args)
2871 {
2872   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2873   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2874 }
2875
2876 u8 *
2877 format_nsh_address_vat (u8 * s, va_list * args)
2878 {
2879   nsh_t *a = va_arg (*args, nsh_t *);
2880   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2881 }
2882
2883 static u8 *
2884 format_lisp_flat_eid (u8 * s, va_list * args)
2885 {
2886   u32 type = va_arg (*args, u32);
2887   u8 *eid = va_arg (*args, u8 *);
2888   u32 eid_len = va_arg (*args, u32);
2889
2890   switch (type)
2891     {
2892     case 0:
2893       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2894     case 1:
2895       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2896     case 2:
2897       return format (s, "%U", format_ethernet_address, eid);
2898     case 3:
2899       return format (s, "%U", format_nsh_address_vat, eid);
2900     }
2901   return 0;
2902 }
2903
2904 static u8 *
2905 format_lisp_eid_vat (u8 * s, va_list * args)
2906 {
2907   u32 type = va_arg (*args, u32);
2908   u8 *eid = va_arg (*args, u8 *);
2909   u32 eid_len = va_arg (*args, u32);
2910   u8 *seid = va_arg (*args, u8 *);
2911   u32 seid_len = va_arg (*args, u32);
2912   u32 is_src_dst = va_arg (*args, u32);
2913
2914   if (is_src_dst)
2915     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2916
2917   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2918
2919   return s;
2920 }
2921
2922 static void
2923 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2924 {
2925   vat_main_t *vam = &vat_main;
2926   u8 *s = 0, *eid = 0;
2927
2928   if (~0 == mp->locator_set_index)
2929     s = format (0, "action: %d", mp->action);
2930   else
2931     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2932
2933   eid = format (0, "%U", format_lisp_eid_vat,
2934                 mp->eid_type,
2935                 mp->eid,
2936                 mp->eid_prefix_len,
2937                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2938   vec_add1 (eid, 0);
2939
2940   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2941          clib_net_to_host_u32 (mp->vni),
2942          eid,
2943          mp->is_local ? "local" : "remote",
2944          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2945          clib_net_to_host_u16 (mp->key_id), mp->key);
2946
2947   vec_free (s);
2948   vec_free (eid);
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2953                                              * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   vat_json_node_t *node = 0;
2957   u8 *eid = 0;
2958
2959   if (VAT_JSON_ARRAY != vam->json_tree.type)
2960     {
2961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2962       vat_json_init_array (&vam->json_tree);
2963     }
2964   node = vat_json_array_add (&vam->json_tree);
2965
2966   vat_json_init_object (node);
2967   if (~0 == mp->locator_set_index)
2968     vat_json_object_add_uint (node, "action", mp->action);
2969   else
2970     vat_json_object_add_uint (node, "locator_set_index",
2971                               clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2974   if (mp->eid_type == 3)
2975     {
2976       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2977       vat_json_init_object (nsh_json);
2978       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2979       vat_json_object_add_uint (nsh_json, "spi",
2980                                 clib_net_to_host_u32 (nsh->spi));
2981       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2982     }
2983   else
2984     {
2985       eid = format (0, "%U", format_lisp_eid_vat,
2986                     mp->eid_type,
2987                     mp->eid,
2988                     mp->eid_prefix_len,
2989                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2990       vec_add1 (eid, 0);
2991       vat_json_object_add_string_copy (node, "eid", eid);
2992       vec_free (eid);
2993     }
2994   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2995   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2996   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2997
2998   if (mp->key_id)
2999     {
3000       vat_json_object_add_uint (node, "key_id",
3001                                 clib_net_to_host_u16 (mp->key_id));
3002       vat_json_object_add_string_copy (node, "key", mp->key);
3003     }
3004 }
3005
3006 static void
3007 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *seid = 0, *deid = 0;
3011   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3012
3013   deid = format (0, "%U", format_lisp_eid_vat,
3014                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3015
3016   seid = format (0, "%U", format_lisp_eid_vat,
3017                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3018
3019   vec_add1 (deid, 0);
3020   vec_add1 (seid, 0);
3021
3022   if (mp->is_ip4)
3023     format_ip_address_fcn = format_ip4_address;
3024   else
3025     format_ip_address_fcn = format_ip6_address;
3026
3027
3028   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3029          clib_net_to_host_u32 (mp->vni),
3030          seid, deid,
3031          format_ip_address_fcn, mp->lloc,
3032          format_ip_address_fcn, mp->rloc,
3033          clib_net_to_host_u32 (mp->pkt_count),
3034          clib_net_to_host_u32 (mp->bytes));
3035
3036   vec_free (deid);
3037   vec_free (seid);
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3042 {
3043   struct in6_addr ip6;
3044   struct in_addr ip4;
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = 0;
3047   u8 *deid = 0, *seid = 0;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055
3056   vat_json_init_object (node);
3057   deid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3059
3060   seid = format (0, "%U", format_lisp_eid_vat,
3061                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3062
3063   vec_add1 (deid, 0);
3064   vec_add1 (seid, 0);
3065
3066   vat_json_object_add_string_copy (node, "seid", seid);
3067   vat_json_object_add_string_copy (node, "deid", deid);
3068   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3069
3070   if (mp->is_ip4)
3071     {
3072       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3073       vat_json_object_add_ip4 (node, "lloc", ip4);
3074       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3075       vat_json_object_add_ip4 (node, "rloc", ip4);
3076     }
3077   else
3078     {
3079       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3080       vat_json_object_add_ip6 (node, "lloc", ip6);
3081       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3082       vat_json_object_add_ip6 (node, "rloc", ip6);
3083     }
3084   vat_json_object_add_uint (node, "pkt_count",
3085                             clib_net_to_host_u32 (mp->pkt_count));
3086   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3087
3088   vec_free (deid);
3089   vec_free (seid);
3090 }
3091
3092 static void
3093   vl_api_one_eid_table_map_details_t_handler
3094   (vl_api_one_eid_table_map_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097
3098   u8 *line = format (0, "%=10d%=10d",
3099                      clib_net_to_host_u32 (mp->vni),
3100                      clib_net_to_host_u32 (mp->dp_table));
3101   print (vam->ofp, "%v", line);
3102   vec_free (line);
3103 }
3104
3105 static void
3106   vl_api_one_eid_table_map_details_t_handler_json
3107   (vl_api_one_eid_table_map_details_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t *node = NULL;
3111
3112   if (VAT_JSON_ARRAY != vam->json_tree.type)
3113     {
3114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3115       vat_json_init_array (&vam->json_tree);
3116     }
3117   node = vat_json_array_add (&vam->json_tree);
3118   vat_json_init_object (node);
3119   vat_json_object_add_uint (node, "dp_table",
3120                             clib_net_to_host_u32 (mp->dp_table));
3121   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3122 }
3123
3124 static void
3125   vl_api_one_eid_table_vni_details_t_handler
3126   (vl_api_one_eid_table_vni_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129
3130   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3131   print (vam->ofp, "%v", line);
3132   vec_free (line);
3133 }
3134
3135 static void
3136   vl_api_one_eid_table_vni_details_t_handler_json
3137   (vl_api_one_eid_table_vni_details_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   vat_json_node_t *node = NULL;
3141
3142   if (VAT_JSON_ARRAY != vam->json_tree.type)
3143     {
3144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3145       vat_json_init_array (&vam->json_tree);
3146     }
3147   node = vat_json_array_add (&vam->json_tree);
3148   vat_json_init_object (node);
3149   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3150 }
3151
3152 static void
3153   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3154   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3155 {
3156   vat_main_t *vam = &vat_main;
3157   int retval = clib_net_to_host_u32 (mp->retval);
3158
3159   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3160   print (vam->ofp, "fallback threshold value: %d", mp->value);
3161
3162   vam->retval = retval;
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3168   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t _node, *node = &_node;
3172   int retval = clib_net_to_host_u32 (mp->retval);
3173
3174   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3175   vat_json_init_object (node);
3176   vat_json_object_add_uint (node, "value", mp->value);
3177
3178   vat_json_print (vam->ofp, node);
3179   vat_json_free (node);
3180
3181   vam->retval = retval;
3182   vam->result_ready = 1;
3183 }
3184
3185 static void
3186   vl_api_show_one_map_register_state_reply_t_handler
3187   (vl_api_show_one_map_register_state_reply_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   int retval = clib_net_to_host_u32 (mp->retval);
3191
3192   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3193
3194   vam->retval = retval;
3195   vam->result_ready = 1;
3196 }
3197
3198 static void
3199   vl_api_show_one_map_register_state_reply_t_handler_json
3200   (vl_api_show_one_map_register_state_reply_t * mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203   vat_json_node_t _node, *node = &_node;
3204   int retval = clib_net_to_host_u32 (mp->retval);
3205
3206   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3207
3208   vat_json_init_object (node);
3209   vat_json_object_add_string_copy (node, "state", s);
3210
3211   vat_json_print (vam->ofp, node);
3212   vat_json_free (node);
3213
3214   vam->retval = retval;
3215   vam->result_ready = 1;
3216   vec_free (s);
3217 }
3218
3219 static void
3220   vl_api_show_one_rloc_probe_state_reply_t_handler
3221   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   int retval = clib_net_to_host_u32 (mp->retval);
3225
3226   if (retval)
3227     goto end;
3228
3229   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3230 end:
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3237   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3244   vat_json_init_object (node);
3245   vat_json_object_add_string_copy (node, "state", s);
3246
3247   vat_json_print (vam->ofp, node);
3248   vat_json_free (node);
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252   vec_free (s);
3253 }
3254
3255 static void
3256   vl_api_show_one_stats_enable_disable_reply_t_handler
3257   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   int retval = clib_net_to_host_u32 (mp->retval);
3261
3262   if (retval)
3263     goto end;
3264
3265   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3266 end:
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3273   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t _node, *node = &_node;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3293 {
3294   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3295   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3296   e->vni = clib_net_to_host_u32 (e->vni);
3297 }
3298
3299 static void
3300   gpe_fwd_entries_get_reply_t_net_to_host
3301   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3302 {
3303   u32 i;
3304
3305   mp->count = clib_net_to_host_u32 (mp->count);
3306   for (i = 0; i < mp->count; i++)
3307     {
3308       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3309     }
3310 }
3311
3312 static u8 *
3313 format_gpe_encap_mode (u8 * s, va_list * args)
3314 {
3315   u32 mode = va_arg (*args, u32);
3316
3317   switch (mode)
3318     {
3319     case 0:
3320       return format (s, "lisp");
3321     case 1:
3322       return format (s, "vxlan");
3323     }
3324   return 0;
3325 }
3326
3327 static void
3328   vl_api_gpe_get_encap_mode_reply_t_handler
3329   (vl_api_gpe_get_encap_mode_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332
3333   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3334   vam->retval = ntohl (mp->retval);
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_gpe_get_encap_mode_reply_t_handler_json
3340   (vl_api_gpe_get_encap_mode_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t node;
3344
3345   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3346   vec_add1 (encap_mode, 0);
3347
3348   vat_json_init_object (&node);
3349   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3350
3351   vec_free (encap_mode);
3352   vat_json_print (vam->ofp, &node);
3353   vat_json_free (&node);
3354
3355   vam->retval = ntohl (mp->retval);
3356   vam->result_ready = 1;
3357 }
3358
3359 static void
3360   vl_api_gpe_fwd_entry_path_details_t_handler
3361   (vl_api_gpe_fwd_entry_path_details_t * mp)
3362 {
3363   vat_main_t *vam = &vat_main;
3364   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3365
3366   if (mp->lcl_loc.is_ip4)
3367     format_ip_address_fcn = format_ip4_address;
3368   else
3369     format_ip_address_fcn = format_ip6_address;
3370
3371   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3372          format_ip_address_fcn, &mp->lcl_loc,
3373          format_ip_address_fcn, &mp->rmt_loc);
3374 }
3375
3376 static void
3377 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3378 {
3379   struct in6_addr ip6;
3380   struct in_addr ip4;
3381
3382   if (loc->is_ip4)
3383     {
3384       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3385       vat_json_object_add_ip4 (n, "address", ip4);
3386     }
3387   else
3388     {
3389       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3390       vat_json_object_add_ip6 (n, "address", ip6);
3391     }
3392   vat_json_object_add_uint (n, "weight", loc->weight);
3393 }
3394
3395 static void
3396   vl_api_gpe_fwd_entry_path_details_t_handler_json
3397   (vl_api_gpe_fwd_entry_path_details_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   vat_json_node_t *node = NULL;
3401   vat_json_node_t *loc_node;
3402
3403   if (VAT_JSON_ARRAY != vam->json_tree.type)
3404     {
3405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3406       vat_json_init_array (&vam->json_tree);
3407     }
3408   node = vat_json_array_add (&vam->json_tree);
3409   vat_json_init_object (node);
3410
3411   loc_node = vat_json_object_add (node, "local_locator");
3412   vat_json_init_object (loc_node);
3413   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3414
3415   loc_node = vat_json_object_add (node, "remote_locator");
3416   vat_json_init_object (loc_node);
3417   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3418 }
3419
3420 static void
3421   vl_api_gpe_fwd_entries_get_reply_t_handler
3422   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   u32 i;
3426   int retval = clib_net_to_host_u32 (mp->retval);
3427   vl_api_gpe_fwd_entry_t *e;
3428
3429   if (retval)
3430     goto end;
3431
3432   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3433
3434   for (i = 0; i < mp->count; i++)
3435     {
3436       e = &mp->entries[i];
3437       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3438              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3439              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3440     }
3441
3442 end:
3443   vam->retval = retval;
3444   vam->result_ready = 1;
3445 }
3446
3447 static void
3448   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3449   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3450 {
3451   u8 *s = 0;
3452   vat_main_t *vam = &vat_main;
3453   vat_json_node_t *e = 0, root;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *fwd;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462   vat_json_init_array (&root);
3463
3464   for (i = 0; i < mp->count; i++)
3465     {
3466       e = vat_json_array_add (&root);
3467       fwd = &mp->entries[i];
3468
3469       vat_json_init_object (e);
3470       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3471       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3472       vat_json_object_add_int (e, "vni", fwd->vni);
3473       vat_json_object_add_int (e, "action", fwd->action);
3474
3475       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3476                   fwd->leid_prefix_len);
3477       vec_add1 (s, 0);
3478       vat_json_object_add_string_copy (e, "leid", s);
3479       vec_free (s);
3480
3481       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3482                   fwd->reid_prefix_len);
3483       vec_add1 (s, 0);
3484       vat_json_object_add_string_copy (e, "reid", s);
3485       vec_free (s);
3486     }
3487
3488   vat_json_print (vam->ofp, &root);
3489   vat_json_free (&root);
3490
3491 end:
3492   vam->retval = retval;
3493   vam->result_ready = 1;
3494 }
3495
3496 static void
3497   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3498   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3499 {
3500   vat_main_t *vam = &vat_main;
3501   u32 i, n;
3502   int retval = clib_net_to_host_u32 (mp->retval);
3503   vl_api_gpe_native_fwd_rpath_t *r;
3504
3505   if (retval)
3506     goto end;
3507
3508   n = clib_net_to_host_u32 (mp->count);
3509
3510   for (i = 0; i < n; i++)
3511     {
3512       r = &mp->entries[i];
3513       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3514              clib_net_to_host_u32 (r->fib_index),
3515              clib_net_to_host_u32 (r->nh_sw_if_index),
3516              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3517     }
3518
3519 end:
3520   vam->retval = retval;
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3526   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t root, *e;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533   u8 *s;
3534
3535   if (retval)
3536     goto end;
3537
3538   n = clib_net_to_host_u32 (mp->count);
3539   vat_json_init_array (&root);
3540
3541   for (i = 0; i < n; i++)
3542     {
3543       e = vat_json_array_add (&root);
3544       vat_json_init_object (e);
3545       r = &mp->entries[i];
3546       s =
3547         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3548                 r->nh_addr);
3549       vec_add1 (s, 0);
3550       vat_json_object_add_string_copy (e, "ip4", s);
3551       vec_free (s);
3552
3553       vat_json_object_add_uint (e, "fib_index",
3554                                 clib_net_to_host_u32 (r->fib_index));
3555       vat_json_object_add_uint (e, "nh_sw_if_index",
3556                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3557     }
3558
3559   vat_json_print (vam->ofp, &root);
3560   vat_json_free (&root);
3561
3562 end:
3563   vam->retval = retval;
3564   vam->result_ready = 1;
3565 }
3566
3567 static void
3568   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3569   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3570 {
3571   vat_main_t *vam = &vat_main;
3572   u32 i, n;
3573   int retval = clib_net_to_host_u32 (mp->retval);
3574
3575   if (retval)
3576     goto end;
3577
3578   n = clib_net_to_host_u32 (mp->count);
3579
3580   for (i = 0; i < n; i++)
3581     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3582
3583 end:
3584   vam->retval = retval;
3585   vam->result_ready = 1;
3586 }
3587
3588 static void
3589   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3590   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   vat_json_node_t root;
3594   u32 i, n;
3595   int retval = clib_net_to_host_u32 (mp->retval);
3596
3597   if (retval)
3598     goto end;
3599
3600   n = clib_net_to_host_u32 (mp->count);
3601   vat_json_init_array (&root);
3602
3603   for (i = 0; i < n; i++)
3604     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3605
3606   vat_json_print (vam->ofp, &root);
3607   vat_json_free (&root);
3608
3609 end:
3610   vam->retval = retval;
3611   vam->result_ready = 1;
3612 }
3613
3614 static void
3615   vl_api_one_ndp_entries_get_reply_t_handler
3616   (vl_api_one_ndp_entries_get_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   u32 i, n;
3620   int retval = clib_net_to_host_u32 (mp->retval);
3621
3622   if (retval)
3623     goto end;
3624
3625   n = clib_net_to_host_u32 (mp->count);
3626
3627   for (i = 0; i < n; i++)
3628     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3629            format_ethernet_address, mp->entries[i].mac);
3630
3631 end:
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634 }
3635
3636 static void
3637   vl_api_one_ndp_entries_get_reply_t_handler_json
3638   (vl_api_one_ndp_entries_get_reply_t * mp)
3639 {
3640   u8 *s = 0;
3641   vat_main_t *vam = &vat_main;
3642   vat_json_node_t *e = 0, root;
3643   u32 i, n;
3644   int retval = clib_net_to_host_u32 (mp->retval);
3645   vl_api_one_ndp_entry_t *arp_entry;
3646
3647   if (retval)
3648     goto end;
3649
3650   n = clib_net_to_host_u32 (mp->count);
3651   vat_json_init_array (&root);
3652
3653   for (i = 0; i < n; i++)
3654     {
3655       e = vat_json_array_add (&root);
3656       arp_entry = &mp->entries[i];
3657
3658       vat_json_init_object (e);
3659       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3660       vec_add1 (s, 0);
3661
3662       vat_json_object_add_string_copy (e, "mac", s);
3663       vec_free (s);
3664
3665       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3666       vec_add1 (s, 0);
3667       vat_json_object_add_string_copy (e, "ip6", s);
3668       vec_free (s);
3669     }
3670
3671   vat_json_print (vam->ofp, &root);
3672   vat_json_free (&root);
3673
3674 end:
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_one_l2_arp_entries_get_reply_t_handler
3681   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686
3687   if (retval)
3688     goto end;
3689
3690   n = clib_net_to_host_u32 (mp->count);
3691
3692   for (i = 0; i < n; i++)
3693     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3694            format_ethernet_address, mp->entries[i].mac);
3695
3696 end:
3697   vam->retval = retval;
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3703   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3704 {
3705   u8 *s = 0;
3706   vat_main_t *vam = &vat_main;
3707   vat_json_node_t *e = 0, root;
3708   u32 i, n;
3709   int retval = clib_net_to_host_u32 (mp->retval);
3710   vl_api_one_l2_arp_entry_t *arp_entry;
3711
3712   if (retval)
3713     goto end;
3714
3715   n = clib_net_to_host_u32 (mp->count);
3716   vat_json_init_array (&root);
3717
3718   for (i = 0; i < n; i++)
3719     {
3720       e = vat_json_array_add (&root);
3721       arp_entry = &mp->entries[i];
3722
3723       vat_json_init_object (e);
3724       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3725       vec_add1 (s, 0);
3726
3727       vat_json_object_add_string_copy (e, "mac", s);
3728       vec_free (s);
3729
3730       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3731       vec_add1 (s, 0);
3732       vat_json_object_add_string_copy (e, "ip4", s);
3733       vec_free (s);
3734     }
3735
3736   vat_json_print (vam->ofp, &root);
3737   vat_json_free (&root);
3738
3739 end:
3740   vam->retval = retval;
3741   vam->result_ready = 1;
3742 }
3743
3744 static void
3745 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3746 {
3747   vat_main_t *vam = &vat_main;
3748   u32 i, n;
3749   int retval = clib_net_to_host_u32 (mp->retval);
3750
3751   if (retval)
3752     goto end;
3753
3754   n = clib_net_to_host_u32 (mp->count);
3755
3756   for (i = 0; i < n; i++)
3757     {
3758       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3759     }
3760
3761 end:
3762   vam->retval = retval;
3763   vam->result_ready = 1;
3764 }
3765
3766 static void
3767   vl_api_one_ndp_bd_get_reply_t_handler_json
3768   (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   vat_json_node_t root;
3772   u32 i, n;
3773   int retval = clib_net_to_host_u32 (mp->retval);
3774
3775   if (retval)
3776     goto end;
3777
3778   n = clib_net_to_host_u32 (mp->count);
3779   vat_json_init_array (&root);
3780
3781   for (i = 0; i < n; i++)
3782     {
3783       vat_json_array_add_uint (&root,
3784                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3785     }
3786
3787   vat_json_print (vam->ofp, &root);
3788   vat_json_free (&root);
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_l2_arp_bd_get_reply_t_handler
3797   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   u32 i, n;
3801   int retval = clib_net_to_host_u32 (mp->retval);
3802
3803   if (retval)
3804     goto end;
3805
3806   n = clib_net_to_host_u32 (mp->count);
3807
3808   for (i = 0; i < n; i++)
3809     {
3810       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3811     }
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   vat_json_node_t root;
3824   u32 i, n;
3825   int retval = clib_net_to_host_u32 (mp->retval);
3826
3827   if (retval)
3828     goto end;
3829
3830   n = clib_net_to_host_u32 (mp->count);
3831   vat_json_init_array (&root);
3832
3833   for (i = 0; i < n; i++)
3834     {
3835       vat_json_array_add_uint (&root,
3836                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3837     }
3838
3839   vat_json_print (vam->ofp, &root);
3840   vat_json_free (&root);
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_adjacencies_get_reply_t_handler
3849   (vl_api_one_adjacencies_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   u32 i, n;
3853   int retval = clib_net_to_host_u32 (mp->retval);
3854   vl_api_one_adjacency_t *a;
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860
3861   for (i = 0; i < n; i++)
3862     {
3863       a = &mp->adjacencies[i];
3864       print (vam->ofp, "%U %40U",
3865              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3866              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3867     }
3868
3869 end:
3870   vam->retval = retval;
3871   vam->result_ready = 1;
3872 }
3873
3874 static void
3875   vl_api_one_adjacencies_get_reply_t_handler_json
3876   (vl_api_one_adjacencies_get_reply_t * mp)
3877 {
3878   u8 *s = 0;
3879   vat_main_t *vam = &vat_main;
3880   vat_json_node_t *e = 0, root;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     {
3893       e = vat_json_array_add (&root);
3894       a = &mp->adjacencies[i];
3895
3896       vat_json_init_object (e);
3897       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3898                   a->leid_prefix_len);
3899       vec_add1 (s, 0);
3900       vat_json_object_add_string_copy (e, "leid", s);
3901       vec_free (s);
3902
3903       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3904                   a->reid_prefix_len);
3905       vec_add1 (s, 0);
3906       vat_json_object_add_string_copy (e, "reid", s);
3907       vec_free (s);
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3920 {
3921   vat_main_t *vam = &vat_main;
3922
3923   print (vam->ofp, "%=20U",
3924          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3925          mp->ip_address);
3926 }
3927
3928 static void
3929   vl_api_one_map_server_details_t_handler_json
3930   (vl_api_one_map_server_details_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t *node = NULL;
3934   struct in6_addr ip6;
3935   struct in_addr ip4;
3936
3937   if (VAT_JSON_ARRAY != vam->json_tree.type)
3938     {
3939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3940       vat_json_init_array (&vam->json_tree);
3941     }
3942   node = vat_json_array_add (&vam->json_tree);
3943
3944   vat_json_init_object (node);
3945   if (mp->is_ipv6)
3946     {
3947       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3948       vat_json_object_add_ip6 (node, "map-server", ip6);
3949     }
3950   else
3951     {
3952       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3953       vat_json_object_add_ip4 (node, "map-server", ip4);
3954     }
3955 }
3956
3957 static void
3958 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3959                                            * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962
3963   print (vam->ofp, "%=20U",
3964          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3965          mp->ip_address);
3966 }
3967
3968 static void
3969   vl_api_one_map_resolver_details_t_handler_json
3970   (vl_api_one_map_resolver_details_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   vat_json_node_t *node = NULL;
3974   struct in6_addr ip6;
3975   struct in_addr ip4;
3976
3977   if (VAT_JSON_ARRAY != vam->json_tree.type)
3978     {
3979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3980       vat_json_init_array (&vam->json_tree);
3981     }
3982   node = vat_json_array_add (&vam->json_tree);
3983
3984   vat_json_init_object (node);
3985   if (mp->is_ipv6)
3986     {
3987       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3988       vat_json_object_add_ip6 (node, "map resolver", ip6);
3989     }
3990   else
3991     {
3992       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3993       vat_json_object_add_ip4 (node, "map resolver", ip4);
3994     }
3995 }
3996
3997 static void
3998 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   i32 retval = ntohl (mp->retval);
4002
4003   if (0 <= retval)
4004     {
4005       print (vam->ofp, "feature: %s\ngpe: %s",
4006              mp->feature_status ? "enabled" : "disabled",
4007              mp->gpe_status ? "enabled" : "disabled");
4008     }
4009
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015   vl_api_show_one_status_reply_t_handler_json
4016   (vl_api_show_one_status_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   vat_json_node_t node;
4020   u8 *gpe_status = NULL;
4021   u8 *feature_status = NULL;
4022
4023   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4024   feature_status = format (0, "%s",
4025                            mp->feature_status ? "enabled" : "disabled");
4026   vec_add1 (gpe_status, 0);
4027   vec_add1 (feature_status, 0);
4028
4029   vat_json_init_object (&node);
4030   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4031   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4032
4033   vec_free (gpe_status);
4034   vec_free (feature_status);
4035
4036   vat_json_print (vam->ofp, &node);
4037   vat_json_free (&node);
4038
4039   vam->retval = ntohl (mp->retval);
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4045   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   i32 retval = ntohl (mp->retval);
4049
4050   if (retval >= 0)
4051     {
4052       print (vam->ofp, "%=20s", mp->locator_set_name);
4053     }
4054
4055   vam->retval = retval;
4056   vam->result_ready = 1;
4057 }
4058
4059 static void
4060   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4061   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   vat_json_node_t *node = NULL;
4065
4066   if (VAT_JSON_ARRAY != vam->json_tree.type)
4067     {
4068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4069       vat_json_init_array (&vam->json_tree);
4070     }
4071   node = vat_json_array_add (&vam->json_tree);
4072
4073   vat_json_init_object (node);
4074   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4075
4076   vat_json_print (vam->ofp, node);
4077   vat_json_free (node);
4078
4079   vam->retval = ntohl (mp->retval);
4080   vam->result_ready = 1;
4081 }
4082
4083 static u8 *
4084 format_lisp_map_request_mode (u8 * s, va_list * args)
4085 {
4086   u32 mode = va_arg (*args, u32);
4087
4088   switch (mode)
4089     {
4090     case 0:
4091       return format (0, "dst-only");
4092     case 1:
4093       return format (0, "src-dst");
4094     }
4095   return 0;
4096 }
4097
4098 static void
4099   vl_api_show_one_map_request_mode_reply_t_handler
4100   (vl_api_show_one_map_request_mode_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       u32 mode = mp->mode;
4108       print (vam->ofp, "map_request_mode: %U",
4109              format_lisp_map_request_mode, mode);
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_map_request_mode_reply_t_handler_json
4118   (vl_api_show_one_map_request_mode_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *s = 0;
4123   u32 mode;
4124
4125   mode = mp->mode;
4126   s = format (0, "%U", format_lisp_map_request_mode, mode);
4127   vec_add1 (s, 0);
4128
4129   vat_json_init_object (&node);
4130   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4131   vat_json_print (vam->ofp, &node);
4132   vat_json_free (&node);
4133
4134   vec_free (s);
4135   vam->retval = ntohl (mp->retval);
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_one_show_xtr_mode_reply_t_handler
4141   (vl_api_one_show_xtr_mode_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (0 <= retval)
4147     {
4148       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_show_xtr_mode_reply_t_handler_json
4157   (vl_api_one_show_xtr_mode_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t node;
4161   u8 *status = 0;
4162
4163   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4164   vec_add1 (status, 0);
4165
4166   vat_json_init_object (&node);
4167   vat_json_object_add_string_copy (&node, "status", status);
4168
4169   vec_free (status);
4170
4171   vat_json_print (vam->ofp, &node);
4172   vat_json_free (&node);
4173
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_show_pitr_mode_reply_t_handler
4180   (vl_api_one_show_pitr_mode_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   i32 retval = ntohl (mp->retval);
4184
4185   if (0 <= retval)
4186     {
4187       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4188     }
4189
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_show_pitr_mode_reply_t_handler_json
4196   (vl_api_one_show_pitr_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t node;
4200   u8 *status = 0;
4201
4202   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4203   vec_add1 (status, 0);
4204
4205   vat_json_init_object (&node);
4206   vat_json_object_add_string_copy (&node, "status", status);
4207
4208   vec_free (status);
4209
4210   vat_json_print (vam->ofp, &node);
4211   vat_json_free (&node);
4212
4213   vam->retval = ntohl (mp->retval);
4214   vam->result_ready = 1;
4215 }
4216
4217 static void
4218   vl_api_one_show_petr_mode_reply_t_handler
4219   (vl_api_one_show_petr_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4227     }
4228
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_one_show_petr_mode_reply_t_handler_json
4235   (vl_api_one_show_petr_mode_reply_t * mp)
4236 {
4237   vat_main_t *vam = &vat_main;
4238   vat_json_node_t node;
4239   u8 *status = 0;
4240
4241   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4242   vec_add1 (status, 0);
4243
4244   vat_json_init_object (&node);
4245   vat_json_object_add_string_copy (&node, "status", status);
4246
4247   vec_free (status);
4248
4249   vat_json_print (vam->ofp, &node);
4250   vat_json_free (&node);
4251
4252   vam->retval = ntohl (mp->retval);
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_show_one_use_petr_reply_t_handler
4258   (vl_api_show_one_use_petr_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   i32 retval = ntohl (mp->retval);
4262
4263   if (0 <= retval)
4264     {
4265       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4266       if (mp->status)
4267         {
4268           print (vam->ofp, "Proxy-ETR address; %U",
4269                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4270                  mp->address);
4271         }
4272     }
4273
4274   vam->retval = retval;
4275   vam->result_ready = 1;
4276 }
4277
4278 static void
4279   vl_api_show_one_use_petr_reply_t_handler_json
4280   (vl_api_show_one_use_petr_reply_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t node;
4284   u8 *status = 0;
4285   struct in_addr ip4;
4286   struct in6_addr ip6;
4287
4288   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293   if (mp->status)
4294     {
4295       if (mp->is_ip4)
4296         {
4297           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4298           vat_json_object_add_ip6 (&node, "address", ip6);
4299         }
4300       else
4301         {
4302           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4303           vat_json_object_add_ip4 (&node, "address", ip4);
4304         }
4305     }
4306
4307   vec_free (status);
4308
4309   vat_json_print (vam->ofp, &node);
4310   vat_json_free (&node);
4311
4312   vam->retval = ntohl (mp->retval);
4313   vam->result_ready = 1;
4314 }
4315
4316 static void
4317   vl_api_show_one_nsh_mapping_reply_t_handler
4318   (vl_api_show_one_nsh_mapping_reply_t * mp)
4319 {
4320   vat_main_t *vam = &vat_main;
4321   i32 retval = ntohl (mp->retval);
4322
4323   if (0 <= retval)
4324     {
4325       print (vam->ofp, "%-20s%-16s",
4326              mp->is_set ? "set" : "not-set",
4327              mp->is_set ? (char *) mp->locator_set_name : "");
4328     }
4329
4330   vam->retval = retval;
4331   vam->result_ready = 1;
4332 }
4333
4334 static void
4335   vl_api_show_one_nsh_mapping_reply_t_handler_json
4336   (vl_api_show_one_nsh_mapping_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   vat_json_node_t node;
4340   u8 *status = 0;
4341
4342   status = format (0, "%s", mp->is_set ? "yes" : "no");
4343   vec_add1 (status, 0);
4344
4345   vat_json_init_object (&node);
4346   vat_json_object_add_string_copy (&node, "is_set", status);
4347   if (mp->is_set)
4348     {
4349       vat_json_object_add_string_copy (&node, "locator_set",
4350                                        mp->locator_set_name);
4351     }
4352
4353   vec_free (status);
4354
4355   vat_json_print (vam->ofp, &node);
4356   vat_json_free (&node);
4357
4358   vam->retval = ntohl (mp->retval);
4359   vam->result_ready = 1;
4360 }
4361
4362 static void
4363   vl_api_show_one_map_register_ttl_reply_t_handler
4364   (vl_api_show_one_map_register_ttl_reply_t * mp)
4365 {
4366   vat_main_t *vam = &vat_main;
4367   i32 retval = ntohl (mp->retval);
4368
4369   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "ttl: %u", mp->ttl);
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_map_register_ttl_reply_t_handler_json
4382   (vl_api_show_one_map_register_ttl_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386
4387   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4388   vat_json_init_object (&node);
4389   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static void
4399 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4400 {
4401   vat_main_t *vam = &vat_main;
4402   i32 retval = ntohl (mp->retval);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "%-20s%-16s",
4407              mp->status ? "enabled" : "disabled",
4408              mp->status ? (char *) mp->locator_set_name : "");
4409     }
4410
4411   vam->retval = retval;
4412   vam->result_ready = 1;
4413 }
4414
4415 static void
4416 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4417 {
4418   vat_main_t *vam = &vat_main;
4419   vat_json_node_t node;
4420   u8 *status = 0;
4421
4422   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4423   vec_add1 (status, 0);
4424
4425   vat_json_init_object (&node);
4426   vat_json_object_add_string_copy (&node, "status", status);
4427   if (mp->status)
4428     {
4429       vat_json_object_add_string_copy (&node, "locator_set",
4430                                        mp->locator_set_name);
4431     }
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static u8 *
4443 format_policer_type (u8 * s, va_list * va)
4444 {
4445   u32 i = va_arg (*va, u32);
4446
4447   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4448     s = format (s, "1r2c");
4449   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4450     s = format (s, "1r3c");
4451   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4452     s = format (s, "2r3c-2698");
4453   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4454     s = format (s, "2r3c-4115");
4455   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4456     s = format (s, "2r3c-mef5cf1");
4457   else
4458     s = format (s, "ILLEGAL");
4459   return s;
4460 }
4461
4462 static u8 *
4463 format_policer_rate_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_RATE_KBPS)
4468     s = format (s, "kbps");
4469   else if (i == SSE2_QOS_RATE_PPS)
4470     s = format (s, "pps");
4471   else
4472     s = format (s, "ILLEGAL");
4473   return s;
4474 }
4475
4476 static u8 *
4477 format_policer_round_type (u8 * s, va_list * va)
4478 {
4479   u32 i = va_arg (*va, u32);
4480
4481   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4482     s = format (s, "closest");
4483   else if (i == SSE2_QOS_ROUND_TO_UP)
4484     s = format (s, "up");
4485   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4486     s = format (s, "down");
4487   else
4488     s = format (s, "ILLEGAL");
4489   return s;
4490 }
4491
4492 static u8 *
4493 format_policer_action_type (u8 * s, va_list * va)
4494 {
4495   u32 i = va_arg (*va, u32);
4496
4497   if (i == SSE2_QOS_ACTION_DROP)
4498     s = format (s, "drop");
4499   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4500     s = format (s, "transmit");
4501   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4502     s = format (s, "mark-and-transmit");
4503   else
4504     s = format (s, "ILLEGAL");
4505   return s;
4506 }
4507
4508 static u8 *
4509 format_dscp (u8 * s, va_list * va)
4510 {
4511   u32 i = va_arg (*va, u32);
4512   char *t = 0;
4513
4514   switch (i)
4515     {
4516 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4517       foreach_vnet_dscp
4518 #undef _
4519     default:
4520       return format (s, "ILLEGAL");
4521     }
4522   s = format (s, "%s", t);
4523   return s;
4524 }
4525
4526 static void
4527 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4528 {
4529   vat_main_t *vam = &vat_main;
4530   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4531
4532   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4533     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4534   else
4535     conform_dscp_str = format (0, "");
4536
4537   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4538     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4539   else
4540     exceed_dscp_str = format (0, "");
4541
4542   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4544   else
4545     violate_dscp_str = format (0, "");
4546
4547   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4548          "rate type %U, round type %U, %s rate, %s color-aware, "
4549          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4550          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4551          "conform action %U%s, exceed action %U%s, violate action %U%s",
4552          mp->name,
4553          format_policer_type, mp->type,
4554          ntohl (mp->cir),
4555          ntohl (mp->eir),
4556          clib_net_to_host_u64 (mp->cb),
4557          clib_net_to_host_u64 (mp->eb),
4558          format_policer_rate_type, mp->rate_type,
4559          format_policer_round_type, mp->round_type,
4560          mp->single_rate ? "single" : "dual",
4561          mp->color_aware ? "is" : "not",
4562          ntohl (mp->cir_tokens_per_period),
4563          ntohl (mp->pir_tokens_per_period),
4564          ntohl (mp->scale),
4565          ntohl (mp->current_limit),
4566          ntohl (mp->current_bucket),
4567          ntohl (mp->extended_limit),
4568          ntohl (mp->extended_bucket),
4569          clib_net_to_host_u64 (mp->last_update_time),
4570          format_policer_action_type, mp->conform_action_type,
4571          conform_dscp_str,
4572          format_policer_action_type, mp->exceed_action_type,
4573          exceed_dscp_str,
4574          format_policer_action_type, mp->violate_action_type,
4575          violate_dscp_str);
4576
4577   vec_free (conform_dscp_str);
4578   vec_free (exceed_dscp_str);
4579   vec_free (violate_dscp_str);
4580 }
4581
4582 static void vl_api_policer_details_t_handler_json
4583   (vl_api_policer_details_t * mp)
4584 {
4585   vat_main_t *vam = &vat_main;
4586   vat_json_node_t *node;
4587   u8 *rate_type_str, *round_type_str, *type_str;
4588   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4589
4590   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4591   round_type_str =
4592     format (0, "%U", format_policer_round_type, mp->round_type);
4593   type_str = format (0, "%U", format_policer_type, mp->type);
4594   conform_action_str = format (0, "%U", format_policer_action_type,
4595                                mp->conform_action_type);
4596   exceed_action_str = format (0, "%U", format_policer_action_type,
4597                               mp->exceed_action_type);
4598   violate_action_str = format (0, "%U", format_policer_action_type,
4599                                mp->violate_action_type);
4600
4601   if (VAT_JSON_ARRAY != vam->json_tree.type)
4602     {
4603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4604       vat_json_init_array (&vam->json_tree);
4605     }
4606   node = vat_json_array_add (&vam->json_tree);
4607
4608   vat_json_init_object (node);
4609   vat_json_object_add_string_copy (node, "name", mp->name);
4610   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4611   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4612   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4613   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4614   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4615   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4616   vat_json_object_add_string_copy (node, "type", type_str);
4617   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4618   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4619   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4620   vat_json_object_add_uint (node, "cir_tokens_per_period",
4621                             ntohl (mp->cir_tokens_per_period));
4622   vat_json_object_add_uint (node, "eir_tokens_per_period",
4623                             ntohl (mp->pir_tokens_per_period));
4624   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4625   vat_json_object_add_uint (node, "current_bucket",
4626                             ntohl (mp->current_bucket));
4627   vat_json_object_add_uint (node, "extended_limit",
4628                             ntohl (mp->extended_limit));
4629   vat_json_object_add_uint (node, "extended_bucket",
4630                             ntohl (mp->extended_bucket));
4631   vat_json_object_add_uint (node, "last_update_time",
4632                             ntohl (mp->last_update_time));
4633   vat_json_object_add_string_copy (node, "conform_action",
4634                                    conform_action_str);
4635   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4638       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4642   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4643     {
4644       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4645       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4646       vec_free (dscp_str);
4647     }
4648   vat_json_object_add_string_copy (node, "violate_action",
4649                                    violate_action_str);
4650   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4651     {
4652       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4653       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4654       vec_free (dscp_str);
4655     }
4656
4657   vec_free (rate_type_str);
4658   vec_free (round_type_str);
4659   vec_free (type_str);
4660   vec_free (conform_action_str);
4661   vec_free (exceed_action_str);
4662   vec_free (violate_action_str);
4663 }
4664
4665 static void
4666 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4667                                            mp)
4668 {
4669   vat_main_t *vam = &vat_main;
4670   int i, count = ntohl (mp->count);
4671
4672   if (count > 0)
4673     print (vam->ofp, "classify table ids (%d) : ", count);
4674   for (i = 0; i < count; i++)
4675     {
4676       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4677       print (vam->ofp, (i < count - 1) ? "," : "");
4678     }
4679   vam->retval = ntohl (mp->retval);
4680   vam->result_ready = 1;
4681 }
4682
4683 static void
4684   vl_api_classify_table_ids_reply_t_handler_json
4685   (vl_api_classify_table_ids_reply_t * mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   int i, count = ntohl (mp->count);
4689
4690   if (count > 0)
4691     {
4692       vat_json_node_t node;
4693
4694       vat_json_init_object (&node);
4695       for (i = 0; i < count; i++)
4696         {
4697           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4698         }
4699       vat_json_print (vam->ofp, &node);
4700       vat_json_free (&node);
4701     }
4702   vam->retval = ntohl (mp->retval);
4703   vam->result_ready = 1;
4704 }
4705
4706 static void
4707   vl_api_classify_table_by_interface_reply_t_handler
4708   (vl_api_classify_table_by_interface_reply_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   u32 table_id;
4712
4713   table_id = ntohl (mp->l2_table_id);
4714   if (table_id != ~0)
4715     print (vam->ofp, "l2 table id : %d", table_id);
4716   else
4717     print (vam->ofp, "l2 table id : No input ACL tables configured");
4718   table_id = ntohl (mp->ip4_table_id);
4719   if (table_id != ~0)
4720     print (vam->ofp, "ip4 table id : %d", table_id);
4721   else
4722     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4723   table_id = ntohl (mp->ip6_table_id);
4724   if (table_id != ~0)
4725     print (vam->ofp, "ip6 table id : %d", table_id);
4726   else
4727     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4728   vam->retval = ntohl (mp->retval);
4729   vam->result_ready = 1;
4730 }
4731
4732 static void
4733   vl_api_classify_table_by_interface_reply_t_handler_json
4734   (vl_api_classify_table_by_interface_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   vat_json_node_t node;
4738
4739   vat_json_init_object (&node);
4740
4741   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4742   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4743   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4744
4745   vat_json_print (vam->ofp, &node);
4746   vat_json_free (&node);
4747
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void vl_api_policer_add_del_reply_t_handler
4753   (vl_api_policer_add_del_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   i32 retval = ntohl (mp->retval);
4757   if (vam->async_mode)
4758     {
4759       vam->async_errors += (retval < 0);
4760     }
4761   else
4762     {
4763       vam->retval = retval;
4764       vam->result_ready = 1;
4765       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4766         /*
4767          * Note: this is just barely thread-safe, depends on
4768          * the main thread spinning waiting for an answer...
4769          */
4770         errmsg ("policer index %d", ntohl (mp->policer_index));
4771     }
4772 }
4773
4774 static void vl_api_policer_add_del_reply_t_handler_json
4775   (vl_api_policer_add_del_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   vat_json_node_t node;
4779
4780   vat_json_init_object (&node);
4781   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4782   vat_json_object_add_uint (&node, "policer_index",
4783                             ntohl (mp->policer_index));
4784
4785   vat_json_print (vam->ofp, &node);
4786   vat_json_free (&node);
4787
4788   vam->retval = ntohl (mp->retval);
4789   vam->result_ready = 1;
4790 }
4791
4792 /* Format hex dump. */
4793 u8 *
4794 format_hex_bytes (u8 * s, va_list * va)
4795 {
4796   u8 *bytes = va_arg (*va, u8 *);
4797   int n_bytes = va_arg (*va, int);
4798   uword i;
4799
4800   /* Print short or long form depending on byte count. */
4801   uword short_form = n_bytes <= 32;
4802   u32 indent = format_get_indent (s);
4803
4804   if (n_bytes == 0)
4805     return s;
4806
4807   for (i = 0; i < n_bytes; i++)
4808     {
4809       if (!short_form && (i % 32) == 0)
4810         s = format (s, "%08x: ", i);
4811       s = format (s, "%02x", bytes[i]);
4812       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4813         s = format (s, "\n%U", format_white_space, indent);
4814     }
4815
4816   return s;
4817 }
4818
4819 static void
4820 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4821                                             * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (retval == 0)
4826     {
4827       print (vam->ofp, "classify table info :");
4828       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4829              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4830              ntohl (mp->miss_next_index));
4831       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4832              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4833              ntohl (mp->match_n_vectors));
4834       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4835              ntohl (mp->mask_length));
4836     }
4837   vam->retval = retval;
4838   vam->result_ready = 1;
4839 }
4840
4841 static void
4842   vl_api_classify_table_info_reply_t_handler_json
4843   (vl_api_classify_table_info_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   i32 retval = ntohl (mp->retval);
4849   if (retval == 0)
4850     {
4851       vat_json_init_object (&node);
4852
4853       vat_json_object_add_int (&node, "sessions",
4854                                ntohl (mp->active_sessions));
4855       vat_json_object_add_int (&node, "nexttbl",
4856                                ntohl (mp->next_table_index));
4857       vat_json_object_add_int (&node, "nextnode",
4858                                ntohl (mp->miss_next_index));
4859       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4860       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4861       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4862       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4863                       ntohl (mp->mask_length), 0);
4864       vat_json_object_add_string_copy (&node, "mask", s);
4865
4866       vat_json_print (vam->ofp, &node);
4867       vat_json_free (&node);
4868     }
4869   vam->retval = ntohl (mp->retval);
4870   vam->result_ready = 1;
4871 }
4872
4873 static void
4874 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4875                                            mp)
4876 {
4877   vat_main_t *vam = &vat_main;
4878
4879   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4880          ntohl (mp->hit_next_index), ntohl (mp->advance),
4881          ntohl (mp->opaque_index));
4882   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4883          ntohl (mp->match_length));
4884 }
4885
4886 static void
4887   vl_api_classify_session_details_t_handler_json
4888   (vl_api_classify_session_details_t * mp)
4889 {
4890   vat_main_t *vam = &vat_main;
4891   vat_json_node_t *node = NULL;
4892
4893   if (VAT_JSON_ARRAY != vam->json_tree.type)
4894     {
4895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4896       vat_json_init_array (&vam->json_tree);
4897     }
4898   node = vat_json_array_add (&vam->json_tree);
4899
4900   vat_json_init_object (node);
4901   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4902   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4903   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4904   u8 *s =
4905     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4906             0);
4907   vat_json_object_add_string_copy (node, "match", s);
4908 }
4909
4910 static void vl_api_pg_create_interface_reply_t_handler
4911   (vl_api_pg_create_interface_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914
4915   vam->retval = ntohl (mp->retval);
4916   vam->result_ready = 1;
4917 }
4918
4919 static void vl_api_pg_create_interface_reply_t_handler_json
4920   (vl_api_pg_create_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   i32 retval = ntohl (mp->retval);
4926   if (retval == 0)
4927     {
4928       vat_json_init_object (&node);
4929
4930       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4931
4932       vat_json_print (vam->ofp, &node);
4933       vat_json_free (&node);
4934     }
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_policer_classify_details_t_handler
4940   (vl_api_policer_classify_details_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4945          ntohl (mp->table_index));
4946 }
4947
4948 static void vl_api_policer_classify_details_t_handler_json
4949   (vl_api_policer_classify_details_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t *node;
4953
4954   if (VAT_JSON_ARRAY != vam->json_tree.type)
4955     {
4956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4957       vat_json_init_array (&vam->json_tree);
4958     }
4959   node = vat_json_array_add (&vam->json_tree);
4960
4961   vat_json_init_object (node);
4962   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4963   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4964 }
4965
4966 static void vl_api_flow_classify_details_t_handler
4967   (vl_api_flow_classify_details_t * mp)
4968 {
4969   vat_main_t *vam = &vat_main;
4970
4971   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4972          ntohl (mp->table_index));
4973 }
4974
4975 static void vl_api_flow_classify_details_t_handler_json
4976   (vl_api_flow_classify_details_t * mp)
4977 {
4978   vat_main_t *vam = &vat_main;
4979   vat_json_node_t *node;
4980
4981   if (VAT_JSON_ARRAY != vam->json_tree.type)
4982     {
4983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4984       vat_json_init_array (&vam->json_tree);
4985     }
4986   node = vat_json_array_add (&vam->json_tree);
4987
4988   vat_json_init_object (node);
4989   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4990   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4991 }
4992
4993 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4994 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4995 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4996 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4997 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4999 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5000 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5001 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5002 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5003
5004 /*
5005  * Generate boilerplate reply handlers, which
5006  * dig the return value out of the xxx_reply_t API message,
5007  * stick it into vam->retval, and set vam->result_ready
5008  *
5009  * Could also do this by pointing N message decode slots at
5010  * a single function, but that could break in subtle ways.
5011  */
5012
5013 #define foreach_standard_reply_retval_handler           \
5014 _(sw_interface_set_flags_reply)                         \
5015 _(sw_interface_add_del_address_reply)                   \
5016 _(sw_interface_set_rx_mode_reply)                       \
5017 _(sw_interface_set_rx_placement_reply)                  \
5018 _(sw_interface_set_table_reply)                         \
5019 _(sw_interface_set_mpls_enable_reply)                   \
5020 _(sw_interface_set_vpath_reply)                         \
5021 _(sw_interface_set_vxlan_bypass_reply)                  \
5022 _(sw_interface_set_geneve_bypass_reply)                 \
5023 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5024 _(sw_interface_set_l2_bridge_reply)                     \
5025 _(sw_interface_set_bond_weight_reply)                   \
5026 _(bridge_domain_add_del_reply)                          \
5027 _(sw_interface_set_l2_xconnect_reply)                   \
5028 _(l2fib_add_del_reply)                                  \
5029 _(l2fib_flush_int_reply)                                \
5030 _(l2fib_flush_bd_reply)                                 \
5031 _(ip_route_add_del_reply)                               \
5032 _(ip_table_add_del_reply)                               \
5033 _(ip_table_replace_begin_reply)                         \
5034 _(ip_table_flush_reply)                                 \
5035 _(ip_table_replace_end_reply)                           \
5036 _(ip_mroute_add_del_reply)                              \
5037 _(mpls_route_add_del_reply)                             \
5038 _(mpls_table_add_del_reply)                             \
5039 _(mpls_ip_bind_unbind_reply)                            \
5040 _(bier_route_add_del_reply)                             \
5041 _(bier_table_add_del_reply)                             \
5042 _(sw_interface_set_unnumbered_reply)                    \
5043 _(set_ip_flow_hash_reply)                               \
5044 _(sw_interface_ip6_enable_disable_reply)                \
5045 _(l2_patch_add_del_reply)                               \
5046 _(sr_mpls_policy_add_reply)                             \
5047 _(sr_mpls_policy_mod_reply)                             \
5048 _(sr_mpls_policy_del_reply)                             \
5049 _(sr_policy_add_reply)                                  \
5050 _(sr_policy_mod_reply)                                  \
5051 _(sr_policy_del_reply)                                  \
5052 _(sr_localsid_add_del_reply)                            \
5053 _(sr_steering_add_del_reply)                            \
5054 _(classify_add_del_session_reply)                       \
5055 _(classify_set_interface_ip_table_reply)                \
5056 _(classify_set_interface_l2_tables_reply)               \
5057 _(l2tpv3_set_tunnel_cookies_reply)                      \
5058 _(l2tpv3_interface_enable_disable_reply)                \
5059 _(l2tpv3_set_lookup_key_reply)                          \
5060 _(l2_fib_clear_table_reply)                             \
5061 _(l2_interface_efp_filter_reply)                        \
5062 _(l2_interface_vlan_tag_rewrite_reply)                  \
5063 _(modify_vhost_user_if_reply)                           \
5064 _(delete_vhost_user_if_reply)                           \
5065 _(want_l2_macs_events_reply)                            \
5066 _(input_acl_set_interface_reply)                        \
5067 _(ipsec_spd_add_del_reply)                              \
5068 _(ipsec_interface_add_del_spd_reply)                    \
5069 _(ipsec_spd_entry_add_del_reply)                        \
5070 _(ipsec_sad_entry_add_del_reply)                        \
5071 _(ipsec_tunnel_if_add_del_reply)                        \
5072 _(ipsec_tunnel_if_set_sa_reply)                         \
5073 _(delete_loopback_reply)                                \
5074 _(bd_ip_mac_add_del_reply)                              \
5075 _(bd_ip_mac_flush_reply)                                \
5076 _(want_interface_events_reply)                          \
5077 _(cop_interface_enable_disable_reply)                   \
5078 _(cop_whitelist_enable_disable_reply)                   \
5079 _(sw_interface_clear_stats_reply)                       \
5080 _(ioam_enable_reply)                                    \
5081 _(ioam_disable_reply)                                   \
5082 _(one_add_del_locator_reply)                            \
5083 _(one_add_del_local_eid_reply)                          \
5084 _(one_add_del_remote_mapping_reply)                     \
5085 _(one_add_del_adjacency_reply)                          \
5086 _(one_add_del_map_resolver_reply)                       \
5087 _(one_add_del_map_server_reply)                         \
5088 _(one_enable_disable_reply)                             \
5089 _(one_rloc_probe_enable_disable_reply)                  \
5090 _(one_map_register_enable_disable_reply)                \
5091 _(one_map_register_set_ttl_reply)                       \
5092 _(one_set_transport_protocol_reply)                     \
5093 _(one_map_register_fallback_threshold_reply)            \
5094 _(one_pitr_set_locator_set_reply)                       \
5095 _(one_map_request_mode_reply)                           \
5096 _(one_add_del_map_request_itr_rlocs_reply)              \
5097 _(one_eid_table_add_del_map_reply)                      \
5098 _(one_use_petr_reply)                                   \
5099 _(one_stats_enable_disable_reply)                       \
5100 _(one_add_del_l2_arp_entry_reply)                       \
5101 _(one_add_del_ndp_entry_reply)                          \
5102 _(one_stats_flush_reply)                                \
5103 _(one_enable_disable_xtr_mode_reply)                    \
5104 _(one_enable_disable_pitr_mode_reply)                   \
5105 _(one_enable_disable_petr_mode_reply)                   \
5106 _(gpe_enable_disable_reply)                             \
5107 _(gpe_set_encap_mode_reply)                             \
5108 _(gpe_add_del_iface_reply)                              \
5109 _(gpe_add_del_native_fwd_rpath_reply)                   \
5110 _(af_packet_delete_reply)                               \
5111 _(policer_classify_set_interface_reply)                 \
5112 _(netmap_create_reply)                                  \
5113 _(netmap_delete_reply)                                  \
5114 _(set_ipfix_exporter_reply)                             \
5115 _(set_ipfix_classify_stream_reply)                      \
5116 _(ipfix_classify_table_add_del_reply)                   \
5117 _(flow_classify_set_interface_reply)                    \
5118 _(sw_interface_span_enable_disable_reply)               \
5119 _(pg_capture_reply)                                     \
5120 _(pg_enable_disable_reply)                              \
5121 _(ip_source_and_port_range_check_add_del_reply)         \
5122 _(ip_source_and_port_range_check_interface_add_del_reply)\
5123 _(delete_subif_reply)                                   \
5124 _(l2_interface_pbb_tag_rewrite_reply)                   \
5125 _(set_punt_reply)                                       \
5126 _(feature_enable_disable_reply)                         \
5127 _(feature_gso_enable_disable_reply)                     \
5128 _(sw_interface_tag_add_del_reply)                       \
5129 _(sw_interface_add_del_mac_address_reply)               \
5130 _(hw_interface_set_mtu_reply)                           \
5131 _(p2p_ethernet_add_reply)                               \
5132 _(p2p_ethernet_del_reply)                               \
5133 _(lldp_config_reply)                                    \
5134 _(sw_interface_set_lldp_reply)                          \
5135 _(tcp_configure_src_addresses_reply)                    \
5136 _(session_rule_add_del_reply)                           \
5137 _(ip_container_proxy_add_del_reply)                     \
5138 _(output_acl_set_interface_reply)                       \
5139 _(qos_record_enable_disable_reply)
5140
5141 #define _(n)                                    \
5142     static void vl_api_##n##_t_handler          \
5143     (vl_api_##n##_t * mp)                       \
5144     {                                           \
5145         vat_main_t * vam = &vat_main;           \
5146         i32 retval = ntohl(mp->retval);         \
5147         if (vam->async_mode) {                  \
5148             vam->async_errors += (retval < 0);  \
5149         } else {                                \
5150             vam->retval = retval;               \
5151             vam->result_ready = 1;              \
5152         }                                       \
5153     }
5154 foreach_standard_reply_retval_handler;
5155 #undef _
5156
5157 #define _(n)                                    \
5158     static void vl_api_##n##_t_handler_json     \
5159     (vl_api_##n##_t * mp)                       \
5160     {                                           \
5161         vat_main_t * vam = &vat_main;           \
5162         vat_json_node_t node;                   \
5163         vat_json_init_object(&node);            \
5164         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5165         vat_json_print(vam->ofp, &node);        \
5166         vam->retval = ntohl(mp->retval);        \
5167         vam->result_ready = 1;                  \
5168     }
5169 foreach_standard_reply_retval_handler;
5170 #undef _
5171
5172 /*
5173  * Table of message reply handlers, must include boilerplate handlers
5174  * we just generated
5175  */
5176
5177 #define foreach_vpe_api_reply_msg                                       \
5178 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5179 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5180 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5181 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5182 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5183 _(CLI_REPLY, cli_reply)                                                 \
5184 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5185 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5186   sw_interface_add_del_address_reply)                                   \
5187 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5188 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5189 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5190 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5191 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5192 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5193 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5194 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5195 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5196 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5197   sw_interface_set_l2_xconnect_reply)                                   \
5198 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5199   sw_interface_set_l2_bridge_reply)                                     \
5200 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5201 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5202 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5203 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5204 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5205 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5206 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5207 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5208 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5209 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5210 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5211 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5212 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5213 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5214 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5215 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5216 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5217 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5218 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5219 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5220 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5221 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5222 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5223 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5224 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5225 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5226 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5227 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5228 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5229 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5230 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5231 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5232 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5233 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5234   sw_interface_set_unnumbered_reply)                                    \
5235 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5236 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5237 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5238 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5239   sw_interface_ip6_enable_disable_reply)                                \
5240 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5241 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5242 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5243 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5244 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5245 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5246 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5247 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5248 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5249 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5250 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5251 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5252 classify_set_interface_ip_table_reply)                                  \
5253 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5254   classify_set_interface_l2_tables_reply)                               \
5255 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5256 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5257 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5258 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5259 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5260   l2tpv3_interface_enable_disable_reply)                                \
5261 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5262 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5263 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5264 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5265 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5266 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5267 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5268 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5269 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5270 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5271 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5272 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5273 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5274 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5275 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5276 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5277 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5278 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5279 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5280 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5281 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5282 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5283 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5284 _(L2_MACS_EVENT, l2_macs_event)                                         \
5285 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5286 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5287 _(IP_DETAILS, ip_details)                                               \
5288 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5289 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5290 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5291 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5292 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5293 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5294 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5295 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5296 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5297 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5298 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5299 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5300 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5301 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5302 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5303 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5304 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5305 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5306 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5307 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5308 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5309 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5310 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5311 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5312 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5313 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5314 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5315 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5316   one_map_register_enable_disable_reply)                                \
5317 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5318 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5319 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5320 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5321   one_map_register_fallback_threshold_reply)                            \
5322 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5323   one_rloc_probe_enable_disable_reply)                                  \
5324 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5325 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5326 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5327 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5328 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5329 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5330 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5331 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5332 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5333 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5334 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5335 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5336 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5337 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5338 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5339 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5340   show_one_stats_enable_disable_reply)                                  \
5341 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5342 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5343 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5344 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5345 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5346 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5347 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5348 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5349   one_enable_disable_pitr_mode_reply)                                   \
5350 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5351   one_enable_disable_petr_mode_reply)                                   \
5352 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5353 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5354 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5355 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5356 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5357 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5358 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5359 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5360 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5361 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5362 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5363 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5364   gpe_add_del_native_fwd_rpath_reply)                                   \
5365 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5366   gpe_fwd_entry_path_details)                                           \
5367 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5368 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5369   one_add_del_map_request_itr_rlocs_reply)                              \
5370 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5371   one_get_map_request_itr_rlocs_reply)                                  \
5372 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5373 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5374 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5375 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5376 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5377 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5378   show_one_map_register_state_reply)                                    \
5379 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5380 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5381   show_one_map_register_fallback_threshold_reply)                       \
5382 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5383 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5384 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5385 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5386 _(POLICER_DETAILS, policer_details)                                     \
5387 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5388 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5389 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5390 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5391 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5392 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5393 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5394 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5395 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5396 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5397 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5398 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5399 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5400 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5401 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5402 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5403 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5404 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5405 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5406 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5407 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5408 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5409 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5410 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5411 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5412 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5413  ip_source_and_port_range_check_add_del_reply)                          \
5414 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5415  ip_source_and_port_range_check_interface_add_del_reply)                \
5416 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5417 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5418 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5419 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5420 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5421 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5422 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5423 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5424 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5425 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5426 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5427 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5428 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5429 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5430 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5431 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5432 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5433 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5434 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5435 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5436 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5437 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5438 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5439
5440 #define foreach_standalone_reply_msg                                    \
5441 _(SW_INTERFACE_EVENT, sw_interface_event)
5442
5443 typedef struct
5444 {
5445   u8 *name;
5446   u32 value;
5447 } name_sort_t;
5448
5449 #define STR_VTR_OP_CASE(op)     \
5450     case L2_VTR_ ## op:         \
5451         return "" # op;
5452
5453 static const char *
5454 str_vtr_op (u32 vtr_op)
5455 {
5456   switch (vtr_op)
5457     {
5458       STR_VTR_OP_CASE (DISABLED);
5459       STR_VTR_OP_CASE (PUSH_1);
5460       STR_VTR_OP_CASE (PUSH_2);
5461       STR_VTR_OP_CASE (POP_1);
5462       STR_VTR_OP_CASE (POP_2);
5463       STR_VTR_OP_CASE (TRANSLATE_1_1);
5464       STR_VTR_OP_CASE (TRANSLATE_1_2);
5465       STR_VTR_OP_CASE (TRANSLATE_2_1);
5466       STR_VTR_OP_CASE (TRANSLATE_2_2);
5467     }
5468
5469   return "UNKNOWN";
5470 }
5471
5472 static int
5473 dump_sub_interface_table (vat_main_t * vam)
5474 {
5475   const sw_interface_subif_t *sub = NULL;
5476
5477   if (vam->json_output)
5478     {
5479       clib_warning
5480         ("JSON output supported only for VPE API calls and dump_stats_table");
5481       return -99;
5482     }
5483
5484   print (vam->ofp,
5485          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5486          "Interface", "sw_if_index",
5487          "sub id", "dot1ad", "tags", "outer id",
5488          "inner id", "exact", "default", "outer any", "inner any");
5489
5490   vec_foreach (sub, vam->sw_if_subif_table)
5491   {
5492     print (vam->ofp,
5493            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5494            sub->interface_name,
5495            sub->sw_if_index,
5496            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5497            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5498            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5499            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5500     if (sub->vtr_op != L2_VTR_DISABLED)
5501       {
5502         print (vam->ofp,
5503                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5504                "tag1: %d tag2: %d ]",
5505                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5506                sub->vtr_tag1, sub->vtr_tag2);
5507       }
5508   }
5509
5510   return 0;
5511 }
5512
5513 static int
5514 name_sort_cmp (void *a1, void *a2)
5515 {
5516   name_sort_t *n1 = a1;
5517   name_sort_t *n2 = a2;
5518
5519   return strcmp ((char *) n1->name, (char *) n2->name);
5520 }
5521
5522 static int
5523 dump_interface_table (vat_main_t * vam)
5524 {
5525   hash_pair_t *p;
5526   name_sort_t *nses = 0, *ns;
5527
5528   if (vam->json_output)
5529     {
5530       clib_warning
5531         ("JSON output supported only for VPE API calls and dump_stats_table");
5532       return -99;
5533     }
5534
5535   /* *INDENT-OFF* */
5536   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5537   ({
5538     vec_add2 (nses, ns, 1);
5539     ns->name = (u8 *)(p->key);
5540     ns->value = (u32) p->value[0];
5541   }));
5542   /* *INDENT-ON* */
5543
5544   vec_sort_with_function (nses, name_sort_cmp);
5545
5546   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5547   vec_foreach (ns, nses)
5548   {
5549     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5550   }
5551   vec_free (nses);
5552   return 0;
5553 }
5554
5555 static int
5556 dump_ip_table (vat_main_t * vam, int is_ipv6)
5557 {
5558   const ip_details_t *det = NULL;
5559   const ip_address_details_t *address = NULL;
5560   u32 i = ~0;
5561
5562   print (vam->ofp, "%-12s", "sw_if_index");
5563
5564   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5565   {
5566     i++;
5567     if (!det->present)
5568       {
5569         continue;
5570       }
5571     print (vam->ofp, "%-12d", i);
5572     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5573     if (!det->addr)
5574       {
5575         continue;
5576       }
5577     vec_foreach (address, det->addr)
5578     {
5579       print (vam->ofp,
5580              "            %-30U%-13d",
5581              is_ipv6 ? format_ip6_address : format_ip4_address,
5582              address->ip, address->prefix_length);
5583     }
5584   }
5585
5586   return 0;
5587 }
5588
5589 static int
5590 dump_ipv4_table (vat_main_t * vam)
5591 {
5592   if (vam->json_output)
5593     {
5594       clib_warning
5595         ("JSON output supported only for VPE API calls and dump_stats_table");
5596       return -99;
5597     }
5598
5599   return dump_ip_table (vam, 0);
5600 }
5601
5602 static int
5603 dump_ipv6_table (vat_main_t * vam)
5604 {
5605   if (vam->json_output)
5606     {
5607       clib_warning
5608         ("JSON output supported only for VPE API calls and dump_stats_table");
5609       return -99;
5610     }
5611
5612   return dump_ip_table (vam, 1);
5613 }
5614
5615 /*
5616  * Pass CLI buffers directly in the CLI_INBAND API message,
5617  * instead of an additional shared memory area.
5618  */
5619 static int
5620 exec_inband (vat_main_t * vam)
5621 {
5622   vl_api_cli_inband_t *mp;
5623   unformat_input_t *i = vam->input;
5624   int ret;
5625
5626   if (vec_len (i->buffer) == 0)
5627     return -1;
5628
5629   if (vam->exec_mode == 0 && unformat (i, "mode"))
5630     {
5631       vam->exec_mode = 1;
5632       return 0;
5633     }
5634   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5635     {
5636       vam->exec_mode = 0;
5637       return 0;
5638     }
5639
5640   /*
5641    * In order for the CLI command to work, it
5642    * must be a vector ending in \n, not a C-string ending
5643    * in \n\0.
5644    */
5645   u32 len = vec_len (vam->input->buffer);
5646   M2 (CLI_INBAND, mp, len);
5647   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5648
5649   S (mp);
5650   W (ret);
5651   /* json responses may or may not include a useful reply... */
5652   if (vec_len (vam->cmd_reply))
5653     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5654   return ret;
5655 }
5656
5657 int
5658 exec (vat_main_t * vam)
5659 {
5660   return exec_inband (vam);
5661 }
5662
5663 static int
5664 api_create_loopback (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_create_loopback_t *mp;
5668   vl_api_create_loopback_instance_t *mp_lbi;
5669   u8 mac_address[6];
5670   u8 mac_set = 0;
5671   u8 is_specified = 0;
5672   u32 user_instance = 0;
5673   int ret;
5674
5675   clib_memset (mac_address, 0, sizeof (mac_address));
5676
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5680         mac_set = 1;
5681       if (unformat (i, "instance %d", &user_instance))
5682         is_specified = 1;
5683       else
5684         break;
5685     }
5686
5687   if (is_specified)
5688     {
5689       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5690       mp_lbi->is_specified = is_specified;
5691       if (is_specified)
5692         mp_lbi->user_instance = htonl (user_instance);
5693       if (mac_set)
5694         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5695       S (mp_lbi);
5696     }
5697   else
5698     {
5699       /* Construct the API message */
5700       M (CREATE_LOOPBACK, mp);
5701       if (mac_set)
5702         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5703       S (mp);
5704     }
5705
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_delete_loopback (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_delete_loopback_t *mp;
5715   u32 sw_if_index = ~0;
5716   int ret;
5717
5718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5719     {
5720       if (unformat (i, "sw_if_index %d", &sw_if_index))
5721         ;
5722       else
5723         break;
5724     }
5725
5726   if (sw_if_index == ~0)
5727     {
5728       errmsg ("missing sw_if_index");
5729       return -99;
5730     }
5731
5732   /* Construct the API message */
5733   M (DELETE_LOOPBACK, mp);
5734   mp->sw_if_index = ntohl (sw_if_index);
5735
5736   S (mp);
5737   W (ret);
5738   return ret;
5739 }
5740
5741 static int
5742 api_want_interface_events (vat_main_t * vam)
5743 {
5744   unformat_input_t *i = vam->input;
5745   vl_api_want_interface_events_t *mp;
5746   int enable = -1;
5747   int ret;
5748
5749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5750     {
5751       if (unformat (i, "enable"))
5752         enable = 1;
5753       else if (unformat (i, "disable"))
5754         enable = 0;
5755       else
5756         break;
5757     }
5758
5759   if (enable == -1)
5760     {
5761       errmsg ("missing enable|disable");
5762       return -99;
5763     }
5764
5765   M (WANT_INTERFACE_EVENTS, mp);
5766   mp->enable_disable = enable;
5767
5768   vam->interface_event_display = enable;
5769
5770   S (mp);
5771   W (ret);
5772   return ret;
5773 }
5774
5775
5776 /* Note: non-static, called once to set up the initial intfc table */
5777 int
5778 api_sw_interface_dump (vat_main_t * vam)
5779 {
5780   vl_api_sw_interface_dump_t *mp;
5781   vl_api_control_ping_t *mp_ping;
5782   hash_pair_t *p;
5783   name_sort_t *nses = 0, *ns;
5784   sw_interface_subif_t *sub = NULL;
5785   int ret;
5786
5787   /* Toss the old name table */
5788   /* *INDENT-OFF* */
5789   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5790   ({
5791     vec_add2 (nses, ns, 1);
5792     ns->name = (u8 *)(p->key);
5793     ns->value = (u32) p->value[0];
5794   }));
5795   /* *INDENT-ON* */
5796
5797   hash_free (vam->sw_if_index_by_interface_name);
5798
5799   vec_foreach (ns, nses) vec_free (ns->name);
5800
5801   vec_free (nses);
5802
5803   vec_foreach (sub, vam->sw_if_subif_table)
5804   {
5805     vec_free (sub->interface_name);
5806   }
5807   vec_free (vam->sw_if_subif_table);
5808
5809   /* recreate the interface name hash table */
5810   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5811
5812   /*
5813    * Ask for all interface names. Otherwise, the epic catalog of
5814    * name filters becomes ridiculously long, and vat ends up needing
5815    * to be taught about new interface types.
5816    */
5817   M (SW_INTERFACE_DUMP, mp);
5818   S (mp);
5819
5820   /* Use a control ping for synchronization */
5821   MPING (CONTROL_PING, mp_ping);
5822   S (mp_ping);
5823
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_sw_interface_set_flags (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_sw_interface_set_flags_t *mp;
5833   u32 sw_if_index;
5834   u8 sw_if_index_set = 0;
5835   u8 admin_up = 0;
5836   int ret;
5837
5838   /* Parse args required to build the message */
5839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840     {
5841       if (unformat (i, "admin-up"))
5842         admin_up = 1;
5843       else if (unformat (i, "admin-down"))
5844         admin_up = 0;
5845       else
5846         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5847         sw_if_index_set = 1;
5848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5849         sw_if_index_set = 1;
5850       else
5851         break;
5852     }
5853
5854   if (sw_if_index_set == 0)
5855     {
5856       errmsg ("missing interface name or sw_if_index");
5857       return -99;
5858     }
5859
5860   /* Construct the API message */
5861   M (SW_INTERFACE_SET_FLAGS, mp);
5862   mp->sw_if_index = ntohl (sw_if_index);
5863   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5864
5865   /* send it... */
5866   S (mp);
5867
5868   /* Wait for a reply, return the good/bad news... */
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_sw_interface_set_rx_mode (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_sw_interface_set_rx_mode_t *mp;
5878   u32 sw_if_index;
5879   u8 sw_if_index_set = 0;
5880   int ret;
5881   u8 queue_id_valid = 0;
5882   u32 queue_id;
5883   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5884
5885   /* Parse args required to build the message */
5886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5887     {
5888       if (unformat (i, "queue %d", &queue_id))
5889         queue_id_valid = 1;
5890       else if (unformat (i, "polling"))
5891         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5892       else if (unformat (i, "interrupt"))
5893         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5894       else if (unformat (i, "adaptive"))
5895         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5896       else
5897         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5898         sw_if_index_set = 1;
5899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5900         sw_if_index_set = 1;
5901       else
5902         break;
5903     }
5904
5905   if (sw_if_index_set == 0)
5906     {
5907       errmsg ("missing interface name or sw_if_index");
5908       return -99;
5909     }
5910   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5911     {
5912       errmsg ("missing rx-mode");
5913       return -99;
5914     }
5915
5916   /* Construct the API message */
5917   M (SW_INTERFACE_SET_RX_MODE, mp);
5918   mp->sw_if_index = ntohl (sw_if_index);
5919   mp->mode = (vl_api_rx_mode_t) mode;
5920   mp->queue_id_valid = queue_id_valid;
5921   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5922
5923   /* send it... */
5924   S (mp);
5925
5926   /* Wait for a reply, return the good/bad news... */
5927   W (ret);
5928   return ret;
5929 }
5930
5931 static int
5932 api_sw_interface_set_rx_placement (vat_main_t * vam)
5933 {
5934   unformat_input_t *i = vam->input;
5935   vl_api_sw_interface_set_rx_placement_t *mp;
5936   u32 sw_if_index;
5937   u8 sw_if_index_set = 0;
5938   int ret;
5939   u8 is_main = 0;
5940   u32 queue_id, thread_index;
5941
5942   /* Parse args required to build the message */
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "queue %d", &queue_id))
5946         ;
5947       else if (unformat (i, "main"))
5948         is_main = 1;
5949       else if (unformat (i, "worker %d", &thread_index))
5950         ;
5951       else
5952         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5953         sw_if_index_set = 1;
5954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5955         sw_if_index_set = 1;
5956       else
5957         break;
5958     }
5959
5960   if (sw_if_index_set == 0)
5961     {
5962       errmsg ("missing interface name or sw_if_index");
5963       return -99;
5964     }
5965
5966   if (is_main)
5967     thread_index = 0;
5968   /* Construct the API message */
5969   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5970   mp->sw_if_index = ntohl (sw_if_index);
5971   mp->worker_id = ntohl (thread_index);
5972   mp->queue_id = ntohl (queue_id);
5973   mp->is_main = is_main;
5974
5975   /* send it... */
5976   S (mp);
5977   /* Wait for a reply, return the good/bad news... */
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static void vl_api_sw_interface_rx_placement_details_t_handler
5983   (vl_api_sw_interface_rx_placement_details_t * mp)
5984 {
5985   vat_main_t *vam = &vat_main;
5986   u32 worker_id = ntohl (mp->worker_id);
5987
5988   print (vam->ofp,
5989          "\n%-11d %-11s %-6d %-5d %-9s",
5990          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5991          worker_id, ntohl (mp->queue_id),
5992          (mp->mode ==
5993           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5994 }
5995
5996 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5997   (vl_api_sw_interface_rx_placement_details_t * mp)
5998 {
5999   vat_main_t *vam = &vat_main;
6000   vat_json_node_t *node = NULL;
6001
6002   if (VAT_JSON_ARRAY != vam->json_tree.type)
6003     {
6004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6005       vat_json_init_array (&vam->json_tree);
6006     }
6007   node = vat_json_array_add (&vam->json_tree);
6008
6009   vat_json_init_object (node);
6010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6011   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6012   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6013   vat_json_object_add_uint (node, "mode", mp->mode);
6014 }
6015
6016 static int
6017 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6018 {
6019   unformat_input_t *i = vam->input;
6020   vl_api_sw_interface_rx_placement_dump_t *mp;
6021   vl_api_control_ping_t *mp_ping;
6022   int ret;
6023   u32 sw_if_index;
6024   u8 sw_if_index_set = 0;
6025
6026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6027     {
6028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6029         sw_if_index_set++;
6030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6031         sw_if_index_set++;
6032       else
6033         break;
6034     }
6035
6036   print (vam->ofp,
6037          "\n%-11s %-11s %-6s %-5s %-4s",
6038          "sw_if_index", "main/worker", "thread", "queue", "mode");
6039
6040   /* Dump Interface rx placement */
6041   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6042
6043   if (sw_if_index_set)
6044     mp->sw_if_index = htonl (sw_if_index);
6045   else
6046     mp->sw_if_index = ~0;
6047
6048   S (mp);
6049
6050   /* Use a control ping for synchronization */
6051   MPING (CONTROL_PING, mp_ping);
6052   S (mp_ping);
6053
6054   W (ret);
6055   return ret;
6056 }
6057
6058 static int
6059 api_sw_interface_clear_stats (vat_main_t * vam)
6060 {
6061   unformat_input_t *i = vam->input;
6062   vl_api_sw_interface_clear_stats_t *mp;
6063   u32 sw_if_index;
6064   u8 sw_if_index_set = 0;
6065   int ret;
6066
6067   /* Parse args required to build the message */
6068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6069     {
6070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6071         sw_if_index_set = 1;
6072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6073         sw_if_index_set = 1;
6074       else
6075         break;
6076     }
6077
6078   /* Construct the API message */
6079   M (SW_INTERFACE_CLEAR_STATS, mp);
6080
6081   if (sw_if_index_set == 1)
6082     mp->sw_if_index = ntohl (sw_if_index);
6083   else
6084     mp->sw_if_index = ~0;
6085
6086   /* send it... */
6087   S (mp);
6088
6089   /* Wait for a reply, return the good/bad news... */
6090   W (ret);
6091   return ret;
6092 }
6093
6094 static int
6095 api_sw_interface_add_del_address (vat_main_t * vam)
6096 {
6097   unformat_input_t *i = vam->input;
6098   vl_api_sw_interface_add_del_address_t *mp;
6099   u32 sw_if_index;
6100   u8 sw_if_index_set = 0;
6101   u8 is_add = 1, del_all = 0;
6102   u32 address_length = 0;
6103   u8 v4_address_set = 0;
6104   u8 v6_address_set = 0;
6105   ip4_address_t v4address;
6106   ip6_address_t v6address;
6107   int ret;
6108
6109   /* Parse args required to build the message */
6110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6111     {
6112       if (unformat (i, "del-all"))
6113         del_all = 1;
6114       else if (unformat (i, "del"))
6115         is_add = 0;
6116       else
6117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6118         sw_if_index_set = 1;
6119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         sw_if_index_set = 1;
6121       else if (unformat (i, "%U/%d",
6122                          unformat_ip4_address, &v4address, &address_length))
6123         v4_address_set = 1;
6124       else if (unformat (i, "%U/%d",
6125                          unformat_ip6_address, &v6address, &address_length))
6126         v6_address_set = 1;
6127       else
6128         break;
6129     }
6130
6131   if (sw_if_index_set == 0)
6132     {
6133       errmsg ("missing interface name or sw_if_index");
6134       return -99;
6135     }
6136   if (v4_address_set && v6_address_set)
6137     {
6138       errmsg ("both v4 and v6 addresses set");
6139       return -99;
6140     }
6141   if (!v4_address_set && !v6_address_set && !del_all)
6142     {
6143       errmsg ("no addresses set");
6144       return -99;
6145     }
6146
6147   /* Construct the API message */
6148   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6149
6150   mp->sw_if_index = ntohl (sw_if_index);
6151   mp->is_add = is_add;
6152   mp->del_all = del_all;
6153   if (v6_address_set)
6154     {
6155       mp->prefix.address.af = ADDRESS_IP6;
6156       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6157     }
6158   else
6159     {
6160       mp->prefix.address.af = ADDRESS_IP4;
6161       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6162     }
6163   mp->prefix.len = address_length;
6164
6165   /* send it... */
6166   S (mp);
6167
6168   /* Wait for a reply, return good/bad news  */
6169   W (ret);
6170   return ret;
6171 }
6172
6173 static int
6174 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6175 {
6176   unformat_input_t *i = vam->input;
6177   vl_api_sw_interface_set_mpls_enable_t *mp;
6178   u32 sw_if_index;
6179   u8 sw_if_index_set = 0;
6180   u8 enable = 1;
6181   int ret;
6182
6183   /* Parse args required to build the message */
6184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6185     {
6186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6187         sw_if_index_set = 1;
6188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6189         sw_if_index_set = 1;
6190       else if (unformat (i, "disable"))
6191         enable = 0;
6192       else if (unformat (i, "dis"))
6193         enable = 0;
6194       else
6195         break;
6196     }
6197
6198   if (sw_if_index_set == 0)
6199     {
6200       errmsg ("missing interface name or sw_if_index");
6201       return -99;
6202     }
6203
6204   /* Construct the API message */
6205   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6206
6207   mp->sw_if_index = ntohl (sw_if_index);
6208   mp->enable = enable;
6209
6210   /* send it... */
6211   S (mp);
6212
6213   /* Wait for a reply... */
6214   W (ret);
6215   return ret;
6216 }
6217
6218 static int
6219 api_sw_interface_set_table (vat_main_t * vam)
6220 {
6221   unformat_input_t *i = vam->input;
6222   vl_api_sw_interface_set_table_t *mp;
6223   u32 sw_if_index, vrf_id = 0;
6224   u8 sw_if_index_set = 0;
6225   u8 is_ipv6 = 0;
6226   int ret;
6227
6228   /* Parse args required to build the message */
6229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6230     {
6231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6232         sw_if_index_set = 1;
6233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else if (unformat (i, "vrf %d", &vrf_id))
6236         ;
6237       else if (unformat (i, "ipv6"))
6238         is_ipv6 = 1;
6239       else
6240         break;
6241     }
6242
6243   if (sw_if_index_set == 0)
6244     {
6245       errmsg ("missing interface name or sw_if_index");
6246       return -99;
6247     }
6248
6249   /* Construct the API message */
6250   M (SW_INTERFACE_SET_TABLE, mp);
6251
6252   mp->sw_if_index = ntohl (sw_if_index);
6253   mp->is_ipv6 = is_ipv6;
6254   mp->vrf_id = ntohl (vrf_id);
6255
6256   /* send it... */
6257   S (mp);
6258
6259   /* Wait for a reply... */
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static void vl_api_sw_interface_get_table_reply_t_handler
6265   (vl_api_sw_interface_get_table_reply_t * mp)
6266 {
6267   vat_main_t *vam = &vat_main;
6268
6269   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6270
6271   vam->retval = ntohl (mp->retval);
6272   vam->result_ready = 1;
6273
6274 }
6275
6276 static void vl_api_sw_interface_get_table_reply_t_handler_json
6277   (vl_api_sw_interface_get_table_reply_t * mp)
6278 {
6279   vat_main_t *vam = &vat_main;
6280   vat_json_node_t node;
6281
6282   vat_json_init_object (&node);
6283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6284   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6285
6286   vat_json_print (vam->ofp, &node);
6287   vat_json_free (&node);
6288
6289   vam->retval = ntohl (mp->retval);
6290   vam->result_ready = 1;
6291 }
6292
6293 static int
6294 api_sw_interface_get_table (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_sw_interface_get_table_t *mp;
6298   u32 sw_if_index;
6299   u8 sw_if_index_set = 0;
6300   u8 is_ipv6 = 0;
6301   int ret;
6302
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306         sw_if_index_set = 1;
6307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "ipv6"))
6310         is_ipv6 = 1;
6311       else
6312         break;
6313     }
6314
6315   if (sw_if_index_set == 0)
6316     {
6317       errmsg ("missing interface name or sw_if_index");
6318       return -99;
6319     }
6320
6321   M (SW_INTERFACE_GET_TABLE, mp);
6322   mp->sw_if_index = htonl (sw_if_index);
6323   mp->is_ipv6 = is_ipv6;
6324
6325   S (mp);
6326   W (ret);
6327   return ret;
6328 }
6329
6330 static int
6331 api_sw_interface_set_vpath (vat_main_t * vam)
6332 {
6333   unformat_input_t *i = vam->input;
6334   vl_api_sw_interface_set_vpath_t *mp;
6335   u32 sw_if_index = 0;
6336   u8 sw_if_index_set = 0;
6337   u8 is_enable = 0;
6338   int ret;
6339
6340   /* Parse args required to build the message */
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "enable"))
6348         is_enable = 1;
6349       else if (unformat (i, "disable"))
6350         is_enable = 0;
6351       else
6352         break;
6353     }
6354
6355   if (sw_if_index_set == 0)
6356     {
6357       errmsg ("missing interface name or sw_if_index");
6358       return -99;
6359     }
6360
6361   /* Construct the API message */
6362   M (SW_INTERFACE_SET_VPATH, mp);
6363
6364   mp->sw_if_index = ntohl (sw_if_index);
6365   mp->enable = is_enable;
6366
6367   /* send it... */
6368   S (mp);
6369
6370   /* Wait for a reply... */
6371   W (ret);
6372   return ret;
6373 }
6374
6375 static int
6376 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6377 {
6378   unformat_input_t *i = vam->input;
6379   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6380   u32 sw_if_index = 0;
6381   u8 sw_if_index_set = 0;
6382   u8 is_enable = 1;
6383   u8 is_ipv6 = 0;
6384   int ret;
6385
6386   /* Parse args required to build the message */
6387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6388     {
6389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6390         sw_if_index_set = 1;
6391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6392         sw_if_index_set = 1;
6393       else if (unformat (i, "enable"))
6394         is_enable = 1;
6395       else if (unformat (i, "disable"))
6396         is_enable = 0;
6397       else if (unformat (i, "ip4"))
6398         is_ipv6 = 0;
6399       else if (unformat (i, "ip6"))
6400         is_ipv6 = 1;
6401       else
6402         break;
6403     }
6404
6405   if (sw_if_index_set == 0)
6406     {
6407       errmsg ("missing interface name or sw_if_index");
6408       return -99;
6409     }
6410
6411   /* Construct the API message */
6412   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6413
6414   mp->sw_if_index = ntohl (sw_if_index);
6415   mp->enable = is_enable;
6416   mp->is_ipv6 = is_ipv6;
6417
6418   /* send it... */
6419   S (mp);
6420
6421   /* Wait for a reply... */
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_sw_interface_set_geneve_bypass_t *mp;
6431   u32 sw_if_index = 0;
6432   u8 sw_if_index_set = 0;
6433   u8 is_enable = 1;
6434   u8 is_ipv6 = 0;
6435   int ret;
6436
6437   /* Parse args required to build the message */
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6443         sw_if_index_set = 1;
6444       else if (unformat (i, "enable"))
6445         is_enable = 1;
6446       else if (unformat (i, "disable"))
6447         is_enable = 0;
6448       else if (unformat (i, "ip4"))
6449         is_ipv6 = 0;
6450       else if (unformat (i, "ip6"))
6451         is_ipv6 = 1;
6452       else
6453         break;
6454     }
6455
6456   if (sw_if_index_set == 0)
6457     {
6458       errmsg ("missing interface name or sw_if_index");
6459       return -99;
6460     }
6461
6462   /* Construct the API message */
6463   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6464
6465   mp->sw_if_index = ntohl (sw_if_index);
6466   mp->enable = is_enable;
6467   mp->is_ipv6 = is_ipv6;
6468
6469   /* send it... */
6470   S (mp);
6471
6472   /* Wait for a reply... */
6473   W (ret);
6474   return ret;
6475 }
6476
6477 static int
6478 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_sw_interface_set_l2_xconnect_t *mp;
6482   u32 rx_sw_if_index;
6483   u8 rx_sw_if_index_set = 0;
6484   u32 tx_sw_if_index;
6485   u8 tx_sw_if_index_set = 0;
6486   u8 enable = 1;
6487   int ret;
6488
6489   /* Parse args required to build the message */
6490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6491     {
6492       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6493         rx_sw_if_index_set = 1;
6494       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6495         tx_sw_if_index_set = 1;
6496       else if (unformat (i, "rx"))
6497         {
6498           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499             {
6500               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6501                             &rx_sw_if_index))
6502                 rx_sw_if_index_set = 1;
6503             }
6504           else
6505             break;
6506         }
6507       else if (unformat (i, "tx"))
6508         {
6509           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510             {
6511               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6512                             &tx_sw_if_index))
6513                 tx_sw_if_index_set = 1;
6514             }
6515           else
6516             break;
6517         }
6518       else if (unformat (i, "enable"))
6519         enable = 1;
6520       else if (unformat (i, "disable"))
6521         enable = 0;
6522       else
6523         break;
6524     }
6525
6526   if (rx_sw_if_index_set == 0)
6527     {
6528       errmsg ("missing rx interface name or rx_sw_if_index");
6529       return -99;
6530     }
6531
6532   if (enable && (tx_sw_if_index_set == 0))
6533     {
6534       errmsg ("missing tx interface name or tx_sw_if_index");
6535       return -99;
6536     }
6537
6538   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6539
6540   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6541   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6542   mp->enable = enable;
6543
6544   S (mp);
6545   W (ret);
6546   return ret;
6547 }
6548
6549 static int
6550 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6551 {
6552   unformat_input_t *i = vam->input;
6553   vl_api_sw_interface_set_l2_bridge_t *mp;
6554   vl_api_l2_port_type_t port_type;
6555   u32 rx_sw_if_index;
6556   u8 rx_sw_if_index_set = 0;
6557   u32 bd_id;
6558   u8 bd_id_set = 0;
6559   u32 shg = 0;
6560   u8 enable = 1;
6561   int ret;
6562
6563   port_type = L2_API_PORT_TYPE_NORMAL;
6564
6565   /* Parse args required to build the message */
6566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567     {
6568       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6569         rx_sw_if_index_set = 1;
6570       else if (unformat (i, "bd_id %d", &bd_id))
6571         bd_id_set = 1;
6572       else
6573         if (unformat
6574             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6575         rx_sw_if_index_set = 1;
6576       else if (unformat (i, "shg %d", &shg))
6577         ;
6578       else if (unformat (i, "bvi"))
6579         port_type = L2_API_PORT_TYPE_BVI;
6580       else if (unformat (i, "uu-fwd"))
6581         port_type = L2_API_PORT_TYPE_UU_FWD;
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (bd_id_set == 0))
6597     {
6598       errmsg ("missing bridge domain");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->bd_id = ntohl (bd_id);
6606   mp->shg = (u8) shg;
6607   mp->port_type = ntohl (port_type);
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_bridge_domain_dump (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_bridge_domain_dump_t *mp;
6620   vl_api_control_ping_t *mp_ping;
6621   u32 bd_id = ~0;
6622   int ret;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "bd_id %d", &bd_id))
6628         ;
6629       else
6630         break;
6631     }
6632
6633   M (BRIDGE_DOMAIN_DUMP, mp);
6634   mp->bd_id = ntohl (bd_id);
6635   S (mp);
6636
6637   /* Use a control ping for synchronization */
6638   MPING (CONTROL_PING, mp_ping);
6639   S (mp_ping);
6640
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_bridge_domain_add_del (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_bridge_domain_add_del_t *mp;
6650   u32 bd_id = ~0;
6651   u8 is_add = 1;
6652   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6653   u8 *bd_tag = NULL;
6654   u32 mac_age = 0;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "bd_id %d", &bd_id))
6661         ;
6662       else if (unformat (i, "flood %d", &flood))
6663         ;
6664       else if (unformat (i, "uu-flood %d", &uu_flood))
6665         ;
6666       else if (unformat (i, "forward %d", &forward))
6667         ;
6668       else if (unformat (i, "learn %d", &learn))
6669         ;
6670       else if (unformat (i, "arp-term %d", &arp_term))
6671         ;
6672       else if (unformat (i, "mac-age %d", &mac_age))
6673         ;
6674       else if (unformat (i, "bd-tag %s", &bd_tag))
6675         ;
6676       else if (unformat (i, "del"))
6677         {
6678           is_add = 0;
6679           flood = uu_flood = forward = learn = 0;
6680         }
6681       else
6682         break;
6683     }
6684
6685   if (bd_id == ~0)
6686     {
6687       errmsg ("missing bridge domain");
6688       ret = -99;
6689       goto done;
6690     }
6691
6692   if (mac_age > 255)
6693     {
6694       errmsg ("mac age must be less than 256 ");
6695       ret = -99;
6696       goto done;
6697     }
6698
6699   if ((bd_tag) && (vec_len (bd_tag) > 63))
6700     {
6701       errmsg ("bd-tag cannot be longer than 63");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6707
6708   mp->bd_id = ntohl (bd_id);
6709   mp->flood = flood;
6710   mp->uu_flood = uu_flood;
6711   mp->forward = forward;
6712   mp->learn = learn;
6713   mp->arp_term = arp_term;
6714   mp->is_add = is_add;
6715   mp->mac_age = (u8) mac_age;
6716   if (bd_tag)
6717     {
6718       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6719       mp->bd_tag[vec_len (bd_tag)] = 0;
6720     }
6721   S (mp);
6722   W (ret);
6723
6724 done:
6725   vec_free (bd_tag);
6726   return ret;
6727 }
6728
6729 static int
6730 api_l2fib_flush_bd (vat_main_t * vam)
6731 {
6732   unformat_input_t *i = vam->input;
6733   vl_api_l2fib_flush_bd_t *mp;
6734   u32 bd_id = ~0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "bd_id %d", &bd_id));
6741       else
6742         break;
6743     }
6744
6745   if (bd_id == ~0)
6746     {
6747       errmsg ("missing bridge domain");
6748       return -99;
6749     }
6750
6751   M (L2FIB_FLUSH_BD, mp);
6752
6753   mp->bd_id = htonl (bd_id);
6754
6755   S (mp);
6756   W (ret);
6757   return ret;
6758 }
6759
6760 static int
6761 api_l2fib_flush_int (vat_main_t * vam)
6762 {
6763   unformat_input_t *i = vam->input;
6764   vl_api_l2fib_flush_int_t *mp;
6765   u32 sw_if_index = ~0;
6766   int ret;
6767
6768   /* Parse args required to build the message */
6769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6770     {
6771       if (unformat (i, "sw_if_index %d", &sw_if_index));
6772       else
6773         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6774       else
6775         break;
6776     }
6777
6778   if (sw_if_index == ~0)
6779     {
6780       errmsg ("missing interface name or sw_if_index");
6781       return -99;
6782     }
6783
6784   M (L2FIB_FLUSH_INT, mp);
6785
6786   mp->sw_if_index = ntohl (sw_if_index);
6787
6788   S (mp);
6789   W (ret);
6790   return ret;
6791 }
6792
6793 static int
6794 api_l2fib_add_del (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_l2fib_add_del_t *mp;
6798   f64 timeout;
6799   u8 mac[6] = { 0 };
6800   u8 mac_set = 0;
6801   u32 bd_id;
6802   u8 bd_id_set = 0;
6803   u32 sw_if_index = 0;
6804   u8 sw_if_index_set = 0;
6805   u8 is_add = 1;
6806   u8 static_mac = 0;
6807   u8 filter_mac = 0;
6808   u8 bvi_mac = 0;
6809   int count = 1;
6810   f64 before = 0;
6811   int j;
6812
6813   /* Parse args required to build the message */
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6817         mac_set = 1;
6818       else if (unformat (i, "bd_id %d", &bd_id))
6819         bd_id_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "sw_if"))
6823         {
6824           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825             {
6826               if (unformat
6827                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6828                 sw_if_index_set = 1;
6829             }
6830           else
6831             break;
6832         }
6833       else if (unformat (i, "static"))
6834         static_mac = 1;
6835       else if (unformat (i, "filter"))
6836         {
6837           filter_mac = 1;
6838           static_mac = 1;
6839         }
6840       else if (unformat (i, "bvi"))
6841         {
6842           bvi_mac = 1;
6843           static_mac = 1;
6844         }
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else if (unformat (i, "count %d", &count))
6848         ;
6849       else
6850         break;
6851     }
6852
6853   if (mac_set == 0)
6854     {
6855       errmsg ("missing mac address");
6856       return -99;
6857     }
6858
6859   if (bd_id_set == 0)
6860     {
6861       errmsg ("missing bridge domain");
6862       return -99;
6863     }
6864
6865   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6866     {
6867       errmsg ("missing interface name or sw_if_index");
6868       return -99;
6869     }
6870
6871   if (count > 1)
6872     {
6873       /* Turn on async mode */
6874       vam->async_mode = 1;
6875       vam->async_errors = 0;
6876       before = vat_time_now (vam);
6877     }
6878
6879   for (j = 0; j < count; j++)
6880     {
6881       M (L2FIB_ADD_DEL, mp);
6882
6883       clib_memcpy (mp->mac, mac, 6);
6884       mp->bd_id = ntohl (bd_id);
6885       mp->is_add = is_add;
6886       mp->sw_if_index = ntohl (sw_if_index);
6887
6888       if (is_add)
6889         {
6890           mp->static_mac = static_mac;
6891           mp->filter_mac = filter_mac;
6892           mp->bvi_mac = bvi_mac;
6893         }
6894       increment_mac_address (mac);
6895       /* send it... */
6896       S (mp);
6897     }
6898
6899   if (count > 1)
6900     {
6901       vl_api_control_ping_t *mp_ping;
6902       f64 after;
6903
6904       /* Shut off async mode */
6905       vam->async_mode = 0;
6906
6907       MPING (CONTROL_PING, mp_ping);
6908       S (mp_ping);
6909
6910       timeout = vat_time_now (vam) + 1.0;
6911       while (vat_time_now (vam) < timeout)
6912         if (vam->result_ready == 1)
6913           goto out;
6914       vam->retval = -99;
6915
6916     out:
6917       if (vam->retval == -99)
6918         errmsg ("timeout");
6919
6920       if (vam->async_errors > 0)
6921         {
6922           errmsg ("%d asynchronous errors", vam->async_errors);
6923           vam->retval = -98;
6924         }
6925       vam->async_errors = 0;
6926       after = vat_time_now (vam);
6927
6928       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6929              count, after - before, count / (after - before));
6930     }
6931   else
6932     {
6933       int ret;
6934
6935       /* Wait for a reply... */
6936       W (ret);
6937       return ret;
6938     }
6939   /* Return the good/bad news */
6940   return (vam->retval);
6941 }
6942
6943 static int
6944 api_bridge_domain_set_mac_age (vat_main_t * vam)
6945 {
6946   unformat_input_t *i = vam->input;
6947   vl_api_bridge_domain_set_mac_age_t *mp;
6948   u32 bd_id = ~0;
6949   u32 mac_age = 0;
6950   int ret;
6951
6952   /* Parse args required to build the message */
6953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6954     {
6955       if (unformat (i, "bd_id %d", &bd_id));
6956       else if (unformat (i, "mac-age %d", &mac_age));
6957       else
6958         break;
6959     }
6960
6961   if (bd_id == ~0)
6962     {
6963       errmsg ("missing bridge domain");
6964       return -99;
6965     }
6966
6967   if (mac_age > 255)
6968     {
6969       errmsg ("mac age must be less than 256 ");
6970       return -99;
6971     }
6972
6973   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6974
6975   mp->bd_id = htonl (bd_id);
6976   mp->mac_age = (u8) mac_age;
6977
6978   S (mp);
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_l2_flags (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_l2_flags_t *mp;
6988   u32 sw_if_index;
6989   u32 flags = 0;
6990   u8 sw_if_index_set = 0;
6991   u8 is_set = 0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index))
6998         sw_if_index_set = 1;
6999       else if (unformat (i, "sw_if"))
7000         {
7001           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7002             {
7003               if (unformat
7004                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005                 sw_if_index_set = 1;
7006             }
7007           else
7008             break;
7009         }
7010       else if (unformat (i, "learn"))
7011         flags |= L2_LEARN;
7012       else if (unformat (i, "forward"))
7013         flags |= L2_FWD;
7014       else if (unformat (i, "flood"))
7015         flags |= L2_FLOOD;
7016       else if (unformat (i, "uu-flood"))
7017         flags |= L2_UU_FLOOD;
7018       else if (unformat (i, "arp-term"))
7019         flags |= L2_ARP_TERM;
7020       else if (unformat (i, "off"))
7021         is_set = 0;
7022       else if (unformat (i, "disable"))
7023         is_set = 0;
7024       else
7025         break;
7026     }
7027
7028   if (sw_if_index_set == 0)
7029     {
7030       errmsg ("missing interface name or sw_if_index");
7031       return -99;
7032     }
7033
7034   M (L2_FLAGS, mp);
7035
7036   mp->sw_if_index = ntohl (sw_if_index);
7037   mp->feature_bitmap = ntohl (flags);
7038   mp->is_set = is_set;
7039
7040   S (mp);
7041   W (ret);
7042   return ret;
7043 }
7044
7045 static int
7046 api_bridge_flags (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_bridge_flags_t *mp;
7050   u32 bd_id;
7051   u8 bd_id_set = 0;
7052   u8 is_set = 1;
7053   bd_flags_t flags = 0;
7054   int ret;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "bd_id %d", &bd_id))
7060         bd_id_set = 1;
7061       else if (unformat (i, "learn"))
7062         flags |= BRIDGE_API_FLAG_LEARN;
7063       else if (unformat (i, "forward"))
7064         flags |= BRIDGE_API_FLAG_FWD;
7065       else if (unformat (i, "flood"))
7066         flags |= BRIDGE_API_FLAG_FLOOD;
7067       else if (unformat (i, "uu-flood"))
7068         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7069       else if (unformat (i, "arp-term"))
7070         flags |= BRIDGE_API_FLAG_ARP_TERM;
7071       else if (unformat (i, "off"))
7072         is_set = 0;
7073       else if (unformat (i, "disable"))
7074         is_set = 0;
7075       else
7076         break;
7077     }
7078
7079   if (bd_id_set == 0)
7080     {
7081       errmsg ("missing bridge domain");
7082       return -99;
7083     }
7084
7085   M (BRIDGE_FLAGS, mp);
7086
7087   mp->bd_id = ntohl (bd_id);
7088   mp->flags = ntohl (flags);
7089   mp->is_set = is_set;
7090
7091   S (mp);
7092   W (ret);
7093   return ret;
7094 }
7095
7096 static int
7097 api_bd_ip_mac_add_del (vat_main_t * vam)
7098 {
7099   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7100   vl_api_mac_address_t mac = { 0 };
7101   unformat_input_t *i = vam->input;
7102   vl_api_bd_ip_mac_add_del_t *mp;
7103   u32 bd_id;
7104   u8 is_add = 1;
7105   u8 bd_id_set = 0;
7106   u8 ip_set = 0;
7107   u8 mac_set = 0;
7108   int ret;
7109
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "bd_id %d", &bd_id))
7115         {
7116           bd_id_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7119         {
7120           ip_set++;
7121         }
7122       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7123         {
7124           mac_set++;
7125         }
7126       else if (unformat (i, "del"))
7127         is_add = 0;
7128       else
7129         break;
7130     }
7131
7132   if (bd_id_set == 0)
7133     {
7134       errmsg ("missing bridge domain");
7135       return -99;
7136     }
7137   else if (ip_set == 0)
7138     {
7139       errmsg ("missing IP address");
7140       return -99;
7141     }
7142   else if (mac_set == 0)
7143     {
7144       errmsg ("missing MAC address");
7145       return -99;
7146     }
7147
7148   M (BD_IP_MAC_ADD_DEL, mp);
7149
7150   mp->entry.bd_id = ntohl (bd_id);
7151   mp->is_add = is_add;
7152
7153   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7154   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7155
7156   S (mp);
7157   W (ret);
7158   return ret;
7159 }
7160
7161 static int
7162 api_bd_ip_mac_flush (vat_main_t * vam)
7163 {
7164   unformat_input_t *i = vam->input;
7165   vl_api_bd_ip_mac_flush_t *mp;
7166   u32 bd_id;
7167   u8 bd_id_set = 0;
7168   int ret;
7169
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "bd_id %d", &bd_id))
7173         {
7174           bd_id_set++;
7175         }
7176       else
7177         break;
7178     }
7179
7180   if (bd_id_set == 0)
7181     {
7182       errmsg ("missing bridge domain");
7183       return -99;
7184     }
7185
7186   M (BD_IP_MAC_FLUSH, mp);
7187
7188   mp->bd_id = ntohl (bd_id);
7189
7190   S (mp);
7191   W (ret);
7192   return ret;
7193 }
7194
7195 static void vl_api_bd_ip_mac_details_t_handler
7196   (vl_api_bd_ip_mac_details_t * mp)
7197 {
7198   vat_main_t *vam = &vat_main;
7199
7200   print (vam->ofp,
7201          "\n%-5d %U %U",
7202          ntohl (mp->entry.bd_id),
7203          format_vl_api_mac_address, mp->entry.mac,
7204          format_vl_api_address, &mp->entry.ip);
7205 }
7206
7207 static void vl_api_bd_ip_mac_details_t_handler_json
7208   (vl_api_bd_ip_mac_details_t * mp)
7209 {
7210   vat_main_t *vam = &vat_main;
7211   vat_json_node_t *node = NULL;
7212
7213   if (VAT_JSON_ARRAY != vam->json_tree.type)
7214     {
7215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7216       vat_json_init_array (&vam->json_tree);
7217     }
7218   node = vat_json_array_add (&vam->json_tree);
7219
7220   vat_json_init_object (node);
7221   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7222   vat_json_object_add_string_copy (node, "mac_address",
7223                                    format (0, "%U", format_vl_api_mac_address,
7224                                            &mp->entry.mac));
7225   u8 *ip = 0;
7226
7227   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7228   vat_json_object_add_string_copy (node, "ip_address", ip);
7229   vec_free (ip);
7230 }
7231
7232 static int
7233 api_bd_ip_mac_dump (vat_main_t * vam)
7234 {
7235   unformat_input_t *i = vam->input;
7236   vl_api_bd_ip_mac_dump_t *mp;
7237   vl_api_control_ping_t *mp_ping;
7238   int ret;
7239   u32 bd_id;
7240   u8 bd_id_set = 0;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "bd_id %d", &bd_id))
7245         {
7246           bd_id_set++;
7247         }
7248       else
7249         break;
7250     }
7251
7252   print (vam->ofp,
7253          "\n%-5s %-7s %-20s %-30s",
7254          "bd_id", "is_ipv6", "mac_address", "ip_address");
7255
7256   /* Dump Bridge Domain Ip to Mac entries */
7257   M (BD_IP_MAC_DUMP, mp);
7258
7259   if (bd_id_set)
7260     mp->bd_id = htonl (bd_id);
7261   else
7262     mp->bd_id = ~0;
7263
7264   S (mp);
7265
7266   /* Use a control ping for synchronization */
7267   MPING (CONTROL_PING, mp_ping);
7268   S (mp_ping);
7269
7270   W (ret);
7271   return ret;
7272 }
7273
7274 static int
7275 api_tap_create_v2 (vat_main_t * vam)
7276 {
7277   unformat_input_t *i = vam->input;
7278   vl_api_tap_create_v2_t *mp;
7279 #define TAP_FLAG_GSO (1 << 0)
7280   u8 mac_address[6];
7281   u8 random_mac = 1;
7282   u32 id = ~0;
7283   u8 *host_if_name = 0;
7284   u8 *host_ns = 0;
7285   u8 host_mac_addr[6];
7286   u8 host_mac_addr_set = 0;
7287   u8 *host_bridge = 0;
7288   ip4_address_t host_ip4_addr;
7289   ip4_address_t host_ip4_gw;
7290   u8 host_ip4_gw_set = 0;
7291   u32 host_ip4_prefix_len = 0;
7292   ip6_address_t host_ip6_addr;
7293   ip6_address_t host_ip6_gw;
7294   u8 host_ip6_gw_set = 0;
7295   u32 host_ip6_prefix_len = 0;
7296   u8 host_mtu_set = 0;
7297   u32 host_mtu_size = 0;
7298   u32 tap_flags = 0;
7299   int ret;
7300   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7301
7302   clib_memset (mac_address, 0, sizeof (mac_address));
7303
7304   /* Parse args required to build the message */
7305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7306     {
7307       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7308         {
7309           random_mac = 0;
7310         }
7311       else if (unformat (i, "id %u", &id))
7312         ;
7313       else if (unformat (i, "host-if-name %s", &host_if_name))
7314         ;
7315       else if (unformat (i, "host-ns %s", &host_ns))
7316         ;
7317       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7318                          host_mac_addr))
7319         host_mac_addr_set = 1;
7320       else if (unformat (i, "host-bridge %s", &host_bridge))
7321         ;
7322       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7323                          &host_ip4_addr, &host_ip4_prefix_len))
7324         ;
7325       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7326                          &host_ip6_addr, &host_ip6_prefix_len))
7327         ;
7328       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7329                          &host_ip4_gw))
7330         host_ip4_gw_set = 1;
7331       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7332                          &host_ip6_gw))
7333         host_ip6_gw_set = 1;
7334       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7335         ;
7336       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7337         ;
7338       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7339         host_mtu_set = 1;
7340       else if (unformat (i, "no-gso"))
7341         tap_flags &= ~TAP_FLAG_GSO;
7342       else if (unformat (i, "gso"))
7343         tap_flags |= TAP_FLAG_GSO;
7344       else
7345         break;
7346     }
7347
7348   if (vec_len (host_if_name) > 63)
7349     {
7350       errmsg ("tap name too long. ");
7351       return -99;
7352     }
7353   if (vec_len (host_ns) > 63)
7354     {
7355       errmsg ("host name space too long. ");
7356       return -99;
7357     }
7358   if (vec_len (host_bridge) > 63)
7359     {
7360       errmsg ("host bridge name too long. ");
7361       return -99;
7362     }
7363   if (host_ip4_prefix_len > 32)
7364     {
7365       errmsg ("host ip4 prefix length not valid. ");
7366       return -99;
7367     }
7368   if (host_ip6_prefix_len > 128)
7369     {
7370       errmsg ("host ip6 prefix length not valid. ");
7371       return -99;
7372     }
7373   if (!is_pow2 (rx_ring_sz))
7374     {
7375       errmsg ("rx ring size must be power of 2. ");
7376       return -99;
7377     }
7378   if (rx_ring_sz > 32768)
7379     {
7380       errmsg ("rx ring size must be 32768 or lower. ");
7381       return -99;
7382     }
7383   if (!is_pow2 (tx_ring_sz))
7384     {
7385       errmsg ("tx ring size must be power of 2. ");
7386       return -99;
7387     }
7388   if (tx_ring_sz > 32768)
7389     {
7390       errmsg ("tx ring size must be 32768 or lower. ");
7391       return -99;
7392     }
7393   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7394     {
7395       errmsg ("host MTU size must be in between 64 and 65355. ");
7396       return -99;
7397     }
7398
7399   /* Construct the API message */
7400   M (TAP_CREATE_V2, mp);
7401
7402   mp->use_random_mac = random_mac;
7403
7404   mp->id = ntohl (id);
7405   mp->host_namespace_set = host_ns != 0;
7406   mp->host_bridge_set = host_bridge != 0;
7407   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7408   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7409   mp->rx_ring_sz = ntohs (rx_ring_sz);
7410   mp->tx_ring_sz = ntohs (tx_ring_sz);
7411   mp->host_mtu_set = host_mtu_set;
7412   mp->host_mtu_size = ntohl (host_mtu_size);
7413   mp->tap_flags = ntohl (tap_flags);
7414
7415   if (random_mac == 0)
7416     clib_memcpy (mp->mac_address, mac_address, 6);
7417   if (host_mac_addr_set)
7418     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7419   if (host_if_name)
7420     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7421   if (host_ns)
7422     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7423   if (host_bridge)
7424     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7425   if (host_ip4_prefix_len)
7426     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7427   if (host_ip6_prefix_len)
7428     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7429   if (host_ip4_gw_set)
7430     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7431   if (host_ip6_gw_set)
7432     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7433
7434   vec_free (host_ns);
7435   vec_free (host_if_name);
7436   vec_free (host_bridge);
7437
7438   /* send it... */
7439   S (mp);
7440
7441   /* Wait for a reply... */
7442   W (ret);
7443   return ret;
7444 }
7445
7446 static int
7447 api_tap_delete_v2 (vat_main_t * vam)
7448 {
7449   unformat_input_t *i = vam->input;
7450   vl_api_tap_delete_v2_t *mp;
7451   u32 sw_if_index = ~0;
7452   u8 sw_if_index_set = 0;
7453   int ret;
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7459         sw_if_index_set = 1;
7460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7461         sw_if_index_set = 1;
7462       else
7463         break;
7464     }
7465
7466   if (sw_if_index_set == 0)
7467     {
7468       errmsg ("missing vpp interface name. ");
7469       return -99;
7470     }
7471
7472   /* Construct the API message */
7473   M (TAP_DELETE_V2, mp);
7474
7475   mp->sw_if_index = ntohl (sw_if_index);
7476
7477   /* send it... */
7478   S (mp);
7479
7480   /* Wait for a reply... */
7481   W (ret);
7482   return ret;
7483 }
7484
7485 uword
7486 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7487 {
7488   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7489   u32 x[4];
7490
7491   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7492     return 0;
7493
7494   addr->domain = x[0];
7495   addr->bus = x[1];
7496   addr->slot = x[2];
7497   addr->function = x[3];
7498
7499   return 1;
7500 }
7501
7502 static int
7503 api_virtio_pci_create (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_virtio_pci_create_t *mp;
7507   u8 mac_address[6];
7508   u8 random_mac = 1;
7509   u8 gso_enabled = 0;
7510   u32 pci_addr = 0;
7511   u64 features = (u64) ~ (0ULL);
7512   int ret;
7513
7514   clib_memset (mac_address, 0, sizeof (mac_address));
7515
7516   /* Parse args required to build the message */
7517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7520         {
7521           random_mac = 0;
7522         }
7523       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7524         ;
7525       else if (unformat (i, "features 0x%llx", &features))
7526         ;
7527       else if (unformat (i, "gso-enabled"))
7528         gso_enabled = 1;
7529       else
7530         break;
7531     }
7532
7533   if (pci_addr == 0)
7534     {
7535       errmsg ("pci address must be non zero. ");
7536       return -99;
7537     }
7538
7539   /* Construct the API message */
7540   M (VIRTIO_PCI_CREATE, mp);
7541
7542   mp->use_random_mac = random_mac;
7543
7544   mp->pci_addr = htonl (pci_addr);
7545   mp->features = clib_host_to_net_u64 (features);
7546   mp->gso_enabled = gso_enabled;
7547
7548   if (random_mac == 0)
7549     clib_memcpy (mp->mac_address, mac_address, 6);
7550
7551   /* send it... */
7552   S (mp);
7553
7554   /* Wait for a reply... */
7555   W (ret);
7556   return ret;
7557 }
7558
7559 static int
7560 api_virtio_pci_delete (vat_main_t * vam)
7561 {
7562   unformat_input_t *i = vam->input;
7563   vl_api_virtio_pci_delete_t *mp;
7564   u32 sw_if_index = ~0;
7565   u8 sw_if_index_set = 0;
7566   int ret;
7567
7568   /* Parse args required to build the message */
7569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7570     {
7571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7572         sw_if_index_set = 1;
7573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7574         sw_if_index_set = 1;
7575       else
7576         break;
7577     }
7578
7579   if (sw_if_index_set == 0)
7580     {
7581       errmsg ("missing vpp interface name. ");
7582       return -99;
7583     }
7584
7585   /* Construct the API message */
7586   M (VIRTIO_PCI_DELETE, mp);
7587
7588   mp->sw_if_index = htonl (sw_if_index);
7589
7590   /* send it... */
7591   S (mp);
7592
7593   /* Wait for a reply... */
7594   W (ret);
7595   return ret;
7596 }
7597
7598 static int
7599 api_bond_create (vat_main_t * vam)
7600 {
7601   unformat_input_t *i = vam->input;
7602   vl_api_bond_create_t *mp;
7603   u8 mac_address[6];
7604   u8 custom_mac = 0;
7605   int ret;
7606   u8 mode;
7607   u8 lb;
7608   u8 mode_is_set = 0;
7609   u32 id = ~0;
7610   u8 numa_only = 0;
7611
7612   clib_memset (mac_address, 0, sizeof (mac_address));
7613   lb = BOND_LB_L2;
7614
7615   /* Parse args required to build the message */
7616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7617     {
7618       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7619         mode_is_set = 1;
7620       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7621                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7622         ;
7623       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7624                          mac_address))
7625         custom_mac = 1;
7626       else if (unformat (i, "numa-only"))
7627         numa_only = 1;
7628       else if (unformat (i, "id %u", &id))
7629         ;
7630       else
7631         break;
7632     }
7633
7634   if (mode_is_set == 0)
7635     {
7636       errmsg ("Missing bond mode. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (BOND_CREATE, mp);
7642
7643   mp->use_custom_mac = custom_mac;
7644
7645   mp->mode = htonl (mode);
7646   mp->lb = htonl (lb);
7647   mp->id = htonl (id);
7648   mp->numa_only = numa_only;
7649
7650   if (custom_mac)
7651     clib_memcpy (mp->mac_address, mac_address, 6);
7652
7653   /* send it... */
7654   S (mp);
7655
7656   /* Wait for a reply... */
7657   W (ret);
7658   return ret;
7659 }
7660
7661 static int
7662 api_bond_delete (vat_main_t * vam)
7663 {
7664   unformat_input_t *i = vam->input;
7665   vl_api_bond_delete_t *mp;
7666   u32 sw_if_index = ~0;
7667   u8 sw_if_index_set = 0;
7668   int ret;
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7674         sw_if_index_set = 1;
7675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7676         sw_if_index_set = 1;
7677       else
7678         break;
7679     }
7680
7681   if (sw_if_index_set == 0)
7682     {
7683       errmsg ("missing vpp interface name. ");
7684       return -99;
7685     }
7686
7687   /* Construct the API message */
7688   M (BOND_DELETE, mp);
7689
7690   mp->sw_if_index = ntohl (sw_if_index);
7691
7692   /* send it... */
7693   S (mp);
7694
7695   /* Wait for a reply... */
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_bond_enslave (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_bond_enslave_t *mp;
7705   u32 bond_sw_if_index;
7706   int ret;
7707   u8 is_passive;
7708   u8 is_long_timeout;
7709   u32 bond_sw_if_index_is_set = 0;
7710   u32 sw_if_index;
7711   u8 sw_if_index_is_set = 0;
7712
7713   /* Parse args required to build the message */
7714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715     {
7716       if (unformat (i, "sw_if_index %d", &sw_if_index))
7717         sw_if_index_is_set = 1;
7718       else if (unformat (i, "bond %u", &bond_sw_if_index))
7719         bond_sw_if_index_is_set = 1;
7720       else if (unformat (i, "passive %d", &is_passive))
7721         ;
7722       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7723         ;
7724       else
7725         break;
7726     }
7727
7728   if (bond_sw_if_index_is_set == 0)
7729     {
7730       errmsg ("Missing bond sw_if_index. ");
7731       return -99;
7732     }
7733   if (sw_if_index_is_set == 0)
7734     {
7735       errmsg ("Missing slave sw_if_index. ");
7736       return -99;
7737     }
7738
7739   /* Construct the API message */
7740   M (BOND_ENSLAVE, mp);
7741
7742   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7743   mp->sw_if_index = ntohl (sw_if_index);
7744   mp->is_long_timeout = is_long_timeout;
7745   mp->is_passive = is_passive;
7746
7747   /* send it... */
7748   S (mp);
7749
7750   /* Wait for a reply... */
7751   W (ret);
7752   return ret;
7753 }
7754
7755 static int
7756 api_bond_detach_slave (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_bond_detach_slave_t *mp;
7760   u32 sw_if_index = ~0;
7761   u8 sw_if_index_set = 0;
7762   int ret;
7763
7764   /* Parse args required to build the message */
7765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7766     {
7767       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7768         sw_if_index_set = 1;
7769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7770         sw_if_index_set = 1;
7771       else
7772         break;
7773     }
7774
7775   if (sw_if_index_set == 0)
7776     {
7777       errmsg ("missing vpp interface name. ");
7778       return -99;
7779     }
7780
7781   /* Construct the API message */
7782   M (BOND_DETACH_SLAVE, mp);
7783
7784   mp->sw_if_index = ntohl (sw_if_index);
7785
7786   /* send it... */
7787   S (mp);
7788
7789   /* Wait for a reply... */
7790   W (ret);
7791   return ret;
7792 }
7793
7794 static int
7795 api_ip_table_add_del (vat_main_t * vam)
7796 {
7797   unformat_input_t *i = vam->input;
7798   vl_api_ip_table_add_del_t *mp;
7799   u32 table_id = ~0;
7800   u8 is_ipv6 = 0;
7801   u8 is_add = 1;
7802   int ret = 0;
7803
7804   /* Parse args required to build the message */
7805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7806     {
7807       if (unformat (i, "ipv6"))
7808         is_ipv6 = 1;
7809       else if (unformat (i, "del"))
7810         is_add = 0;
7811       else if (unformat (i, "add"))
7812         is_add = 1;
7813       else if (unformat (i, "table %d", &table_id))
7814         ;
7815       else
7816         {
7817           clib_warning ("parse error '%U'", format_unformat_error, i);
7818           return -99;
7819         }
7820     }
7821
7822   if (~0 == table_id)
7823     {
7824       errmsg ("missing table-ID");
7825       return -99;
7826     }
7827
7828   /* Construct the API message */
7829   M (IP_TABLE_ADD_DEL, mp);
7830
7831   mp->table.table_id = ntohl (table_id);
7832   mp->table.is_ip6 = is_ipv6;
7833   mp->is_add = is_add;
7834
7835   /* send it... */
7836   S (mp);
7837
7838   /* Wait for a reply... */
7839   W (ret);
7840
7841   return ret;
7842 }
7843
7844 uword
7845 unformat_fib_path (unformat_input_t * input, va_list * args)
7846 {
7847   vat_main_t *vam = va_arg (*args, vat_main_t *);
7848   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7849   u32 weight, preference;
7850   mpls_label_t out_label;
7851
7852   clib_memset (path, 0, sizeof (*path));
7853   path->weight = 1;
7854   path->sw_if_index = ~0;
7855   path->rpf_id = ~0;
7856   path->n_labels = 0;
7857
7858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7859     {
7860       if (unformat (input, "%U %U",
7861                     unformat_vl_api_ip4_address,
7862                     &path->nh.address.ip4,
7863                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7864         {
7865           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7866         }
7867       else if (unformat (input, "%U %U",
7868                          unformat_vl_api_ip6_address,
7869                          &path->nh.address.ip6,
7870                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7871         {
7872           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7873         }
7874       else if (unformat (input, "weight %u", &weight))
7875         {
7876           path->weight = weight;
7877         }
7878       else if (unformat (input, "preference %u", &preference))
7879         {
7880           path->preference = preference;
7881         }
7882       else if (unformat (input, "%U next-hop-table %d",
7883                          unformat_vl_api_ip4_address,
7884                          &path->nh.address.ip4, &path->table_id))
7885         {
7886           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7887         }
7888       else if (unformat (input, "%U next-hop-table %d",
7889                          unformat_vl_api_ip6_address,
7890                          &path->nh.address.ip6, &path->table_id))
7891         {
7892           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7893         }
7894       else if (unformat (input, "%U",
7895                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7896         {
7897           /*
7898            * the recursive next-hops are by default in the default table
7899            */
7900           path->table_id = 0;
7901           path->sw_if_index = ~0;
7902           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7903         }
7904       else if (unformat (input, "%U",
7905                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7906         {
7907           /*
7908            * the recursive next-hops are by default in the default table
7909            */
7910           path->table_id = 0;
7911           path->sw_if_index = ~0;
7912           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7913         }
7914       else if (unformat (input, "resolve-via-host"))
7915         {
7916           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7917         }
7918       else if (unformat (input, "resolve-via-attached"))
7919         {
7920           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7921         }
7922       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7923         {
7924           path->type = FIB_API_PATH_TYPE_LOCAL;
7925           path->sw_if_index = ~0;
7926           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7927         }
7928       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7929         {
7930           path->type = FIB_API_PATH_TYPE_LOCAL;
7931           path->sw_if_index = ~0;
7932           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7933         }
7934       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7935         ;
7936       else if (unformat (input, "via-label %d", &path->nh.via_label))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7939           path->sw_if_index = ~0;
7940         }
7941       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7942         {
7943           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7944           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7945         }
7946       else if (unformat (input, "local"))
7947         {
7948           path->type = FIB_API_PATH_TYPE_LOCAL;
7949         }
7950       else if (unformat (input, "out-labels"))
7951         {
7952           while (unformat (input, "%d", &out_label))
7953             {
7954               path->label_stack[path->n_labels].label = out_label;
7955               path->label_stack[path->n_labels].is_uniform = 0;
7956               path->label_stack[path->n_labels].ttl = 64;
7957               path->n_labels++;
7958             }
7959         }
7960       else if (unformat (input, "via"))
7961         {
7962           /* new path, back up and return */
7963           unformat_put_input (input);
7964           unformat_put_input (input);
7965           unformat_put_input (input);
7966           unformat_put_input (input);
7967           break;
7968         }
7969       else
7970         {
7971           return (0);
7972         }
7973     }
7974
7975   path->proto = ntohl (path->proto);
7976   path->type = ntohl (path->type);
7977   path->flags = ntohl (path->flags);
7978   path->table_id = ntohl (path->table_id);
7979   path->sw_if_index = ntohl (path->sw_if_index);
7980
7981   return (1);
7982 }
7983
7984 static int
7985 api_ip_route_add_del (vat_main_t * vam)
7986 {
7987   unformat_input_t *i = vam->input;
7988   vl_api_ip_route_add_del_t *mp;
7989   u32 vrf_id = 0;
7990   u8 is_add = 1;
7991   u8 is_multipath = 0;
7992   u8 prefix_set = 0;
7993   u8 path_count = 0;
7994   vl_api_prefix_t pfx = { };
7995   vl_api_fib_path_t paths[8];
7996   int count = 1;
7997   int j;
7998   f64 before = 0;
7999   u32 random_add_del = 0;
8000   u32 *random_vector = 0;
8001   u32 random_seed = 0xdeaddabe;
8002
8003   /* Parse args required to build the message */
8004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8005     {
8006       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8007         prefix_set = 1;
8008       else if (unformat (i, "del"))
8009         is_add = 0;
8010       else if (unformat (i, "add"))
8011         is_add = 1;
8012       else if (unformat (i, "vrf %d", &vrf_id))
8013         ;
8014       else if (unformat (i, "count %d", &count))
8015         ;
8016       else if (unformat (i, "random"))
8017         random_add_del = 1;
8018       else if (unformat (i, "multipath"))
8019         is_multipath = 1;
8020       else if (unformat (i, "seed %d", &random_seed))
8021         ;
8022       else
8023         if (unformat
8024             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8025         {
8026           path_count++;
8027           if (8 == path_count)
8028             {
8029               errmsg ("max 8 paths");
8030               return -99;
8031             }
8032         }
8033       else
8034         {
8035           clib_warning ("parse error '%U'", format_unformat_error, i);
8036           return -99;
8037         }
8038     }
8039
8040   if (!path_count)
8041     {
8042       errmsg ("specify a path; via ...");
8043       return -99;
8044     }
8045   if (prefix_set == 0)
8046     {
8047       errmsg ("missing prefix");
8048       return -99;
8049     }
8050
8051   /* Generate a pile of unique, random routes */
8052   if (random_add_del)
8053     {
8054       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8055       u32 this_random_address;
8056       uword *random_hash;
8057
8058       random_hash = hash_create (count, sizeof (uword));
8059
8060       hash_set (random_hash, i->as_u32, 1);
8061       for (j = 0; j <= count; j++)
8062         {
8063           do
8064             {
8065               this_random_address = random_u32 (&random_seed);
8066               this_random_address =
8067                 clib_host_to_net_u32 (this_random_address);
8068             }
8069           while (hash_get (random_hash, this_random_address));
8070           vec_add1 (random_vector, this_random_address);
8071           hash_set (random_hash, this_random_address, 1);
8072         }
8073       hash_free (random_hash);
8074       set_ip4_address (&pfx.address, random_vector[0]);
8075     }
8076
8077   if (count > 1)
8078     {
8079       /* Turn on async mode */
8080       vam->async_mode = 1;
8081       vam->async_errors = 0;
8082       before = vat_time_now (vam);
8083     }
8084
8085   for (j = 0; j < count; j++)
8086     {
8087       /* Construct the API message */
8088       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8089
8090       mp->is_add = is_add;
8091       mp->is_multipath = is_multipath;
8092
8093       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8094       mp->route.table_id = ntohl (vrf_id);
8095       mp->route.n_paths = path_count;
8096
8097       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8098
8099       if (random_add_del)
8100         set_ip4_address (&pfx.address, random_vector[j + 1]);
8101       else
8102         increment_address (&pfx.address);
8103       /* send it... */
8104       S (mp);
8105       /* If we receive SIGTERM, stop now... */
8106       if (vam->do_exit)
8107         break;
8108     }
8109
8110   /* When testing multiple add/del ops, use a control-ping to sync */
8111   if (count > 1)
8112     {
8113       vl_api_control_ping_t *mp_ping;
8114       f64 after;
8115       f64 timeout;
8116
8117       /* Shut off async mode */
8118       vam->async_mode = 0;
8119
8120       MPING (CONTROL_PING, mp_ping);
8121       S (mp_ping);
8122
8123       timeout = vat_time_now (vam) + 1.0;
8124       while (vat_time_now (vam) < timeout)
8125         if (vam->result_ready == 1)
8126           goto out;
8127       vam->retval = -99;
8128
8129     out:
8130       if (vam->retval == -99)
8131         errmsg ("timeout");
8132
8133       if (vam->async_errors > 0)
8134         {
8135           errmsg ("%d asynchronous errors", vam->async_errors);
8136           vam->retval = -98;
8137         }
8138       vam->async_errors = 0;
8139       after = vat_time_now (vam);
8140
8141       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8142       if (j > 0)
8143         count = j;
8144
8145       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8146              count, after - before, count / (after - before));
8147     }
8148   else
8149     {
8150       int ret;
8151
8152       /* Wait for a reply... */
8153       W (ret);
8154       return ret;
8155     }
8156
8157   /* Return the good/bad news */
8158   return (vam->retval);
8159 }
8160
8161 static int
8162 api_ip_mroute_add_del (vat_main_t * vam)
8163 {
8164   unformat_input_t *i = vam->input;
8165   u8 path_set = 0, prefix_set = 0, is_add = 1;
8166   vl_api_ip_mroute_add_del_t *mp;
8167   mfib_entry_flags_t eflags = 0;
8168   vl_api_mfib_path_t path;
8169   vl_api_mprefix_t pfx = { };
8170   u32 vrf_id = 0;
8171   int ret;
8172
8173   /* Parse args required to build the message */
8174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8175     {
8176       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8177         {
8178           prefix_set = 1;
8179           pfx.grp_address_length = htons (pfx.grp_address_length);
8180         }
8181       else if (unformat (i, "del"))
8182         is_add = 0;
8183       else if (unformat (i, "add"))
8184         is_add = 1;
8185       else if (unformat (i, "vrf %d", &vrf_id))
8186         ;
8187       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8188         path.itf_flags = htonl (path.itf_flags);
8189       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8190         ;
8191       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8192         path_set = 1;
8193       else
8194         {
8195           clib_warning ("parse error '%U'", format_unformat_error, i);
8196           return -99;
8197         }
8198     }
8199
8200   if (prefix_set == 0)
8201     {
8202       errmsg ("missing addresses\n");
8203       return -99;
8204     }
8205   if (path_set == 0)
8206     {
8207       errmsg ("missing path\n");
8208       return -99;
8209     }
8210
8211   /* Construct the API message */
8212   M (IP_MROUTE_ADD_DEL, mp);
8213
8214   mp->is_add = is_add;
8215   mp->is_multipath = 1;
8216
8217   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8218   mp->route.table_id = htonl (vrf_id);
8219   mp->route.n_paths = 1;
8220   mp->route.entry_flags = htonl (eflags);
8221
8222   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8223
8224   /* send it... */
8225   S (mp);
8226   /* Wait for a reply... */
8227   W (ret);
8228   return ret;
8229 }
8230
8231 static int
8232 api_mpls_table_add_del (vat_main_t * vam)
8233 {
8234   unformat_input_t *i = vam->input;
8235   vl_api_mpls_table_add_del_t *mp;
8236   u32 table_id = ~0;
8237   u8 is_add = 1;
8238   int ret = 0;
8239
8240   /* Parse args required to build the message */
8241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8242     {
8243       if (unformat (i, "table %d", &table_id))
8244         ;
8245       else if (unformat (i, "del"))
8246         is_add = 0;
8247       else if (unformat (i, "add"))
8248         is_add = 1;
8249       else
8250         {
8251           clib_warning ("parse error '%U'", format_unformat_error, i);
8252           return -99;
8253         }
8254     }
8255
8256   if (~0 == table_id)
8257     {
8258       errmsg ("missing table-ID");
8259       return -99;
8260     }
8261
8262   /* Construct the API message */
8263   M (MPLS_TABLE_ADD_DEL, mp);
8264
8265   mp->mt_table.mt_table_id = ntohl (table_id);
8266   mp->mt_is_add = is_add;
8267
8268   /* send it... */
8269   S (mp);
8270
8271   /* Wait for a reply... */
8272   W (ret);
8273
8274   return ret;
8275 }
8276
8277 static int
8278 api_mpls_route_add_del (vat_main_t * vam)
8279 {
8280   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8281   mpls_label_t local_label = MPLS_LABEL_INVALID;
8282   unformat_input_t *i = vam->input;
8283   vl_api_mpls_route_add_del_t *mp;
8284   vl_api_fib_path_t paths[8];
8285   int count = 1, j;
8286   f64 before = 0;
8287
8288   /* Parse args required to build the message */
8289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8290     {
8291       if (unformat (i, "%d", &local_label))
8292         ;
8293       else if (unformat (i, "eos"))
8294         is_eos = 1;
8295       else if (unformat (i, "non-eos"))
8296         is_eos = 0;
8297       else if (unformat (i, "del"))
8298         is_add = 0;
8299       else if (unformat (i, "add"))
8300         is_add = 1;
8301       else if (unformat (i, "multipath"))
8302         is_multipath = 1;
8303       else if (unformat (i, "count %d", &count))
8304         ;
8305       else
8306         if (unformat
8307             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8308         {
8309           path_count++;
8310           if (8 == path_count)
8311             {
8312               errmsg ("max 8 paths");
8313               return -99;
8314             }
8315         }
8316       else
8317         {
8318           clib_warning ("parse error '%U'", format_unformat_error, i);
8319           return -99;
8320         }
8321     }
8322
8323   if (!path_count)
8324     {
8325       errmsg ("specify a path; via ...");
8326       return -99;
8327     }
8328
8329   if (MPLS_LABEL_INVALID == local_label)
8330     {
8331       errmsg ("missing label");
8332       return -99;
8333     }
8334
8335   if (count > 1)
8336     {
8337       /* Turn on async mode */
8338       vam->async_mode = 1;
8339       vam->async_errors = 0;
8340       before = vat_time_now (vam);
8341     }
8342
8343   for (j = 0; j < count; j++)
8344     {
8345       /* Construct the API message */
8346       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8347
8348       mp->mr_is_add = is_add;
8349       mp->mr_is_multipath = is_multipath;
8350
8351       mp->mr_route.mr_label = local_label;
8352       mp->mr_route.mr_eos = is_eos;
8353       mp->mr_route.mr_table_id = 0;
8354       mp->mr_route.mr_n_paths = path_count;
8355
8356       clib_memcpy (&mp->mr_route.mr_paths, paths,
8357                    sizeof (paths[0]) * path_count);
8358
8359       local_label++;
8360
8361       /* send it... */
8362       S (mp);
8363       /* If we receive SIGTERM, stop now... */
8364       if (vam->do_exit)
8365         break;
8366     }
8367
8368   /* When testing multiple add/del ops, use a control-ping to sync */
8369   if (count > 1)
8370     {
8371       vl_api_control_ping_t *mp_ping;
8372       f64 after;
8373       f64 timeout;
8374
8375       /* Shut off async mode */
8376       vam->async_mode = 0;
8377
8378       MPING (CONTROL_PING, mp_ping);
8379       S (mp_ping);
8380
8381       timeout = vat_time_now (vam) + 1.0;
8382       while (vat_time_now (vam) < timeout)
8383         if (vam->result_ready == 1)
8384           goto out;
8385       vam->retval = -99;
8386
8387     out:
8388       if (vam->retval == -99)
8389         errmsg ("timeout");
8390
8391       if (vam->async_errors > 0)
8392         {
8393           errmsg ("%d asynchronous errors", vam->async_errors);
8394           vam->retval = -98;
8395         }
8396       vam->async_errors = 0;
8397       after = vat_time_now (vam);
8398
8399       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8400       if (j > 0)
8401         count = j;
8402
8403       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8404              count, after - before, count / (after - before));
8405     }
8406   else
8407     {
8408       int ret;
8409
8410       /* Wait for a reply... */
8411       W (ret);
8412       return ret;
8413     }
8414
8415   /* Return the good/bad news */
8416   return (vam->retval);
8417   return (0);
8418 }
8419
8420 static int
8421 api_mpls_ip_bind_unbind (vat_main_t * vam)
8422 {
8423   unformat_input_t *i = vam->input;
8424   vl_api_mpls_ip_bind_unbind_t *mp;
8425   u32 ip_table_id = 0;
8426   u8 is_bind = 1;
8427   vl_api_prefix_t pfx;
8428   u8 prefix_set = 0;
8429   mpls_label_t local_label = MPLS_LABEL_INVALID;
8430   int ret;
8431
8432   /* Parse args required to build the message */
8433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8434     {
8435       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8436         prefix_set = 1;
8437       else if (unformat (i, "%d", &local_label))
8438         ;
8439       else if (unformat (i, "table-id %d", &ip_table_id))
8440         ;
8441       else if (unformat (i, "unbind"))
8442         is_bind = 0;
8443       else if (unformat (i, "bind"))
8444         is_bind = 1;
8445       else
8446         {
8447           clib_warning ("parse error '%U'", format_unformat_error, i);
8448           return -99;
8449         }
8450     }
8451
8452   if (!prefix_set)
8453     {
8454       errmsg ("IP prefix not set");
8455       return -99;
8456     }
8457
8458   if (MPLS_LABEL_INVALID == local_label)
8459     {
8460       errmsg ("missing label");
8461       return -99;
8462     }
8463
8464   /* Construct the API message */
8465   M (MPLS_IP_BIND_UNBIND, mp);
8466
8467   mp->mb_is_bind = is_bind;
8468   mp->mb_ip_table_id = ntohl (ip_table_id);
8469   mp->mb_mpls_table_id = 0;
8470   mp->mb_label = ntohl (local_label);
8471   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8472
8473   /* send it... */
8474   S (mp);
8475
8476   /* Wait for a reply... */
8477   W (ret);
8478   return ret;
8479   return (0);
8480 }
8481
8482 static int
8483 api_sr_mpls_policy_add (vat_main_t * vam)
8484 {
8485   unformat_input_t *i = vam->input;
8486   vl_api_sr_mpls_policy_add_t *mp;
8487   u32 bsid = 0;
8488   u32 weight = 1;
8489   u8 type = 0;
8490   u8 n_segments = 0;
8491   u32 sid;
8492   u32 *segments = NULL;
8493   int ret;
8494
8495   /* Parse args required to build the message */
8496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8497     {
8498       if (unformat (i, "bsid %d", &bsid))
8499         ;
8500       else if (unformat (i, "weight %d", &weight))
8501         ;
8502       else if (unformat (i, "spray"))
8503         type = 1;
8504       else if (unformat (i, "next %d", &sid))
8505         {
8506           n_segments += 1;
8507           vec_add1 (segments, htonl (sid));
8508         }
8509       else
8510         {
8511           clib_warning ("parse error '%U'", format_unformat_error, i);
8512           return -99;
8513         }
8514     }
8515
8516   if (bsid == 0)
8517     {
8518       errmsg ("bsid not set");
8519       return -99;
8520     }
8521
8522   if (n_segments == 0)
8523     {
8524       errmsg ("no sid in segment stack");
8525       return -99;
8526     }
8527
8528   /* Construct the API message */
8529   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8530
8531   mp->bsid = htonl (bsid);
8532   mp->weight = htonl (weight);
8533   mp->type = type;
8534   mp->n_segments = n_segments;
8535   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8536   vec_free (segments);
8537
8538   /* send it... */
8539   S (mp);
8540
8541   /* Wait for a reply... */
8542   W (ret);
8543   return ret;
8544 }
8545
8546 static int
8547 api_sr_mpls_policy_del (vat_main_t * vam)
8548 {
8549   unformat_input_t *i = vam->input;
8550   vl_api_sr_mpls_policy_del_t *mp;
8551   u32 bsid = 0;
8552   int ret;
8553
8554   /* Parse args required to build the message */
8555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8556     {
8557       if (unformat (i, "bsid %d", &bsid))
8558         ;
8559       else
8560         {
8561           clib_warning ("parse error '%U'", format_unformat_error, i);
8562           return -99;
8563         }
8564     }
8565
8566   if (bsid == 0)
8567     {
8568       errmsg ("bsid not set");
8569       return -99;
8570     }
8571
8572   /* Construct the API message */
8573   M (SR_MPLS_POLICY_DEL, mp);
8574
8575   mp->bsid = htonl (bsid);
8576
8577   /* send it... */
8578   S (mp);
8579
8580   /* Wait for a reply... */
8581   W (ret);
8582   return ret;
8583 }
8584
8585 static int
8586 api_bier_table_add_del (vat_main_t * vam)
8587 {
8588   unformat_input_t *i = vam->input;
8589   vl_api_bier_table_add_del_t *mp;
8590   u8 is_add = 1;
8591   u32 set = 0, sub_domain = 0, hdr_len = 3;
8592   mpls_label_t local_label = MPLS_LABEL_INVALID;
8593   int ret;
8594
8595   /* Parse args required to build the message */
8596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8597     {
8598       if (unformat (i, "sub-domain %d", &sub_domain))
8599         ;
8600       else if (unformat (i, "set %d", &set))
8601         ;
8602       else if (unformat (i, "label %d", &local_label))
8603         ;
8604       else if (unformat (i, "hdr-len %d", &hdr_len))
8605         ;
8606       else if (unformat (i, "add"))
8607         is_add = 1;
8608       else if (unformat (i, "del"))
8609         is_add = 0;
8610       else
8611         {
8612           clib_warning ("parse error '%U'", format_unformat_error, i);
8613           return -99;
8614         }
8615     }
8616
8617   if (MPLS_LABEL_INVALID == local_label)
8618     {
8619       errmsg ("missing label\n");
8620       return -99;
8621     }
8622
8623   /* Construct the API message */
8624   M (BIER_TABLE_ADD_DEL, mp);
8625
8626   mp->bt_is_add = is_add;
8627   mp->bt_label = ntohl (local_label);
8628   mp->bt_tbl_id.bt_set = set;
8629   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8630   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8631
8632   /* send it... */
8633   S (mp);
8634
8635   /* Wait for a reply... */
8636   W (ret);
8637
8638   return (ret);
8639 }
8640
8641 static int
8642 api_bier_route_add_del (vat_main_t * vam)
8643 {
8644   unformat_input_t *i = vam->input;
8645   vl_api_bier_route_add_del_t *mp;
8646   u8 is_add = 1;
8647   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8648   ip4_address_t v4_next_hop_address;
8649   ip6_address_t v6_next_hop_address;
8650   u8 next_hop_set = 0;
8651   u8 next_hop_proto_is_ip4 = 1;
8652   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8653   int ret;
8654
8655   /* Parse args required to build the message */
8656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8657     {
8658       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8659         {
8660           next_hop_proto_is_ip4 = 1;
8661           next_hop_set = 1;
8662         }
8663       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8664         {
8665           next_hop_proto_is_ip4 = 0;
8666           next_hop_set = 1;
8667         }
8668       if (unformat (i, "sub-domain %d", &sub_domain))
8669         ;
8670       else if (unformat (i, "set %d", &set))
8671         ;
8672       else if (unformat (i, "hdr-len %d", &hdr_len))
8673         ;
8674       else if (unformat (i, "bp %d", &bp))
8675         ;
8676       else if (unformat (i, "add"))
8677         is_add = 1;
8678       else if (unformat (i, "del"))
8679         is_add = 0;
8680       else if (unformat (i, "out-label %d", &next_hop_out_label))
8681         ;
8682       else
8683         {
8684           clib_warning ("parse error '%U'", format_unformat_error, i);
8685           return -99;
8686         }
8687     }
8688
8689   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8690     {
8691       errmsg ("next hop / label set\n");
8692       return -99;
8693     }
8694   if (0 == bp)
8695     {
8696       errmsg ("bit=position not set\n");
8697       return -99;
8698     }
8699
8700   /* Construct the API message */
8701   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8702
8703   mp->br_is_add = is_add;
8704   mp->br_route.br_tbl_id.bt_set = set;
8705   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8706   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8707   mp->br_route.br_bp = ntohs (bp);
8708   mp->br_route.br_n_paths = 1;
8709   mp->br_route.br_paths[0].n_labels = 1;
8710   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8711   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8712                                     FIB_API_PATH_NH_PROTO_IP4 :
8713                                     FIB_API_PATH_NH_PROTO_IP6);
8714
8715   if (next_hop_proto_is_ip4)
8716     {
8717       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8718                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8719     }
8720   else
8721     {
8722       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8723                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8724     }
8725
8726   /* send it... */
8727   S (mp);
8728
8729   /* Wait for a reply... */
8730   W (ret);
8731
8732   return (ret);
8733 }
8734
8735 static int
8736 api_mpls_tunnel_add_del (vat_main_t * vam)
8737 {
8738   unformat_input_t *i = vam->input;
8739   vl_api_mpls_tunnel_add_del_t *mp;
8740
8741   vl_api_fib_path_t paths[8];
8742   u32 sw_if_index = ~0;
8743   u8 path_count = 0;
8744   u8 l2_only = 0;
8745   u8 is_add = 1;
8746   int ret;
8747
8748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8749     {
8750       if (unformat (i, "add"))
8751         is_add = 1;
8752       else
8753         if (unformat
8754             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8755         is_add = 0;
8756       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8757         is_add = 0;
8758       else if (unformat (i, "l2-only"))
8759         l2_only = 1;
8760       else
8761         if (unformat
8762             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8763         {
8764           path_count++;
8765           if (8 == path_count)
8766             {
8767               errmsg ("max 8 paths");
8768               return -99;
8769             }
8770         }
8771       else
8772         {
8773           clib_warning ("parse error '%U'", format_unformat_error, i);
8774           return -99;
8775         }
8776     }
8777
8778   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8779
8780   mp->mt_is_add = is_add;
8781   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8782   mp->mt_tunnel.mt_l2_only = l2_only;
8783   mp->mt_tunnel.mt_is_multicast = 0;
8784   mp->mt_tunnel.mt_n_paths = path_count;
8785
8786   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8787                sizeof (paths[0]) * path_count);
8788
8789   S (mp);
8790   W (ret);
8791   return ret;
8792 }
8793
8794 static int
8795 api_sw_interface_set_unnumbered (vat_main_t * vam)
8796 {
8797   unformat_input_t *i = vam->input;
8798   vl_api_sw_interface_set_unnumbered_t *mp;
8799   u32 sw_if_index;
8800   u32 unnum_sw_index = ~0;
8801   u8 is_add = 1;
8802   u8 sw_if_index_set = 0;
8803   int ret;
8804
8805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8806     {
8807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8808         sw_if_index_set = 1;
8809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8810         sw_if_index_set = 1;
8811       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8812         ;
8813       else if (unformat (i, "del"))
8814         is_add = 0;
8815       else
8816         {
8817           clib_warning ("parse error '%U'", format_unformat_error, i);
8818           return -99;
8819         }
8820     }
8821
8822   if (sw_if_index_set == 0)
8823     {
8824       errmsg ("missing interface name or sw_if_index");
8825       return -99;
8826     }
8827
8828   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8829
8830   mp->sw_if_index = ntohl (sw_if_index);
8831   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8832   mp->is_add = is_add;
8833
8834   S (mp);
8835   W (ret);
8836   return ret;
8837 }
8838
8839
8840 static int
8841 api_create_vlan_subif (vat_main_t * vam)
8842 {
8843   unformat_input_t *i = vam->input;
8844   vl_api_create_vlan_subif_t *mp;
8845   u32 sw_if_index;
8846   u8 sw_if_index_set = 0;
8847   u32 vlan_id;
8848   u8 vlan_id_set = 0;
8849   int ret;
8850
8851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (unformat (i, "sw_if_index %d", &sw_if_index))
8854         sw_if_index_set = 1;
8855       else
8856         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8857         sw_if_index_set = 1;
8858       else if (unformat (i, "vlan %d", &vlan_id))
8859         vlan_id_set = 1;
8860       else
8861         {
8862           clib_warning ("parse error '%U'", format_unformat_error, i);
8863           return -99;
8864         }
8865     }
8866
8867   if (sw_if_index_set == 0)
8868     {
8869       errmsg ("missing interface name or sw_if_index");
8870       return -99;
8871     }
8872
8873   if (vlan_id_set == 0)
8874     {
8875       errmsg ("missing vlan_id");
8876       return -99;
8877     }
8878   M (CREATE_VLAN_SUBIF, mp);
8879
8880   mp->sw_if_index = ntohl (sw_if_index);
8881   mp->vlan_id = ntohl (vlan_id);
8882
8883   S (mp);
8884   W (ret);
8885   return ret;
8886 }
8887
8888 #define foreach_create_subif_bit                \
8889 _(no_tags)                                      \
8890 _(one_tag)                                      \
8891 _(two_tags)                                     \
8892 _(dot1ad)                                       \
8893 _(exact_match)                                  \
8894 _(default_sub)                                  \
8895 _(outer_vlan_id_any)                            \
8896 _(inner_vlan_id_any)
8897
8898 #define foreach_create_subif_flag               \
8899 _(0, "no_tags")                                 \
8900 _(1, "one_tag")                                 \
8901 _(2, "two_tags")                                \
8902 _(3, "dot1ad")                                  \
8903 _(4, "exact_match")                             \
8904 _(5, "default_sub")                             \
8905 _(6, "outer_vlan_id_any")                       \
8906 _(7, "inner_vlan_id_any")
8907
8908 static int
8909 api_create_subif (vat_main_t * vam)
8910 {
8911   unformat_input_t *i = vam->input;
8912   vl_api_create_subif_t *mp;
8913   u32 sw_if_index;
8914   u8 sw_if_index_set = 0;
8915   u32 sub_id;
8916   u8 sub_id_set = 0;
8917   u32 __attribute__ ((unused)) no_tags = 0;
8918   u32 __attribute__ ((unused)) one_tag = 0;
8919   u32 __attribute__ ((unused)) two_tags = 0;
8920   u32 __attribute__ ((unused)) dot1ad = 0;
8921   u32 __attribute__ ((unused)) exact_match = 0;
8922   u32 __attribute__ ((unused)) default_sub = 0;
8923   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8924   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8925   u32 tmp;
8926   u16 outer_vlan_id = 0;
8927   u16 inner_vlan_id = 0;
8928   int ret;
8929
8930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8931     {
8932       if (unformat (i, "sw_if_index %d", &sw_if_index))
8933         sw_if_index_set = 1;
8934       else
8935         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8936         sw_if_index_set = 1;
8937       else if (unformat (i, "sub_id %d", &sub_id))
8938         sub_id_set = 1;
8939       else if (unformat (i, "outer_vlan_id %d", &tmp))
8940         outer_vlan_id = tmp;
8941       else if (unformat (i, "inner_vlan_id %d", &tmp))
8942         inner_vlan_id = tmp;
8943
8944 #define _(a) else if (unformat (i, #a)) a = 1 ;
8945       foreach_create_subif_bit
8946 #undef _
8947         else
8948         {
8949           clib_warning ("parse error '%U'", format_unformat_error, i);
8950           return -99;
8951         }
8952     }
8953
8954   if (sw_if_index_set == 0)
8955     {
8956       errmsg ("missing interface name or sw_if_index");
8957       return -99;
8958     }
8959
8960   if (sub_id_set == 0)
8961     {
8962       errmsg ("missing sub_id");
8963       return -99;
8964     }
8965   M (CREATE_SUBIF, mp);
8966
8967   mp->sw_if_index = ntohl (sw_if_index);
8968   mp->sub_id = ntohl (sub_id);
8969
8970 #define _(a,b) mp->sub_if_flags |= (1 << a);
8971   foreach_create_subif_flag;
8972 #undef _
8973
8974   mp->outer_vlan_id = ntohs (outer_vlan_id);
8975   mp->inner_vlan_id = ntohs (inner_vlan_id);
8976
8977   S (mp);
8978   W (ret);
8979   return ret;
8980 }
8981
8982 static int
8983 api_ip_table_replace_begin (vat_main_t * vam)
8984 {
8985   unformat_input_t *i = vam->input;
8986   vl_api_ip_table_replace_begin_t *mp;
8987   u32 table_id = 0;
8988   u8 is_ipv6 = 0;
8989
8990   int ret;
8991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8992     {
8993       if (unformat (i, "table %d", &table_id))
8994         ;
8995       else if (unformat (i, "ipv6"))
8996         is_ipv6 = 1;
8997       else
8998         {
8999           clib_warning ("parse error '%U'", format_unformat_error, i);
9000           return -99;
9001         }
9002     }
9003
9004   M (IP_TABLE_REPLACE_BEGIN, mp);
9005
9006   mp->table.table_id = ntohl (table_id);
9007   mp->table.is_ip6 = is_ipv6;
9008
9009   S (mp);
9010   W (ret);
9011   return ret;
9012 }
9013
9014 static int
9015 api_ip_table_flush (vat_main_t * vam)
9016 {
9017   unformat_input_t *i = vam->input;
9018   vl_api_ip_table_flush_t *mp;
9019   u32 table_id = 0;
9020   u8 is_ipv6 = 0;
9021
9022   int ret;
9023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9024     {
9025       if (unformat (i, "table %d", &table_id))
9026         ;
9027       else if (unformat (i, "ipv6"))
9028         is_ipv6 = 1;
9029       else
9030         {
9031           clib_warning ("parse error '%U'", format_unformat_error, i);
9032           return -99;
9033         }
9034     }
9035
9036   M (IP_TABLE_FLUSH, mp);
9037
9038   mp->table.table_id = ntohl (table_id);
9039   mp->table.is_ip6 = is_ipv6;
9040
9041   S (mp);
9042   W (ret);
9043   return ret;
9044 }
9045
9046 static int
9047 api_ip_table_replace_end (vat_main_t * vam)
9048 {
9049   unformat_input_t *i = vam->input;
9050   vl_api_ip_table_replace_end_t *mp;
9051   u32 table_id = 0;
9052   u8 is_ipv6 = 0;
9053
9054   int ret;
9055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9056     {
9057       if (unformat (i, "table %d", &table_id))
9058         ;
9059       else if (unformat (i, "ipv6"))
9060         is_ipv6 = 1;
9061       else
9062         {
9063           clib_warning ("parse error '%U'", format_unformat_error, i);
9064           return -99;
9065         }
9066     }
9067
9068   M (IP_TABLE_REPLACE_END, mp);
9069
9070   mp->table.table_id = ntohl (table_id);
9071   mp->table.is_ip6 = is_ipv6;
9072
9073   S (mp);
9074   W (ret);
9075   return ret;
9076 }
9077
9078 static int
9079 api_set_ip_flow_hash (vat_main_t * vam)
9080 {
9081   unformat_input_t *i = vam->input;
9082   vl_api_set_ip_flow_hash_t *mp;
9083   u32 vrf_id = 0;
9084   u8 is_ipv6 = 0;
9085   u8 vrf_id_set = 0;
9086   u8 src = 0;
9087   u8 dst = 0;
9088   u8 sport = 0;
9089   u8 dport = 0;
9090   u8 proto = 0;
9091   u8 reverse = 0;
9092   int ret;
9093
9094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9095     {
9096       if (unformat (i, "vrf %d", &vrf_id))
9097         vrf_id_set = 1;
9098       else if (unformat (i, "ipv6"))
9099         is_ipv6 = 1;
9100       else if (unformat (i, "src"))
9101         src = 1;
9102       else if (unformat (i, "dst"))
9103         dst = 1;
9104       else if (unformat (i, "sport"))
9105         sport = 1;
9106       else if (unformat (i, "dport"))
9107         dport = 1;
9108       else if (unformat (i, "proto"))
9109         proto = 1;
9110       else if (unformat (i, "reverse"))
9111         reverse = 1;
9112
9113       else
9114         {
9115           clib_warning ("parse error '%U'", format_unformat_error, i);
9116           return -99;
9117         }
9118     }
9119
9120   if (vrf_id_set == 0)
9121     {
9122       errmsg ("missing vrf id");
9123       return -99;
9124     }
9125
9126   M (SET_IP_FLOW_HASH, mp);
9127   mp->src = src;
9128   mp->dst = dst;
9129   mp->sport = sport;
9130   mp->dport = dport;
9131   mp->proto = proto;
9132   mp->reverse = reverse;
9133   mp->vrf_id = ntohl (vrf_id);
9134   mp->is_ipv6 = is_ipv6;
9135
9136   S (mp);
9137   W (ret);
9138   return ret;
9139 }
9140
9141 static int
9142 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9143 {
9144   unformat_input_t *i = vam->input;
9145   vl_api_sw_interface_ip6_enable_disable_t *mp;
9146   u32 sw_if_index;
9147   u8 sw_if_index_set = 0;
9148   u8 enable = 0;
9149   int ret;
9150
9151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9152     {
9153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9154         sw_if_index_set = 1;
9155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9156         sw_if_index_set = 1;
9157       else if (unformat (i, "enable"))
9158         enable = 1;
9159       else if (unformat (i, "disable"))
9160         enable = 0;
9161       else
9162         {
9163           clib_warning ("parse error '%U'", format_unformat_error, i);
9164           return -99;
9165         }
9166     }
9167
9168   if (sw_if_index_set == 0)
9169     {
9170       errmsg ("missing interface name or sw_if_index");
9171       return -99;
9172     }
9173
9174   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9175
9176   mp->sw_if_index = ntohl (sw_if_index);
9177   mp->enable = enable;
9178
9179   S (mp);
9180   W (ret);
9181   return ret;
9182 }
9183
9184
9185 static int
9186 api_l2_patch_add_del (vat_main_t * vam)
9187 {
9188   unformat_input_t *i = vam->input;
9189   vl_api_l2_patch_add_del_t *mp;
9190   u32 rx_sw_if_index;
9191   u8 rx_sw_if_index_set = 0;
9192   u32 tx_sw_if_index;
9193   u8 tx_sw_if_index_set = 0;
9194   u8 is_add = 1;
9195   int ret;
9196
9197   /* Parse args required to build the message */
9198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9199     {
9200       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9201         rx_sw_if_index_set = 1;
9202       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9203         tx_sw_if_index_set = 1;
9204       else if (unformat (i, "rx"))
9205         {
9206           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9207             {
9208               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9209                             &rx_sw_if_index))
9210                 rx_sw_if_index_set = 1;
9211             }
9212           else
9213             break;
9214         }
9215       else if (unformat (i, "tx"))
9216         {
9217           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9218             {
9219               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9220                             &tx_sw_if_index))
9221                 tx_sw_if_index_set = 1;
9222             }
9223           else
9224             break;
9225         }
9226       else if (unformat (i, "del"))
9227         is_add = 0;
9228       else
9229         break;
9230     }
9231
9232   if (rx_sw_if_index_set == 0)
9233     {
9234       errmsg ("missing rx interface name or rx_sw_if_index");
9235       return -99;
9236     }
9237
9238   if (tx_sw_if_index_set == 0)
9239     {
9240       errmsg ("missing tx interface name or tx_sw_if_index");
9241       return -99;
9242     }
9243
9244   M (L2_PATCH_ADD_DEL, mp);
9245
9246   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9247   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9248   mp->is_add = is_add;
9249
9250   S (mp);
9251   W (ret);
9252   return ret;
9253 }
9254
9255 u8 is_del;
9256 u8 localsid_addr[16];
9257 u8 end_psp;
9258 u8 behavior;
9259 u32 sw_if_index;
9260 u32 vlan_index;
9261 u32 fib_table;
9262 u8 nh_addr[16];
9263
9264 static int
9265 api_sr_localsid_add_del (vat_main_t * vam)
9266 {
9267   unformat_input_t *i = vam->input;
9268   vl_api_sr_localsid_add_del_t *mp;
9269
9270   u8 is_del;
9271   ip6_address_t localsid;
9272   u8 end_psp = 0;
9273   u8 behavior = ~0;
9274   u32 sw_if_index;
9275   u32 fib_table = ~(u32) 0;
9276   ip6_address_t nh_addr6;
9277   ip4_address_t nh_addr4;
9278   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9279   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9280
9281   bool nexthop_set = 0;
9282
9283   int ret;
9284
9285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9286     {
9287       if (unformat (i, "del"))
9288         is_del = 1;
9289       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9290       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9291         nexthop_set = 1;
9292       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9293         nexthop_set = 1;
9294       else if (unformat (i, "behavior %u", &behavior));
9295       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9296       else if (unformat (i, "fib-table %u", &fib_table));
9297       else if (unformat (i, "end.psp %u", &behavior));
9298       else
9299         break;
9300     }
9301
9302   M (SR_LOCALSID_ADD_DEL, mp);
9303
9304   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9305
9306   if (nexthop_set)
9307     {
9308       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9309       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9310     }
9311   mp->behavior = behavior;
9312   mp->sw_if_index = ntohl (sw_if_index);
9313   mp->fib_table = ntohl (fib_table);
9314   mp->end_psp = end_psp;
9315   mp->is_del = is_del;
9316
9317   S (mp);
9318   W (ret);
9319   return ret;
9320 }
9321
9322 static int
9323 api_ioam_enable (vat_main_t * vam)
9324 {
9325   unformat_input_t *input = vam->input;
9326   vl_api_ioam_enable_t *mp;
9327   u32 id = 0;
9328   int has_trace_option = 0;
9329   int has_pot_option = 0;
9330   int has_seqno_option = 0;
9331   int has_analyse_option = 0;
9332   int ret;
9333
9334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9335     {
9336       if (unformat (input, "trace"))
9337         has_trace_option = 1;
9338       else if (unformat (input, "pot"))
9339         has_pot_option = 1;
9340       else if (unformat (input, "seqno"))
9341         has_seqno_option = 1;
9342       else if (unformat (input, "analyse"))
9343         has_analyse_option = 1;
9344       else
9345         break;
9346     }
9347   M (IOAM_ENABLE, mp);
9348   mp->id = htons (id);
9349   mp->seqno = has_seqno_option;
9350   mp->analyse = has_analyse_option;
9351   mp->pot_enable = has_pot_option;
9352   mp->trace_enable = has_trace_option;
9353
9354   S (mp);
9355   W (ret);
9356   return ret;
9357 }
9358
9359
9360 static int
9361 api_ioam_disable (vat_main_t * vam)
9362 {
9363   vl_api_ioam_disable_t *mp;
9364   int ret;
9365
9366   M (IOAM_DISABLE, mp);
9367   S (mp);
9368   W (ret);
9369   return ret;
9370 }
9371
9372 #define foreach_tcp_proto_field                 \
9373 _(src_port)                                     \
9374 _(dst_port)
9375
9376 #define foreach_udp_proto_field                 \
9377 _(src_port)                                     \
9378 _(dst_port)
9379
9380 #define foreach_ip4_proto_field                 \
9381 _(src_address)                                  \
9382 _(dst_address)                                  \
9383 _(tos)                                          \
9384 _(length)                                       \
9385 _(fragment_id)                                  \
9386 _(ttl)                                          \
9387 _(protocol)                                     \
9388 _(checksum)
9389
9390 typedef struct
9391 {
9392   u16 src_port, dst_port;
9393 } tcpudp_header_t;
9394
9395 #if VPP_API_TEST_BUILTIN == 0
9396 uword
9397 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9398 {
9399   u8 **maskp = va_arg (*args, u8 **);
9400   u8 *mask = 0;
9401   u8 found_something = 0;
9402   tcp_header_t *tcp;
9403
9404 #define _(a) u8 a=0;
9405   foreach_tcp_proto_field;
9406 #undef _
9407
9408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9409     {
9410       if (0);
9411 #define _(a) else if (unformat (input, #a)) a=1;
9412       foreach_tcp_proto_field
9413 #undef _
9414         else
9415         break;
9416     }
9417
9418 #define _(a) found_something += a;
9419   foreach_tcp_proto_field;
9420 #undef _
9421
9422   if (found_something == 0)
9423     return 0;
9424
9425   vec_validate (mask, sizeof (*tcp) - 1);
9426
9427   tcp = (tcp_header_t *) mask;
9428
9429 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9430   foreach_tcp_proto_field;
9431 #undef _
9432
9433   *maskp = mask;
9434   return 1;
9435 }
9436
9437 uword
9438 unformat_udp_mask (unformat_input_t * input, va_list * args)
9439 {
9440   u8 **maskp = va_arg (*args, u8 **);
9441   u8 *mask = 0;
9442   u8 found_something = 0;
9443   udp_header_t *udp;
9444
9445 #define _(a) u8 a=0;
9446   foreach_udp_proto_field;
9447 #undef _
9448
9449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9450     {
9451       if (0);
9452 #define _(a) else if (unformat (input, #a)) a=1;
9453       foreach_udp_proto_field
9454 #undef _
9455         else
9456         break;
9457     }
9458
9459 #define _(a) found_something += a;
9460   foreach_udp_proto_field;
9461 #undef _
9462
9463   if (found_something == 0)
9464     return 0;
9465
9466   vec_validate (mask, sizeof (*udp) - 1);
9467
9468   udp = (udp_header_t *) mask;
9469
9470 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9471   foreach_udp_proto_field;
9472 #undef _
9473
9474   *maskp = mask;
9475   return 1;
9476 }
9477
9478 uword
9479 unformat_l4_mask (unformat_input_t * input, va_list * args)
9480 {
9481   u8 **maskp = va_arg (*args, u8 **);
9482   u16 src_port = 0, dst_port = 0;
9483   tcpudp_header_t *tcpudp;
9484
9485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9486     {
9487       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9488         return 1;
9489       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9490         return 1;
9491       else if (unformat (input, "src_port"))
9492         src_port = 0xFFFF;
9493       else if (unformat (input, "dst_port"))
9494         dst_port = 0xFFFF;
9495       else
9496         return 0;
9497     }
9498
9499   if (!src_port && !dst_port)
9500     return 0;
9501
9502   u8 *mask = 0;
9503   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9504
9505   tcpudp = (tcpudp_header_t *) mask;
9506   tcpudp->src_port = src_port;
9507   tcpudp->dst_port = dst_port;
9508
9509   *maskp = mask;
9510
9511   return 1;
9512 }
9513
9514 uword
9515 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9516 {
9517   u8 **maskp = va_arg (*args, u8 **);
9518   u8 *mask = 0;
9519   u8 found_something = 0;
9520   ip4_header_t *ip;
9521
9522 #define _(a) u8 a=0;
9523   foreach_ip4_proto_field;
9524 #undef _
9525   u8 version = 0;
9526   u8 hdr_length = 0;
9527
9528
9529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9530     {
9531       if (unformat (input, "version"))
9532         version = 1;
9533       else if (unformat (input, "hdr_length"))
9534         hdr_length = 1;
9535       else if (unformat (input, "src"))
9536         src_address = 1;
9537       else if (unformat (input, "dst"))
9538         dst_address = 1;
9539       else if (unformat (input, "proto"))
9540         protocol = 1;
9541
9542 #define _(a) else if (unformat (input, #a)) a=1;
9543       foreach_ip4_proto_field
9544 #undef _
9545         else
9546         break;
9547     }
9548
9549 #define _(a) found_something += a;
9550   foreach_ip4_proto_field;
9551 #undef _
9552
9553   if (found_something == 0)
9554     return 0;
9555
9556   vec_validate (mask, sizeof (*ip) - 1);
9557
9558   ip = (ip4_header_t *) mask;
9559
9560 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9561   foreach_ip4_proto_field;
9562 #undef _
9563
9564   ip->ip_version_and_header_length = 0;
9565
9566   if (version)
9567     ip->ip_version_and_header_length |= 0xF0;
9568
9569   if (hdr_length)
9570     ip->ip_version_and_header_length |= 0x0F;
9571
9572   *maskp = mask;
9573   return 1;
9574 }
9575
9576 #define foreach_ip6_proto_field                 \
9577 _(src_address)                                  \
9578 _(dst_address)                                  \
9579 _(payload_length)                               \
9580 _(hop_limit)                                    \
9581 _(protocol)
9582
9583 uword
9584 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9585 {
9586   u8 **maskp = va_arg (*args, u8 **);
9587   u8 *mask = 0;
9588   u8 found_something = 0;
9589   ip6_header_t *ip;
9590   u32 ip_version_traffic_class_and_flow_label;
9591
9592 #define _(a) u8 a=0;
9593   foreach_ip6_proto_field;
9594 #undef _
9595   u8 version = 0;
9596   u8 traffic_class = 0;
9597   u8 flow_label = 0;
9598
9599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9600     {
9601       if (unformat (input, "version"))
9602         version = 1;
9603       else if (unformat (input, "traffic-class"))
9604         traffic_class = 1;
9605       else if (unformat (input, "flow-label"))
9606         flow_label = 1;
9607       else if (unformat (input, "src"))
9608         src_address = 1;
9609       else if (unformat (input, "dst"))
9610         dst_address = 1;
9611       else if (unformat (input, "proto"))
9612         protocol = 1;
9613
9614 #define _(a) else if (unformat (input, #a)) a=1;
9615       foreach_ip6_proto_field
9616 #undef _
9617         else
9618         break;
9619     }
9620
9621 #define _(a) found_something += a;
9622   foreach_ip6_proto_field;
9623 #undef _
9624
9625   if (found_something == 0)
9626     return 0;
9627
9628   vec_validate (mask, sizeof (*ip) - 1);
9629
9630   ip = (ip6_header_t *) mask;
9631
9632 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9633   foreach_ip6_proto_field;
9634 #undef _
9635
9636   ip_version_traffic_class_and_flow_label = 0;
9637
9638   if (version)
9639     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9640
9641   if (traffic_class)
9642     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9643
9644   if (flow_label)
9645     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9646
9647   ip->ip_version_traffic_class_and_flow_label =
9648     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9649
9650   *maskp = mask;
9651   return 1;
9652 }
9653
9654 uword
9655 unformat_l3_mask (unformat_input_t * input, va_list * args)
9656 {
9657   u8 **maskp = va_arg (*args, u8 **);
9658
9659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9660     {
9661       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9662         return 1;
9663       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9664         return 1;
9665       else
9666         break;
9667     }
9668   return 0;
9669 }
9670
9671 uword
9672 unformat_l2_mask (unformat_input_t * input, va_list * args)
9673 {
9674   u8 **maskp = va_arg (*args, u8 **);
9675   u8 *mask = 0;
9676   u8 src = 0;
9677   u8 dst = 0;
9678   u8 proto = 0;
9679   u8 tag1 = 0;
9680   u8 tag2 = 0;
9681   u8 ignore_tag1 = 0;
9682   u8 ignore_tag2 = 0;
9683   u8 cos1 = 0;
9684   u8 cos2 = 0;
9685   u8 dot1q = 0;
9686   u8 dot1ad = 0;
9687   int len = 14;
9688
9689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9690     {
9691       if (unformat (input, "src"))
9692         src = 1;
9693       else if (unformat (input, "dst"))
9694         dst = 1;
9695       else if (unformat (input, "proto"))
9696         proto = 1;
9697       else if (unformat (input, "tag1"))
9698         tag1 = 1;
9699       else if (unformat (input, "tag2"))
9700         tag2 = 1;
9701       else if (unformat (input, "ignore-tag1"))
9702         ignore_tag1 = 1;
9703       else if (unformat (input, "ignore-tag2"))
9704         ignore_tag2 = 1;
9705       else if (unformat (input, "cos1"))
9706         cos1 = 1;
9707       else if (unformat (input, "cos2"))
9708         cos2 = 1;
9709       else if (unformat (input, "dot1q"))
9710         dot1q = 1;
9711       else if (unformat (input, "dot1ad"))
9712         dot1ad = 1;
9713       else
9714         break;
9715     }
9716   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9717        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9718     return 0;
9719
9720   if (tag1 || ignore_tag1 || cos1 || dot1q)
9721     len = 18;
9722   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9723     len = 22;
9724
9725   vec_validate (mask, len - 1);
9726
9727   if (dst)
9728     clib_memset (mask, 0xff, 6);
9729
9730   if (src)
9731     clib_memset (mask + 6, 0xff, 6);
9732
9733   if (tag2 || dot1ad)
9734     {
9735       /* inner vlan tag */
9736       if (tag2)
9737         {
9738           mask[19] = 0xff;
9739           mask[18] = 0x0f;
9740         }
9741       if (cos2)
9742         mask[18] |= 0xe0;
9743       if (proto)
9744         mask[21] = mask[20] = 0xff;
9745       if (tag1)
9746         {
9747           mask[15] = 0xff;
9748           mask[14] = 0x0f;
9749         }
9750       if (cos1)
9751         mask[14] |= 0xe0;
9752       *maskp = mask;
9753       return 1;
9754     }
9755   if (tag1 | dot1q)
9756     {
9757       if (tag1)
9758         {
9759           mask[15] = 0xff;
9760           mask[14] = 0x0f;
9761         }
9762       if (cos1)
9763         mask[14] |= 0xe0;
9764       if (proto)
9765         mask[16] = mask[17] = 0xff;
9766
9767       *maskp = mask;
9768       return 1;
9769     }
9770   if (cos2)
9771     mask[18] |= 0xe0;
9772   if (cos1)
9773     mask[14] |= 0xe0;
9774   if (proto)
9775     mask[12] = mask[13] = 0xff;
9776
9777   *maskp = mask;
9778   return 1;
9779 }
9780
9781 uword
9782 unformat_classify_mask (unformat_input_t * input, va_list * args)
9783 {
9784   u8 **maskp = va_arg (*args, u8 **);
9785   u32 *skipp = va_arg (*args, u32 *);
9786   u32 *matchp = va_arg (*args, u32 *);
9787   u32 match;
9788   u8 *mask = 0;
9789   u8 *l2 = 0;
9790   u8 *l3 = 0;
9791   u8 *l4 = 0;
9792   int i;
9793
9794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9795     {
9796       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9797         ;
9798       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9799         ;
9800       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9801         ;
9802       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9803         ;
9804       else
9805         break;
9806     }
9807
9808   if (l4 && !l3)
9809     {
9810       vec_free (mask);
9811       vec_free (l2);
9812       vec_free (l4);
9813       return 0;
9814     }
9815
9816   if (mask || l2 || l3 || l4)
9817     {
9818       if (l2 || l3 || l4)
9819         {
9820           /* "With a free Ethernet header in every package" */
9821           if (l2 == 0)
9822             vec_validate (l2, 13);
9823           mask = l2;
9824           if (vec_len (l3))
9825             {
9826               vec_append (mask, l3);
9827               vec_free (l3);
9828             }
9829           if (vec_len (l4))
9830             {
9831               vec_append (mask, l4);
9832               vec_free (l4);
9833             }
9834         }
9835
9836       /* Scan forward looking for the first significant mask octet */
9837       for (i = 0; i < vec_len (mask); i++)
9838         if (mask[i])
9839           break;
9840
9841       /* compute (skip, match) params */
9842       *skipp = i / sizeof (u32x4);
9843       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9844
9845       /* Pad mask to an even multiple of the vector size */
9846       while (vec_len (mask) % sizeof (u32x4))
9847         vec_add1 (mask, 0);
9848
9849       match = vec_len (mask) / sizeof (u32x4);
9850
9851       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9852         {
9853           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9854           if (*tmp || *(tmp + 1))
9855             break;
9856           match--;
9857         }
9858       if (match == 0)
9859         clib_warning ("BUG: match 0");
9860
9861       _vec_len (mask) = match * sizeof (u32x4);
9862
9863       *matchp = match;
9864       *maskp = mask;
9865
9866       return 1;
9867     }
9868
9869   return 0;
9870 }
9871 #endif /* VPP_API_TEST_BUILTIN */
9872
9873 #define foreach_l2_next                         \
9874 _(drop, DROP)                                   \
9875 _(ethernet, ETHERNET_INPUT)                     \
9876 _(ip4, IP4_INPUT)                               \
9877 _(ip6, IP6_INPUT)
9878
9879 uword
9880 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9881 {
9882   u32 *miss_next_indexp = va_arg (*args, u32 *);
9883   u32 next_index = 0;
9884   u32 tmp;
9885
9886 #define _(n,N) \
9887   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9888   foreach_l2_next;
9889 #undef _
9890
9891   if (unformat (input, "%d", &tmp))
9892     {
9893       next_index = tmp;
9894       goto out;
9895     }
9896
9897   return 0;
9898
9899 out:
9900   *miss_next_indexp = next_index;
9901   return 1;
9902 }
9903
9904 #define foreach_ip_next                         \
9905 _(drop, DROP)                                   \
9906 _(local, LOCAL)                                 \
9907 _(rewrite, REWRITE)
9908
9909 uword
9910 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9911 {
9912   u32 *miss_next_indexp = va_arg (*args, u32 *);
9913   u32 next_index = 0;
9914   u32 tmp;
9915
9916 #define _(n,N) \
9917   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9918   foreach_ip_next;
9919 #undef _
9920
9921   if (unformat (input, "%d", &tmp))
9922     {
9923       next_index = tmp;
9924       goto out;
9925     }
9926
9927   return 0;
9928
9929 out:
9930   *miss_next_indexp = next_index;
9931   return 1;
9932 }
9933
9934 #define foreach_acl_next                        \
9935 _(deny, DENY)
9936
9937 uword
9938 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9939 {
9940   u32 *miss_next_indexp = va_arg (*args, u32 *);
9941   u32 next_index = 0;
9942   u32 tmp;
9943
9944 #define _(n,N) \
9945   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9946   foreach_acl_next;
9947 #undef _
9948
9949   if (unformat (input, "permit"))
9950     {
9951       next_index = ~0;
9952       goto out;
9953     }
9954   else if (unformat (input, "%d", &tmp))
9955     {
9956       next_index = tmp;
9957       goto out;
9958     }
9959
9960   return 0;
9961
9962 out:
9963   *miss_next_indexp = next_index;
9964   return 1;
9965 }
9966
9967 uword
9968 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9969 {
9970   u32 *r = va_arg (*args, u32 *);
9971
9972   if (unformat (input, "conform-color"))
9973     *r = POLICE_CONFORM;
9974   else if (unformat (input, "exceed-color"))
9975     *r = POLICE_EXCEED;
9976   else
9977     return 0;
9978
9979   return 1;
9980 }
9981
9982 static int
9983 api_classify_add_del_table (vat_main_t * vam)
9984 {
9985   unformat_input_t *i = vam->input;
9986   vl_api_classify_add_del_table_t *mp;
9987
9988   u32 nbuckets = 2;
9989   u32 skip = ~0;
9990   u32 match = ~0;
9991   int is_add = 1;
9992   int del_chain = 0;
9993   u32 table_index = ~0;
9994   u32 next_table_index = ~0;
9995   u32 miss_next_index = ~0;
9996   u32 memory_size = 32 << 20;
9997   u8 *mask = 0;
9998   u32 current_data_flag = 0;
9999   int current_data_offset = 0;
10000   int ret;
10001
10002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10003     {
10004       if (unformat (i, "del"))
10005         is_add = 0;
10006       else if (unformat (i, "del-chain"))
10007         {
10008           is_add = 0;
10009           del_chain = 1;
10010         }
10011       else if (unformat (i, "buckets %d", &nbuckets))
10012         ;
10013       else if (unformat (i, "memory_size %d", &memory_size))
10014         ;
10015       else if (unformat (i, "skip %d", &skip))
10016         ;
10017       else if (unformat (i, "match %d", &match))
10018         ;
10019       else if (unformat (i, "table %d", &table_index))
10020         ;
10021       else if (unformat (i, "mask %U", unformat_classify_mask,
10022                          &mask, &skip, &match))
10023         ;
10024       else if (unformat (i, "next-table %d", &next_table_index))
10025         ;
10026       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10027                          &miss_next_index))
10028         ;
10029       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10030                          &miss_next_index))
10031         ;
10032       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10033                          &miss_next_index))
10034         ;
10035       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10036         ;
10037       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10038         ;
10039       else
10040         break;
10041     }
10042
10043   if (is_add && mask == 0)
10044     {
10045       errmsg ("Mask required");
10046       return -99;
10047     }
10048
10049   if (is_add && skip == ~0)
10050     {
10051       errmsg ("skip count required");
10052       return -99;
10053     }
10054
10055   if (is_add && match == ~0)
10056     {
10057       errmsg ("match count required");
10058       return -99;
10059     }
10060
10061   if (!is_add && table_index == ~0)
10062     {
10063       errmsg ("table index required for delete");
10064       return -99;
10065     }
10066
10067   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10068
10069   mp->is_add = is_add;
10070   mp->del_chain = del_chain;
10071   mp->table_index = ntohl (table_index);
10072   mp->nbuckets = ntohl (nbuckets);
10073   mp->memory_size = ntohl (memory_size);
10074   mp->skip_n_vectors = ntohl (skip);
10075   mp->match_n_vectors = ntohl (match);
10076   mp->next_table_index = ntohl (next_table_index);
10077   mp->miss_next_index = ntohl (miss_next_index);
10078   mp->current_data_flag = ntohl (current_data_flag);
10079   mp->current_data_offset = ntohl (current_data_offset);
10080   mp->mask_len = ntohl (vec_len (mask));
10081   clib_memcpy (mp->mask, mask, vec_len (mask));
10082
10083   vec_free (mask);
10084
10085   S (mp);
10086   W (ret);
10087   return ret;
10088 }
10089
10090 #if VPP_API_TEST_BUILTIN == 0
10091 uword
10092 unformat_l4_match (unformat_input_t * input, va_list * args)
10093 {
10094   u8 **matchp = va_arg (*args, u8 **);
10095
10096   u8 *proto_header = 0;
10097   int src_port = 0;
10098   int dst_port = 0;
10099
10100   tcpudp_header_t h;
10101
10102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10103     {
10104       if (unformat (input, "src_port %d", &src_port))
10105         ;
10106       else if (unformat (input, "dst_port %d", &dst_port))
10107         ;
10108       else
10109         return 0;
10110     }
10111
10112   h.src_port = clib_host_to_net_u16 (src_port);
10113   h.dst_port = clib_host_to_net_u16 (dst_port);
10114   vec_validate (proto_header, sizeof (h) - 1);
10115   memcpy (proto_header, &h, sizeof (h));
10116
10117   *matchp = proto_header;
10118
10119   return 1;
10120 }
10121
10122 uword
10123 unformat_ip4_match (unformat_input_t * input, va_list * args)
10124 {
10125   u8 **matchp = va_arg (*args, u8 **);
10126   u8 *match = 0;
10127   ip4_header_t *ip;
10128   int version = 0;
10129   u32 version_val;
10130   int hdr_length = 0;
10131   u32 hdr_length_val;
10132   int src = 0, dst = 0;
10133   ip4_address_t src_val, dst_val;
10134   int proto = 0;
10135   u32 proto_val;
10136   int tos = 0;
10137   u32 tos_val;
10138   int length = 0;
10139   u32 length_val;
10140   int fragment_id = 0;
10141   u32 fragment_id_val;
10142   int ttl = 0;
10143   int ttl_val;
10144   int checksum = 0;
10145   u32 checksum_val;
10146
10147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (input, "version %d", &version_val))
10150         version = 1;
10151       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10152         hdr_length = 1;
10153       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10154         src = 1;
10155       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10156         dst = 1;
10157       else if (unformat (input, "proto %d", &proto_val))
10158         proto = 1;
10159       else if (unformat (input, "tos %d", &tos_val))
10160         tos = 1;
10161       else if (unformat (input, "length %d", &length_val))
10162         length = 1;
10163       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10164         fragment_id = 1;
10165       else if (unformat (input, "ttl %d", &ttl_val))
10166         ttl = 1;
10167       else if (unformat (input, "checksum %d", &checksum_val))
10168         checksum = 1;
10169       else
10170         break;
10171     }
10172
10173   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10174       + ttl + checksum == 0)
10175     return 0;
10176
10177   /*
10178    * Aligned because we use the real comparison functions
10179    */
10180   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10181
10182   ip = (ip4_header_t *) match;
10183
10184   /* These are realistically matched in practice */
10185   if (src)
10186     ip->src_address.as_u32 = src_val.as_u32;
10187
10188   if (dst)
10189     ip->dst_address.as_u32 = dst_val.as_u32;
10190
10191   if (proto)
10192     ip->protocol = proto_val;
10193
10194
10195   /* These are not, but they're included for completeness */
10196   if (version)
10197     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10198
10199   if (hdr_length)
10200     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10201
10202   if (tos)
10203     ip->tos = tos_val;
10204
10205   if (length)
10206     ip->length = clib_host_to_net_u16 (length_val);
10207
10208   if (ttl)
10209     ip->ttl = ttl_val;
10210
10211   if (checksum)
10212     ip->checksum = clib_host_to_net_u16 (checksum_val);
10213
10214   *matchp = match;
10215   return 1;
10216 }
10217
10218 uword
10219 unformat_ip6_match (unformat_input_t * input, va_list * args)
10220 {
10221   u8 **matchp = va_arg (*args, u8 **);
10222   u8 *match = 0;
10223   ip6_header_t *ip;
10224   int version = 0;
10225   u32 version_val;
10226   u8 traffic_class = 0;
10227   u32 traffic_class_val = 0;
10228   u8 flow_label = 0;
10229   u8 flow_label_val;
10230   int src = 0, dst = 0;
10231   ip6_address_t src_val, dst_val;
10232   int proto = 0;
10233   u32 proto_val;
10234   int payload_length = 0;
10235   u32 payload_length_val;
10236   int hop_limit = 0;
10237   int hop_limit_val;
10238   u32 ip_version_traffic_class_and_flow_label;
10239
10240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10241     {
10242       if (unformat (input, "version %d", &version_val))
10243         version = 1;
10244       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10245         traffic_class = 1;
10246       else if (unformat (input, "flow_label %d", &flow_label_val))
10247         flow_label = 1;
10248       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10249         src = 1;
10250       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10251         dst = 1;
10252       else if (unformat (input, "proto %d", &proto_val))
10253         proto = 1;
10254       else if (unformat (input, "payload_length %d", &payload_length_val))
10255         payload_length = 1;
10256       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10257         hop_limit = 1;
10258       else
10259         break;
10260     }
10261
10262   if (version + traffic_class + flow_label + src + dst + proto +
10263       payload_length + hop_limit == 0)
10264     return 0;
10265
10266   /*
10267    * Aligned because we use the real comparison functions
10268    */
10269   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10270
10271   ip = (ip6_header_t *) match;
10272
10273   if (src)
10274     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10275
10276   if (dst)
10277     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10278
10279   if (proto)
10280     ip->protocol = proto_val;
10281
10282   ip_version_traffic_class_and_flow_label = 0;
10283
10284   if (version)
10285     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10286
10287   if (traffic_class)
10288     ip_version_traffic_class_and_flow_label |=
10289       (traffic_class_val & 0xFF) << 20;
10290
10291   if (flow_label)
10292     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10293
10294   ip->ip_version_traffic_class_and_flow_label =
10295     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10296
10297   if (payload_length)
10298     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10299
10300   if (hop_limit)
10301     ip->hop_limit = hop_limit_val;
10302
10303   *matchp = match;
10304   return 1;
10305 }
10306
10307 uword
10308 unformat_l3_match (unformat_input_t * input, va_list * args)
10309 {
10310   u8 **matchp = va_arg (*args, u8 **);
10311
10312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10313     {
10314       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10315         return 1;
10316       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10317         return 1;
10318       else
10319         break;
10320     }
10321   return 0;
10322 }
10323
10324 uword
10325 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10326 {
10327   u8 *tagp = va_arg (*args, u8 *);
10328   u32 tag;
10329
10330   if (unformat (input, "%d", &tag))
10331     {
10332       tagp[0] = (tag >> 8) & 0x0F;
10333       tagp[1] = tag & 0xFF;
10334       return 1;
10335     }
10336
10337   return 0;
10338 }
10339
10340 uword
10341 unformat_l2_match (unformat_input_t * input, va_list * args)
10342 {
10343   u8 **matchp = va_arg (*args, u8 **);
10344   u8 *match = 0;
10345   u8 src = 0;
10346   u8 src_val[6];
10347   u8 dst = 0;
10348   u8 dst_val[6];
10349   u8 proto = 0;
10350   u16 proto_val;
10351   u8 tag1 = 0;
10352   u8 tag1_val[2];
10353   u8 tag2 = 0;
10354   u8 tag2_val[2];
10355   int len = 14;
10356   u8 ignore_tag1 = 0;
10357   u8 ignore_tag2 = 0;
10358   u8 cos1 = 0;
10359   u8 cos2 = 0;
10360   u32 cos1_val = 0;
10361   u32 cos2_val = 0;
10362
10363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10364     {
10365       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10366         src = 1;
10367       else
10368         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10369         dst = 1;
10370       else if (unformat (input, "proto %U",
10371                          unformat_ethernet_type_host_byte_order, &proto_val))
10372         proto = 1;
10373       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10374         tag1 = 1;
10375       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10376         tag2 = 1;
10377       else if (unformat (input, "ignore-tag1"))
10378         ignore_tag1 = 1;
10379       else if (unformat (input, "ignore-tag2"))
10380         ignore_tag2 = 1;
10381       else if (unformat (input, "cos1 %d", &cos1_val))
10382         cos1 = 1;
10383       else if (unformat (input, "cos2 %d", &cos2_val))
10384         cos2 = 1;
10385       else
10386         break;
10387     }
10388   if ((src + dst + proto + tag1 + tag2 +
10389        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10390     return 0;
10391
10392   if (tag1 || ignore_tag1 || cos1)
10393     len = 18;
10394   if (tag2 || ignore_tag2 || cos2)
10395     len = 22;
10396
10397   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10398
10399   if (dst)
10400     clib_memcpy (match, dst_val, 6);
10401
10402   if (src)
10403     clib_memcpy (match + 6, src_val, 6);
10404
10405   if (tag2)
10406     {
10407       /* inner vlan tag */
10408       match[19] = tag2_val[1];
10409       match[18] = tag2_val[0];
10410       if (cos2)
10411         match[18] |= (cos2_val & 0x7) << 5;
10412       if (proto)
10413         {
10414           match[21] = proto_val & 0xff;
10415           match[20] = proto_val >> 8;
10416         }
10417       if (tag1)
10418         {
10419           match[15] = tag1_val[1];
10420           match[14] = tag1_val[0];
10421         }
10422       if (cos1)
10423         match[14] |= (cos1_val & 0x7) << 5;
10424       *matchp = match;
10425       return 1;
10426     }
10427   if (tag1)
10428     {
10429       match[15] = tag1_val[1];
10430       match[14] = tag1_val[0];
10431       if (proto)
10432         {
10433           match[17] = proto_val & 0xff;
10434           match[16] = proto_val >> 8;
10435         }
10436       if (cos1)
10437         match[14] |= (cos1_val & 0x7) << 5;
10438
10439       *matchp = match;
10440       return 1;
10441     }
10442   if (cos2)
10443     match[18] |= (cos2_val & 0x7) << 5;
10444   if (cos1)
10445     match[14] |= (cos1_val & 0x7) << 5;
10446   if (proto)
10447     {
10448       match[13] = proto_val & 0xff;
10449       match[12] = proto_val >> 8;
10450     }
10451
10452   *matchp = match;
10453   return 1;
10454 }
10455
10456 uword
10457 unformat_qos_source (unformat_input_t * input, va_list * args)
10458 {
10459   int *qs = va_arg (*args, int *);
10460
10461   if (unformat (input, "ip"))
10462     *qs = QOS_SOURCE_IP;
10463   else if (unformat (input, "mpls"))
10464     *qs = QOS_SOURCE_MPLS;
10465   else if (unformat (input, "ext"))
10466     *qs = QOS_SOURCE_EXT;
10467   else if (unformat (input, "vlan"))
10468     *qs = QOS_SOURCE_VLAN;
10469   else
10470     return 0;
10471
10472   return 1;
10473 }
10474 #endif
10475
10476 uword
10477 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10478 {
10479   u8 **matchp = va_arg (*args, u8 **);
10480   u32 skip_n_vectors = va_arg (*args, u32);
10481   u32 match_n_vectors = va_arg (*args, u32);
10482
10483   u8 *match = 0;
10484   u8 *l2 = 0;
10485   u8 *l3 = 0;
10486   u8 *l4 = 0;
10487
10488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10489     {
10490       if (unformat (input, "hex %U", unformat_hex_string, &match))
10491         ;
10492       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10493         ;
10494       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10495         ;
10496       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10497         ;
10498       else
10499         break;
10500     }
10501
10502   if (l4 && !l3)
10503     {
10504       vec_free (match);
10505       vec_free (l2);
10506       vec_free (l4);
10507       return 0;
10508     }
10509
10510   if (match || l2 || l3 || l4)
10511     {
10512       if (l2 || l3 || l4)
10513         {
10514           /* "Win a free Ethernet header in every packet" */
10515           if (l2 == 0)
10516             vec_validate_aligned (l2, 13, sizeof (u32x4));
10517           match = l2;
10518           if (vec_len (l3))
10519             {
10520               vec_append_aligned (match, l3, sizeof (u32x4));
10521               vec_free (l3);
10522             }
10523           if (vec_len (l4))
10524             {
10525               vec_append_aligned (match, l4, sizeof (u32x4));
10526               vec_free (l4);
10527             }
10528         }
10529
10530       /* Make sure the vector is big enough even if key is all 0's */
10531       vec_validate_aligned
10532         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10533          sizeof (u32x4));
10534
10535       /* Set size, include skipped vectors */
10536       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10537
10538       *matchp = match;
10539
10540       return 1;
10541     }
10542
10543   return 0;
10544 }
10545
10546 static int
10547 api_classify_add_del_session (vat_main_t * vam)
10548 {
10549   unformat_input_t *i = vam->input;
10550   vl_api_classify_add_del_session_t *mp;
10551   int is_add = 1;
10552   u32 table_index = ~0;
10553   u32 hit_next_index = ~0;
10554   u32 opaque_index = ~0;
10555   u8 *match = 0;
10556   i32 advance = 0;
10557   u32 skip_n_vectors = 0;
10558   u32 match_n_vectors = 0;
10559   u32 action = 0;
10560   u32 metadata = 0;
10561   int ret;
10562
10563   /*
10564    * Warning: you have to supply skip_n and match_n
10565    * because the API client cant simply look at the classify
10566    * table object.
10567    */
10568
10569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10570     {
10571       if (unformat (i, "del"))
10572         is_add = 0;
10573       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10574                          &hit_next_index))
10575         ;
10576       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10577                          &hit_next_index))
10578         ;
10579       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10580                          &hit_next_index))
10581         ;
10582       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10583         ;
10584       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10585         ;
10586       else if (unformat (i, "opaque-index %d", &opaque_index))
10587         ;
10588       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10589         ;
10590       else if (unformat (i, "match_n %d", &match_n_vectors))
10591         ;
10592       else if (unformat (i, "match %U", api_unformat_classify_match,
10593                          &match, skip_n_vectors, match_n_vectors))
10594         ;
10595       else if (unformat (i, "advance %d", &advance))
10596         ;
10597       else if (unformat (i, "table-index %d", &table_index))
10598         ;
10599       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10600         action = 1;
10601       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10602         action = 2;
10603       else if (unformat (i, "action %d", &action))
10604         ;
10605       else if (unformat (i, "metadata %d", &metadata))
10606         ;
10607       else
10608         break;
10609     }
10610
10611   if (table_index == ~0)
10612     {
10613       errmsg ("Table index required");
10614       return -99;
10615     }
10616
10617   if (is_add && match == 0)
10618     {
10619       errmsg ("Match value required");
10620       return -99;
10621     }
10622
10623   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10624
10625   mp->is_add = is_add;
10626   mp->table_index = ntohl (table_index);
10627   mp->hit_next_index = ntohl (hit_next_index);
10628   mp->opaque_index = ntohl (opaque_index);
10629   mp->advance = ntohl (advance);
10630   mp->action = action;
10631   mp->metadata = ntohl (metadata);
10632   mp->match_len = ntohl (vec_len (match));
10633   clib_memcpy (mp->match, match, vec_len (match));
10634   vec_free (match);
10635
10636   S (mp);
10637   W (ret);
10638   return ret;
10639 }
10640
10641 static int
10642 api_classify_set_interface_ip_table (vat_main_t * vam)
10643 {
10644   unformat_input_t *i = vam->input;
10645   vl_api_classify_set_interface_ip_table_t *mp;
10646   u32 sw_if_index;
10647   int sw_if_index_set;
10648   u32 table_index = ~0;
10649   u8 is_ipv6 = 0;
10650   int ret;
10651
10652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10653     {
10654       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10655         sw_if_index_set = 1;
10656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10657         sw_if_index_set = 1;
10658       else if (unformat (i, "table %d", &table_index))
10659         ;
10660       else
10661         {
10662           clib_warning ("parse error '%U'", format_unformat_error, i);
10663           return -99;
10664         }
10665     }
10666
10667   if (sw_if_index_set == 0)
10668     {
10669       errmsg ("missing interface name or sw_if_index");
10670       return -99;
10671     }
10672
10673
10674   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10675
10676   mp->sw_if_index = ntohl (sw_if_index);
10677   mp->table_index = ntohl (table_index);
10678   mp->is_ipv6 = is_ipv6;
10679
10680   S (mp);
10681   W (ret);
10682   return ret;
10683 }
10684
10685 static int
10686 api_classify_set_interface_l2_tables (vat_main_t * vam)
10687 {
10688   unformat_input_t *i = vam->input;
10689   vl_api_classify_set_interface_l2_tables_t *mp;
10690   u32 sw_if_index;
10691   int sw_if_index_set;
10692   u32 ip4_table_index = ~0;
10693   u32 ip6_table_index = ~0;
10694   u32 other_table_index = ~0;
10695   u32 is_input = 1;
10696   int ret;
10697
10698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10699     {
10700       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10701         sw_if_index_set = 1;
10702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10703         sw_if_index_set = 1;
10704       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10705         ;
10706       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10707         ;
10708       else if (unformat (i, "other-table %d", &other_table_index))
10709         ;
10710       else if (unformat (i, "is-input %d", &is_input))
10711         ;
10712       else
10713         {
10714           clib_warning ("parse error '%U'", format_unformat_error, i);
10715           return -99;
10716         }
10717     }
10718
10719   if (sw_if_index_set == 0)
10720     {
10721       errmsg ("missing interface name or sw_if_index");
10722       return -99;
10723     }
10724
10725
10726   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10727
10728   mp->sw_if_index = ntohl (sw_if_index);
10729   mp->ip4_table_index = ntohl (ip4_table_index);
10730   mp->ip6_table_index = ntohl (ip6_table_index);
10731   mp->other_table_index = ntohl (other_table_index);
10732   mp->is_input = (u8) is_input;
10733
10734   S (mp);
10735   W (ret);
10736   return ret;
10737 }
10738
10739 static int
10740 api_set_ipfix_exporter (vat_main_t * vam)
10741 {
10742   unformat_input_t *i = vam->input;
10743   vl_api_set_ipfix_exporter_t *mp;
10744   ip4_address_t collector_address;
10745   u8 collector_address_set = 0;
10746   u32 collector_port = ~0;
10747   ip4_address_t src_address;
10748   u8 src_address_set = 0;
10749   u32 vrf_id = ~0;
10750   u32 path_mtu = ~0;
10751   u32 template_interval = ~0;
10752   u8 udp_checksum = 0;
10753   int ret;
10754
10755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (i, "collector_address %U", unformat_ip4_address,
10758                     &collector_address))
10759         collector_address_set = 1;
10760       else if (unformat (i, "collector_port %d", &collector_port))
10761         ;
10762       else if (unformat (i, "src_address %U", unformat_ip4_address,
10763                          &src_address))
10764         src_address_set = 1;
10765       else if (unformat (i, "vrf_id %d", &vrf_id))
10766         ;
10767       else if (unformat (i, "path_mtu %d", &path_mtu))
10768         ;
10769       else if (unformat (i, "template_interval %d", &template_interval))
10770         ;
10771       else if (unformat (i, "udp_checksum"))
10772         udp_checksum = 1;
10773       else
10774         break;
10775     }
10776
10777   if (collector_address_set == 0)
10778     {
10779       errmsg ("collector_address required");
10780       return -99;
10781     }
10782
10783   if (src_address_set == 0)
10784     {
10785       errmsg ("src_address required");
10786       return -99;
10787     }
10788
10789   M (SET_IPFIX_EXPORTER, mp);
10790
10791   memcpy (mp->collector_address.un.ip4, collector_address.data,
10792           sizeof (collector_address.data));
10793   mp->collector_port = htons ((u16) collector_port);
10794   memcpy (mp->src_address.un.ip4, src_address.data,
10795           sizeof (src_address.data));
10796   mp->vrf_id = htonl (vrf_id);
10797   mp->path_mtu = htonl (path_mtu);
10798   mp->template_interval = htonl (template_interval);
10799   mp->udp_checksum = udp_checksum;
10800
10801   S (mp);
10802   W (ret);
10803   return ret;
10804 }
10805
10806 static int
10807 api_set_ipfix_classify_stream (vat_main_t * vam)
10808 {
10809   unformat_input_t *i = vam->input;
10810   vl_api_set_ipfix_classify_stream_t *mp;
10811   u32 domain_id = 0;
10812   u32 src_port = UDP_DST_PORT_ipfix;
10813   int ret;
10814
10815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10816     {
10817       if (unformat (i, "domain %d", &domain_id))
10818         ;
10819       else if (unformat (i, "src_port %d", &src_port))
10820         ;
10821       else
10822         {
10823           errmsg ("unknown input `%U'", format_unformat_error, i);
10824           return -99;
10825         }
10826     }
10827
10828   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10829
10830   mp->domain_id = htonl (domain_id);
10831   mp->src_port = htons ((u16) src_port);
10832
10833   S (mp);
10834   W (ret);
10835   return ret;
10836 }
10837
10838 static int
10839 api_ipfix_classify_table_add_del (vat_main_t * vam)
10840 {
10841   unformat_input_t *i = vam->input;
10842   vl_api_ipfix_classify_table_add_del_t *mp;
10843   int is_add = -1;
10844   u32 classify_table_index = ~0;
10845   u8 ip_version = 0;
10846   u8 transport_protocol = 255;
10847   int ret;
10848
10849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10850     {
10851       if (unformat (i, "add"))
10852         is_add = 1;
10853       else if (unformat (i, "del"))
10854         is_add = 0;
10855       else if (unformat (i, "table %d", &classify_table_index))
10856         ;
10857       else if (unformat (i, "ip4"))
10858         ip_version = 4;
10859       else if (unformat (i, "ip6"))
10860         ip_version = 6;
10861       else if (unformat (i, "tcp"))
10862         transport_protocol = 6;
10863       else if (unformat (i, "udp"))
10864         transport_protocol = 17;
10865       else
10866         {
10867           errmsg ("unknown input `%U'", format_unformat_error, i);
10868           return -99;
10869         }
10870     }
10871
10872   if (is_add == -1)
10873     {
10874       errmsg ("expecting: add|del");
10875       return -99;
10876     }
10877   if (classify_table_index == ~0)
10878     {
10879       errmsg ("classifier table not specified");
10880       return -99;
10881     }
10882   if (ip_version == 0)
10883     {
10884       errmsg ("IP version not specified");
10885       return -99;
10886     }
10887
10888   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10889
10890   mp->is_add = is_add;
10891   mp->table_id = htonl (classify_table_index);
10892   mp->ip_version = ip_version;
10893   mp->transport_protocol = transport_protocol;
10894
10895   S (mp);
10896   W (ret);
10897   return ret;
10898 }
10899
10900 static int
10901 api_get_node_index (vat_main_t * vam)
10902 {
10903   unformat_input_t *i = vam->input;
10904   vl_api_get_node_index_t *mp;
10905   u8 *name = 0;
10906   int ret;
10907
10908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10909     {
10910       if (unformat (i, "node %s", &name))
10911         ;
10912       else
10913         break;
10914     }
10915   if (name == 0)
10916     {
10917       errmsg ("node name required");
10918       return -99;
10919     }
10920   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10921     {
10922       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10923       return -99;
10924     }
10925
10926   M (GET_NODE_INDEX, mp);
10927   clib_memcpy (mp->node_name, name, vec_len (name));
10928   vec_free (name);
10929
10930   S (mp);
10931   W (ret);
10932   return ret;
10933 }
10934
10935 static int
10936 api_get_next_index (vat_main_t * vam)
10937 {
10938   unformat_input_t *i = vam->input;
10939   vl_api_get_next_index_t *mp;
10940   u8 *node_name = 0, *next_node_name = 0;
10941   int ret;
10942
10943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10944     {
10945       if (unformat (i, "node-name %s", &node_name))
10946         ;
10947       else if (unformat (i, "next-node-name %s", &next_node_name))
10948         break;
10949     }
10950
10951   if (node_name == 0)
10952     {
10953       errmsg ("node name required");
10954       return -99;
10955     }
10956   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10957     {
10958       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10959       return -99;
10960     }
10961
10962   if (next_node_name == 0)
10963     {
10964       errmsg ("next node name required");
10965       return -99;
10966     }
10967   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10968     {
10969       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10970       return -99;
10971     }
10972
10973   M (GET_NEXT_INDEX, mp);
10974   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10975   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10976   vec_free (node_name);
10977   vec_free (next_node_name);
10978
10979   S (mp);
10980   W (ret);
10981   return ret;
10982 }
10983
10984 static int
10985 api_add_node_next (vat_main_t * vam)
10986 {
10987   unformat_input_t *i = vam->input;
10988   vl_api_add_node_next_t *mp;
10989   u8 *name = 0;
10990   u8 *next = 0;
10991   int ret;
10992
10993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10994     {
10995       if (unformat (i, "node %s", &name))
10996         ;
10997       else if (unformat (i, "next %s", &next))
10998         ;
10999       else
11000         break;
11001     }
11002   if (name == 0)
11003     {
11004       errmsg ("node name required");
11005       return -99;
11006     }
11007   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11008     {
11009       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11010       return -99;
11011     }
11012   if (next == 0)
11013     {
11014       errmsg ("next node required");
11015       return -99;
11016     }
11017   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11018     {
11019       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11020       return -99;
11021     }
11022
11023   M (ADD_NODE_NEXT, mp);
11024   clib_memcpy (mp->node_name, name, vec_len (name));
11025   clib_memcpy (mp->next_name, next, vec_len (next));
11026   vec_free (name);
11027   vec_free (next);
11028
11029   S (mp);
11030   W (ret);
11031   return ret;
11032 }
11033
11034 static int
11035 api_l2tpv3_create_tunnel (vat_main_t * vam)
11036 {
11037   unformat_input_t *i = vam->input;
11038   ip6_address_t client_address, our_address;
11039   int client_address_set = 0;
11040   int our_address_set = 0;
11041   u32 local_session_id = 0;
11042   u32 remote_session_id = 0;
11043   u64 local_cookie = 0;
11044   u64 remote_cookie = 0;
11045   u8 l2_sublayer_present = 0;
11046   vl_api_l2tpv3_create_tunnel_t *mp;
11047   int ret;
11048
11049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11050     {
11051       if (unformat (i, "client_address %U", unformat_ip6_address,
11052                     &client_address))
11053         client_address_set = 1;
11054       else if (unformat (i, "our_address %U", unformat_ip6_address,
11055                          &our_address))
11056         our_address_set = 1;
11057       else if (unformat (i, "local_session_id %d", &local_session_id))
11058         ;
11059       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11060         ;
11061       else if (unformat (i, "local_cookie %lld", &local_cookie))
11062         ;
11063       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11064         ;
11065       else if (unformat (i, "l2-sublayer-present"))
11066         l2_sublayer_present = 1;
11067       else
11068         break;
11069     }
11070
11071   if (client_address_set == 0)
11072     {
11073       errmsg ("client_address required");
11074       return -99;
11075     }
11076
11077   if (our_address_set == 0)
11078     {
11079       errmsg ("our_address required");
11080       return -99;
11081     }
11082
11083   M (L2TPV3_CREATE_TUNNEL, mp);
11084
11085   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11086                sizeof (ip6_address_t));
11087
11088   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11089                sizeof (ip6_address_t));
11090
11091   mp->local_session_id = ntohl (local_session_id);
11092   mp->remote_session_id = ntohl (remote_session_id);
11093   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11094   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11095   mp->l2_sublayer_present = l2_sublayer_present;
11096
11097   S (mp);
11098   W (ret);
11099   return ret;
11100 }
11101
11102 static int
11103 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11104 {
11105   unformat_input_t *i = vam->input;
11106   u32 sw_if_index;
11107   u8 sw_if_index_set = 0;
11108   u64 new_local_cookie = 0;
11109   u64 new_remote_cookie = 0;
11110   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11111   int ret;
11112
11113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11114     {
11115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11116         sw_if_index_set = 1;
11117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11118         sw_if_index_set = 1;
11119       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11120         ;
11121       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11122         ;
11123       else
11124         break;
11125     }
11126
11127   if (sw_if_index_set == 0)
11128     {
11129       errmsg ("missing interface name or sw_if_index");
11130       return -99;
11131     }
11132
11133   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11134
11135   mp->sw_if_index = ntohl (sw_if_index);
11136   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11137   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11138
11139   S (mp);
11140   W (ret);
11141   return ret;
11142 }
11143
11144 static int
11145 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11146 {
11147   unformat_input_t *i = vam->input;
11148   vl_api_l2tpv3_interface_enable_disable_t *mp;
11149   u32 sw_if_index;
11150   u8 sw_if_index_set = 0;
11151   u8 enable_disable = 1;
11152   int ret;
11153
11154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11155     {
11156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11157         sw_if_index_set = 1;
11158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11159         sw_if_index_set = 1;
11160       else if (unformat (i, "enable"))
11161         enable_disable = 1;
11162       else if (unformat (i, "disable"))
11163         enable_disable = 0;
11164       else
11165         break;
11166     }
11167
11168   if (sw_if_index_set == 0)
11169     {
11170       errmsg ("missing interface name or sw_if_index");
11171       return -99;
11172     }
11173
11174   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11175
11176   mp->sw_if_index = ntohl (sw_if_index);
11177   mp->enable_disable = enable_disable;
11178
11179   S (mp);
11180   W (ret);
11181   return ret;
11182 }
11183
11184 static int
11185 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11186 {
11187   unformat_input_t *i = vam->input;
11188   vl_api_l2tpv3_set_lookup_key_t *mp;
11189   u8 key = ~0;
11190   int ret;
11191
11192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11193     {
11194       if (unformat (i, "lookup_v6_src"))
11195         key = L2T_LOOKUP_SRC_ADDRESS;
11196       else if (unformat (i, "lookup_v6_dst"))
11197         key = L2T_LOOKUP_DST_ADDRESS;
11198       else if (unformat (i, "lookup_session_id"))
11199         key = L2T_LOOKUP_SESSION_ID;
11200       else
11201         break;
11202     }
11203
11204   if (key == (u8) ~ 0)
11205     {
11206       errmsg ("l2tp session lookup key unset");
11207       return -99;
11208     }
11209
11210   M (L2TPV3_SET_LOOKUP_KEY, mp);
11211
11212   mp->key = key;
11213
11214   S (mp);
11215   W (ret);
11216   return ret;
11217 }
11218
11219 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11220   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11221 {
11222   vat_main_t *vam = &vat_main;
11223
11224   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11225          format_ip6_address, mp->our_address,
11226          format_ip6_address, mp->client_address,
11227          clib_net_to_host_u32 (mp->sw_if_index));
11228
11229   print (vam->ofp,
11230          "   local cookies %016llx %016llx remote cookie %016llx",
11231          clib_net_to_host_u64 (mp->local_cookie[0]),
11232          clib_net_to_host_u64 (mp->local_cookie[1]),
11233          clib_net_to_host_u64 (mp->remote_cookie));
11234
11235   print (vam->ofp, "   local session-id %d remote session-id %d",
11236          clib_net_to_host_u32 (mp->local_session_id),
11237          clib_net_to_host_u32 (mp->remote_session_id));
11238
11239   print (vam->ofp, "   l2 specific sublayer %s\n",
11240          mp->l2_sublayer_present ? "preset" : "absent");
11241
11242 }
11243
11244 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11245   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11246 {
11247   vat_main_t *vam = &vat_main;
11248   vat_json_node_t *node = NULL;
11249   struct in6_addr addr;
11250
11251   if (VAT_JSON_ARRAY != vam->json_tree.type)
11252     {
11253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11254       vat_json_init_array (&vam->json_tree);
11255     }
11256   node = vat_json_array_add (&vam->json_tree);
11257
11258   vat_json_init_object (node);
11259
11260   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11261   vat_json_object_add_ip6 (node, "our_address", addr);
11262   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11263   vat_json_object_add_ip6 (node, "client_address", addr);
11264
11265   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11266   vat_json_init_array (lc);
11267   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11268   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11269   vat_json_object_add_uint (node, "remote_cookie",
11270                             clib_net_to_host_u64 (mp->remote_cookie));
11271
11272   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11273   vat_json_object_add_uint (node, "local_session_id",
11274                             clib_net_to_host_u32 (mp->local_session_id));
11275   vat_json_object_add_uint (node, "remote_session_id",
11276                             clib_net_to_host_u32 (mp->remote_session_id));
11277   vat_json_object_add_string_copy (node, "l2_sublayer",
11278                                    mp->l2_sublayer_present ? (u8 *) "present"
11279                                    : (u8 *) "absent");
11280 }
11281
11282 static int
11283 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11284 {
11285   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11286   vl_api_control_ping_t *mp_ping;
11287   int ret;
11288
11289   /* Get list of l2tpv3-tunnel interfaces */
11290   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11291   S (mp);
11292
11293   /* Use a control ping for synchronization */
11294   MPING (CONTROL_PING, mp_ping);
11295   S (mp_ping);
11296
11297   W (ret);
11298   return ret;
11299 }
11300
11301
11302 static void vl_api_sw_interface_tap_v2_details_t_handler
11303   (vl_api_sw_interface_tap_v2_details_t * mp)
11304 {
11305   vat_main_t *vam = &vat_main;
11306
11307   u8 *ip4 =
11308     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11309             mp->host_ip4_prefix.len);
11310   u8 *ip6 =
11311     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11312             mp->host_ip6_prefix.len);
11313
11314   print (vam->ofp,
11315          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11316          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11317          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11318          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11319          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11320
11321   vec_free (ip4);
11322   vec_free (ip6);
11323 }
11324
11325 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11326   (vl_api_sw_interface_tap_v2_details_t * mp)
11327 {
11328   vat_main_t *vam = &vat_main;
11329   vat_json_node_t *node = NULL;
11330
11331   if (VAT_JSON_ARRAY != vam->json_tree.type)
11332     {
11333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11334       vat_json_init_array (&vam->json_tree);
11335     }
11336   node = vat_json_array_add (&vam->json_tree);
11337
11338   vat_json_init_object (node);
11339   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11340   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11341   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11342   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11343   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11344   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11345   vat_json_object_add_string_copy (node, "host_mac_addr",
11346                                    format (0, "%U", format_ethernet_address,
11347                                            &mp->host_mac_addr));
11348   vat_json_object_add_string_copy (node, "host_namespace",
11349                                    mp->host_namespace);
11350   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11351   vat_json_object_add_string_copy (node, "host_ip4_addr",
11352                                    format (0, "%U/%d", format_ip4_address,
11353                                            mp->host_ip4_prefix.address,
11354                                            mp->host_ip4_prefix.len));
11355   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11356                                    format (0, "%U/%d", format_ip6_address,
11357                                            mp->host_ip6_prefix.address,
11358                                            mp->host_ip6_prefix.len));
11359
11360 }
11361
11362 static int
11363 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11364 {
11365   vl_api_sw_interface_tap_v2_dump_t *mp;
11366   vl_api_control_ping_t *mp_ping;
11367   int ret;
11368
11369   print (vam->ofp,
11370          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11371          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11372          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11373          "host_ip6_addr");
11374
11375   /* Get list of tap interfaces */
11376   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11377   S (mp);
11378
11379   /* Use a control ping for synchronization */
11380   MPING (CONTROL_PING, mp_ping);
11381   S (mp_ping);
11382
11383   W (ret);
11384   return ret;
11385 }
11386
11387 static void vl_api_sw_interface_virtio_pci_details_t_handler
11388   (vl_api_sw_interface_virtio_pci_details_t * mp)
11389 {
11390   vat_main_t *vam = &vat_main;
11391
11392   typedef union
11393   {
11394     struct
11395     {
11396       u16 domain;
11397       u8 bus;
11398       u8 slot:5;
11399       u8 function:3;
11400     };
11401     u32 as_u32;
11402   } pci_addr_t;
11403   pci_addr_t addr;
11404   addr.as_u32 = ntohl (mp->pci_addr);
11405   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11406                          addr.slot, addr.function);
11407
11408   print (vam->ofp,
11409          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11410          pci_addr, ntohl (mp->sw_if_index),
11411          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11412          format_ethernet_address, mp->mac_addr,
11413          clib_net_to_host_u64 (mp->features));
11414   vec_free (pci_addr);
11415 }
11416
11417 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11418   (vl_api_sw_interface_virtio_pci_details_t * mp)
11419 {
11420   vat_main_t *vam = &vat_main;
11421   vat_json_node_t *node = NULL;
11422
11423   if (VAT_JSON_ARRAY != vam->json_tree.type)
11424     {
11425       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11426       vat_json_init_array (&vam->json_tree);
11427     }
11428   node = vat_json_array_add (&vam->json_tree);
11429
11430   vat_json_init_object (node);
11431   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11432   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11433   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11434   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11435   vat_json_object_add_uint (node, "features",
11436                             clib_net_to_host_u64 (mp->features));
11437   vat_json_object_add_string_copy (node, "mac_addr",
11438                                    format (0, "%U", format_ethernet_address,
11439                                            &mp->mac_addr));
11440 }
11441
11442 static int
11443 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11444 {
11445   vl_api_sw_interface_virtio_pci_dump_t *mp;
11446   vl_api_control_ping_t *mp_ping;
11447   int ret;
11448
11449   print (vam->ofp,
11450          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11451          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11452          "mac_addr", "features");
11453
11454   /* Get list of tap interfaces */
11455   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11456   S (mp);
11457
11458   /* Use a control ping for synchronization */
11459   MPING (CONTROL_PING, mp_ping);
11460   S (mp_ping);
11461
11462   W (ret);
11463   return ret;
11464 }
11465
11466 static int
11467 api_vxlan_offload_rx (vat_main_t * vam)
11468 {
11469   unformat_input_t *line_input = vam->input;
11470   vl_api_vxlan_offload_rx_t *mp;
11471   u32 hw_if_index = ~0, rx_if_index = ~0;
11472   u8 is_add = 1;
11473   int ret;
11474
11475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11476     {
11477       if (unformat (line_input, "del"))
11478         is_add = 0;
11479       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11480                          &hw_if_index))
11481         ;
11482       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11483         ;
11484       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11485                          &rx_if_index))
11486         ;
11487       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11488         ;
11489       else
11490         {
11491           errmsg ("parse error '%U'", format_unformat_error, line_input);
11492           return -99;
11493         }
11494     }
11495
11496   if (hw_if_index == ~0)
11497     {
11498       errmsg ("no hw interface");
11499       return -99;
11500     }
11501
11502   if (rx_if_index == ~0)
11503     {
11504       errmsg ("no rx tunnel");
11505       return -99;
11506     }
11507
11508   M (VXLAN_OFFLOAD_RX, mp);
11509
11510   mp->hw_if_index = ntohl (hw_if_index);
11511   mp->sw_if_index = ntohl (rx_if_index);
11512   mp->enable = is_add;
11513
11514   S (mp);
11515   W (ret);
11516   return ret;
11517 }
11518
11519 static uword unformat_vxlan_decap_next
11520   (unformat_input_t * input, va_list * args)
11521 {
11522   u32 *result = va_arg (*args, u32 *);
11523   u32 tmp;
11524
11525   if (unformat (input, "l2"))
11526     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11527   else if (unformat (input, "%d", &tmp))
11528     *result = tmp;
11529   else
11530     return 0;
11531   return 1;
11532 }
11533
11534 static int
11535 api_vxlan_add_del_tunnel (vat_main_t * vam)
11536 {
11537   unformat_input_t *line_input = vam->input;
11538   vl_api_vxlan_add_del_tunnel_t *mp;
11539   ip46_address_t src, dst;
11540   u8 is_add = 1;
11541   u8 ipv4_set = 0, ipv6_set = 0;
11542   u8 src_set = 0;
11543   u8 dst_set = 0;
11544   u8 grp_set = 0;
11545   u32 instance = ~0;
11546   u32 mcast_sw_if_index = ~0;
11547   u32 encap_vrf_id = 0;
11548   u32 decap_next_index = ~0;
11549   u32 vni = 0;
11550   int ret;
11551
11552   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11553   clib_memset (&src, 0, sizeof src);
11554   clib_memset (&dst, 0, sizeof dst);
11555
11556   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11557     {
11558       if (unformat (line_input, "del"))
11559         is_add = 0;
11560       else if (unformat (line_input, "instance %d", &instance))
11561         ;
11562       else
11563         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11564         {
11565           ipv4_set = 1;
11566           src_set = 1;
11567         }
11568       else
11569         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11570         {
11571           ipv4_set = 1;
11572           dst_set = 1;
11573         }
11574       else
11575         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11576         {
11577           ipv6_set = 1;
11578           src_set = 1;
11579         }
11580       else
11581         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11582         {
11583           ipv6_set = 1;
11584           dst_set = 1;
11585         }
11586       else if (unformat (line_input, "group %U %U",
11587                          unformat_ip4_address, &dst.ip4,
11588                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11589         {
11590           grp_set = dst_set = 1;
11591           ipv4_set = 1;
11592         }
11593       else if (unformat (line_input, "group %U",
11594                          unformat_ip4_address, &dst.ip4))
11595         {
11596           grp_set = dst_set = 1;
11597           ipv4_set = 1;
11598         }
11599       else if (unformat (line_input, "group %U %U",
11600                          unformat_ip6_address, &dst.ip6,
11601                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11602         {
11603           grp_set = dst_set = 1;
11604           ipv6_set = 1;
11605         }
11606       else if (unformat (line_input, "group %U",
11607                          unformat_ip6_address, &dst.ip6))
11608         {
11609           grp_set = dst_set = 1;
11610           ipv6_set = 1;
11611         }
11612       else
11613         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11614         ;
11615       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11616         ;
11617       else if (unformat (line_input, "decap-next %U",
11618                          unformat_vxlan_decap_next, &decap_next_index))
11619         ;
11620       else if (unformat (line_input, "vni %d", &vni))
11621         ;
11622       else
11623         {
11624           errmsg ("parse error '%U'", format_unformat_error, line_input);
11625           return -99;
11626         }
11627     }
11628
11629   if (src_set == 0)
11630     {
11631       errmsg ("tunnel src address not specified");
11632       return -99;
11633     }
11634   if (dst_set == 0)
11635     {
11636       errmsg ("tunnel dst address not specified");
11637       return -99;
11638     }
11639
11640   if (grp_set && !ip46_address_is_multicast (&dst))
11641     {
11642       errmsg ("tunnel group address not multicast");
11643       return -99;
11644     }
11645   if (grp_set && mcast_sw_if_index == ~0)
11646     {
11647       errmsg ("tunnel nonexistent multicast device");
11648       return -99;
11649     }
11650   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11651     {
11652       errmsg ("tunnel dst address must be unicast");
11653       return -99;
11654     }
11655
11656
11657   if (ipv4_set && ipv6_set)
11658     {
11659       errmsg ("both IPv4 and IPv6 addresses specified");
11660       return -99;
11661     }
11662
11663   if ((vni == 0) || (vni >> 24))
11664     {
11665       errmsg ("vni not specified or out of range");
11666       return -99;
11667     }
11668
11669   M (VXLAN_ADD_DEL_TUNNEL, mp);
11670
11671   if (ipv6_set)
11672     {
11673       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11674       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11675     }
11676   else
11677     {
11678       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11679       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11680     }
11681
11682   mp->instance = htonl (instance);
11683   mp->encap_vrf_id = ntohl (encap_vrf_id);
11684   mp->decap_next_index = ntohl (decap_next_index);
11685   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11686   mp->vni = ntohl (vni);
11687   mp->is_add = is_add;
11688   mp->is_ipv6 = ipv6_set;
11689
11690   S (mp);
11691   W (ret);
11692   return ret;
11693 }
11694
11695 static void vl_api_vxlan_tunnel_details_t_handler
11696   (vl_api_vxlan_tunnel_details_t * mp)
11697 {
11698   vat_main_t *vam = &vat_main;
11699   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11700   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11701
11702   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11703          ntohl (mp->sw_if_index),
11704          ntohl (mp->instance),
11705          format_ip46_address, &src, IP46_TYPE_ANY,
11706          format_ip46_address, &dst, IP46_TYPE_ANY,
11707          ntohl (mp->encap_vrf_id),
11708          ntohl (mp->decap_next_index), ntohl (mp->vni),
11709          ntohl (mp->mcast_sw_if_index));
11710 }
11711
11712 static void vl_api_vxlan_tunnel_details_t_handler_json
11713   (vl_api_vxlan_tunnel_details_t * mp)
11714 {
11715   vat_main_t *vam = &vat_main;
11716   vat_json_node_t *node = NULL;
11717
11718   if (VAT_JSON_ARRAY != vam->json_tree.type)
11719     {
11720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11721       vat_json_init_array (&vam->json_tree);
11722     }
11723   node = vat_json_array_add (&vam->json_tree);
11724
11725   vat_json_init_object (node);
11726   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11727
11728   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11729
11730   if (mp->is_ipv6)
11731     {
11732       struct in6_addr ip6;
11733
11734       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11735       vat_json_object_add_ip6 (node, "src_address", ip6);
11736       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11737       vat_json_object_add_ip6 (node, "dst_address", ip6);
11738     }
11739   else
11740     {
11741       struct in_addr ip4;
11742
11743       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11744       vat_json_object_add_ip4 (node, "src_address", ip4);
11745       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11746       vat_json_object_add_ip4 (node, "dst_address", ip4);
11747     }
11748   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11749   vat_json_object_add_uint (node, "decap_next_index",
11750                             ntohl (mp->decap_next_index));
11751   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11752   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11753   vat_json_object_add_uint (node, "mcast_sw_if_index",
11754                             ntohl (mp->mcast_sw_if_index));
11755 }
11756
11757 static int
11758 api_vxlan_tunnel_dump (vat_main_t * vam)
11759 {
11760   unformat_input_t *i = vam->input;
11761   vl_api_vxlan_tunnel_dump_t *mp;
11762   vl_api_control_ping_t *mp_ping;
11763   u32 sw_if_index;
11764   u8 sw_if_index_set = 0;
11765   int ret;
11766
11767   /* Parse args required to build the message */
11768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11769     {
11770       if (unformat (i, "sw_if_index %d", &sw_if_index))
11771         sw_if_index_set = 1;
11772       else
11773         break;
11774     }
11775
11776   if (sw_if_index_set == 0)
11777     {
11778       sw_if_index = ~0;
11779     }
11780
11781   if (!vam->json_output)
11782     {
11783       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11784              "sw_if_index", "instance", "src_address", "dst_address",
11785              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11786     }
11787
11788   /* Get list of vxlan-tunnel interfaces */
11789   M (VXLAN_TUNNEL_DUMP, mp);
11790
11791   mp->sw_if_index = htonl (sw_if_index);
11792
11793   S (mp);
11794
11795   /* Use a control ping for synchronization */
11796   MPING (CONTROL_PING, mp_ping);
11797   S (mp_ping);
11798
11799   W (ret);
11800   return ret;
11801 }
11802
11803 static uword unformat_geneve_decap_next
11804   (unformat_input_t * input, va_list * args)
11805 {
11806   u32 *result = va_arg (*args, u32 *);
11807   u32 tmp;
11808
11809   if (unformat (input, "l2"))
11810     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11811   else if (unformat (input, "%d", &tmp))
11812     *result = tmp;
11813   else
11814     return 0;
11815   return 1;
11816 }
11817
11818 static int
11819 api_geneve_add_del_tunnel (vat_main_t * vam)
11820 {
11821   unformat_input_t *line_input = vam->input;
11822   vl_api_geneve_add_del_tunnel_t *mp;
11823   ip46_address_t src, dst;
11824   u8 is_add = 1;
11825   u8 ipv4_set = 0, ipv6_set = 0;
11826   u8 src_set = 0;
11827   u8 dst_set = 0;
11828   u8 grp_set = 0;
11829   u32 mcast_sw_if_index = ~0;
11830   u32 encap_vrf_id = 0;
11831   u32 decap_next_index = ~0;
11832   u32 vni = 0;
11833   int ret;
11834
11835   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11836   clib_memset (&src, 0, sizeof src);
11837   clib_memset (&dst, 0, sizeof dst);
11838
11839   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (line_input, "del"))
11842         is_add = 0;
11843       else
11844         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11845         {
11846           ipv4_set = 1;
11847           src_set = 1;
11848         }
11849       else
11850         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11851         {
11852           ipv4_set = 1;
11853           dst_set = 1;
11854         }
11855       else
11856         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11857         {
11858           ipv6_set = 1;
11859           src_set = 1;
11860         }
11861       else
11862         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11863         {
11864           ipv6_set = 1;
11865           dst_set = 1;
11866         }
11867       else if (unformat (line_input, "group %U %U",
11868                          unformat_ip4_address, &dst.ip4,
11869                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11870         {
11871           grp_set = dst_set = 1;
11872           ipv4_set = 1;
11873         }
11874       else if (unformat (line_input, "group %U",
11875                          unformat_ip4_address, &dst.ip4))
11876         {
11877           grp_set = dst_set = 1;
11878           ipv4_set = 1;
11879         }
11880       else if (unformat (line_input, "group %U %U",
11881                          unformat_ip6_address, &dst.ip6,
11882                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11883         {
11884           grp_set = dst_set = 1;
11885           ipv6_set = 1;
11886         }
11887       else if (unformat (line_input, "group %U",
11888                          unformat_ip6_address, &dst.ip6))
11889         {
11890           grp_set = dst_set = 1;
11891           ipv6_set = 1;
11892         }
11893       else
11894         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11895         ;
11896       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11897         ;
11898       else if (unformat (line_input, "decap-next %U",
11899                          unformat_geneve_decap_next, &decap_next_index))
11900         ;
11901       else if (unformat (line_input, "vni %d", &vni))
11902         ;
11903       else
11904         {
11905           errmsg ("parse error '%U'", format_unformat_error, line_input);
11906           return -99;
11907         }
11908     }
11909
11910   if (src_set == 0)
11911     {
11912       errmsg ("tunnel src address not specified");
11913       return -99;
11914     }
11915   if (dst_set == 0)
11916     {
11917       errmsg ("tunnel dst address not specified");
11918       return -99;
11919     }
11920
11921   if (grp_set && !ip46_address_is_multicast (&dst))
11922     {
11923       errmsg ("tunnel group address not multicast");
11924       return -99;
11925     }
11926   if (grp_set && mcast_sw_if_index == ~0)
11927     {
11928       errmsg ("tunnel nonexistent multicast device");
11929       return -99;
11930     }
11931   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11932     {
11933       errmsg ("tunnel dst address must be unicast");
11934       return -99;
11935     }
11936
11937
11938   if (ipv4_set && ipv6_set)
11939     {
11940       errmsg ("both IPv4 and IPv6 addresses specified");
11941       return -99;
11942     }
11943
11944   if ((vni == 0) || (vni >> 24))
11945     {
11946       errmsg ("vni not specified or out of range");
11947       return -99;
11948     }
11949
11950   M (GENEVE_ADD_DEL_TUNNEL, mp);
11951
11952   if (ipv6_set)
11953     {
11954       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11955       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11956     }
11957   else
11958     {
11959       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11960       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11961     }
11962   mp->encap_vrf_id = ntohl (encap_vrf_id);
11963   mp->decap_next_index = ntohl (decap_next_index);
11964   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11965   mp->vni = ntohl (vni);
11966   mp->is_add = is_add;
11967
11968   S (mp);
11969   W (ret);
11970   return ret;
11971 }
11972
11973 static void vl_api_geneve_tunnel_details_t_handler
11974   (vl_api_geneve_tunnel_details_t * mp)
11975 {
11976   vat_main_t *vam = &vat_main;
11977   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
11978   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
11979
11980   if (mp->src_address.af == ADDRESS_IP6)
11981     {
11982       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
11983       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
11984     }
11985   else
11986     {
11987       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
11988       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
11989     }
11990
11991   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11992          ntohl (mp->sw_if_index),
11993          format_ip46_address, &src, IP46_TYPE_ANY,
11994          format_ip46_address, &dst, IP46_TYPE_ANY,
11995          ntohl (mp->encap_vrf_id),
11996          ntohl (mp->decap_next_index), ntohl (mp->vni),
11997          ntohl (mp->mcast_sw_if_index));
11998 }
11999
12000 static void vl_api_geneve_tunnel_details_t_handler_json
12001   (vl_api_geneve_tunnel_details_t * mp)
12002 {
12003   vat_main_t *vam = &vat_main;
12004   vat_json_node_t *node = NULL;
12005   bool is_ipv6;
12006
12007   if (VAT_JSON_ARRAY != vam->json_tree.type)
12008     {
12009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12010       vat_json_init_array (&vam->json_tree);
12011     }
12012   node = vat_json_array_add (&vam->json_tree);
12013
12014   vat_json_init_object (node);
12015   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12016   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12017   if (is_ipv6)
12018     {
12019       struct in6_addr ip6;
12020
12021       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12022       vat_json_object_add_ip6 (node, "src_address", ip6);
12023       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12024       vat_json_object_add_ip6 (node, "dst_address", ip6);
12025     }
12026   else
12027     {
12028       struct in_addr ip4;
12029
12030       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12031       vat_json_object_add_ip4 (node, "src_address", ip4);
12032       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12033       vat_json_object_add_ip4 (node, "dst_address", ip4);
12034     }
12035   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12036   vat_json_object_add_uint (node, "decap_next_index",
12037                             ntohl (mp->decap_next_index));
12038   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12039   vat_json_object_add_uint (node, "mcast_sw_if_index",
12040                             ntohl (mp->mcast_sw_if_index));
12041 }
12042
12043 static int
12044 api_geneve_tunnel_dump (vat_main_t * vam)
12045 {
12046   unformat_input_t *i = vam->input;
12047   vl_api_geneve_tunnel_dump_t *mp;
12048   vl_api_control_ping_t *mp_ping;
12049   u32 sw_if_index;
12050   u8 sw_if_index_set = 0;
12051   int ret;
12052
12053   /* Parse args required to build the message */
12054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12055     {
12056       if (unformat (i, "sw_if_index %d", &sw_if_index))
12057         sw_if_index_set = 1;
12058       else
12059         break;
12060     }
12061
12062   if (sw_if_index_set == 0)
12063     {
12064       sw_if_index = ~0;
12065     }
12066
12067   if (!vam->json_output)
12068     {
12069       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12070              "sw_if_index", "local_address", "remote_address",
12071              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12072     }
12073
12074   /* Get list of geneve-tunnel interfaces */
12075   M (GENEVE_TUNNEL_DUMP, mp);
12076
12077   mp->sw_if_index = htonl (sw_if_index);
12078
12079   S (mp);
12080
12081   /* Use a control ping for synchronization */
12082   M (CONTROL_PING, mp_ping);
12083   S (mp_ping);
12084
12085   W (ret);
12086   return ret;
12087 }
12088
12089 static int
12090 api_gre_tunnel_add_del (vat_main_t * vam)
12091 {
12092   unformat_input_t *line_input = vam->input;
12093   vl_api_address_t src = { }, dst =
12094   {
12095   };
12096   vl_api_gre_tunnel_add_del_t *mp;
12097   vl_api_gre_tunnel_type_t t_type;
12098   u8 is_add = 1;
12099   u8 src_set = 0;
12100   u8 dst_set = 0;
12101   u32 outer_table_id = 0;
12102   u32 session_id = 0;
12103   u32 instance = ~0;
12104   int ret;
12105
12106   t_type = GRE_API_TUNNEL_TYPE_L3;
12107
12108   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12109     {
12110       if (unformat (line_input, "del"))
12111         is_add = 0;
12112       else if (unformat (line_input, "instance %d", &instance))
12113         ;
12114       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12115         {
12116           src_set = 1;
12117         }
12118       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12119         {
12120           dst_set = 1;
12121         }
12122       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12123         ;
12124       else if (unformat (line_input, "teb"))
12125         t_type = GRE_API_TUNNEL_TYPE_TEB;
12126       else if (unformat (line_input, "erspan %d", &session_id))
12127         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12128       else
12129         {
12130           errmsg ("parse error '%U'", format_unformat_error, line_input);
12131           return -99;
12132         }
12133     }
12134
12135   if (src_set == 0)
12136     {
12137       errmsg ("tunnel src address not specified");
12138       return -99;
12139     }
12140   if (dst_set == 0)
12141     {
12142       errmsg ("tunnel dst address not specified");
12143       return -99;
12144     }
12145
12146   M (GRE_TUNNEL_ADD_DEL, mp);
12147
12148   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12149   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12150
12151   mp->tunnel.instance = htonl (instance);
12152   mp->tunnel.outer_table_id = htonl (outer_table_id);
12153   mp->is_add = is_add;
12154   mp->tunnel.session_id = htons ((u16) session_id);
12155   mp->tunnel.type = htonl (t_type);
12156
12157   S (mp);
12158   W (ret);
12159   return ret;
12160 }
12161
12162 static void vl_api_gre_tunnel_details_t_handler
12163   (vl_api_gre_tunnel_details_t * mp)
12164 {
12165   vat_main_t *vam = &vat_main;
12166
12167   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12168          ntohl (mp->tunnel.sw_if_index),
12169          ntohl (mp->tunnel.instance),
12170          format_vl_api_address, &mp->tunnel.src,
12171          format_vl_api_address, &mp->tunnel.dst,
12172          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12173          ntohl (mp->tunnel.session_id));
12174 }
12175
12176 static void vl_api_gre_tunnel_details_t_handler_json
12177   (vl_api_gre_tunnel_details_t * mp)
12178 {
12179   vat_main_t *vam = &vat_main;
12180   vat_json_node_t *node = NULL;
12181
12182   if (VAT_JSON_ARRAY != vam->json_tree.type)
12183     {
12184       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12185       vat_json_init_array (&vam->json_tree);
12186     }
12187   node = vat_json_array_add (&vam->json_tree);
12188
12189   vat_json_init_object (node);
12190   vat_json_object_add_uint (node, "sw_if_index",
12191                             ntohl (mp->tunnel.sw_if_index));
12192   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12193
12194   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12195   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12196   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12197   vat_json_object_add_uint (node, "outer_table_id",
12198                             ntohl (mp->tunnel.outer_table_id));
12199   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12200 }
12201
12202 static int
12203 api_gre_tunnel_dump (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   vl_api_gre_tunnel_dump_t *mp;
12207   vl_api_control_ping_t *mp_ping;
12208   u32 sw_if_index;
12209   u8 sw_if_index_set = 0;
12210   int ret;
12211
12212   /* Parse args required to build the message */
12213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12214     {
12215       if (unformat (i, "sw_if_index %d", &sw_if_index))
12216         sw_if_index_set = 1;
12217       else
12218         break;
12219     }
12220
12221   if (sw_if_index_set == 0)
12222     {
12223       sw_if_index = ~0;
12224     }
12225
12226   if (!vam->json_output)
12227     {
12228       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12229              "sw_if_index", "instance", "src_address", "dst_address",
12230              "tunnel_type", "outer_fib_id", "session_id");
12231     }
12232
12233   /* Get list of gre-tunnel interfaces */
12234   M (GRE_TUNNEL_DUMP, mp);
12235
12236   mp->sw_if_index = htonl (sw_if_index);
12237
12238   S (mp);
12239
12240   /* Use a control ping for synchronization */
12241   MPING (CONTROL_PING, mp_ping);
12242   S (mp_ping);
12243
12244   W (ret);
12245   return ret;
12246 }
12247
12248 static int
12249 api_l2_fib_clear_table (vat_main_t * vam)
12250 {
12251 //  unformat_input_t * i = vam->input;
12252   vl_api_l2_fib_clear_table_t *mp;
12253   int ret;
12254
12255   M (L2_FIB_CLEAR_TABLE, mp);
12256
12257   S (mp);
12258   W (ret);
12259   return ret;
12260 }
12261
12262 static int
12263 api_l2_interface_efp_filter (vat_main_t * vam)
12264 {
12265   unformat_input_t *i = vam->input;
12266   vl_api_l2_interface_efp_filter_t *mp;
12267   u32 sw_if_index;
12268   u8 enable = 1;
12269   u8 sw_if_index_set = 0;
12270   int ret;
12271
12272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12273     {
12274       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12275         sw_if_index_set = 1;
12276       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12277         sw_if_index_set = 1;
12278       else if (unformat (i, "enable"))
12279         enable = 1;
12280       else if (unformat (i, "disable"))
12281         enable = 0;
12282       else
12283         {
12284           clib_warning ("parse error '%U'", format_unformat_error, i);
12285           return -99;
12286         }
12287     }
12288
12289   if (sw_if_index_set == 0)
12290     {
12291       errmsg ("missing sw_if_index");
12292       return -99;
12293     }
12294
12295   M (L2_INTERFACE_EFP_FILTER, mp);
12296
12297   mp->sw_if_index = ntohl (sw_if_index);
12298   mp->enable_disable = enable;
12299
12300   S (mp);
12301   W (ret);
12302   return ret;
12303 }
12304
12305 #define foreach_vtr_op                          \
12306 _("disable",  L2_VTR_DISABLED)                  \
12307 _("push-1",  L2_VTR_PUSH_1)                     \
12308 _("push-2",  L2_VTR_PUSH_2)                     \
12309 _("pop-1",  L2_VTR_POP_1)                       \
12310 _("pop-2",  L2_VTR_POP_2)                       \
12311 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12312 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12313 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12314 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12315
12316 static int
12317 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12318 {
12319   unformat_input_t *i = vam->input;
12320   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12321   u32 sw_if_index;
12322   u8 sw_if_index_set = 0;
12323   u8 vtr_op_set = 0;
12324   u32 vtr_op = 0;
12325   u32 push_dot1q = 1;
12326   u32 tag1 = ~0;
12327   u32 tag2 = ~0;
12328   int ret;
12329
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12333         sw_if_index_set = 1;
12334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12335         sw_if_index_set = 1;
12336       else if (unformat (i, "vtr_op %d", &vtr_op))
12337         vtr_op_set = 1;
12338 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12339       foreach_vtr_op
12340 #undef _
12341         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12342         ;
12343       else if (unformat (i, "tag1 %d", &tag1))
12344         ;
12345       else if (unformat (i, "tag2 %d", &tag2))
12346         ;
12347       else
12348         {
12349           clib_warning ("parse error '%U'", format_unformat_error, i);
12350           return -99;
12351         }
12352     }
12353
12354   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12355     {
12356       errmsg ("missing vtr operation or sw_if_index");
12357       return -99;
12358     }
12359
12360   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12361   mp->sw_if_index = ntohl (sw_if_index);
12362   mp->vtr_op = ntohl (vtr_op);
12363   mp->push_dot1q = ntohl (push_dot1q);
12364   mp->tag1 = ntohl (tag1);
12365   mp->tag2 = ntohl (tag2);
12366
12367   S (mp);
12368   W (ret);
12369   return ret;
12370 }
12371
12372 static int
12373 api_create_vhost_user_if (vat_main_t * vam)
12374 {
12375   unformat_input_t *i = vam->input;
12376   vl_api_create_vhost_user_if_t *mp;
12377   u8 *file_name;
12378   u8 is_server = 0;
12379   u8 file_name_set = 0;
12380   u32 custom_dev_instance = ~0;
12381   u8 hwaddr[6];
12382   u8 use_custom_mac = 0;
12383   u8 disable_mrg_rxbuf = 0;
12384   u8 disable_indirect_desc = 0;
12385   u8 *tag = 0;
12386   u8 enable_gso = 0;
12387   int ret;
12388
12389   /* Shut up coverity */
12390   clib_memset (hwaddr, 0, sizeof (hwaddr));
12391
12392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12393     {
12394       if (unformat (i, "socket %s", &file_name))
12395         {
12396           file_name_set = 1;
12397         }
12398       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12399         ;
12400       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12401         use_custom_mac = 1;
12402       else if (unformat (i, "server"))
12403         is_server = 1;
12404       else if (unformat (i, "disable_mrg_rxbuf"))
12405         disable_mrg_rxbuf = 1;
12406       else if (unformat (i, "disable_indirect_desc"))
12407         disable_indirect_desc = 1;
12408       else if (unformat (i, "gso"))
12409         enable_gso = 1;
12410       else if (unformat (i, "tag %s", &tag))
12411         ;
12412       else
12413         break;
12414     }
12415
12416   if (file_name_set == 0)
12417     {
12418       errmsg ("missing socket file name");
12419       return -99;
12420     }
12421
12422   if (vec_len (file_name) > 255)
12423     {
12424       errmsg ("socket file name too long");
12425       return -99;
12426     }
12427   vec_add1 (file_name, 0);
12428
12429   M (CREATE_VHOST_USER_IF, mp);
12430
12431   mp->is_server = is_server;
12432   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12433   mp->disable_indirect_desc = disable_indirect_desc;
12434   mp->enable_gso = enable_gso;
12435   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12436   vec_free (file_name);
12437   if (custom_dev_instance != ~0)
12438     {
12439       mp->renumber = 1;
12440       mp->custom_dev_instance = ntohl (custom_dev_instance);
12441     }
12442
12443   mp->use_custom_mac = use_custom_mac;
12444   clib_memcpy (mp->mac_address, hwaddr, 6);
12445   if (tag)
12446     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12447   vec_free (tag);
12448
12449   S (mp);
12450   W (ret);
12451   return ret;
12452 }
12453
12454 static int
12455 api_modify_vhost_user_if (vat_main_t * vam)
12456 {
12457   unformat_input_t *i = vam->input;
12458   vl_api_modify_vhost_user_if_t *mp;
12459   u8 *file_name;
12460   u8 is_server = 0;
12461   u8 file_name_set = 0;
12462   u32 custom_dev_instance = ~0;
12463   u8 sw_if_index_set = 0;
12464   u32 sw_if_index = (u32) ~ 0;
12465   u8 enable_gso = 0;
12466   int ret;
12467
12468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12471         sw_if_index_set = 1;
12472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12473         sw_if_index_set = 1;
12474       else if (unformat (i, "socket %s", &file_name))
12475         {
12476           file_name_set = 1;
12477         }
12478       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12479         ;
12480       else if (unformat (i, "server"))
12481         is_server = 1;
12482       else if (unformat (i, "gso"))
12483         enable_gso = 1;
12484       else
12485         break;
12486     }
12487
12488   if (sw_if_index_set == 0)
12489     {
12490       errmsg ("missing sw_if_index or interface name");
12491       return -99;
12492     }
12493
12494   if (file_name_set == 0)
12495     {
12496       errmsg ("missing socket file name");
12497       return -99;
12498     }
12499
12500   if (vec_len (file_name) > 255)
12501     {
12502       errmsg ("socket file name too long");
12503       return -99;
12504     }
12505   vec_add1 (file_name, 0);
12506
12507   M (MODIFY_VHOST_USER_IF, mp);
12508
12509   mp->sw_if_index = ntohl (sw_if_index);
12510   mp->is_server = is_server;
12511   mp->enable_gso = enable_gso;
12512   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12513   vec_free (file_name);
12514   if (custom_dev_instance != ~0)
12515     {
12516       mp->renumber = 1;
12517       mp->custom_dev_instance = ntohl (custom_dev_instance);
12518     }
12519
12520   S (mp);
12521   W (ret);
12522   return ret;
12523 }
12524
12525 static int
12526 api_delete_vhost_user_if (vat_main_t * vam)
12527 {
12528   unformat_input_t *i = vam->input;
12529   vl_api_delete_vhost_user_if_t *mp;
12530   u32 sw_if_index = ~0;
12531   u8 sw_if_index_set = 0;
12532   int ret;
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12537         sw_if_index_set = 1;
12538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12539         sw_if_index_set = 1;
12540       else
12541         break;
12542     }
12543
12544   if (sw_if_index_set == 0)
12545     {
12546       errmsg ("missing sw_if_index or interface name");
12547       return -99;
12548     }
12549
12550
12551   M (DELETE_VHOST_USER_IF, mp);
12552
12553   mp->sw_if_index = ntohl (sw_if_index);
12554
12555   S (mp);
12556   W (ret);
12557   return ret;
12558 }
12559
12560 static void vl_api_sw_interface_vhost_user_details_t_handler
12561   (vl_api_sw_interface_vhost_user_details_t * mp)
12562 {
12563   vat_main_t *vam = &vat_main;
12564   u64 features;
12565
12566   features =
12567     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12568                                                     clib_net_to_host_u32
12569                                                     (mp->features_last_32) <<
12570                                                     32);
12571
12572   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12573          (char *) mp->interface_name,
12574          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12575          features, mp->is_server,
12576          ntohl (mp->num_regions), (char *) mp->sock_filename);
12577   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12578 }
12579
12580 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12581   (vl_api_sw_interface_vhost_user_details_t * mp)
12582 {
12583   vat_main_t *vam = &vat_main;
12584   vat_json_node_t *node = NULL;
12585
12586   if (VAT_JSON_ARRAY != vam->json_tree.type)
12587     {
12588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12589       vat_json_init_array (&vam->json_tree);
12590     }
12591   node = vat_json_array_add (&vam->json_tree);
12592
12593   vat_json_init_object (node);
12594   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12595   vat_json_object_add_string_copy (node, "interface_name",
12596                                    mp->interface_name);
12597   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12598                             ntohl (mp->virtio_net_hdr_sz));
12599   vat_json_object_add_uint (node, "features_first_32",
12600                             clib_net_to_host_u32 (mp->features_first_32));
12601   vat_json_object_add_uint (node, "features_last_32",
12602                             clib_net_to_host_u32 (mp->features_last_32));
12603   vat_json_object_add_uint (node, "is_server", mp->is_server);
12604   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12605   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12606   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12607 }
12608
12609 static int
12610 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12611 {
12612   vl_api_sw_interface_vhost_user_dump_t *mp;
12613   vl_api_control_ping_t *mp_ping;
12614   int ret;
12615   print (vam->ofp,
12616          "Interface name            idx hdr_sz features server regions filename");
12617
12618   /* Get list of vhost-user interfaces */
12619   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12620   S (mp);
12621
12622   /* Use a control ping for synchronization */
12623   MPING (CONTROL_PING, mp_ping);
12624   S (mp_ping);
12625
12626   W (ret);
12627   return ret;
12628 }
12629
12630 static int
12631 api_show_version (vat_main_t * vam)
12632 {
12633   vl_api_show_version_t *mp;
12634   int ret;
12635
12636   M (SHOW_VERSION, mp);
12637
12638   S (mp);
12639   W (ret);
12640   return ret;
12641 }
12642
12643
12644 static int
12645 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12646 {
12647   unformat_input_t *line_input = vam->input;
12648   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12649   ip4_address_t local4, remote4;
12650   ip6_address_t local6, remote6;
12651   u8 is_add = 1;
12652   u8 ipv4_set = 0, ipv6_set = 0;
12653   u8 local_set = 0;
12654   u8 remote_set = 0;
12655   u8 grp_set = 0;
12656   u32 mcast_sw_if_index = ~0;
12657   u32 encap_vrf_id = 0;
12658   u32 decap_vrf_id = 0;
12659   u8 protocol = ~0;
12660   u32 vni;
12661   u8 vni_set = 0;
12662   int ret;
12663
12664   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12665   clib_memset (&local4, 0, sizeof local4);
12666   clib_memset (&remote4, 0, sizeof remote4);
12667   clib_memset (&local6, 0, sizeof local6);
12668   clib_memset (&remote6, 0, sizeof remote6);
12669
12670   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12671     {
12672       if (unformat (line_input, "del"))
12673         is_add = 0;
12674       else if (unformat (line_input, "local %U",
12675                          unformat_ip4_address, &local4))
12676         {
12677           local_set = 1;
12678           ipv4_set = 1;
12679         }
12680       else if (unformat (line_input, "remote %U",
12681                          unformat_ip4_address, &remote4))
12682         {
12683           remote_set = 1;
12684           ipv4_set = 1;
12685         }
12686       else if (unformat (line_input, "local %U",
12687                          unformat_ip6_address, &local6))
12688         {
12689           local_set = 1;
12690           ipv6_set = 1;
12691         }
12692       else if (unformat (line_input, "remote %U",
12693                          unformat_ip6_address, &remote6))
12694         {
12695           remote_set = 1;
12696           ipv6_set = 1;
12697         }
12698       else if (unformat (line_input, "group %U %U",
12699                          unformat_ip4_address, &remote4,
12700                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12701         {
12702           grp_set = remote_set = 1;
12703           ipv4_set = 1;
12704         }
12705       else if (unformat (line_input, "group %U",
12706                          unformat_ip4_address, &remote4))
12707         {
12708           grp_set = remote_set = 1;
12709           ipv4_set = 1;
12710         }
12711       else if (unformat (line_input, "group %U %U",
12712                          unformat_ip6_address, &remote6,
12713                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12714         {
12715           grp_set = remote_set = 1;
12716           ipv6_set = 1;
12717         }
12718       else if (unformat (line_input, "group %U",
12719                          unformat_ip6_address, &remote6))
12720         {
12721           grp_set = remote_set = 1;
12722           ipv6_set = 1;
12723         }
12724       else
12725         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12726         ;
12727       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12728         ;
12729       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12730         ;
12731       else if (unformat (line_input, "vni %d", &vni))
12732         vni_set = 1;
12733       else if (unformat (line_input, "next-ip4"))
12734         protocol = 1;
12735       else if (unformat (line_input, "next-ip6"))
12736         protocol = 2;
12737       else if (unformat (line_input, "next-ethernet"))
12738         protocol = 3;
12739       else if (unformat (line_input, "next-nsh"))
12740         protocol = 4;
12741       else
12742         {
12743           errmsg ("parse error '%U'", format_unformat_error, line_input);
12744           return -99;
12745         }
12746     }
12747
12748   if (local_set == 0)
12749     {
12750       errmsg ("tunnel local address not specified");
12751       return -99;
12752     }
12753   if (remote_set == 0)
12754     {
12755       errmsg ("tunnel remote address not specified");
12756       return -99;
12757     }
12758   if (grp_set && mcast_sw_if_index == ~0)
12759     {
12760       errmsg ("tunnel nonexistent multicast device");
12761       return -99;
12762     }
12763   if (ipv4_set && ipv6_set)
12764     {
12765       errmsg ("both IPv4 and IPv6 addresses specified");
12766       return -99;
12767     }
12768
12769   if (vni_set == 0)
12770     {
12771       errmsg ("vni not specified");
12772       return -99;
12773     }
12774
12775   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12776
12777
12778   if (ipv6_set)
12779     {
12780       clib_memcpy (&mp->local, &local6, sizeof (local6));
12781       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12782     }
12783   else
12784     {
12785       clib_memcpy (&mp->local, &local4, sizeof (local4));
12786       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12787     }
12788
12789   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12790   mp->encap_vrf_id = ntohl (encap_vrf_id);
12791   mp->decap_vrf_id = ntohl (decap_vrf_id);
12792   mp->protocol = protocol;
12793   mp->vni = ntohl (vni);
12794   mp->is_add = is_add;
12795   mp->is_ipv6 = ipv6_set;
12796
12797   S (mp);
12798   W (ret);
12799   return ret;
12800 }
12801
12802 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12803   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12804 {
12805   vat_main_t *vam = &vat_main;
12806   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12807   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12808
12809   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12810          ntohl (mp->sw_if_index),
12811          format_ip46_address, &local, IP46_TYPE_ANY,
12812          format_ip46_address, &remote, IP46_TYPE_ANY,
12813          ntohl (mp->vni), mp->protocol,
12814          ntohl (mp->mcast_sw_if_index),
12815          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12816 }
12817
12818
12819 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12820   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12821 {
12822   vat_main_t *vam = &vat_main;
12823   vat_json_node_t *node = NULL;
12824   struct in_addr ip4;
12825   struct in6_addr ip6;
12826
12827   if (VAT_JSON_ARRAY != vam->json_tree.type)
12828     {
12829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12830       vat_json_init_array (&vam->json_tree);
12831     }
12832   node = vat_json_array_add (&vam->json_tree);
12833
12834   vat_json_init_object (node);
12835   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12836   if (mp->is_ipv6)
12837     {
12838       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12839       vat_json_object_add_ip6 (node, "local", ip6);
12840       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12841       vat_json_object_add_ip6 (node, "remote", ip6);
12842     }
12843   else
12844     {
12845       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12846       vat_json_object_add_ip4 (node, "local", ip4);
12847       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12848       vat_json_object_add_ip4 (node, "remote", ip4);
12849     }
12850   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12851   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12852   vat_json_object_add_uint (node, "mcast_sw_if_index",
12853                             ntohl (mp->mcast_sw_if_index));
12854   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12855   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12856   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12857 }
12858
12859 static int
12860 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12861 {
12862   unformat_input_t *i = vam->input;
12863   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12864   vl_api_control_ping_t *mp_ping;
12865   u32 sw_if_index;
12866   u8 sw_if_index_set = 0;
12867   int ret;
12868
12869   /* Parse args required to build the message */
12870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12871     {
12872       if (unformat (i, "sw_if_index %d", &sw_if_index))
12873         sw_if_index_set = 1;
12874       else
12875         break;
12876     }
12877
12878   if (sw_if_index_set == 0)
12879     {
12880       sw_if_index = ~0;
12881     }
12882
12883   if (!vam->json_output)
12884     {
12885       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12886              "sw_if_index", "local", "remote", "vni",
12887              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12888     }
12889
12890   /* Get list of vxlan-tunnel interfaces */
12891   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12892
12893   mp->sw_if_index = htonl (sw_if_index);
12894
12895   S (mp);
12896
12897   /* Use a control ping for synchronization */
12898   MPING (CONTROL_PING, mp_ping);
12899   S (mp_ping);
12900
12901   W (ret);
12902   return ret;
12903 }
12904
12905 static void vl_api_l2_fib_table_details_t_handler
12906   (vl_api_l2_fib_table_details_t * mp)
12907 {
12908   vat_main_t *vam = &vat_main;
12909
12910   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12911          "       %d       %d     %d",
12912          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12913          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12914          mp->bvi_mac);
12915 }
12916
12917 static void vl_api_l2_fib_table_details_t_handler_json
12918   (vl_api_l2_fib_table_details_t * mp)
12919 {
12920   vat_main_t *vam = &vat_main;
12921   vat_json_node_t *node = NULL;
12922
12923   if (VAT_JSON_ARRAY != vam->json_tree.type)
12924     {
12925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12926       vat_json_init_array (&vam->json_tree);
12927     }
12928   node = vat_json_array_add (&vam->json_tree);
12929
12930   vat_json_init_object (node);
12931   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12932   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12933   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12934   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12935   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12936   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12937 }
12938
12939 static int
12940 api_l2_fib_table_dump (vat_main_t * vam)
12941 {
12942   unformat_input_t *i = vam->input;
12943   vl_api_l2_fib_table_dump_t *mp;
12944   vl_api_control_ping_t *mp_ping;
12945   u32 bd_id;
12946   u8 bd_id_set = 0;
12947   int ret;
12948
12949   /* Parse args required to build the message */
12950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12951     {
12952       if (unformat (i, "bd_id %d", &bd_id))
12953         bd_id_set = 1;
12954       else
12955         break;
12956     }
12957
12958   if (bd_id_set == 0)
12959     {
12960       errmsg ("missing bridge domain");
12961       return -99;
12962     }
12963
12964   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12965
12966   /* Get list of l2 fib entries */
12967   M (L2_FIB_TABLE_DUMP, mp);
12968
12969   mp->bd_id = ntohl (bd_id);
12970   S (mp);
12971
12972   /* Use a control ping for synchronization */
12973   MPING (CONTROL_PING, mp_ping);
12974   S (mp_ping);
12975
12976   W (ret);
12977   return ret;
12978 }
12979
12980
12981 static int
12982 api_interface_name_renumber (vat_main_t * vam)
12983 {
12984   unformat_input_t *line_input = vam->input;
12985   vl_api_interface_name_renumber_t *mp;
12986   u32 sw_if_index = ~0;
12987   u32 new_show_dev_instance = ~0;
12988   int ret;
12989
12990   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12991     {
12992       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12993                     &sw_if_index))
12994         ;
12995       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12996         ;
12997       else if (unformat (line_input, "new_show_dev_instance %d",
12998                          &new_show_dev_instance))
12999         ;
13000       else
13001         break;
13002     }
13003
13004   if (sw_if_index == ~0)
13005     {
13006       errmsg ("missing interface name or sw_if_index");
13007       return -99;
13008     }
13009
13010   if (new_show_dev_instance == ~0)
13011     {
13012       errmsg ("missing new_show_dev_instance");
13013       return -99;
13014     }
13015
13016   M (INTERFACE_NAME_RENUMBER, mp);
13017
13018   mp->sw_if_index = ntohl (sw_if_index);
13019   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13020
13021   S (mp);
13022   W (ret);
13023   return ret;
13024 }
13025
13026 static int
13027 api_want_l2_macs_events (vat_main_t * vam)
13028 {
13029   unformat_input_t *line_input = vam->input;
13030   vl_api_want_l2_macs_events_t *mp;
13031   u8 enable_disable = 1;
13032   u32 scan_delay = 0;
13033   u32 max_macs_in_event = 0;
13034   u32 learn_limit = 0;
13035   int ret;
13036
13037   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13038     {
13039       if (unformat (line_input, "learn-limit %d", &learn_limit))
13040         ;
13041       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13042         ;
13043       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13044         ;
13045       else if (unformat (line_input, "disable"))
13046         enable_disable = 0;
13047       else
13048         break;
13049     }
13050
13051   M (WANT_L2_MACS_EVENTS, mp);
13052   mp->enable_disable = enable_disable;
13053   mp->pid = htonl (getpid ());
13054   mp->learn_limit = htonl (learn_limit);
13055   mp->scan_delay = (u8) scan_delay;
13056   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13057   S (mp);
13058   W (ret);
13059   return ret;
13060 }
13061
13062 static int
13063 api_input_acl_set_interface (vat_main_t * vam)
13064 {
13065   unformat_input_t *i = vam->input;
13066   vl_api_input_acl_set_interface_t *mp;
13067   u32 sw_if_index;
13068   int sw_if_index_set;
13069   u32 ip4_table_index = ~0;
13070   u32 ip6_table_index = ~0;
13071   u32 l2_table_index = ~0;
13072   u8 is_add = 1;
13073   int ret;
13074
13075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13076     {
13077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13078         sw_if_index_set = 1;
13079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13080         sw_if_index_set = 1;
13081       else if (unformat (i, "del"))
13082         is_add = 0;
13083       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13084         ;
13085       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13086         ;
13087       else if (unformat (i, "l2-table %d", &l2_table_index))
13088         ;
13089       else
13090         {
13091           clib_warning ("parse error '%U'", format_unformat_error, i);
13092           return -99;
13093         }
13094     }
13095
13096   if (sw_if_index_set == 0)
13097     {
13098       errmsg ("missing interface name or sw_if_index");
13099       return -99;
13100     }
13101
13102   M (INPUT_ACL_SET_INTERFACE, mp);
13103
13104   mp->sw_if_index = ntohl (sw_if_index);
13105   mp->ip4_table_index = ntohl (ip4_table_index);
13106   mp->ip6_table_index = ntohl (ip6_table_index);
13107   mp->l2_table_index = ntohl (l2_table_index);
13108   mp->is_add = is_add;
13109
13110   S (mp);
13111   W (ret);
13112   return ret;
13113 }
13114
13115 static int
13116 api_output_acl_set_interface (vat_main_t * vam)
13117 {
13118   unformat_input_t *i = vam->input;
13119   vl_api_output_acl_set_interface_t *mp;
13120   u32 sw_if_index;
13121   int sw_if_index_set;
13122   u32 ip4_table_index = ~0;
13123   u32 ip6_table_index = ~0;
13124   u32 l2_table_index = ~0;
13125   u8 is_add = 1;
13126   int ret;
13127
13128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13129     {
13130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13131         sw_if_index_set = 1;
13132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13133         sw_if_index_set = 1;
13134       else if (unformat (i, "del"))
13135         is_add = 0;
13136       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13137         ;
13138       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13139         ;
13140       else if (unformat (i, "l2-table %d", &l2_table_index))
13141         ;
13142       else
13143         {
13144           clib_warning ("parse error '%U'", format_unformat_error, i);
13145           return -99;
13146         }
13147     }
13148
13149   if (sw_if_index_set == 0)
13150     {
13151       errmsg ("missing interface name or sw_if_index");
13152       return -99;
13153     }
13154
13155   M (OUTPUT_ACL_SET_INTERFACE, mp);
13156
13157   mp->sw_if_index = ntohl (sw_if_index);
13158   mp->ip4_table_index = ntohl (ip4_table_index);
13159   mp->ip6_table_index = ntohl (ip6_table_index);
13160   mp->l2_table_index = ntohl (l2_table_index);
13161   mp->is_add = is_add;
13162
13163   S (mp);
13164   W (ret);
13165   return ret;
13166 }
13167
13168 static int
13169 api_ip_address_dump (vat_main_t * vam)
13170 {
13171   unformat_input_t *i = vam->input;
13172   vl_api_ip_address_dump_t *mp;
13173   vl_api_control_ping_t *mp_ping;
13174   u32 sw_if_index = ~0;
13175   u8 sw_if_index_set = 0;
13176   u8 ipv4_set = 0;
13177   u8 ipv6_set = 0;
13178   int ret;
13179
13180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13181     {
13182       if (unformat (i, "sw_if_index %d", &sw_if_index))
13183         sw_if_index_set = 1;
13184       else
13185         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13186         sw_if_index_set = 1;
13187       else if (unformat (i, "ipv4"))
13188         ipv4_set = 1;
13189       else if (unformat (i, "ipv6"))
13190         ipv6_set = 1;
13191       else
13192         break;
13193     }
13194
13195   if (ipv4_set && ipv6_set)
13196     {
13197       errmsg ("ipv4 and ipv6 flags cannot be both set");
13198       return -99;
13199     }
13200
13201   if ((!ipv4_set) && (!ipv6_set))
13202     {
13203       errmsg ("no ipv4 nor ipv6 flag set");
13204       return -99;
13205     }
13206
13207   if (sw_if_index_set == 0)
13208     {
13209       errmsg ("missing interface name or sw_if_index");
13210       return -99;
13211     }
13212
13213   vam->current_sw_if_index = sw_if_index;
13214   vam->is_ipv6 = ipv6_set;
13215
13216   M (IP_ADDRESS_DUMP, mp);
13217   mp->sw_if_index = ntohl (sw_if_index);
13218   mp->is_ipv6 = ipv6_set;
13219   S (mp);
13220
13221   /* Use a control ping for synchronization */
13222   MPING (CONTROL_PING, mp_ping);
13223   S (mp_ping);
13224
13225   W (ret);
13226   return ret;
13227 }
13228
13229 static int
13230 api_ip_dump (vat_main_t * vam)
13231 {
13232   vl_api_ip_dump_t *mp;
13233   vl_api_control_ping_t *mp_ping;
13234   unformat_input_t *in = vam->input;
13235   int ipv4_set = 0;
13236   int ipv6_set = 0;
13237   int is_ipv6;
13238   int i;
13239   int ret;
13240
13241   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13242     {
13243       if (unformat (in, "ipv4"))
13244         ipv4_set = 1;
13245       else if (unformat (in, "ipv6"))
13246         ipv6_set = 1;
13247       else
13248         break;
13249     }
13250
13251   if (ipv4_set && ipv6_set)
13252     {
13253       errmsg ("ipv4 and ipv6 flags cannot be both set");
13254       return -99;
13255     }
13256
13257   if ((!ipv4_set) && (!ipv6_set))
13258     {
13259       errmsg ("no ipv4 nor ipv6 flag set");
13260       return -99;
13261     }
13262
13263   is_ipv6 = ipv6_set;
13264   vam->is_ipv6 = is_ipv6;
13265
13266   /* free old data */
13267   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13268     {
13269       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13270     }
13271   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13272
13273   M (IP_DUMP, mp);
13274   mp->is_ipv6 = ipv6_set;
13275   S (mp);
13276
13277   /* Use a control ping for synchronization */
13278   MPING (CONTROL_PING, mp_ping);
13279   S (mp_ping);
13280
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static int
13286 api_ipsec_spd_add_del (vat_main_t * vam)
13287 {
13288   unformat_input_t *i = vam->input;
13289   vl_api_ipsec_spd_add_del_t *mp;
13290   u32 spd_id = ~0;
13291   u8 is_add = 1;
13292   int ret;
13293
13294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13295     {
13296       if (unformat (i, "spd_id %d", &spd_id))
13297         ;
13298       else if (unformat (i, "del"))
13299         is_add = 0;
13300       else
13301         {
13302           clib_warning ("parse error '%U'", format_unformat_error, i);
13303           return -99;
13304         }
13305     }
13306   if (spd_id == ~0)
13307     {
13308       errmsg ("spd_id must be set");
13309       return -99;
13310     }
13311
13312   M (IPSEC_SPD_ADD_DEL, mp);
13313
13314   mp->spd_id = ntohl (spd_id);
13315   mp->is_add = is_add;
13316
13317   S (mp);
13318   W (ret);
13319   return ret;
13320 }
13321
13322 static int
13323 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13324 {
13325   unformat_input_t *i = vam->input;
13326   vl_api_ipsec_interface_add_del_spd_t *mp;
13327   u32 sw_if_index;
13328   u8 sw_if_index_set = 0;
13329   u32 spd_id = (u32) ~ 0;
13330   u8 is_add = 1;
13331   int ret;
13332
13333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13334     {
13335       if (unformat (i, "del"))
13336         is_add = 0;
13337       else if (unformat (i, "spd_id %d", &spd_id))
13338         ;
13339       else
13340         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13341         sw_if_index_set = 1;
13342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13343         sw_if_index_set = 1;
13344       else
13345         {
13346           clib_warning ("parse error '%U'", format_unformat_error, i);
13347           return -99;
13348         }
13349
13350     }
13351
13352   if (spd_id == (u32) ~ 0)
13353     {
13354       errmsg ("spd_id must be set");
13355       return -99;
13356     }
13357
13358   if (sw_if_index_set == 0)
13359     {
13360       errmsg ("missing interface name or sw_if_index");
13361       return -99;
13362     }
13363
13364   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13365
13366   mp->spd_id = ntohl (spd_id);
13367   mp->sw_if_index = ntohl (sw_if_index);
13368   mp->is_add = is_add;
13369
13370   S (mp);
13371   W (ret);
13372   return ret;
13373 }
13374
13375 static int
13376 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13377 {
13378   unformat_input_t *i = vam->input;
13379   vl_api_ipsec_spd_entry_add_del_t *mp;
13380   u8 is_add = 1, is_outbound = 0;
13381   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13382   i32 priority = 0;
13383   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13384   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13385   vl_api_address_t laddr_start = { }, laddr_stop =
13386   {
13387   }, raddr_start =
13388   {
13389   }, raddr_stop =
13390   {
13391   };
13392   int ret;
13393
13394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13395     {
13396       if (unformat (i, "del"))
13397         is_add = 0;
13398       if (unformat (i, "outbound"))
13399         is_outbound = 1;
13400       if (unformat (i, "inbound"))
13401         is_outbound = 0;
13402       else if (unformat (i, "spd_id %d", &spd_id))
13403         ;
13404       else if (unformat (i, "sa_id %d", &sa_id))
13405         ;
13406       else if (unformat (i, "priority %d", &priority))
13407         ;
13408       else if (unformat (i, "protocol %d", &protocol))
13409         ;
13410       else if (unformat (i, "lport_start %d", &lport_start))
13411         ;
13412       else if (unformat (i, "lport_stop %d", &lport_stop))
13413         ;
13414       else if (unformat (i, "rport_start %d", &rport_start))
13415         ;
13416       else if (unformat (i, "rport_stop %d", &rport_stop))
13417         ;
13418       else if (unformat (i, "laddr_start %U",
13419                          unformat_vl_api_address, &laddr_start))
13420         ;
13421       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13422                          &laddr_stop))
13423         ;
13424       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13425                          &raddr_start))
13426         ;
13427       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13428                          &raddr_stop))
13429         ;
13430       else
13431         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13432         {
13433           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13434             {
13435               clib_warning ("unsupported action: 'resolve'");
13436               return -99;
13437             }
13438         }
13439       else
13440         {
13441           clib_warning ("parse error '%U'", format_unformat_error, i);
13442           return -99;
13443         }
13444
13445     }
13446
13447   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13448
13449   mp->is_add = is_add;
13450
13451   mp->entry.spd_id = ntohl (spd_id);
13452   mp->entry.priority = ntohl (priority);
13453   mp->entry.is_outbound = is_outbound;
13454
13455   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13456                sizeof (vl_api_address_t));
13457   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13458                sizeof (vl_api_address_t));
13459   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13460                sizeof (vl_api_address_t));
13461   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13462                sizeof (vl_api_address_t));
13463
13464   mp->entry.protocol = (u8) protocol;
13465   mp->entry.local_port_start = ntohs ((u16) lport_start);
13466   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13467   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13468   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13469   mp->entry.policy = (u8) policy;
13470   mp->entry.sa_id = ntohl (sa_id);
13471
13472   S (mp);
13473   W (ret);
13474   return ret;
13475 }
13476
13477 static int
13478 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13479 {
13480   unformat_input_t *i = vam->input;
13481   vl_api_ipsec_sad_entry_add_del_t *mp;
13482   u32 sad_id = 0, spi = 0;
13483   u8 *ck = 0, *ik = 0;
13484   u8 is_add = 1;
13485
13486   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13487   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13488   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13489   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13490   vl_api_address_t tun_src, tun_dst;
13491   int ret;
13492
13493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13494     {
13495       if (unformat (i, "del"))
13496         is_add = 0;
13497       else if (unformat (i, "sad_id %d", &sad_id))
13498         ;
13499       else if (unformat (i, "spi %d", &spi))
13500         ;
13501       else if (unformat (i, "esp"))
13502         protocol = IPSEC_API_PROTO_ESP;
13503       else
13504         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13505         {
13506           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13507           if (ADDRESS_IP6 == tun_src.af)
13508             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13509         }
13510       else
13511         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13512         {
13513           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13514           if (ADDRESS_IP6 == tun_src.af)
13515             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13516         }
13517       else
13518         if (unformat (i, "crypto_alg %U",
13519                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13520         ;
13521       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13522         ;
13523       else if (unformat (i, "integ_alg %U",
13524                          unformat_ipsec_api_integ_alg, &integ_alg))
13525         ;
13526       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13527         ;
13528       else
13529         {
13530           clib_warning ("parse error '%U'", format_unformat_error, i);
13531           return -99;
13532         }
13533
13534     }
13535
13536   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13537
13538   mp->is_add = is_add;
13539   mp->entry.sad_id = ntohl (sad_id);
13540   mp->entry.protocol = protocol;
13541   mp->entry.spi = ntohl (spi);
13542   mp->entry.flags = flags;
13543
13544   mp->entry.crypto_algorithm = crypto_alg;
13545   mp->entry.integrity_algorithm = integ_alg;
13546   mp->entry.crypto_key.length = vec_len (ck);
13547   mp->entry.integrity_key.length = vec_len (ik);
13548
13549   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13550     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13551
13552   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13553     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13554
13555   if (ck)
13556     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13557   if (ik)
13558     clib_memcpy (mp->entry.integrity_key.data, ik,
13559                  mp->entry.integrity_key.length);
13560
13561   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13562     {
13563       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13564                    sizeof (mp->entry.tunnel_src));
13565       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13566                    sizeof (mp->entry.tunnel_dst));
13567     }
13568
13569   S (mp);
13570   W (ret);
13571   return ret;
13572 }
13573
13574 static int
13575 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13576 {
13577   unformat_input_t *i = vam->input;
13578   vl_api_ipsec_tunnel_if_add_del_t *mp;
13579   u32 local_spi = 0, remote_spi = 0;
13580   u32 crypto_alg = 0, integ_alg = 0;
13581   u8 *lck = NULL, *rck = NULL;
13582   u8 *lik = NULL, *rik = NULL;
13583   vl_api_address_t local_ip = { 0 };
13584   vl_api_address_t remote_ip = { 0 };
13585   f64 before = 0;
13586   u8 is_add = 1;
13587   u8 esn = 0;
13588   u8 anti_replay = 0;
13589   u8 renumber = 0;
13590   u32 instance = ~0;
13591   u32 count = 1, jj;
13592   int ret = -1;
13593
13594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13595     {
13596       if (unformat (i, "del"))
13597         is_add = 0;
13598       else if (unformat (i, "esn"))
13599         esn = 1;
13600       else if (unformat (i, "anti-replay"))
13601         anti_replay = 1;
13602       else if (unformat (i, "count %d", &count))
13603         ;
13604       else if (unformat (i, "local_spi %d", &local_spi))
13605         ;
13606       else if (unformat (i, "remote_spi %d", &remote_spi))
13607         ;
13608       else
13609         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13610         ;
13611       else
13612         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13613         ;
13614       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13615         ;
13616       else
13617         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13618         ;
13619       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13620         ;
13621       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13622         ;
13623       else
13624         if (unformat
13625             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13626         {
13627           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13628             {
13629               errmsg ("unsupported crypto-alg: '%U'\n",
13630                       format_ipsec_crypto_alg, crypto_alg);
13631               return -99;
13632             }
13633         }
13634       else
13635         if (unformat
13636             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13637         {
13638           if (integ_alg >= IPSEC_INTEG_N_ALG)
13639             {
13640               errmsg ("unsupported integ-alg: '%U'\n",
13641                       format_ipsec_integ_alg, integ_alg);
13642               return -99;
13643             }
13644         }
13645       else if (unformat (i, "instance %u", &instance))
13646         renumber = 1;
13647       else
13648         {
13649           errmsg ("parse error '%U'\n", format_unformat_error, i);
13650           return -99;
13651         }
13652     }
13653
13654   if (count > 1)
13655     {
13656       /* Turn on async mode */
13657       vam->async_mode = 1;
13658       vam->async_errors = 0;
13659       before = vat_time_now (vam);
13660     }
13661
13662   for (jj = 0; jj < count; jj++)
13663     {
13664       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13665
13666       mp->is_add = is_add;
13667       mp->esn = esn;
13668       mp->anti_replay = anti_replay;
13669
13670       if (jj > 0)
13671         increment_address (&remote_ip);
13672
13673       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13674       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13675
13676       mp->local_spi = htonl (local_spi + jj);
13677       mp->remote_spi = htonl (remote_spi + jj);
13678       mp->crypto_alg = (u8) crypto_alg;
13679
13680       mp->local_crypto_key_len = 0;
13681       if (lck)
13682         {
13683           mp->local_crypto_key_len = vec_len (lck);
13684           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13685             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13686           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13687         }
13688
13689       mp->remote_crypto_key_len = 0;
13690       if (rck)
13691         {
13692           mp->remote_crypto_key_len = vec_len (rck);
13693           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13694             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13695           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13696         }
13697
13698       mp->integ_alg = (u8) integ_alg;
13699
13700       mp->local_integ_key_len = 0;
13701       if (lik)
13702         {
13703           mp->local_integ_key_len = vec_len (lik);
13704           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13705             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13706           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13707         }
13708
13709       mp->remote_integ_key_len = 0;
13710       if (rik)
13711         {
13712           mp->remote_integ_key_len = vec_len (rik);
13713           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13714             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13715           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13716         }
13717
13718       if (renumber)
13719         {
13720           mp->renumber = renumber;
13721           mp->show_instance = ntohl (instance);
13722         }
13723       S (mp);
13724     }
13725
13726   /* When testing multiple add/del ops, use a control-ping to sync */
13727   if (count > 1)
13728     {
13729       vl_api_control_ping_t *mp_ping;
13730       f64 after;
13731       f64 timeout;
13732
13733       /* Shut off async mode */
13734       vam->async_mode = 0;
13735
13736       MPING (CONTROL_PING, mp_ping);
13737       S (mp_ping);
13738
13739       timeout = vat_time_now (vam) + 1.0;
13740       while (vat_time_now (vam) < timeout)
13741         if (vam->result_ready == 1)
13742           goto out;
13743       vam->retval = -99;
13744
13745     out:
13746       if (vam->retval == -99)
13747         errmsg ("timeout");
13748
13749       if (vam->async_errors > 0)
13750         {
13751           errmsg ("%d asynchronous errors", vam->async_errors);
13752           vam->retval = -98;
13753         }
13754       vam->async_errors = 0;
13755       after = vat_time_now (vam);
13756
13757       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13758       if (jj > 0)
13759         count = jj;
13760
13761       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13762              count, after - before, count / (after - before));
13763     }
13764   else
13765     {
13766       /* Wait for a reply... */
13767       W (ret);
13768       return ret;
13769     }
13770
13771   return ret;
13772 }
13773
13774 static void
13775 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13776 {
13777   vat_main_t *vam = &vat_main;
13778
13779   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13780          "crypto_key %U integ_alg %u integ_key %U flags %x "
13781          "tunnel_src_addr %U tunnel_dst_addr %U "
13782          "salt %u seq_outbound %lu last_seq_inbound %lu "
13783          "replay_window %lu\n",
13784          ntohl (mp->entry.sad_id),
13785          ntohl (mp->sw_if_index),
13786          ntohl (mp->entry.spi),
13787          ntohl (mp->entry.protocol),
13788          ntohl (mp->entry.crypto_algorithm),
13789          format_hex_bytes, mp->entry.crypto_key.data,
13790          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13791          format_hex_bytes, mp->entry.integrity_key.data,
13792          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13793          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13794          &mp->entry.tunnel_dst, ntohl (mp->salt),
13795          clib_net_to_host_u64 (mp->seq_outbound),
13796          clib_net_to_host_u64 (mp->last_seq_inbound),
13797          clib_net_to_host_u64 (mp->replay_window));
13798 }
13799
13800 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13801 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13802
13803 static void vl_api_ipsec_sa_details_t_handler_json
13804   (vl_api_ipsec_sa_details_t * mp)
13805 {
13806   vat_main_t *vam = &vat_main;
13807   vat_json_node_t *node = NULL;
13808   vl_api_ipsec_sad_flags_t flags;
13809
13810   if (VAT_JSON_ARRAY != vam->json_tree.type)
13811     {
13812       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13813       vat_json_init_array (&vam->json_tree);
13814     }
13815   node = vat_json_array_add (&vam->json_tree);
13816
13817   vat_json_init_object (node);
13818   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13819   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13820   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13821   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13822   vat_json_object_add_uint (node, "crypto_alg",
13823                             ntohl (mp->entry.crypto_algorithm));
13824   vat_json_object_add_uint (node, "integ_alg",
13825                             ntohl (mp->entry.integrity_algorithm));
13826   flags = ntohl (mp->entry.flags);
13827   vat_json_object_add_uint (node, "use_esn",
13828                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13829   vat_json_object_add_uint (node, "use_anti_replay",
13830                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13831   vat_json_object_add_uint (node, "is_tunnel",
13832                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13833   vat_json_object_add_uint (node, "is_tunnel_ip6",
13834                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13835   vat_json_object_add_uint (node, "udp_encap",
13836                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13837   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13838                              mp->entry.crypto_key.length);
13839   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13840                              mp->entry.integrity_key.length);
13841   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13842   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13843   vat_json_object_add_uint (node, "replay_window",
13844                             clib_net_to_host_u64 (mp->replay_window));
13845 }
13846
13847 static int
13848 api_ipsec_sa_dump (vat_main_t * vam)
13849 {
13850   unformat_input_t *i = vam->input;
13851   vl_api_ipsec_sa_dump_t *mp;
13852   vl_api_control_ping_t *mp_ping;
13853   u32 sa_id = ~0;
13854   int ret;
13855
13856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13857     {
13858       if (unformat (i, "sa_id %d", &sa_id))
13859         ;
13860       else
13861         {
13862           clib_warning ("parse error '%U'", format_unformat_error, i);
13863           return -99;
13864         }
13865     }
13866
13867   M (IPSEC_SA_DUMP, mp);
13868
13869   mp->sa_id = ntohl (sa_id);
13870
13871   S (mp);
13872
13873   /* Use a control ping for synchronization */
13874   M (CONTROL_PING, mp_ping);
13875   S (mp_ping);
13876
13877   W (ret);
13878   return ret;
13879 }
13880
13881 static int
13882 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13883 {
13884   unformat_input_t *i = vam->input;
13885   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13886   u32 sw_if_index = ~0;
13887   u32 sa_id = ~0;
13888   u8 is_outbound = (u8) ~ 0;
13889   int ret;
13890
13891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13892     {
13893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13894         ;
13895       else if (unformat (i, "sa_id %d", &sa_id))
13896         ;
13897       else if (unformat (i, "outbound"))
13898         is_outbound = 1;
13899       else if (unformat (i, "inbound"))
13900         is_outbound = 0;
13901       else
13902         {
13903           clib_warning ("parse error '%U'", format_unformat_error, i);
13904           return -99;
13905         }
13906     }
13907
13908   if (sw_if_index == ~0)
13909     {
13910       errmsg ("interface must be specified");
13911       return -99;
13912     }
13913
13914   if (sa_id == ~0)
13915     {
13916       errmsg ("SA ID must be specified");
13917       return -99;
13918     }
13919
13920   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13921
13922   mp->sw_if_index = htonl (sw_if_index);
13923   mp->sa_id = htonl (sa_id);
13924   mp->is_outbound = is_outbound;
13925
13926   S (mp);
13927   W (ret);
13928
13929   return ret;
13930 }
13931
13932 static int
13933 api_get_first_msg_id (vat_main_t * vam)
13934 {
13935   vl_api_get_first_msg_id_t *mp;
13936   unformat_input_t *i = vam->input;
13937   u8 *name;
13938   u8 name_set = 0;
13939   int ret;
13940
13941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13942     {
13943       if (unformat (i, "client %s", &name))
13944         name_set = 1;
13945       else
13946         break;
13947     }
13948
13949   if (name_set == 0)
13950     {
13951       errmsg ("missing client name");
13952       return -99;
13953     }
13954   vec_add1 (name, 0);
13955
13956   if (vec_len (name) > 63)
13957     {
13958       errmsg ("client name too long");
13959       return -99;
13960     }
13961
13962   M (GET_FIRST_MSG_ID, mp);
13963   clib_memcpy (mp->name, name, vec_len (name));
13964   S (mp);
13965   W (ret);
13966   return ret;
13967 }
13968
13969 static int
13970 api_cop_interface_enable_disable (vat_main_t * vam)
13971 {
13972   unformat_input_t *line_input = vam->input;
13973   vl_api_cop_interface_enable_disable_t *mp;
13974   u32 sw_if_index = ~0;
13975   u8 enable_disable = 1;
13976   int ret;
13977
13978   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13979     {
13980       if (unformat (line_input, "disable"))
13981         enable_disable = 0;
13982       if (unformat (line_input, "enable"))
13983         enable_disable = 1;
13984       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13985                          vam, &sw_if_index))
13986         ;
13987       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13988         ;
13989       else
13990         break;
13991     }
13992
13993   if (sw_if_index == ~0)
13994     {
13995       errmsg ("missing interface name or sw_if_index");
13996       return -99;
13997     }
13998
13999   /* Construct the API message */
14000   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14001   mp->sw_if_index = ntohl (sw_if_index);
14002   mp->enable_disable = enable_disable;
14003
14004   /* send it... */
14005   S (mp);
14006   /* Wait for the reply */
14007   W (ret);
14008   return ret;
14009 }
14010
14011 static int
14012 api_cop_whitelist_enable_disable (vat_main_t * vam)
14013 {
14014   unformat_input_t *line_input = vam->input;
14015   vl_api_cop_whitelist_enable_disable_t *mp;
14016   u32 sw_if_index = ~0;
14017   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14018   u32 fib_id = 0;
14019   int ret;
14020
14021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (line_input, "ip4"))
14024         ip4 = 1;
14025       else if (unformat (line_input, "ip6"))
14026         ip6 = 1;
14027       else if (unformat (line_input, "default"))
14028         default_cop = 1;
14029       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14030                          vam, &sw_if_index))
14031         ;
14032       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14033         ;
14034       else if (unformat (line_input, "fib-id %d", &fib_id))
14035         ;
14036       else
14037         break;
14038     }
14039
14040   if (sw_if_index == ~0)
14041     {
14042       errmsg ("missing interface name or sw_if_index");
14043       return -99;
14044     }
14045
14046   /* Construct the API message */
14047   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14048   mp->sw_if_index = ntohl (sw_if_index);
14049   mp->fib_id = ntohl (fib_id);
14050   mp->ip4 = ip4;
14051   mp->ip6 = ip6;
14052   mp->default_cop = default_cop;
14053
14054   /* send it... */
14055   S (mp);
14056   /* Wait for the reply */
14057   W (ret);
14058   return ret;
14059 }
14060
14061 static int
14062 api_get_node_graph (vat_main_t * vam)
14063 {
14064   vl_api_get_node_graph_t *mp;
14065   int ret;
14066
14067   M (GET_NODE_GRAPH, mp);
14068
14069   /* send it... */
14070   S (mp);
14071   /* Wait for the reply */
14072   W (ret);
14073   return ret;
14074 }
14075
14076 /* *INDENT-OFF* */
14077 /** Used for parsing LISP eids */
14078 typedef CLIB_PACKED(struct{
14079   u8 addr[16];   /**< eid address */
14080   u32 len;       /**< prefix length if IP */
14081   u8 type;      /**< type of eid */
14082 }) lisp_eid_vat_t;
14083 /* *INDENT-ON* */
14084
14085 static uword
14086 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14087 {
14088   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14089
14090   clib_memset (a, 0, sizeof (a[0]));
14091
14092   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14093     {
14094       a->type = 0;              /* ipv4 type */
14095     }
14096   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14097     {
14098       a->type = 1;              /* ipv6 type */
14099     }
14100   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14101     {
14102       a->type = 2;              /* mac type */
14103     }
14104   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14105     {
14106       a->type = 3;              /* NSH type */
14107       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14108       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14109     }
14110   else
14111     {
14112       return 0;
14113     }
14114
14115   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14116     {
14117       return 0;
14118     }
14119
14120   return 1;
14121 }
14122
14123 static int
14124 lisp_eid_size_vat (u8 type)
14125 {
14126   switch (type)
14127     {
14128     case 0:
14129       return 4;
14130     case 1:
14131       return 16;
14132     case 2:
14133       return 6;
14134     case 3:
14135       return 5;
14136     }
14137   return 0;
14138 }
14139
14140 static void
14141 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14142 {
14143   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14144 }
14145
14146 static int
14147 api_one_add_del_locator_set (vat_main_t * vam)
14148 {
14149   unformat_input_t *input = vam->input;
14150   vl_api_one_add_del_locator_set_t *mp;
14151   u8 is_add = 1;
14152   u8 *locator_set_name = NULL;
14153   u8 locator_set_name_set = 0;
14154   vl_api_local_locator_t locator, *locators = 0;
14155   u32 sw_if_index, priority, weight;
14156   u32 data_len = 0;
14157
14158   int ret;
14159   /* Parse args required to build the message */
14160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14161     {
14162       if (unformat (input, "del"))
14163         {
14164           is_add = 0;
14165         }
14166       else if (unformat (input, "locator-set %s", &locator_set_name))
14167         {
14168           locator_set_name_set = 1;
14169         }
14170       else if (unformat (input, "sw_if_index %u p %u w %u",
14171                          &sw_if_index, &priority, &weight))
14172         {
14173           locator.sw_if_index = htonl (sw_if_index);
14174           locator.priority = priority;
14175           locator.weight = weight;
14176           vec_add1 (locators, locator);
14177         }
14178       else
14179         if (unformat
14180             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14181              &sw_if_index, &priority, &weight))
14182         {
14183           locator.sw_if_index = htonl (sw_if_index);
14184           locator.priority = priority;
14185           locator.weight = weight;
14186           vec_add1 (locators, locator);
14187         }
14188       else
14189         break;
14190     }
14191
14192   if (locator_set_name_set == 0)
14193     {
14194       errmsg ("missing locator-set name");
14195       vec_free (locators);
14196       return -99;
14197     }
14198
14199   if (vec_len (locator_set_name) > 64)
14200     {
14201       errmsg ("locator-set name too long");
14202       vec_free (locator_set_name);
14203       vec_free (locators);
14204       return -99;
14205     }
14206   vec_add1 (locator_set_name, 0);
14207
14208   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14209
14210   /* Construct the API message */
14211   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14212
14213   mp->is_add = is_add;
14214   clib_memcpy (mp->locator_set_name, locator_set_name,
14215                vec_len (locator_set_name));
14216   vec_free (locator_set_name);
14217
14218   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14219   if (locators)
14220     clib_memcpy (mp->locators, locators, data_len);
14221   vec_free (locators);
14222
14223   /* send it... */
14224   S (mp);
14225
14226   /* Wait for a reply... */
14227   W (ret);
14228   return ret;
14229 }
14230
14231 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14232
14233 static int
14234 api_one_add_del_locator (vat_main_t * vam)
14235 {
14236   unformat_input_t *input = vam->input;
14237   vl_api_one_add_del_locator_t *mp;
14238   u32 tmp_if_index = ~0;
14239   u32 sw_if_index = ~0;
14240   u8 sw_if_index_set = 0;
14241   u8 sw_if_index_if_name_set = 0;
14242   u32 priority = ~0;
14243   u8 priority_set = 0;
14244   u32 weight = ~0;
14245   u8 weight_set = 0;
14246   u8 is_add = 1;
14247   u8 *locator_set_name = NULL;
14248   u8 locator_set_name_set = 0;
14249   int ret;
14250
14251   /* Parse args required to build the message */
14252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14253     {
14254       if (unformat (input, "del"))
14255         {
14256           is_add = 0;
14257         }
14258       else if (unformat (input, "locator-set %s", &locator_set_name))
14259         {
14260           locator_set_name_set = 1;
14261         }
14262       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14263                          &tmp_if_index))
14264         {
14265           sw_if_index_if_name_set = 1;
14266           sw_if_index = tmp_if_index;
14267         }
14268       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14269         {
14270           sw_if_index_set = 1;
14271           sw_if_index = tmp_if_index;
14272         }
14273       else if (unformat (input, "p %d", &priority))
14274         {
14275           priority_set = 1;
14276         }
14277       else if (unformat (input, "w %d", &weight))
14278         {
14279           weight_set = 1;
14280         }
14281       else
14282         break;
14283     }
14284
14285   if (locator_set_name_set == 0)
14286     {
14287       errmsg ("missing locator-set name");
14288       return -99;
14289     }
14290
14291   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14292     {
14293       errmsg ("missing sw_if_index");
14294       vec_free (locator_set_name);
14295       return -99;
14296     }
14297
14298   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14299     {
14300       errmsg ("cannot use both params interface name and sw_if_index");
14301       vec_free (locator_set_name);
14302       return -99;
14303     }
14304
14305   if (priority_set == 0)
14306     {
14307       errmsg ("missing locator-set priority");
14308       vec_free (locator_set_name);
14309       return -99;
14310     }
14311
14312   if (weight_set == 0)
14313     {
14314       errmsg ("missing locator-set weight");
14315       vec_free (locator_set_name);
14316       return -99;
14317     }
14318
14319   if (vec_len (locator_set_name) > 64)
14320     {
14321       errmsg ("locator-set name too long");
14322       vec_free (locator_set_name);
14323       return -99;
14324     }
14325   vec_add1 (locator_set_name, 0);
14326
14327   /* Construct the API message */
14328   M (ONE_ADD_DEL_LOCATOR, mp);
14329
14330   mp->is_add = is_add;
14331   mp->sw_if_index = ntohl (sw_if_index);
14332   mp->priority = priority;
14333   mp->weight = weight;
14334   clib_memcpy (mp->locator_set_name, locator_set_name,
14335                vec_len (locator_set_name));
14336   vec_free (locator_set_name);
14337
14338   /* send it... */
14339   S (mp);
14340
14341   /* Wait for a reply... */
14342   W (ret);
14343   return ret;
14344 }
14345
14346 #define api_lisp_add_del_locator api_one_add_del_locator
14347
14348 uword
14349 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14350 {
14351   u32 *key_id = va_arg (*args, u32 *);
14352   u8 *s = 0;
14353
14354   if (unformat (input, "%s", &s))
14355     {
14356       if (!strcmp ((char *) s, "sha1"))
14357         key_id[0] = HMAC_SHA_1_96;
14358       else if (!strcmp ((char *) s, "sha256"))
14359         key_id[0] = HMAC_SHA_256_128;
14360       else
14361         {
14362           clib_warning ("invalid key_id: '%s'", s);
14363           key_id[0] = HMAC_NO_KEY;
14364         }
14365     }
14366   else
14367     return 0;
14368
14369   vec_free (s);
14370   return 1;
14371 }
14372
14373 static int
14374 api_one_add_del_local_eid (vat_main_t * vam)
14375 {
14376   unformat_input_t *input = vam->input;
14377   vl_api_one_add_del_local_eid_t *mp;
14378   u8 is_add = 1;
14379   u8 eid_set = 0;
14380   lisp_eid_vat_t _eid, *eid = &_eid;
14381   u8 *locator_set_name = 0;
14382   u8 locator_set_name_set = 0;
14383   u32 vni = 0;
14384   u16 key_id = 0;
14385   u8 *key = 0;
14386   int ret;
14387
14388   /* Parse args required to build the message */
14389   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (input, "del"))
14392         {
14393           is_add = 0;
14394         }
14395       else if (unformat (input, "vni %d", &vni))
14396         {
14397           ;
14398         }
14399       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14400         {
14401           eid_set = 1;
14402         }
14403       else if (unformat (input, "locator-set %s", &locator_set_name))
14404         {
14405           locator_set_name_set = 1;
14406         }
14407       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14408         ;
14409       else if (unformat (input, "secret-key %_%v%_", &key))
14410         ;
14411       else
14412         break;
14413     }
14414
14415   if (locator_set_name_set == 0)
14416     {
14417       errmsg ("missing locator-set name");
14418       return -99;
14419     }
14420
14421   if (0 == eid_set)
14422     {
14423       errmsg ("EID address not set!");
14424       vec_free (locator_set_name);
14425       return -99;
14426     }
14427
14428   if (key && (0 == key_id))
14429     {
14430       errmsg ("invalid key_id!");
14431       return -99;
14432     }
14433
14434   if (vec_len (key) > 64)
14435     {
14436       errmsg ("key too long");
14437       vec_free (key);
14438       return -99;
14439     }
14440
14441   if (vec_len (locator_set_name) > 64)
14442     {
14443       errmsg ("locator-set name too long");
14444       vec_free (locator_set_name);
14445       return -99;
14446     }
14447   vec_add1 (locator_set_name, 0);
14448
14449   /* Construct the API message */
14450   M (ONE_ADD_DEL_LOCAL_EID, mp);
14451
14452   mp->is_add = is_add;
14453   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14454   mp->eid_type = eid->type;
14455   mp->prefix_len = eid->len;
14456   mp->vni = clib_host_to_net_u32 (vni);
14457   mp->key_id = clib_host_to_net_u16 (key_id);
14458   clib_memcpy (mp->locator_set_name, locator_set_name,
14459                vec_len (locator_set_name));
14460   clib_memcpy (mp->key, key, vec_len (key));
14461
14462   vec_free (locator_set_name);
14463   vec_free (key);
14464
14465   /* send it... */
14466   S (mp);
14467
14468   /* Wait for a reply... */
14469   W (ret);
14470   return ret;
14471 }
14472
14473 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14474
14475 static int
14476 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14477 {
14478   u32 dp_table = 0, vni = 0;;
14479   unformat_input_t *input = vam->input;
14480   vl_api_gpe_add_del_fwd_entry_t *mp;
14481   u8 is_add = 1;
14482   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14483   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14484   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14485   u32 action = ~0, w;
14486   ip4_address_t rmt_rloc4, lcl_rloc4;
14487   ip6_address_t rmt_rloc6, lcl_rloc6;
14488   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14489   int ret;
14490
14491   clib_memset (&rloc, 0, sizeof (rloc));
14492
14493   /* Parse args required to build the message */
14494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14495     {
14496       if (unformat (input, "del"))
14497         is_add = 0;
14498       else if (unformat (input, "add"))
14499         is_add = 1;
14500       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14501         {
14502           rmt_eid_set = 1;
14503         }
14504       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14505         {
14506           lcl_eid_set = 1;
14507         }
14508       else if (unformat (input, "vrf %d", &dp_table))
14509         ;
14510       else if (unformat (input, "bd %d", &dp_table))
14511         ;
14512       else if (unformat (input, "vni %d", &vni))
14513         ;
14514       else if (unformat (input, "w %d", &w))
14515         {
14516           if (!curr_rloc)
14517             {
14518               errmsg ("No RLOC configured for setting priority/weight!");
14519               return -99;
14520             }
14521           curr_rloc->weight = w;
14522         }
14523       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14524                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14525         {
14526           rloc.is_ip4 = 1;
14527
14528           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14529           rloc.weight = 0;
14530           vec_add1 (lcl_locs, rloc);
14531
14532           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14533           vec_add1 (rmt_locs, rloc);
14534           /* weight saved in rmt loc */
14535           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14536         }
14537       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14538                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14539         {
14540           rloc.is_ip4 = 0;
14541           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14542           rloc.weight = 0;
14543           vec_add1 (lcl_locs, rloc);
14544
14545           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14546           vec_add1 (rmt_locs, rloc);
14547           /* weight saved in rmt loc */
14548           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14549         }
14550       else if (unformat (input, "action %d", &action))
14551         {
14552           ;
14553         }
14554       else
14555         {
14556           clib_warning ("parse error '%U'", format_unformat_error, input);
14557           return -99;
14558         }
14559     }
14560
14561   if (!rmt_eid_set)
14562     {
14563       errmsg ("remote eid addresses not set");
14564       return -99;
14565     }
14566
14567   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14568     {
14569       errmsg ("eid types don't match");
14570       return -99;
14571     }
14572
14573   if (0 == rmt_locs && (u32) ~ 0 == action)
14574     {
14575       errmsg ("action not set for negative mapping");
14576       return -99;
14577     }
14578
14579   /* Construct the API message */
14580   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14581       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14582
14583   mp->is_add = is_add;
14584   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14585   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14586   mp->eid_type = rmt_eid->type;
14587   mp->dp_table = clib_host_to_net_u32 (dp_table);
14588   mp->vni = clib_host_to_net_u32 (vni);
14589   mp->rmt_len = rmt_eid->len;
14590   mp->lcl_len = lcl_eid->len;
14591   mp->action = action;
14592
14593   if (0 != rmt_locs && 0 != lcl_locs)
14594     {
14595       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14596       clib_memcpy (mp->locs, lcl_locs,
14597                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14598
14599       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14600       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14601                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14602     }
14603   vec_free (lcl_locs);
14604   vec_free (rmt_locs);
14605
14606   /* send it... */
14607   S (mp);
14608
14609   /* Wait for a reply... */
14610   W (ret);
14611   return ret;
14612 }
14613
14614 static int
14615 api_one_add_del_map_server (vat_main_t * vam)
14616 {
14617   unformat_input_t *input = vam->input;
14618   vl_api_one_add_del_map_server_t *mp;
14619   u8 is_add = 1;
14620   u8 ipv4_set = 0;
14621   u8 ipv6_set = 0;
14622   ip4_address_t ipv4;
14623   ip6_address_t ipv6;
14624   int ret;
14625
14626   /* Parse args required to build the message */
14627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (input, "del"))
14630         {
14631           is_add = 0;
14632         }
14633       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14634         {
14635           ipv4_set = 1;
14636         }
14637       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14638         {
14639           ipv6_set = 1;
14640         }
14641       else
14642         break;
14643     }
14644
14645   if (ipv4_set && ipv6_set)
14646     {
14647       errmsg ("both eid v4 and v6 addresses set");
14648       return -99;
14649     }
14650
14651   if (!ipv4_set && !ipv6_set)
14652     {
14653       errmsg ("eid addresses not set");
14654       return -99;
14655     }
14656
14657   /* Construct the API message */
14658   M (ONE_ADD_DEL_MAP_SERVER, mp);
14659
14660   mp->is_add = is_add;
14661   if (ipv6_set)
14662     {
14663       mp->is_ipv6 = 1;
14664       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14665     }
14666   else
14667     {
14668       mp->is_ipv6 = 0;
14669       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14670     }
14671
14672   /* send it... */
14673   S (mp);
14674
14675   /* Wait for a reply... */
14676   W (ret);
14677   return ret;
14678 }
14679
14680 #define api_lisp_add_del_map_server api_one_add_del_map_server
14681
14682 static int
14683 api_one_add_del_map_resolver (vat_main_t * vam)
14684 {
14685   unformat_input_t *input = vam->input;
14686   vl_api_one_add_del_map_resolver_t *mp;
14687   u8 is_add = 1;
14688   u8 ipv4_set = 0;
14689   u8 ipv6_set = 0;
14690   ip4_address_t ipv4;
14691   ip6_address_t ipv6;
14692   int ret;
14693
14694   /* Parse args required to build the message */
14695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14696     {
14697       if (unformat (input, "del"))
14698         {
14699           is_add = 0;
14700         }
14701       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14702         {
14703           ipv4_set = 1;
14704         }
14705       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14706         {
14707           ipv6_set = 1;
14708         }
14709       else
14710         break;
14711     }
14712
14713   if (ipv4_set && ipv6_set)
14714     {
14715       errmsg ("both eid v4 and v6 addresses set");
14716       return -99;
14717     }
14718
14719   if (!ipv4_set && !ipv6_set)
14720     {
14721       errmsg ("eid addresses not set");
14722       return -99;
14723     }
14724
14725   /* Construct the API message */
14726   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14727
14728   mp->is_add = is_add;
14729   if (ipv6_set)
14730     {
14731       mp->is_ipv6 = 1;
14732       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14733     }
14734   else
14735     {
14736       mp->is_ipv6 = 0;
14737       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14738     }
14739
14740   /* send it... */
14741   S (mp);
14742
14743   /* Wait for a reply... */
14744   W (ret);
14745   return ret;
14746 }
14747
14748 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14749
14750 static int
14751 api_lisp_gpe_enable_disable (vat_main_t * vam)
14752 {
14753   unformat_input_t *input = vam->input;
14754   vl_api_gpe_enable_disable_t *mp;
14755   u8 is_set = 0;
14756   u8 is_en = 1;
14757   int ret;
14758
14759   /* Parse args required to build the message */
14760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14761     {
14762       if (unformat (input, "enable"))
14763         {
14764           is_set = 1;
14765           is_en = 1;
14766         }
14767       else if (unformat (input, "disable"))
14768         {
14769           is_set = 1;
14770           is_en = 0;
14771         }
14772       else
14773         break;
14774     }
14775
14776   if (is_set == 0)
14777     {
14778       errmsg ("Value not set");
14779       return -99;
14780     }
14781
14782   /* Construct the API message */
14783   M (GPE_ENABLE_DISABLE, mp);
14784
14785   mp->is_en = is_en;
14786
14787   /* send it... */
14788   S (mp);
14789
14790   /* Wait for a reply... */
14791   W (ret);
14792   return ret;
14793 }
14794
14795 static int
14796 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14797 {
14798   unformat_input_t *input = vam->input;
14799   vl_api_one_rloc_probe_enable_disable_t *mp;
14800   u8 is_set = 0;
14801   u8 is_en = 0;
14802   int ret;
14803
14804   /* Parse args required to build the message */
14805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14806     {
14807       if (unformat (input, "enable"))
14808         {
14809           is_set = 1;
14810           is_en = 1;
14811         }
14812       else if (unformat (input, "disable"))
14813         is_set = 1;
14814       else
14815         break;
14816     }
14817
14818   if (!is_set)
14819     {
14820       errmsg ("Value not set");
14821       return -99;
14822     }
14823
14824   /* Construct the API message */
14825   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14826
14827   mp->is_enabled = is_en;
14828
14829   /* send it... */
14830   S (mp);
14831
14832   /* Wait for a reply... */
14833   W (ret);
14834   return ret;
14835 }
14836
14837 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14838
14839 static int
14840 api_one_map_register_enable_disable (vat_main_t * vam)
14841 {
14842   unformat_input_t *input = vam->input;
14843   vl_api_one_map_register_enable_disable_t *mp;
14844   u8 is_set = 0;
14845   u8 is_en = 0;
14846   int ret;
14847
14848   /* Parse args required to build the message */
14849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14850     {
14851       if (unformat (input, "enable"))
14852         {
14853           is_set = 1;
14854           is_en = 1;
14855         }
14856       else if (unformat (input, "disable"))
14857         is_set = 1;
14858       else
14859         break;
14860     }
14861
14862   if (!is_set)
14863     {
14864       errmsg ("Value not set");
14865       return -99;
14866     }
14867
14868   /* Construct the API message */
14869   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14870
14871   mp->is_enabled = is_en;
14872
14873   /* send it... */
14874   S (mp);
14875
14876   /* Wait for a reply... */
14877   W (ret);
14878   return ret;
14879 }
14880
14881 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14882
14883 static int
14884 api_one_enable_disable (vat_main_t * vam)
14885 {
14886   unformat_input_t *input = vam->input;
14887   vl_api_one_enable_disable_t *mp;
14888   u8 is_set = 0;
14889   u8 is_en = 0;
14890   int ret;
14891
14892   /* Parse args required to build the message */
14893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14894     {
14895       if (unformat (input, "enable"))
14896         {
14897           is_set = 1;
14898           is_en = 1;
14899         }
14900       else if (unformat (input, "disable"))
14901         {
14902           is_set = 1;
14903         }
14904       else
14905         break;
14906     }
14907
14908   if (!is_set)
14909     {
14910       errmsg ("Value not set");
14911       return -99;
14912     }
14913
14914   /* Construct the API message */
14915   M (ONE_ENABLE_DISABLE, mp);
14916
14917   mp->is_en = is_en;
14918
14919   /* send it... */
14920   S (mp);
14921
14922   /* Wait for a reply... */
14923   W (ret);
14924   return ret;
14925 }
14926
14927 #define api_lisp_enable_disable api_one_enable_disable
14928
14929 static int
14930 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14931 {
14932   unformat_input_t *input = vam->input;
14933   vl_api_one_enable_disable_xtr_mode_t *mp;
14934   u8 is_set = 0;
14935   u8 is_en = 0;
14936   int ret;
14937
14938   /* Parse args required to build the message */
14939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14940     {
14941       if (unformat (input, "enable"))
14942         {
14943           is_set = 1;
14944           is_en = 1;
14945         }
14946       else if (unformat (input, "disable"))
14947         {
14948           is_set = 1;
14949         }
14950       else
14951         break;
14952     }
14953
14954   if (!is_set)
14955     {
14956       errmsg ("Value not set");
14957       return -99;
14958     }
14959
14960   /* Construct the API message */
14961   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14962
14963   mp->is_en = is_en;
14964
14965   /* send it... */
14966   S (mp);
14967
14968   /* Wait for a reply... */
14969   W (ret);
14970   return ret;
14971 }
14972
14973 static int
14974 api_one_show_xtr_mode (vat_main_t * vam)
14975 {
14976   vl_api_one_show_xtr_mode_t *mp;
14977   int ret;
14978
14979   /* Construct the API message */
14980   M (ONE_SHOW_XTR_MODE, mp);
14981
14982   /* send it... */
14983   S (mp);
14984
14985   /* Wait for a reply... */
14986   W (ret);
14987   return ret;
14988 }
14989
14990 static int
14991 api_one_enable_disable_pitr_mode (vat_main_t * vam)
14992 {
14993   unformat_input_t *input = vam->input;
14994   vl_api_one_enable_disable_pitr_mode_t *mp;
14995   u8 is_set = 0;
14996   u8 is_en = 0;
14997   int ret;
14998
14999   /* Parse args required to build the message */
15000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15001     {
15002       if (unformat (input, "enable"))
15003         {
15004           is_set = 1;
15005           is_en = 1;
15006         }
15007       else if (unformat (input, "disable"))
15008         {
15009           is_set = 1;
15010         }
15011       else
15012         break;
15013     }
15014
15015   if (!is_set)
15016     {
15017       errmsg ("Value not set");
15018       return -99;
15019     }
15020
15021   /* Construct the API message */
15022   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15023
15024   mp->is_en = is_en;
15025
15026   /* send it... */
15027   S (mp);
15028
15029   /* Wait for a reply... */
15030   W (ret);
15031   return ret;
15032 }
15033
15034 static int
15035 api_one_show_pitr_mode (vat_main_t * vam)
15036 {
15037   vl_api_one_show_pitr_mode_t *mp;
15038   int ret;
15039
15040   /* Construct the API message */
15041   M (ONE_SHOW_PITR_MODE, mp);
15042
15043   /* send it... */
15044   S (mp);
15045
15046   /* Wait for a reply... */
15047   W (ret);
15048   return ret;
15049 }
15050
15051 static int
15052 api_one_enable_disable_petr_mode (vat_main_t * vam)
15053 {
15054   unformat_input_t *input = vam->input;
15055   vl_api_one_enable_disable_petr_mode_t *mp;
15056   u8 is_set = 0;
15057   u8 is_en = 0;
15058   int ret;
15059
15060   /* Parse args required to build the message */
15061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (input, "enable"))
15064         {
15065           is_set = 1;
15066           is_en = 1;
15067         }
15068       else if (unformat (input, "disable"))
15069         {
15070           is_set = 1;
15071         }
15072       else
15073         break;
15074     }
15075
15076   if (!is_set)
15077     {
15078       errmsg ("Value not set");
15079       return -99;
15080     }
15081
15082   /* Construct the API message */
15083   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15084
15085   mp->is_en = is_en;
15086
15087   /* send it... */
15088   S (mp);
15089
15090   /* Wait for a reply... */
15091   W (ret);
15092   return ret;
15093 }
15094
15095 static int
15096 api_one_show_petr_mode (vat_main_t * vam)
15097 {
15098   vl_api_one_show_petr_mode_t *mp;
15099   int ret;
15100
15101   /* Construct the API message */
15102   M (ONE_SHOW_PETR_MODE, mp);
15103
15104   /* send it... */
15105   S (mp);
15106
15107   /* Wait for a reply... */
15108   W (ret);
15109   return ret;
15110 }
15111
15112 static int
15113 api_show_one_map_register_state (vat_main_t * vam)
15114 {
15115   vl_api_show_one_map_register_state_t *mp;
15116   int ret;
15117
15118   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15119
15120   /* send */
15121   S (mp);
15122
15123   /* wait for reply */
15124   W (ret);
15125   return ret;
15126 }
15127
15128 #define api_show_lisp_map_register_state api_show_one_map_register_state
15129
15130 static int
15131 api_show_one_rloc_probe_state (vat_main_t * vam)
15132 {
15133   vl_api_show_one_rloc_probe_state_t *mp;
15134   int ret;
15135
15136   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15137
15138   /* send */
15139   S (mp);
15140
15141   /* wait for reply */
15142   W (ret);
15143   return ret;
15144 }
15145
15146 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15147
15148 static int
15149 api_one_add_del_ndp_entry (vat_main_t * vam)
15150 {
15151   vl_api_one_add_del_ndp_entry_t *mp;
15152   unformat_input_t *input = vam->input;
15153   u8 is_add = 1;
15154   u8 mac_set = 0;
15155   u8 bd_set = 0;
15156   u8 ip_set = 0;
15157   u8 mac[6] = { 0, };
15158   u8 ip6[16] = { 0, };
15159   u32 bd = ~0;
15160   int ret;
15161
15162   /* Parse args required to build the message */
15163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15164     {
15165       if (unformat (input, "del"))
15166         is_add = 0;
15167       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15168         mac_set = 1;
15169       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15170         ip_set = 1;
15171       else if (unformat (input, "bd %d", &bd))
15172         bd_set = 1;
15173       else
15174         {
15175           errmsg ("parse error '%U'", format_unformat_error, input);
15176           return -99;
15177         }
15178     }
15179
15180   if (!bd_set || !ip_set || (!mac_set && is_add))
15181     {
15182       errmsg ("Missing BD, IP or MAC!");
15183       return -99;
15184     }
15185
15186   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15187   mp->is_add = is_add;
15188   clib_memcpy (mp->mac, mac, 6);
15189   mp->bd = clib_host_to_net_u32 (bd);
15190   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15191
15192   /* send */
15193   S (mp);
15194
15195   /* wait for reply */
15196   W (ret);
15197   return ret;
15198 }
15199
15200 static int
15201 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15202 {
15203   vl_api_one_add_del_l2_arp_entry_t *mp;
15204   unformat_input_t *input = vam->input;
15205   u8 is_add = 1;
15206   u8 mac_set = 0;
15207   u8 bd_set = 0;
15208   u8 ip_set = 0;
15209   u8 mac[6] = { 0, };
15210   u32 ip4 = 0, bd = ~0;
15211   int ret;
15212
15213   /* Parse args required to build the message */
15214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15215     {
15216       if (unformat (input, "del"))
15217         is_add = 0;
15218       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15219         mac_set = 1;
15220       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15221         ip_set = 1;
15222       else if (unformat (input, "bd %d", &bd))
15223         bd_set = 1;
15224       else
15225         {
15226           errmsg ("parse error '%U'", format_unformat_error, input);
15227           return -99;
15228         }
15229     }
15230
15231   if (!bd_set || !ip_set || (!mac_set && is_add))
15232     {
15233       errmsg ("Missing BD, IP or MAC!");
15234       return -99;
15235     }
15236
15237   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15238   mp->is_add = is_add;
15239   clib_memcpy (mp->mac, mac, 6);
15240   mp->bd = clib_host_to_net_u32 (bd);
15241   mp->ip4 = ip4;
15242
15243   /* send */
15244   S (mp);
15245
15246   /* wait for reply */
15247   W (ret);
15248   return ret;
15249 }
15250
15251 static int
15252 api_one_ndp_bd_get (vat_main_t * vam)
15253 {
15254   vl_api_one_ndp_bd_get_t *mp;
15255   int ret;
15256
15257   M (ONE_NDP_BD_GET, mp);
15258
15259   /* send */
15260   S (mp);
15261
15262   /* wait for reply */
15263   W (ret);
15264   return ret;
15265 }
15266
15267 static int
15268 api_one_ndp_entries_get (vat_main_t * vam)
15269 {
15270   vl_api_one_ndp_entries_get_t *mp;
15271   unformat_input_t *input = vam->input;
15272   u8 bd_set = 0;
15273   u32 bd = ~0;
15274   int ret;
15275
15276   /* Parse args required to build the message */
15277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15278     {
15279       if (unformat (input, "bd %d", &bd))
15280         bd_set = 1;
15281       else
15282         {
15283           errmsg ("parse error '%U'", format_unformat_error, input);
15284           return -99;
15285         }
15286     }
15287
15288   if (!bd_set)
15289     {
15290       errmsg ("Expected bridge domain!");
15291       return -99;
15292     }
15293
15294   M (ONE_NDP_ENTRIES_GET, mp);
15295   mp->bd = clib_host_to_net_u32 (bd);
15296
15297   /* send */
15298   S (mp);
15299
15300   /* wait for reply */
15301   W (ret);
15302   return ret;
15303 }
15304
15305 static int
15306 api_one_l2_arp_bd_get (vat_main_t * vam)
15307 {
15308   vl_api_one_l2_arp_bd_get_t *mp;
15309   int ret;
15310
15311   M (ONE_L2_ARP_BD_GET, mp);
15312
15313   /* send */
15314   S (mp);
15315
15316   /* wait for reply */
15317   W (ret);
15318   return ret;
15319 }
15320
15321 static int
15322 api_one_l2_arp_entries_get (vat_main_t * vam)
15323 {
15324   vl_api_one_l2_arp_entries_get_t *mp;
15325   unformat_input_t *input = vam->input;
15326   u8 bd_set = 0;
15327   u32 bd = ~0;
15328   int ret;
15329
15330   /* Parse args required to build the message */
15331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15332     {
15333       if (unformat (input, "bd %d", &bd))
15334         bd_set = 1;
15335       else
15336         {
15337           errmsg ("parse error '%U'", format_unformat_error, input);
15338           return -99;
15339         }
15340     }
15341
15342   if (!bd_set)
15343     {
15344       errmsg ("Expected bridge domain!");
15345       return -99;
15346     }
15347
15348   M (ONE_L2_ARP_ENTRIES_GET, mp);
15349   mp->bd = clib_host_to_net_u32 (bd);
15350
15351   /* send */
15352   S (mp);
15353
15354   /* wait for reply */
15355   W (ret);
15356   return ret;
15357 }
15358
15359 static int
15360 api_one_stats_enable_disable (vat_main_t * vam)
15361 {
15362   vl_api_one_stats_enable_disable_t *mp;
15363   unformat_input_t *input = vam->input;
15364   u8 is_set = 0;
15365   u8 is_en = 0;
15366   int ret;
15367
15368   /* Parse args required to build the message */
15369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15370     {
15371       if (unformat (input, "enable"))
15372         {
15373           is_set = 1;
15374           is_en = 1;
15375         }
15376       else if (unformat (input, "disable"))
15377         {
15378           is_set = 1;
15379         }
15380       else
15381         break;
15382     }
15383
15384   if (!is_set)
15385     {
15386       errmsg ("Value not set");
15387       return -99;
15388     }
15389
15390   M (ONE_STATS_ENABLE_DISABLE, mp);
15391   mp->is_en = is_en;
15392
15393   /* send */
15394   S (mp);
15395
15396   /* wait for reply */
15397   W (ret);
15398   return ret;
15399 }
15400
15401 static int
15402 api_show_one_stats_enable_disable (vat_main_t * vam)
15403 {
15404   vl_api_show_one_stats_enable_disable_t *mp;
15405   int ret;
15406
15407   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15408
15409   /* send */
15410   S (mp);
15411
15412   /* wait for reply */
15413   W (ret);
15414   return ret;
15415 }
15416
15417 static int
15418 api_show_one_map_request_mode (vat_main_t * vam)
15419 {
15420   vl_api_show_one_map_request_mode_t *mp;
15421   int ret;
15422
15423   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15424
15425   /* send */
15426   S (mp);
15427
15428   /* wait for reply */
15429   W (ret);
15430   return ret;
15431 }
15432
15433 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15434
15435 static int
15436 api_one_map_request_mode (vat_main_t * vam)
15437 {
15438   unformat_input_t *input = vam->input;
15439   vl_api_one_map_request_mode_t *mp;
15440   u8 mode = 0;
15441   int ret;
15442
15443   /* Parse args required to build the message */
15444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15445     {
15446       if (unformat (input, "dst-only"))
15447         mode = 0;
15448       else if (unformat (input, "src-dst"))
15449         mode = 1;
15450       else
15451         {
15452           errmsg ("parse error '%U'", format_unformat_error, input);
15453           return -99;
15454         }
15455     }
15456
15457   M (ONE_MAP_REQUEST_MODE, mp);
15458
15459   mp->mode = mode;
15460
15461   /* send */
15462   S (mp);
15463
15464   /* wait for reply */
15465   W (ret);
15466   return ret;
15467 }
15468
15469 #define api_lisp_map_request_mode api_one_map_request_mode
15470
15471 /**
15472  * Enable/disable ONE proxy ITR.
15473  *
15474  * @param vam vpp API test context
15475  * @return return code
15476  */
15477 static int
15478 api_one_pitr_set_locator_set (vat_main_t * vam)
15479 {
15480   u8 ls_name_set = 0;
15481   unformat_input_t *input = vam->input;
15482   vl_api_one_pitr_set_locator_set_t *mp;
15483   u8 is_add = 1;
15484   u8 *ls_name = 0;
15485   int ret;
15486
15487   /* Parse args required to build the message */
15488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15489     {
15490       if (unformat (input, "del"))
15491         is_add = 0;
15492       else if (unformat (input, "locator-set %s", &ls_name))
15493         ls_name_set = 1;
15494       else
15495         {
15496           errmsg ("parse error '%U'", format_unformat_error, input);
15497           return -99;
15498         }
15499     }
15500
15501   if (!ls_name_set)
15502     {
15503       errmsg ("locator-set name not set!");
15504       return -99;
15505     }
15506
15507   M (ONE_PITR_SET_LOCATOR_SET, mp);
15508
15509   mp->is_add = is_add;
15510   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15511   vec_free (ls_name);
15512
15513   /* send */
15514   S (mp);
15515
15516   /* wait for reply */
15517   W (ret);
15518   return ret;
15519 }
15520
15521 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15522
15523 static int
15524 api_one_nsh_set_locator_set (vat_main_t * vam)
15525 {
15526   u8 ls_name_set = 0;
15527   unformat_input_t *input = vam->input;
15528   vl_api_one_nsh_set_locator_set_t *mp;
15529   u8 is_add = 1;
15530   u8 *ls_name = 0;
15531   int ret;
15532
15533   /* Parse args required to build the message */
15534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15535     {
15536       if (unformat (input, "del"))
15537         is_add = 0;
15538       else if (unformat (input, "ls %s", &ls_name))
15539         ls_name_set = 1;
15540       else
15541         {
15542           errmsg ("parse error '%U'", format_unformat_error, input);
15543           return -99;
15544         }
15545     }
15546
15547   if (!ls_name_set && is_add)
15548     {
15549       errmsg ("locator-set name not set!");
15550       return -99;
15551     }
15552
15553   M (ONE_NSH_SET_LOCATOR_SET, mp);
15554
15555   mp->is_add = is_add;
15556   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15557   vec_free (ls_name);
15558
15559   /* send */
15560   S (mp);
15561
15562   /* wait for reply */
15563   W (ret);
15564   return ret;
15565 }
15566
15567 static int
15568 api_show_one_pitr (vat_main_t * vam)
15569 {
15570   vl_api_show_one_pitr_t *mp;
15571   int ret;
15572
15573   if (!vam->json_output)
15574     {
15575       print (vam->ofp, "%=20s", "lisp status:");
15576     }
15577
15578   M (SHOW_ONE_PITR, mp);
15579   /* send it... */
15580   S (mp);
15581
15582   /* Wait for a reply... */
15583   W (ret);
15584   return ret;
15585 }
15586
15587 #define api_show_lisp_pitr api_show_one_pitr
15588
15589 static int
15590 api_one_use_petr (vat_main_t * vam)
15591 {
15592   unformat_input_t *input = vam->input;
15593   vl_api_one_use_petr_t *mp;
15594   u8 is_add = 0;
15595   ip_address_t ip;
15596   int ret;
15597
15598   clib_memset (&ip, 0, sizeof (ip));
15599
15600   /* Parse args required to build the message */
15601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15602     {
15603       if (unformat (input, "disable"))
15604         is_add = 0;
15605       else
15606         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15607         {
15608           is_add = 1;
15609           ip_addr_version (&ip) = AF_IP4;
15610         }
15611       else
15612         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15613         {
15614           is_add = 1;
15615           ip_addr_version (&ip) = AF_IP6;
15616         }
15617       else
15618         {
15619           errmsg ("parse error '%U'", format_unformat_error, input);
15620           return -99;
15621         }
15622     }
15623
15624   M (ONE_USE_PETR, mp);
15625
15626   mp->is_add = is_add;
15627   if (is_add)
15628     {
15629       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15630       if (mp->is_ip4)
15631         clib_memcpy (mp->address, &ip, 4);
15632       else
15633         clib_memcpy (mp->address, &ip, 16);
15634     }
15635
15636   /* send */
15637   S (mp);
15638
15639   /* wait for reply */
15640   W (ret);
15641   return ret;
15642 }
15643
15644 #define api_lisp_use_petr api_one_use_petr
15645
15646 static int
15647 api_show_one_nsh_mapping (vat_main_t * vam)
15648 {
15649   vl_api_show_one_use_petr_t *mp;
15650   int ret;
15651
15652   if (!vam->json_output)
15653     {
15654       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15655     }
15656
15657   M (SHOW_ONE_NSH_MAPPING, mp);
15658   /* send it... */
15659   S (mp);
15660
15661   /* Wait for a reply... */
15662   W (ret);
15663   return ret;
15664 }
15665
15666 static int
15667 api_show_one_use_petr (vat_main_t * vam)
15668 {
15669   vl_api_show_one_use_petr_t *mp;
15670   int ret;
15671
15672   if (!vam->json_output)
15673     {
15674       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15675     }
15676
15677   M (SHOW_ONE_USE_PETR, mp);
15678   /* send it... */
15679   S (mp);
15680
15681   /* Wait for a reply... */
15682   W (ret);
15683   return ret;
15684 }
15685
15686 #define api_show_lisp_use_petr api_show_one_use_petr
15687
15688 /**
15689  * Add/delete mapping between vni and vrf
15690  */
15691 static int
15692 api_one_eid_table_add_del_map (vat_main_t * vam)
15693 {
15694   unformat_input_t *input = vam->input;
15695   vl_api_one_eid_table_add_del_map_t *mp;
15696   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15697   u32 vni, vrf, bd_index;
15698   int ret;
15699
15700   /* Parse args required to build the message */
15701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15702     {
15703       if (unformat (input, "del"))
15704         is_add = 0;
15705       else if (unformat (input, "vrf %d", &vrf))
15706         vrf_set = 1;
15707       else if (unformat (input, "bd_index %d", &bd_index))
15708         bd_index_set = 1;
15709       else if (unformat (input, "vni %d", &vni))
15710         vni_set = 1;
15711       else
15712         break;
15713     }
15714
15715   if (!vni_set || (!vrf_set && !bd_index_set))
15716     {
15717       errmsg ("missing arguments!");
15718       return -99;
15719     }
15720
15721   if (vrf_set && bd_index_set)
15722     {
15723       errmsg ("error: both vrf and bd entered!");
15724       return -99;
15725     }
15726
15727   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15728
15729   mp->is_add = is_add;
15730   mp->vni = htonl (vni);
15731   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15732   mp->is_l2 = bd_index_set;
15733
15734   /* send */
15735   S (mp);
15736
15737   /* wait for reply */
15738   W (ret);
15739   return ret;
15740 }
15741
15742 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15743
15744 uword
15745 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15746 {
15747   u32 *action = va_arg (*args, u32 *);
15748   u8 *s = 0;
15749
15750   if (unformat (input, "%s", &s))
15751     {
15752       if (!strcmp ((char *) s, "no-action"))
15753         action[0] = 0;
15754       else if (!strcmp ((char *) s, "natively-forward"))
15755         action[0] = 1;
15756       else if (!strcmp ((char *) s, "send-map-request"))
15757         action[0] = 2;
15758       else if (!strcmp ((char *) s, "drop"))
15759         action[0] = 3;
15760       else
15761         {
15762           clib_warning ("invalid action: '%s'", s);
15763           action[0] = 3;
15764         }
15765     }
15766   else
15767     return 0;
15768
15769   vec_free (s);
15770   return 1;
15771 }
15772
15773 /**
15774  * Add/del remote mapping to/from ONE control plane
15775  *
15776  * @param vam vpp API test context
15777  * @return return code
15778  */
15779 static int
15780 api_one_add_del_remote_mapping (vat_main_t * vam)
15781 {
15782   unformat_input_t *input = vam->input;
15783   vl_api_one_add_del_remote_mapping_t *mp;
15784   u32 vni = 0;
15785   lisp_eid_vat_t _eid, *eid = &_eid;
15786   lisp_eid_vat_t _seid, *seid = &_seid;
15787   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15788   u32 action = ~0, p, w, data_len;
15789   ip4_address_t rloc4;
15790   ip6_address_t rloc6;
15791   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15792   int ret;
15793
15794   clib_memset (&rloc, 0, sizeof (rloc));
15795
15796   /* Parse args required to build the message */
15797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15798     {
15799       if (unformat (input, "del-all"))
15800         {
15801           del_all = 1;
15802         }
15803       else if (unformat (input, "del"))
15804         {
15805           is_add = 0;
15806         }
15807       else if (unformat (input, "add"))
15808         {
15809           is_add = 1;
15810         }
15811       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15812         {
15813           eid_set = 1;
15814         }
15815       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15816         {
15817           seid_set = 1;
15818         }
15819       else if (unformat (input, "vni %d", &vni))
15820         {
15821           ;
15822         }
15823       else if (unformat (input, "p %d w %d", &p, &w))
15824         {
15825           if (!curr_rloc)
15826             {
15827               errmsg ("No RLOC configured for setting priority/weight!");
15828               return -99;
15829             }
15830           curr_rloc->priority = p;
15831           curr_rloc->weight = w;
15832         }
15833       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15834         {
15835           rloc.is_ip4 = 1;
15836           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15837           vec_add1 (rlocs, rloc);
15838           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15839         }
15840       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15841         {
15842           rloc.is_ip4 = 0;
15843           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15844           vec_add1 (rlocs, rloc);
15845           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15846         }
15847       else if (unformat (input, "action %U",
15848                          unformat_negative_mapping_action, &action))
15849         {
15850           ;
15851         }
15852       else
15853         {
15854           clib_warning ("parse error '%U'", format_unformat_error, input);
15855           return -99;
15856         }
15857     }
15858
15859   if (0 == eid_set)
15860     {
15861       errmsg ("missing params!");
15862       return -99;
15863     }
15864
15865   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15866     {
15867       errmsg ("no action set for negative map-reply!");
15868       return -99;
15869     }
15870
15871   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15872
15873   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15874   mp->is_add = is_add;
15875   mp->vni = htonl (vni);
15876   mp->action = (u8) action;
15877   mp->is_src_dst = seid_set;
15878   mp->eid_len = eid->len;
15879   mp->seid_len = seid->len;
15880   mp->del_all = del_all;
15881   mp->eid_type = eid->type;
15882   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15883   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15884
15885   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15886   clib_memcpy (mp->rlocs, rlocs, data_len);
15887   vec_free (rlocs);
15888
15889   /* send it... */
15890   S (mp);
15891
15892   /* Wait for a reply... */
15893   W (ret);
15894   return ret;
15895 }
15896
15897 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15898
15899 /**
15900  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15901  * forwarding entries in data-plane accordingly.
15902  *
15903  * @param vam vpp API test context
15904  * @return return code
15905  */
15906 static int
15907 api_one_add_del_adjacency (vat_main_t * vam)
15908 {
15909   unformat_input_t *input = vam->input;
15910   vl_api_one_add_del_adjacency_t *mp;
15911   u32 vni = 0;
15912   ip4_address_t leid4, reid4;
15913   ip6_address_t leid6, reid6;
15914   u8 reid_mac[6] = { 0 };
15915   u8 leid_mac[6] = { 0 };
15916   u8 reid_type, leid_type;
15917   u32 leid_len = 0, reid_len = 0, len;
15918   u8 is_add = 1;
15919   int ret;
15920
15921   leid_type = reid_type = (u8) ~ 0;
15922
15923   /* Parse args required to build the message */
15924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15925     {
15926       if (unformat (input, "del"))
15927         {
15928           is_add = 0;
15929         }
15930       else if (unformat (input, "add"))
15931         {
15932           is_add = 1;
15933         }
15934       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15935                          &reid4, &len))
15936         {
15937           reid_type = 0;        /* ipv4 */
15938           reid_len = len;
15939         }
15940       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15941                          &reid6, &len))
15942         {
15943           reid_type = 1;        /* ipv6 */
15944           reid_len = len;
15945         }
15946       else if (unformat (input, "reid %U", unformat_ethernet_address,
15947                          reid_mac))
15948         {
15949           reid_type = 2;        /* mac */
15950         }
15951       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15952                          &leid4, &len))
15953         {
15954           leid_type = 0;        /* ipv4 */
15955           leid_len = len;
15956         }
15957       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15958                          &leid6, &len))
15959         {
15960           leid_type = 1;        /* ipv6 */
15961           leid_len = len;
15962         }
15963       else if (unformat (input, "leid %U", unformat_ethernet_address,
15964                          leid_mac))
15965         {
15966           leid_type = 2;        /* mac */
15967         }
15968       else if (unformat (input, "vni %d", &vni))
15969         {
15970           ;
15971         }
15972       else
15973         {
15974           errmsg ("parse error '%U'", format_unformat_error, input);
15975           return -99;
15976         }
15977     }
15978
15979   if ((u8) ~ 0 == reid_type)
15980     {
15981       errmsg ("missing params!");
15982       return -99;
15983     }
15984
15985   if (leid_type != reid_type)
15986     {
15987       errmsg ("remote and local EIDs are of different types!");
15988       return -99;
15989     }
15990
15991   M (ONE_ADD_DEL_ADJACENCY, mp);
15992   mp->is_add = is_add;
15993   mp->vni = htonl (vni);
15994   mp->leid_len = leid_len;
15995   mp->reid_len = reid_len;
15996   mp->eid_type = reid_type;
15997
15998   switch (mp->eid_type)
15999     {
16000     case 0:
16001       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16002       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16003       break;
16004     case 1:
16005       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16006       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16007       break;
16008     case 2:
16009       clib_memcpy (mp->leid, leid_mac, 6);
16010       clib_memcpy (mp->reid, reid_mac, 6);
16011       break;
16012     default:
16013       errmsg ("unknown EID type %d!", mp->eid_type);
16014       return 0;
16015     }
16016
16017   /* send it... */
16018   S (mp);
16019
16020   /* Wait for a reply... */
16021   W (ret);
16022   return ret;
16023 }
16024
16025 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16026
16027 uword
16028 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16029 {
16030   u32 *mode = va_arg (*args, u32 *);
16031
16032   if (unformat (input, "lisp"))
16033     *mode = 0;
16034   else if (unformat (input, "vxlan"))
16035     *mode = 1;
16036   else
16037     return 0;
16038
16039   return 1;
16040 }
16041
16042 static int
16043 api_gpe_get_encap_mode (vat_main_t * vam)
16044 {
16045   vl_api_gpe_get_encap_mode_t *mp;
16046   int ret;
16047
16048   /* Construct the API message */
16049   M (GPE_GET_ENCAP_MODE, mp);
16050
16051   /* send it... */
16052   S (mp);
16053
16054   /* Wait for a reply... */
16055   W (ret);
16056   return ret;
16057 }
16058
16059 static int
16060 api_gpe_set_encap_mode (vat_main_t * vam)
16061 {
16062   unformat_input_t *input = vam->input;
16063   vl_api_gpe_set_encap_mode_t *mp;
16064   int ret;
16065   u32 mode = 0;
16066
16067   /* Parse args required to build the message */
16068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16069     {
16070       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16071         ;
16072       else
16073         break;
16074     }
16075
16076   /* Construct the API message */
16077   M (GPE_SET_ENCAP_MODE, mp);
16078
16079   mp->mode = mode;
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_lisp_gpe_add_del_iface (vat_main_t * vam)
16091 {
16092   unformat_input_t *input = vam->input;
16093   vl_api_gpe_add_del_iface_t *mp;
16094   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16095   u32 dp_table = 0, vni = 0;
16096   int ret;
16097
16098   /* Parse args required to build the message */
16099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16100     {
16101       if (unformat (input, "up"))
16102         {
16103           action_set = 1;
16104           is_add = 1;
16105         }
16106       else if (unformat (input, "down"))
16107         {
16108           action_set = 1;
16109           is_add = 0;
16110         }
16111       else if (unformat (input, "table_id %d", &dp_table))
16112         {
16113           dp_table_set = 1;
16114         }
16115       else if (unformat (input, "bd_id %d", &dp_table))
16116         {
16117           dp_table_set = 1;
16118           is_l2 = 1;
16119         }
16120       else if (unformat (input, "vni %d", &vni))
16121         {
16122           vni_set = 1;
16123         }
16124       else
16125         break;
16126     }
16127
16128   if (action_set == 0)
16129     {
16130       errmsg ("Action not set");
16131       return -99;
16132     }
16133   if (dp_table_set == 0 || vni_set == 0)
16134     {
16135       errmsg ("vni and dp_table must be set");
16136       return -99;
16137     }
16138
16139   /* Construct the API message */
16140   M (GPE_ADD_DEL_IFACE, mp);
16141
16142   mp->is_add = is_add;
16143   mp->dp_table = clib_host_to_net_u32 (dp_table);
16144   mp->is_l2 = is_l2;
16145   mp->vni = clib_host_to_net_u32 (vni);
16146
16147   /* send it... */
16148   S (mp);
16149
16150   /* Wait for a reply... */
16151   W (ret);
16152   return ret;
16153 }
16154
16155 static int
16156 api_one_map_register_fallback_threshold (vat_main_t * vam)
16157 {
16158   unformat_input_t *input = vam->input;
16159   vl_api_one_map_register_fallback_threshold_t *mp;
16160   u32 value = 0;
16161   u8 is_set = 0;
16162   int ret;
16163
16164   /* Parse args required to build the message */
16165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16166     {
16167       if (unformat (input, "%u", &value))
16168         is_set = 1;
16169       else
16170         {
16171           clib_warning ("parse error '%U'", format_unformat_error, input);
16172           return -99;
16173         }
16174     }
16175
16176   if (!is_set)
16177     {
16178       errmsg ("fallback threshold value is missing!");
16179       return -99;
16180     }
16181
16182   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16183   mp->value = clib_host_to_net_u32 (value);
16184
16185   /* send it... */
16186   S (mp);
16187
16188   /* Wait for a reply... */
16189   W (ret);
16190   return ret;
16191 }
16192
16193 static int
16194 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16195 {
16196   vl_api_show_one_map_register_fallback_threshold_t *mp;
16197   int ret;
16198
16199   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16200
16201   /* send it... */
16202   S (mp);
16203
16204   /* Wait for a reply... */
16205   W (ret);
16206   return ret;
16207 }
16208
16209 uword
16210 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16211 {
16212   u32 *proto = va_arg (*args, u32 *);
16213
16214   if (unformat (input, "udp"))
16215     *proto = 1;
16216   else if (unformat (input, "api"))
16217     *proto = 2;
16218   else
16219     return 0;
16220
16221   return 1;
16222 }
16223
16224 static int
16225 api_one_set_transport_protocol (vat_main_t * vam)
16226 {
16227   unformat_input_t *input = vam->input;
16228   vl_api_one_set_transport_protocol_t *mp;
16229   u8 is_set = 0;
16230   u32 protocol = 0;
16231   int ret;
16232
16233   /* Parse args required to build the message */
16234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16235     {
16236       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16237         is_set = 1;
16238       else
16239         {
16240           clib_warning ("parse error '%U'", format_unformat_error, input);
16241           return -99;
16242         }
16243     }
16244
16245   if (!is_set)
16246     {
16247       errmsg ("Transport protocol missing!");
16248       return -99;
16249     }
16250
16251   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16252   mp->protocol = (u8) protocol;
16253
16254   /* send it... */
16255   S (mp);
16256
16257   /* Wait for a reply... */
16258   W (ret);
16259   return ret;
16260 }
16261
16262 static int
16263 api_one_get_transport_protocol (vat_main_t * vam)
16264 {
16265   vl_api_one_get_transport_protocol_t *mp;
16266   int ret;
16267
16268   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16269
16270   /* send it... */
16271   S (mp);
16272
16273   /* Wait for a reply... */
16274   W (ret);
16275   return ret;
16276 }
16277
16278 static int
16279 api_one_map_register_set_ttl (vat_main_t * vam)
16280 {
16281   unformat_input_t *input = vam->input;
16282   vl_api_one_map_register_set_ttl_t *mp;
16283   u32 ttl = 0;
16284   u8 is_set = 0;
16285   int ret;
16286
16287   /* Parse args required to build the message */
16288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16289     {
16290       if (unformat (input, "%u", &ttl))
16291         is_set = 1;
16292       else
16293         {
16294           clib_warning ("parse error '%U'", format_unformat_error, input);
16295           return -99;
16296         }
16297     }
16298
16299   if (!is_set)
16300     {
16301       errmsg ("TTL value missing!");
16302       return -99;
16303     }
16304
16305   M (ONE_MAP_REGISTER_SET_TTL, mp);
16306   mp->ttl = clib_host_to_net_u32 (ttl);
16307
16308   /* send it... */
16309   S (mp);
16310
16311   /* Wait for a reply... */
16312   W (ret);
16313   return ret;
16314 }
16315
16316 static int
16317 api_show_one_map_register_ttl (vat_main_t * vam)
16318 {
16319   vl_api_show_one_map_register_ttl_t *mp;
16320   int ret;
16321
16322   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16323
16324   /* send it... */
16325   S (mp);
16326
16327   /* Wait for a reply... */
16328   W (ret);
16329   return ret;
16330 }
16331
16332 /**
16333  * Add/del map request itr rlocs from ONE control plane and updates
16334  *
16335  * @param vam vpp API test context
16336  * @return return code
16337  */
16338 static int
16339 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16340 {
16341   unformat_input_t *input = vam->input;
16342   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16343   u8 *locator_set_name = 0;
16344   u8 locator_set_name_set = 0;
16345   u8 is_add = 1;
16346   int ret;
16347
16348   /* Parse args required to build the message */
16349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16350     {
16351       if (unformat (input, "del"))
16352         {
16353           is_add = 0;
16354         }
16355       else if (unformat (input, "%_%v%_", &locator_set_name))
16356         {
16357           locator_set_name_set = 1;
16358         }
16359       else
16360         {
16361           clib_warning ("parse error '%U'", format_unformat_error, input);
16362           return -99;
16363         }
16364     }
16365
16366   if (is_add && !locator_set_name_set)
16367     {
16368       errmsg ("itr-rloc is not set!");
16369       return -99;
16370     }
16371
16372   if (is_add && vec_len (locator_set_name) > 64)
16373     {
16374       errmsg ("itr-rloc locator-set name too long");
16375       vec_free (locator_set_name);
16376       return -99;
16377     }
16378
16379   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16380   mp->is_add = is_add;
16381   if (is_add)
16382     {
16383       clib_memcpy (mp->locator_set_name, locator_set_name,
16384                    vec_len (locator_set_name));
16385     }
16386   else
16387     {
16388       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16389     }
16390   vec_free (locator_set_name);
16391
16392   /* send it... */
16393   S (mp);
16394
16395   /* Wait for a reply... */
16396   W (ret);
16397   return ret;
16398 }
16399
16400 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16401
16402 static int
16403 api_one_locator_dump (vat_main_t * vam)
16404 {
16405   unformat_input_t *input = vam->input;
16406   vl_api_one_locator_dump_t *mp;
16407   vl_api_control_ping_t *mp_ping;
16408   u8 is_index_set = 0, is_name_set = 0;
16409   u8 *ls_name = 0;
16410   u32 ls_index = ~0;
16411   int ret;
16412
16413   /* Parse args required to build the message */
16414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16415     {
16416       if (unformat (input, "ls_name %_%v%_", &ls_name))
16417         {
16418           is_name_set = 1;
16419         }
16420       else if (unformat (input, "ls_index %d", &ls_index))
16421         {
16422           is_index_set = 1;
16423         }
16424       else
16425         {
16426           errmsg ("parse error '%U'", format_unformat_error, input);
16427           return -99;
16428         }
16429     }
16430
16431   if (!is_index_set && !is_name_set)
16432     {
16433       errmsg ("error: expected one of index or name!");
16434       return -99;
16435     }
16436
16437   if (is_index_set && is_name_set)
16438     {
16439       errmsg ("error: only one param expected!");
16440       return -99;
16441     }
16442
16443   if (vec_len (ls_name) > 62)
16444     {
16445       errmsg ("error: locator set name too long!");
16446       return -99;
16447     }
16448
16449   if (!vam->json_output)
16450     {
16451       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16452     }
16453
16454   M (ONE_LOCATOR_DUMP, mp);
16455   mp->is_index_set = is_index_set;
16456
16457   if (is_index_set)
16458     mp->ls_index = clib_host_to_net_u32 (ls_index);
16459   else
16460     {
16461       vec_add1 (ls_name, 0);
16462       strncpy ((char *) mp->ls_name, (char *) ls_name,
16463                sizeof (mp->ls_name) - 1);
16464     }
16465
16466   /* send it... */
16467   S (mp);
16468
16469   /* Use a control ping for synchronization */
16470   MPING (CONTROL_PING, mp_ping);
16471   S (mp_ping);
16472
16473   /* Wait for a reply... */
16474   W (ret);
16475   return ret;
16476 }
16477
16478 #define api_lisp_locator_dump api_one_locator_dump
16479
16480 static int
16481 api_one_locator_set_dump (vat_main_t * vam)
16482 {
16483   vl_api_one_locator_set_dump_t *mp;
16484   vl_api_control_ping_t *mp_ping;
16485   unformat_input_t *input = vam->input;
16486   u8 filter = 0;
16487   int ret;
16488
16489   /* Parse args required to build the message */
16490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16491     {
16492       if (unformat (input, "local"))
16493         {
16494           filter = 1;
16495         }
16496       else if (unformat (input, "remote"))
16497         {
16498           filter = 2;
16499         }
16500       else
16501         {
16502           errmsg ("parse error '%U'", format_unformat_error, input);
16503           return -99;
16504         }
16505     }
16506
16507   if (!vam->json_output)
16508     {
16509       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16510     }
16511
16512   M (ONE_LOCATOR_SET_DUMP, mp);
16513
16514   mp->filter = filter;
16515
16516   /* send it... */
16517   S (mp);
16518
16519   /* Use a control ping for synchronization */
16520   MPING (CONTROL_PING, mp_ping);
16521   S (mp_ping);
16522
16523   /* Wait for a reply... */
16524   W (ret);
16525   return ret;
16526 }
16527
16528 #define api_lisp_locator_set_dump api_one_locator_set_dump
16529
16530 static int
16531 api_one_eid_table_map_dump (vat_main_t * vam)
16532 {
16533   u8 is_l2 = 0;
16534   u8 mode_set = 0;
16535   unformat_input_t *input = vam->input;
16536   vl_api_one_eid_table_map_dump_t *mp;
16537   vl_api_control_ping_t *mp_ping;
16538   int ret;
16539
16540   /* Parse args required to build the message */
16541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16542     {
16543       if (unformat (input, "l2"))
16544         {
16545           is_l2 = 1;
16546           mode_set = 1;
16547         }
16548       else if (unformat (input, "l3"))
16549         {
16550           is_l2 = 0;
16551           mode_set = 1;
16552         }
16553       else
16554         {
16555           errmsg ("parse error '%U'", format_unformat_error, input);
16556           return -99;
16557         }
16558     }
16559
16560   if (!mode_set)
16561     {
16562       errmsg ("expected one of 'l2' or 'l3' parameter!");
16563       return -99;
16564     }
16565
16566   if (!vam->json_output)
16567     {
16568       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16569     }
16570
16571   M (ONE_EID_TABLE_MAP_DUMP, mp);
16572   mp->is_l2 = is_l2;
16573
16574   /* send it... */
16575   S (mp);
16576
16577   /* Use a control ping for synchronization */
16578   MPING (CONTROL_PING, mp_ping);
16579   S (mp_ping);
16580
16581   /* Wait for a reply... */
16582   W (ret);
16583   return ret;
16584 }
16585
16586 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16587
16588 static int
16589 api_one_eid_table_vni_dump (vat_main_t * vam)
16590 {
16591   vl_api_one_eid_table_vni_dump_t *mp;
16592   vl_api_control_ping_t *mp_ping;
16593   int ret;
16594
16595   if (!vam->json_output)
16596     {
16597       print (vam->ofp, "VNI");
16598     }
16599
16600   M (ONE_EID_TABLE_VNI_DUMP, mp);
16601
16602   /* send it... */
16603   S (mp);
16604
16605   /* Use a control ping for synchronization */
16606   MPING (CONTROL_PING, mp_ping);
16607   S (mp_ping);
16608
16609   /* Wait for a reply... */
16610   W (ret);
16611   return ret;
16612 }
16613
16614 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16615
16616 static int
16617 api_one_eid_table_dump (vat_main_t * vam)
16618 {
16619   unformat_input_t *i = vam->input;
16620   vl_api_one_eid_table_dump_t *mp;
16621   vl_api_control_ping_t *mp_ping;
16622   struct in_addr ip4;
16623   struct in6_addr ip6;
16624   u8 mac[6];
16625   u8 eid_type = ~0, eid_set = 0;
16626   u32 prefix_length = ~0, t, vni = 0;
16627   u8 filter = 0;
16628   int ret;
16629   lisp_nsh_api_t nsh;
16630
16631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16632     {
16633       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16634         {
16635           eid_set = 1;
16636           eid_type = 0;
16637           prefix_length = t;
16638         }
16639       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16640         {
16641           eid_set = 1;
16642           eid_type = 1;
16643           prefix_length = t;
16644         }
16645       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16646         {
16647           eid_set = 1;
16648           eid_type = 2;
16649         }
16650       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16651         {
16652           eid_set = 1;
16653           eid_type = 3;
16654         }
16655       else if (unformat (i, "vni %d", &t))
16656         {
16657           vni = t;
16658         }
16659       else if (unformat (i, "local"))
16660         {
16661           filter = 1;
16662         }
16663       else if (unformat (i, "remote"))
16664         {
16665           filter = 2;
16666         }
16667       else
16668         {
16669           errmsg ("parse error '%U'", format_unformat_error, i);
16670           return -99;
16671         }
16672     }
16673
16674   if (!vam->json_output)
16675     {
16676       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16677              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16678     }
16679
16680   M (ONE_EID_TABLE_DUMP, mp);
16681
16682   mp->filter = filter;
16683   if (eid_set)
16684     {
16685       mp->eid_set = 1;
16686       mp->vni = htonl (vni);
16687       mp->eid_type = eid_type;
16688       switch (eid_type)
16689         {
16690         case 0:
16691           mp->prefix_length = prefix_length;
16692           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16693           break;
16694         case 1:
16695           mp->prefix_length = prefix_length;
16696           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16697           break;
16698         case 2:
16699           clib_memcpy (mp->eid, mac, sizeof (mac));
16700           break;
16701         case 3:
16702           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16703           break;
16704         default:
16705           errmsg ("unknown EID type %d!", eid_type);
16706           return -99;
16707         }
16708     }
16709
16710   /* send it... */
16711   S (mp);
16712
16713   /* Use a control ping for synchronization */
16714   MPING (CONTROL_PING, mp_ping);
16715   S (mp_ping);
16716
16717   /* Wait for a reply... */
16718   W (ret);
16719   return ret;
16720 }
16721
16722 #define api_lisp_eid_table_dump api_one_eid_table_dump
16723
16724 static int
16725 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16726 {
16727   unformat_input_t *i = vam->input;
16728   vl_api_gpe_fwd_entries_get_t *mp;
16729   u8 vni_set = 0;
16730   u32 vni = ~0;
16731   int ret;
16732
16733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16734     {
16735       if (unformat (i, "vni %d", &vni))
16736         {
16737           vni_set = 1;
16738         }
16739       else
16740         {
16741           errmsg ("parse error '%U'", format_unformat_error, i);
16742           return -99;
16743         }
16744     }
16745
16746   if (!vni_set)
16747     {
16748       errmsg ("vni not set!");
16749       return -99;
16750     }
16751
16752   if (!vam->json_output)
16753     {
16754       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16755              "leid", "reid");
16756     }
16757
16758   M (GPE_FWD_ENTRIES_GET, mp);
16759   mp->vni = clib_host_to_net_u32 (vni);
16760
16761   /* send it... */
16762   S (mp);
16763
16764   /* Wait for a reply... */
16765   W (ret);
16766   return ret;
16767 }
16768
16769 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16770 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16771 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16772 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16773 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16774 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16775 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16776 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16777
16778 static int
16779 api_one_adjacencies_get (vat_main_t * vam)
16780 {
16781   unformat_input_t *i = vam->input;
16782   vl_api_one_adjacencies_get_t *mp;
16783   u8 vni_set = 0;
16784   u32 vni = ~0;
16785   int ret;
16786
16787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16788     {
16789       if (unformat (i, "vni %d", &vni))
16790         {
16791           vni_set = 1;
16792         }
16793       else
16794         {
16795           errmsg ("parse error '%U'", format_unformat_error, i);
16796           return -99;
16797         }
16798     }
16799
16800   if (!vni_set)
16801     {
16802       errmsg ("vni not set!");
16803       return -99;
16804     }
16805
16806   if (!vam->json_output)
16807     {
16808       print (vam->ofp, "%s %40s", "leid", "reid");
16809     }
16810
16811   M (ONE_ADJACENCIES_GET, mp);
16812   mp->vni = clib_host_to_net_u32 (vni);
16813
16814   /* send it... */
16815   S (mp);
16816
16817   /* Wait for a reply... */
16818   W (ret);
16819   return ret;
16820 }
16821
16822 #define api_lisp_adjacencies_get api_one_adjacencies_get
16823
16824 static int
16825 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16826 {
16827   unformat_input_t *i = vam->input;
16828   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16829   int ret;
16830   u8 ip_family_set = 0, is_ip4 = 1;
16831
16832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16833     {
16834       if (unformat (i, "ip4"))
16835         {
16836           ip_family_set = 1;
16837           is_ip4 = 1;
16838         }
16839       else if (unformat (i, "ip6"))
16840         {
16841           ip_family_set = 1;
16842           is_ip4 = 0;
16843         }
16844       else
16845         {
16846           errmsg ("parse error '%U'", format_unformat_error, i);
16847           return -99;
16848         }
16849     }
16850
16851   if (!ip_family_set)
16852     {
16853       errmsg ("ip family not set!");
16854       return -99;
16855     }
16856
16857   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16858   mp->is_ip4 = is_ip4;
16859
16860   /* send it... */
16861   S (mp);
16862
16863   /* Wait for a reply... */
16864   W (ret);
16865   return ret;
16866 }
16867
16868 static int
16869 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16870 {
16871   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16872   int ret;
16873
16874   if (!vam->json_output)
16875     {
16876       print (vam->ofp, "VNIs");
16877     }
16878
16879   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16880
16881   /* send it... */
16882   S (mp);
16883
16884   /* Wait for a reply... */
16885   W (ret);
16886   return ret;
16887 }
16888
16889 static int
16890 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16891 {
16892   unformat_input_t *i = vam->input;
16893   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16894   int ret = 0;
16895   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16896   struct in_addr ip4;
16897   struct in6_addr ip6;
16898   u32 table_id = 0, nh_sw_if_index = ~0;
16899
16900   clib_memset (&ip4, 0, sizeof (ip4));
16901   clib_memset (&ip6, 0, sizeof (ip6));
16902
16903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16904     {
16905       if (unformat (i, "del"))
16906         is_add = 0;
16907       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16908                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16909         {
16910           ip_set = 1;
16911           is_ip4 = 1;
16912         }
16913       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16914                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16915         {
16916           ip_set = 1;
16917           is_ip4 = 0;
16918         }
16919       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16920         {
16921           ip_set = 1;
16922           is_ip4 = 1;
16923           nh_sw_if_index = ~0;
16924         }
16925       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16926         {
16927           ip_set = 1;
16928           is_ip4 = 0;
16929           nh_sw_if_index = ~0;
16930         }
16931       else if (unformat (i, "table %d", &table_id))
16932         ;
16933       else
16934         {
16935           errmsg ("parse error '%U'", format_unformat_error, i);
16936           return -99;
16937         }
16938     }
16939
16940   if (!ip_set)
16941     {
16942       errmsg ("nh addr not set!");
16943       return -99;
16944     }
16945
16946   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16947   mp->is_add = is_add;
16948   mp->table_id = clib_host_to_net_u32 (table_id);
16949   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16950   mp->is_ip4 = is_ip4;
16951   if (is_ip4)
16952     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16953   else
16954     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16955
16956   /* send it... */
16957   S (mp);
16958
16959   /* Wait for a reply... */
16960   W (ret);
16961   return ret;
16962 }
16963
16964 static int
16965 api_one_map_server_dump (vat_main_t * vam)
16966 {
16967   vl_api_one_map_server_dump_t *mp;
16968   vl_api_control_ping_t *mp_ping;
16969   int ret;
16970
16971   if (!vam->json_output)
16972     {
16973       print (vam->ofp, "%=20s", "Map server");
16974     }
16975
16976   M (ONE_MAP_SERVER_DUMP, mp);
16977   /* send it... */
16978   S (mp);
16979
16980   /* Use a control ping for synchronization */
16981   MPING (CONTROL_PING, mp_ping);
16982   S (mp_ping);
16983
16984   /* Wait for a reply... */
16985   W (ret);
16986   return ret;
16987 }
16988
16989 #define api_lisp_map_server_dump api_one_map_server_dump
16990
16991 static int
16992 api_one_map_resolver_dump (vat_main_t * vam)
16993 {
16994   vl_api_one_map_resolver_dump_t *mp;
16995   vl_api_control_ping_t *mp_ping;
16996   int ret;
16997
16998   if (!vam->json_output)
16999     {
17000       print (vam->ofp, "%=20s", "Map resolver");
17001     }
17002
17003   M (ONE_MAP_RESOLVER_DUMP, mp);
17004   /* send it... */
17005   S (mp);
17006
17007   /* Use a control ping for synchronization */
17008   MPING (CONTROL_PING, mp_ping);
17009   S (mp_ping);
17010
17011   /* Wait for a reply... */
17012   W (ret);
17013   return ret;
17014 }
17015
17016 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17017
17018 static int
17019 api_one_stats_flush (vat_main_t * vam)
17020 {
17021   vl_api_one_stats_flush_t *mp;
17022   int ret = 0;
17023
17024   M (ONE_STATS_FLUSH, mp);
17025   S (mp);
17026   W (ret);
17027   return ret;
17028 }
17029
17030 static int
17031 api_one_stats_dump (vat_main_t * vam)
17032 {
17033   vl_api_one_stats_dump_t *mp;
17034   vl_api_control_ping_t *mp_ping;
17035   int ret;
17036
17037   M (ONE_STATS_DUMP, mp);
17038   /* send it... */
17039   S (mp);
17040
17041   /* Use a control ping for synchronization */
17042   MPING (CONTROL_PING, mp_ping);
17043   S (mp_ping);
17044
17045   /* Wait for a reply... */
17046   W (ret);
17047   return ret;
17048 }
17049
17050 static int
17051 api_show_one_status (vat_main_t * vam)
17052 {
17053   vl_api_show_one_status_t *mp;
17054   int ret;
17055
17056   if (!vam->json_output)
17057     {
17058       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17059     }
17060
17061   M (SHOW_ONE_STATUS, mp);
17062   /* send it... */
17063   S (mp);
17064   /* Wait for a reply... */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 #define api_show_lisp_status api_show_one_status
17070
17071 static int
17072 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17073 {
17074   vl_api_gpe_fwd_entry_path_dump_t *mp;
17075   vl_api_control_ping_t *mp_ping;
17076   unformat_input_t *i = vam->input;
17077   u32 fwd_entry_index = ~0;
17078   int ret;
17079
17080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17081     {
17082       if (unformat (i, "index %d", &fwd_entry_index))
17083         ;
17084       else
17085         break;
17086     }
17087
17088   if (~0 == fwd_entry_index)
17089     {
17090       errmsg ("no index specified!");
17091       return -99;
17092     }
17093
17094   if (!vam->json_output)
17095     {
17096       print (vam->ofp, "first line");
17097     }
17098
17099   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17100
17101   /* send it... */
17102   S (mp);
17103   /* Use a control ping for synchronization */
17104   MPING (CONTROL_PING, mp_ping);
17105   S (mp_ping);
17106
17107   /* Wait for a reply... */
17108   W (ret);
17109   return ret;
17110 }
17111
17112 static int
17113 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17114 {
17115   vl_api_one_get_map_request_itr_rlocs_t *mp;
17116   int ret;
17117
17118   if (!vam->json_output)
17119     {
17120       print (vam->ofp, "%=20s", "itr-rlocs:");
17121     }
17122
17123   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17124   /* send it... */
17125   S (mp);
17126   /* Wait for a reply... */
17127   W (ret);
17128   return ret;
17129 }
17130
17131 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17132
17133 static int
17134 api_af_packet_create (vat_main_t * vam)
17135 {
17136   unformat_input_t *i = vam->input;
17137   vl_api_af_packet_create_t *mp;
17138   u8 *host_if_name = 0;
17139   u8 hw_addr[6];
17140   u8 random_hw_addr = 1;
17141   int ret;
17142
17143   clib_memset (hw_addr, 0, sizeof (hw_addr));
17144
17145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17146     {
17147       if (unformat (i, "name %s", &host_if_name))
17148         vec_add1 (host_if_name, 0);
17149       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17150         random_hw_addr = 0;
17151       else
17152         break;
17153     }
17154
17155   if (!vec_len (host_if_name))
17156     {
17157       errmsg ("host-interface name must be specified");
17158       return -99;
17159     }
17160
17161   if (vec_len (host_if_name) > 64)
17162     {
17163       errmsg ("host-interface name too long");
17164       return -99;
17165     }
17166
17167   M (AF_PACKET_CREATE, mp);
17168
17169   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17170   clib_memcpy (mp->hw_addr, hw_addr, 6);
17171   mp->use_random_hw_addr = random_hw_addr;
17172   vec_free (host_if_name);
17173
17174   S (mp);
17175
17176   /* *INDENT-OFF* */
17177   W2 (ret,
17178       ({
17179         if (ret == 0)
17180           fprintf (vam->ofp ? vam->ofp : stderr,
17181                    " new sw_if_index = %d\n", vam->sw_if_index);
17182       }));
17183   /* *INDENT-ON* */
17184   return ret;
17185 }
17186
17187 static int
17188 api_af_packet_delete (vat_main_t * vam)
17189 {
17190   unformat_input_t *i = vam->input;
17191   vl_api_af_packet_delete_t *mp;
17192   u8 *host_if_name = 0;
17193   int ret;
17194
17195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17196     {
17197       if (unformat (i, "name %s", &host_if_name))
17198         vec_add1 (host_if_name, 0);
17199       else
17200         break;
17201     }
17202
17203   if (!vec_len (host_if_name))
17204     {
17205       errmsg ("host-interface name must be specified");
17206       return -99;
17207     }
17208
17209   if (vec_len (host_if_name) > 64)
17210     {
17211       errmsg ("host-interface name too long");
17212       return -99;
17213     }
17214
17215   M (AF_PACKET_DELETE, mp);
17216
17217   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17218   vec_free (host_if_name);
17219
17220   S (mp);
17221   W (ret);
17222   return ret;
17223 }
17224
17225 static void vl_api_af_packet_details_t_handler
17226   (vl_api_af_packet_details_t * mp)
17227 {
17228   vat_main_t *vam = &vat_main;
17229
17230   print (vam->ofp, "%-16s %d",
17231          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17232 }
17233
17234 static void vl_api_af_packet_details_t_handler_json
17235   (vl_api_af_packet_details_t * mp)
17236 {
17237   vat_main_t *vam = &vat_main;
17238   vat_json_node_t *node = NULL;
17239
17240   if (VAT_JSON_ARRAY != vam->json_tree.type)
17241     {
17242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17243       vat_json_init_array (&vam->json_tree);
17244     }
17245   node = vat_json_array_add (&vam->json_tree);
17246
17247   vat_json_init_object (node);
17248   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17249   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17250 }
17251
17252 static int
17253 api_af_packet_dump (vat_main_t * vam)
17254 {
17255   vl_api_af_packet_dump_t *mp;
17256   vl_api_control_ping_t *mp_ping;
17257   int ret;
17258
17259   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17260   /* Get list of tap interfaces */
17261   M (AF_PACKET_DUMP, mp);
17262   S (mp);
17263
17264   /* Use a control ping for synchronization */
17265   MPING (CONTROL_PING, mp_ping);
17266   S (mp_ping);
17267
17268   W (ret);
17269   return ret;
17270 }
17271
17272 static int
17273 api_policer_add_del (vat_main_t * vam)
17274 {
17275   unformat_input_t *i = vam->input;
17276   vl_api_policer_add_del_t *mp;
17277   u8 is_add = 1;
17278   u8 *name = 0;
17279   u32 cir = 0;
17280   u32 eir = 0;
17281   u64 cb = 0;
17282   u64 eb = 0;
17283   u8 rate_type = 0;
17284   u8 round_type = 0;
17285   u8 type = 0;
17286   u8 color_aware = 0;
17287   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17288   int ret;
17289
17290   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17291   conform_action.dscp = 0;
17292   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17293   exceed_action.dscp = 0;
17294   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17295   violate_action.dscp = 0;
17296
17297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17298     {
17299       if (unformat (i, "del"))
17300         is_add = 0;
17301       else if (unformat (i, "name %s", &name))
17302         vec_add1 (name, 0);
17303       else if (unformat (i, "cir %u", &cir))
17304         ;
17305       else if (unformat (i, "eir %u", &eir))
17306         ;
17307       else if (unformat (i, "cb %u", &cb))
17308         ;
17309       else if (unformat (i, "eb %u", &eb))
17310         ;
17311       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17312                          &rate_type))
17313         ;
17314       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17315                          &round_type))
17316         ;
17317       else if (unformat (i, "type %U", unformat_policer_type, &type))
17318         ;
17319       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17320                          &conform_action))
17321         ;
17322       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17323                          &exceed_action))
17324         ;
17325       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17326                          &violate_action))
17327         ;
17328       else if (unformat (i, "color-aware"))
17329         color_aware = 1;
17330       else
17331         break;
17332     }
17333
17334   if (!vec_len (name))
17335     {
17336       errmsg ("policer name must be specified");
17337       return -99;
17338     }
17339
17340   if (vec_len (name) > 64)
17341     {
17342       errmsg ("policer name too long");
17343       return -99;
17344     }
17345
17346   M (POLICER_ADD_DEL, mp);
17347
17348   clib_memcpy (mp->name, name, vec_len (name));
17349   vec_free (name);
17350   mp->is_add = is_add;
17351   mp->cir = ntohl (cir);
17352   mp->eir = ntohl (eir);
17353   mp->cb = clib_net_to_host_u64 (cb);
17354   mp->eb = clib_net_to_host_u64 (eb);
17355   mp->rate_type = rate_type;
17356   mp->round_type = round_type;
17357   mp->type = type;
17358   mp->conform_action_type = conform_action.action_type;
17359   mp->conform_dscp = conform_action.dscp;
17360   mp->exceed_action_type = exceed_action.action_type;
17361   mp->exceed_dscp = exceed_action.dscp;
17362   mp->violate_action_type = violate_action.action_type;
17363   mp->violate_dscp = violate_action.dscp;
17364   mp->color_aware = color_aware;
17365
17366   S (mp);
17367   W (ret);
17368   return ret;
17369 }
17370
17371 static int
17372 api_policer_dump (vat_main_t * vam)
17373 {
17374   unformat_input_t *i = vam->input;
17375   vl_api_policer_dump_t *mp;
17376   vl_api_control_ping_t *mp_ping;
17377   u8 *match_name = 0;
17378   u8 match_name_valid = 0;
17379   int ret;
17380
17381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17382     {
17383       if (unformat (i, "name %s", &match_name))
17384         {
17385           vec_add1 (match_name, 0);
17386           match_name_valid = 1;
17387         }
17388       else
17389         break;
17390     }
17391
17392   M (POLICER_DUMP, mp);
17393   mp->match_name_valid = match_name_valid;
17394   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17395   vec_free (match_name);
17396   /* send it... */
17397   S (mp);
17398
17399   /* Use a control ping for synchronization */
17400   MPING (CONTROL_PING, mp_ping);
17401   S (mp_ping);
17402
17403   /* Wait for a reply... */
17404   W (ret);
17405   return ret;
17406 }
17407
17408 static int
17409 api_policer_classify_set_interface (vat_main_t * vam)
17410 {
17411   unformat_input_t *i = vam->input;
17412   vl_api_policer_classify_set_interface_t *mp;
17413   u32 sw_if_index;
17414   int sw_if_index_set;
17415   u32 ip4_table_index = ~0;
17416   u32 ip6_table_index = ~0;
17417   u32 l2_table_index = ~0;
17418   u8 is_add = 1;
17419   int ret;
17420
17421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17422     {
17423       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17424         sw_if_index_set = 1;
17425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17426         sw_if_index_set = 1;
17427       else if (unformat (i, "del"))
17428         is_add = 0;
17429       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17430         ;
17431       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17432         ;
17433       else if (unformat (i, "l2-table %d", &l2_table_index))
17434         ;
17435       else
17436         {
17437           clib_warning ("parse error '%U'", format_unformat_error, i);
17438           return -99;
17439         }
17440     }
17441
17442   if (sw_if_index_set == 0)
17443     {
17444       errmsg ("missing interface name or sw_if_index");
17445       return -99;
17446     }
17447
17448   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17449
17450   mp->sw_if_index = ntohl (sw_if_index);
17451   mp->ip4_table_index = ntohl (ip4_table_index);
17452   mp->ip6_table_index = ntohl (ip6_table_index);
17453   mp->l2_table_index = ntohl (l2_table_index);
17454   mp->is_add = is_add;
17455
17456   S (mp);
17457   W (ret);
17458   return ret;
17459 }
17460
17461 static int
17462 api_policer_classify_dump (vat_main_t * vam)
17463 {
17464   unformat_input_t *i = vam->input;
17465   vl_api_policer_classify_dump_t *mp;
17466   vl_api_control_ping_t *mp_ping;
17467   u8 type = POLICER_CLASSIFY_N_TABLES;
17468   int ret;
17469
17470   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17471     ;
17472   else
17473     {
17474       errmsg ("classify table type must be specified");
17475       return -99;
17476     }
17477
17478   if (!vam->json_output)
17479     {
17480       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17481     }
17482
17483   M (POLICER_CLASSIFY_DUMP, mp);
17484   mp->type = type;
17485   /* send it... */
17486   S (mp);
17487
17488   /* Use a control ping for synchronization */
17489   MPING (CONTROL_PING, mp_ping);
17490   S (mp_ping);
17491
17492   /* Wait for a reply... */
17493   W (ret);
17494   return ret;
17495 }
17496
17497 static int
17498 api_netmap_create (vat_main_t * vam)
17499 {
17500   unformat_input_t *i = vam->input;
17501   vl_api_netmap_create_t *mp;
17502   u8 *if_name = 0;
17503   u8 hw_addr[6];
17504   u8 random_hw_addr = 1;
17505   u8 is_pipe = 0;
17506   u8 is_master = 0;
17507   int ret;
17508
17509   clib_memset (hw_addr, 0, sizeof (hw_addr));
17510
17511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17512     {
17513       if (unformat (i, "name %s", &if_name))
17514         vec_add1 (if_name, 0);
17515       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17516         random_hw_addr = 0;
17517       else if (unformat (i, "pipe"))
17518         is_pipe = 1;
17519       else if (unformat (i, "master"))
17520         is_master = 1;
17521       else if (unformat (i, "slave"))
17522         is_master = 0;
17523       else
17524         break;
17525     }
17526
17527   if (!vec_len (if_name))
17528     {
17529       errmsg ("interface name must be specified");
17530       return -99;
17531     }
17532
17533   if (vec_len (if_name) > 64)
17534     {
17535       errmsg ("interface name too long");
17536       return -99;
17537     }
17538
17539   M (NETMAP_CREATE, mp);
17540
17541   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17542   clib_memcpy (mp->hw_addr, hw_addr, 6);
17543   mp->use_random_hw_addr = random_hw_addr;
17544   mp->is_pipe = is_pipe;
17545   mp->is_master = is_master;
17546   vec_free (if_name);
17547
17548   S (mp);
17549   W (ret);
17550   return ret;
17551 }
17552
17553 static int
17554 api_netmap_delete (vat_main_t * vam)
17555 {
17556   unformat_input_t *i = vam->input;
17557   vl_api_netmap_delete_t *mp;
17558   u8 *if_name = 0;
17559   int ret;
17560
17561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17562     {
17563       if (unformat (i, "name %s", &if_name))
17564         vec_add1 (if_name, 0);
17565       else
17566         break;
17567     }
17568
17569   if (!vec_len (if_name))
17570     {
17571       errmsg ("interface name must be specified");
17572       return -99;
17573     }
17574
17575   if (vec_len (if_name) > 64)
17576     {
17577       errmsg ("interface name too long");
17578       return -99;
17579     }
17580
17581   M (NETMAP_DELETE, mp);
17582
17583   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17584   vec_free (if_name);
17585
17586   S (mp);
17587   W (ret);
17588   return ret;
17589 }
17590
17591 static u8 *
17592 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17593 {
17594   vl_api_fib_path_nh_proto_t proto =
17595     va_arg (*args, vl_api_fib_path_nh_proto_t);
17596
17597   switch (proto)
17598     {
17599     case FIB_API_PATH_NH_PROTO_IP4:
17600       s = format (s, "ip4");
17601       break;
17602     case FIB_API_PATH_NH_PROTO_IP6:
17603       s = format (s, "ip6");
17604       break;
17605     case FIB_API_PATH_NH_PROTO_MPLS:
17606       s = format (s, "mpls");
17607       break;
17608     case FIB_API_PATH_NH_PROTO_BIER:
17609       s = format (s, "bier");
17610       break;
17611     case FIB_API_PATH_NH_PROTO_ETHERNET:
17612       s = format (s, "ethernet");
17613       break;
17614     }
17615
17616   return (s);
17617 }
17618
17619 static u8 *
17620 format_vl_api_ip_address_union (u8 * s, va_list * args)
17621 {
17622   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17623   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17624
17625   switch (af)
17626     {
17627     case ADDRESS_IP4:
17628       s = format (s, "%U", format_ip4_address, u->ip4);
17629       break;
17630     case ADDRESS_IP6:
17631       s = format (s, "%U", format_ip6_address, u->ip6);
17632       break;
17633     }
17634   return (s);
17635 }
17636
17637 static u8 *
17638 format_vl_api_fib_path_type (u8 * s, va_list * args)
17639 {
17640   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17641
17642   switch (t)
17643     {
17644     case FIB_API_PATH_TYPE_NORMAL:
17645       s = format (s, "normal");
17646       break;
17647     case FIB_API_PATH_TYPE_LOCAL:
17648       s = format (s, "local");
17649       break;
17650     case FIB_API_PATH_TYPE_DROP:
17651       s = format (s, "drop");
17652       break;
17653     case FIB_API_PATH_TYPE_UDP_ENCAP:
17654       s = format (s, "udp-encap");
17655       break;
17656     case FIB_API_PATH_TYPE_BIER_IMP:
17657       s = format (s, "bier-imp");
17658       break;
17659     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17660       s = format (s, "unreach");
17661       break;
17662     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17663       s = format (s, "prohibit");
17664       break;
17665     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17666       s = format (s, "src-lookup");
17667       break;
17668     case FIB_API_PATH_TYPE_DVR:
17669       s = format (s, "dvr");
17670       break;
17671     case FIB_API_PATH_TYPE_INTERFACE_RX:
17672       s = format (s, "interface-rx");
17673       break;
17674     case FIB_API_PATH_TYPE_CLASSIFY:
17675       s = format (s, "classify");
17676       break;
17677     }
17678
17679   return (s);
17680 }
17681
17682 static void
17683 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17684 {
17685   print (vam->ofp,
17686          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17687          ntohl (fp->weight), ntohl (fp->sw_if_index),
17688          format_vl_api_fib_path_type, fp->type,
17689          format_fib_api_path_nh_proto, fp->proto,
17690          format_vl_api_ip_address_union, &fp->nh.address);
17691 }
17692
17693 static void
17694 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17695                                  vl_api_fib_path_t * fp)
17696 {
17697   struct in_addr ip4;
17698   struct in6_addr ip6;
17699
17700   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17701   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17702   vat_json_object_add_uint (node, "type", fp->type);
17703   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17704   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17705     {
17706       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17707       vat_json_object_add_ip4 (node, "next_hop", ip4);
17708     }
17709   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17710     {
17711       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17712       vat_json_object_add_ip6 (node, "next_hop", ip6);
17713     }
17714 }
17715
17716 static void
17717 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17718 {
17719   vat_main_t *vam = &vat_main;
17720   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17721   vl_api_fib_path_t *fp;
17722   i32 i;
17723
17724   print (vam->ofp, "sw_if_index %d via:",
17725          ntohl (mp->mt_tunnel.mt_sw_if_index));
17726   fp = mp->mt_tunnel.mt_paths;
17727   for (i = 0; i < count; i++)
17728     {
17729       vl_api_fib_path_print (vam, fp);
17730       fp++;
17731     }
17732
17733   print (vam->ofp, "");
17734 }
17735
17736 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17737 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17738
17739 static void
17740 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17741 {
17742   vat_main_t *vam = &vat_main;
17743   vat_json_node_t *node = NULL;
17744   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17745   vl_api_fib_path_t *fp;
17746   i32 i;
17747
17748   if (VAT_JSON_ARRAY != vam->json_tree.type)
17749     {
17750       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17751       vat_json_init_array (&vam->json_tree);
17752     }
17753   node = vat_json_array_add (&vam->json_tree);
17754
17755   vat_json_init_object (node);
17756   vat_json_object_add_uint (node, "sw_if_index",
17757                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17758
17759   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17760
17761   fp = mp->mt_tunnel.mt_paths;
17762   for (i = 0; i < count; i++)
17763     {
17764       vl_api_mpls_fib_path_json_print (node, fp);
17765       fp++;
17766     }
17767 }
17768
17769 static int
17770 api_mpls_tunnel_dump (vat_main_t * vam)
17771 {
17772   vl_api_mpls_tunnel_dump_t *mp;
17773   vl_api_control_ping_t *mp_ping;
17774   int ret;
17775
17776   M (MPLS_TUNNEL_DUMP, mp);
17777
17778   S (mp);
17779
17780   /* Use a control ping for synchronization */
17781   MPING (CONTROL_PING, mp_ping);
17782   S (mp_ping);
17783
17784   W (ret);
17785   return ret;
17786 }
17787
17788 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17789 #define vl_api_mpls_table_details_t_print vl_noop_handler
17790
17791
17792 static void
17793 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17794 {
17795   vat_main_t *vam = &vat_main;
17796
17797   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17798 }
17799
17800 static void vl_api_mpls_table_details_t_handler_json
17801   (vl_api_mpls_table_details_t * mp)
17802 {
17803   vat_main_t *vam = &vat_main;
17804   vat_json_node_t *node = NULL;
17805
17806   if (VAT_JSON_ARRAY != vam->json_tree.type)
17807     {
17808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17809       vat_json_init_array (&vam->json_tree);
17810     }
17811   node = vat_json_array_add (&vam->json_tree);
17812
17813   vat_json_init_object (node);
17814   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17815 }
17816
17817 static int
17818 api_mpls_table_dump (vat_main_t * vam)
17819 {
17820   vl_api_mpls_table_dump_t *mp;
17821   vl_api_control_ping_t *mp_ping;
17822   int ret;
17823
17824   M (MPLS_TABLE_DUMP, mp);
17825   S (mp);
17826
17827   /* Use a control ping for synchronization */
17828   MPING (CONTROL_PING, mp_ping);
17829   S (mp_ping);
17830
17831   W (ret);
17832   return ret;
17833 }
17834
17835 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17836 #define vl_api_mpls_route_details_t_print vl_noop_handler
17837
17838 static void
17839 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17840 {
17841   vat_main_t *vam = &vat_main;
17842   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17843   vl_api_fib_path_t *fp;
17844   int i;
17845
17846   print (vam->ofp,
17847          "table-id %d, label %u, ess_bit %u",
17848          ntohl (mp->mr_route.mr_table_id),
17849          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17850   fp = mp->mr_route.mr_paths;
17851   for (i = 0; i < count; i++)
17852     {
17853       vl_api_fib_path_print (vam, fp);
17854       fp++;
17855     }
17856 }
17857
17858 static void vl_api_mpls_route_details_t_handler_json
17859   (vl_api_mpls_route_details_t * mp)
17860 {
17861   vat_main_t *vam = &vat_main;
17862   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17863   vat_json_node_t *node = NULL;
17864   vl_api_fib_path_t *fp;
17865   int i;
17866
17867   if (VAT_JSON_ARRAY != vam->json_tree.type)
17868     {
17869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17870       vat_json_init_array (&vam->json_tree);
17871     }
17872   node = vat_json_array_add (&vam->json_tree);
17873
17874   vat_json_init_object (node);
17875   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17876   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17877   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17878   vat_json_object_add_uint (node, "path_count", count);
17879   fp = mp->mr_route.mr_paths;
17880   for (i = 0; i < count; i++)
17881     {
17882       vl_api_mpls_fib_path_json_print (node, fp);
17883       fp++;
17884     }
17885 }
17886
17887 static int
17888 api_mpls_route_dump (vat_main_t * vam)
17889 {
17890   unformat_input_t *input = vam->input;
17891   vl_api_mpls_route_dump_t *mp;
17892   vl_api_control_ping_t *mp_ping;
17893   u32 table_id;
17894   int ret;
17895
17896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (input, "table_id %d", &table_id))
17899         ;
17900       else
17901         break;
17902     }
17903   if (table_id == ~0)
17904     {
17905       errmsg ("missing table id");
17906       return -99;
17907     }
17908
17909   M (MPLS_ROUTE_DUMP, mp);
17910
17911   mp->table.mt_table_id = ntohl (table_id);
17912   S (mp);
17913
17914   /* Use a control ping for synchronization */
17915   MPING (CONTROL_PING, mp_ping);
17916   S (mp_ping);
17917
17918   W (ret);
17919   return ret;
17920 }
17921
17922 #define vl_api_ip_table_details_t_endian vl_noop_handler
17923 #define vl_api_ip_table_details_t_print vl_noop_handler
17924
17925 static void
17926 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17927 {
17928   vat_main_t *vam = &vat_main;
17929
17930   print (vam->ofp,
17931          "%s; table-id %d, prefix %U/%d",
17932          mp->table.name, ntohl (mp->table.table_id));
17933 }
17934
17935
17936 static void vl_api_ip_table_details_t_handler_json
17937   (vl_api_ip_table_details_t * mp)
17938 {
17939   vat_main_t *vam = &vat_main;
17940   vat_json_node_t *node = NULL;
17941
17942   if (VAT_JSON_ARRAY != vam->json_tree.type)
17943     {
17944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17945       vat_json_init_array (&vam->json_tree);
17946     }
17947   node = vat_json_array_add (&vam->json_tree);
17948
17949   vat_json_init_object (node);
17950   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17951 }
17952
17953 static int
17954 api_ip_table_dump (vat_main_t * vam)
17955 {
17956   vl_api_ip_table_dump_t *mp;
17957   vl_api_control_ping_t *mp_ping;
17958   int ret;
17959
17960   M (IP_TABLE_DUMP, mp);
17961   S (mp);
17962
17963   /* Use a control ping for synchronization */
17964   MPING (CONTROL_PING, mp_ping);
17965   S (mp_ping);
17966
17967   W (ret);
17968   return ret;
17969 }
17970
17971 static int
17972 api_ip_mtable_dump (vat_main_t * vam)
17973 {
17974   vl_api_ip_mtable_dump_t *mp;
17975   vl_api_control_ping_t *mp_ping;
17976   int ret;
17977
17978   M (IP_MTABLE_DUMP, mp);
17979   S (mp);
17980
17981   /* Use a control ping for synchronization */
17982   MPING (CONTROL_PING, mp_ping);
17983   S (mp_ping);
17984
17985   W (ret);
17986   return ret;
17987 }
17988
17989 static int
17990 api_ip_mroute_dump (vat_main_t * vam)
17991 {
17992   unformat_input_t *input = vam->input;
17993   vl_api_control_ping_t *mp_ping;
17994   vl_api_ip_mroute_dump_t *mp;
17995   int ret, is_ip6;
17996   u32 table_id;
17997
17998   is_ip6 = 0;
17999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18000     {
18001       if (unformat (input, "table_id %d", &table_id))
18002         ;
18003       else if (unformat (input, "ip6"))
18004         is_ip6 = 1;
18005       else if (unformat (input, "ip4"))
18006         is_ip6 = 0;
18007       else
18008         break;
18009     }
18010   if (table_id == ~0)
18011     {
18012       errmsg ("missing table id");
18013       return -99;
18014     }
18015
18016   M (IP_MROUTE_DUMP, mp);
18017   mp->table.table_id = table_id;
18018   mp->table.is_ip6 = is_ip6;
18019   S (mp);
18020
18021   /* Use a control ping for synchronization */
18022   MPING (CONTROL_PING, mp_ping);
18023   S (mp_ping);
18024
18025   W (ret);
18026   return ret;
18027 }
18028
18029 #define vl_api_ip_route_details_t_endian vl_noop_handler
18030 #define vl_api_ip_route_details_t_print vl_noop_handler
18031
18032 static void
18033 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18034 {
18035   vat_main_t *vam = &vat_main;
18036   u8 count = mp->route.n_paths;
18037   vl_api_fib_path_t *fp;
18038   int i;
18039
18040   print (vam->ofp,
18041          "table-id %d, prefix %U/%d",
18042          ntohl (mp->route.table_id),
18043          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18044   for (i = 0; i < count; i++)
18045     {
18046       fp = &mp->route.paths[i];
18047
18048       vl_api_fib_path_print (vam, fp);
18049       fp++;
18050     }
18051 }
18052
18053 static void vl_api_ip_route_details_t_handler_json
18054   (vl_api_ip_route_details_t * mp)
18055 {
18056   vat_main_t *vam = &vat_main;
18057   u8 count = mp->route.n_paths;
18058   vat_json_node_t *node = NULL;
18059   struct in_addr ip4;
18060   struct in6_addr ip6;
18061   vl_api_fib_path_t *fp;
18062   int i;
18063
18064   if (VAT_JSON_ARRAY != vam->json_tree.type)
18065     {
18066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18067       vat_json_init_array (&vam->json_tree);
18068     }
18069   node = vat_json_array_add (&vam->json_tree);
18070
18071   vat_json_init_object (node);
18072   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18073   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18074     {
18075       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18076       vat_json_object_add_ip6 (node, "prefix", ip6);
18077     }
18078   else
18079     {
18080       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18081       vat_json_object_add_ip4 (node, "prefix", ip4);
18082     }
18083   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18084   vat_json_object_add_uint (node, "path_count", count);
18085   for (i = 0; i < count; i++)
18086     {
18087       fp = &mp->route.paths[i];
18088       vl_api_mpls_fib_path_json_print (node, fp);
18089     }
18090 }
18091
18092 static int
18093 api_ip_route_dump (vat_main_t * vam)
18094 {
18095   unformat_input_t *input = vam->input;
18096   vl_api_ip_route_dump_t *mp;
18097   vl_api_control_ping_t *mp_ping;
18098   u32 table_id;
18099   u8 is_ip6;
18100   int ret;
18101
18102   is_ip6 = 0;
18103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18104     {
18105       if (unformat (input, "table_id %d", &table_id))
18106         ;
18107       else if (unformat (input, "ip6"))
18108         is_ip6 = 1;
18109       else if (unformat (input, "ip4"))
18110         is_ip6 = 0;
18111       else
18112         break;
18113     }
18114   if (table_id == ~0)
18115     {
18116       errmsg ("missing table id");
18117       return -99;
18118     }
18119
18120   M (IP_ROUTE_DUMP, mp);
18121
18122   mp->table.table_id = table_id;
18123   mp->table.is_ip6 = is_ip6;
18124
18125   S (mp);
18126
18127   /* Use a control ping for synchronization */
18128   MPING (CONTROL_PING, mp_ping);
18129   S (mp_ping);
18130
18131   W (ret);
18132   return ret;
18133 }
18134
18135 int
18136 api_classify_table_ids (vat_main_t * vam)
18137 {
18138   vl_api_classify_table_ids_t *mp;
18139   int ret;
18140
18141   /* Construct the API message */
18142   M (CLASSIFY_TABLE_IDS, mp);
18143   mp->context = 0;
18144
18145   S (mp);
18146   W (ret);
18147   return ret;
18148 }
18149
18150 int
18151 api_classify_table_by_interface (vat_main_t * vam)
18152 {
18153   unformat_input_t *input = vam->input;
18154   vl_api_classify_table_by_interface_t *mp;
18155
18156   u32 sw_if_index = ~0;
18157   int ret;
18158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18159     {
18160       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18161         ;
18162       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18163         ;
18164       else
18165         break;
18166     }
18167   if (sw_if_index == ~0)
18168     {
18169       errmsg ("missing interface name or sw_if_index");
18170       return -99;
18171     }
18172
18173   /* Construct the API message */
18174   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18175   mp->context = 0;
18176   mp->sw_if_index = ntohl (sw_if_index);
18177
18178   S (mp);
18179   W (ret);
18180   return ret;
18181 }
18182
18183 int
18184 api_classify_table_info (vat_main_t * vam)
18185 {
18186   unformat_input_t *input = vam->input;
18187   vl_api_classify_table_info_t *mp;
18188
18189   u32 table_id = ~0;
18190   int ret;
18191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18192     {
18193       if (unformat (input, "table_id %d", &table_id))
18194         ;
18195       else
18196         break;
18197     }
18198   if (table_id == ~0)
18199     {
18200       errmsg ("missing table id");
18201       return -99;
18202     }
18203
18204   /* Construct the API message */
18205   M (CLASSIFY_TABLE_INFO, mp);
18206   mp->context = 0;
18207   mp->table_id = ntohl (table_id);
18208
18209   S (mp);
18210   W (ret);
18211   return ret;
18212 }
18213
18214 int
18215 api_classify_session_dump (vat_main_t * vam)
18216 {
18217   unformat_input_t *input = vam->input;
18218   vl_api_classify_session_dump_t *mp;
18219   vl_api_control_ping_t *mp_ping;
18220
18221   u32 table_id = ~0;
18222   int ret;
18223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18224     {
18225       if (unformat (input, "table_id %d", &table_id))
18226         ;
18227       else
18228         break;
18229     }
18230   if (table_id == ~0)
18231     {
18232       errmsg ("missing table id");
18233       return -99;
18234     }
18235
18236   /* Construct the API message */
18237   M (CLASSIFY_SESSION_DUMP, mp);
18238   mp->context = 0;
18239   mp->table_id = ntohl (table_id);
18240   S (mp);
18241
18242   /* Use a control ping for synchronization */
18243   MPING (CONTROL_PING, mp_ping);
18244   S (mp_ping);
18245
18246   W (ret);
18247   return ret;
18248 }
18249
18250 static void
18251 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18252 {
18253   vat_main_t *vam = &vat_main;
18254
18255   print (vam->ofp, "collector_address %U, collector_port %d, "
18256          "src_address %U, vrf_id %d, path_mtu %u, "
18257          "template_interval %u, udp_checksum %d",
18258          format_ip4_address, mp->collector_address,
18259          ntohs (mp->collector_port),
18260          format_ip4_address, mp->src_address,
18261          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18262          ntohl (mp->template_interval), mp->udp_checksum);
18263
18264   vam->retval = 0;
18265   vam->result_ready = 1;
18266 }
18267
18268 static void
18269   vl_api_ipfix_exporter_details_t_handler_json
18270   (vl_api_ipfix_exporter_details_t * mp)
18271 {
18272   vat_main_t *vam = &vat_main;
18273   vat_json_node_t node;
18274   struct in_addr collector_address;
18275   struct in_addr src_address;
18276
18277   vat_json_init_object (&node);
18278   clib_memcpy (&collector_address, &mp->collector_address,
18279                sizeof (collector_address));
18280   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18281   vat_json_object_add_uint (&node, "collector_port",
18282                             ntohs (mp->collector_port));
18283   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18284   vat_json_object_add_ip4 (&node, "src_address", src_address);
18285   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18286   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18287   vat_json_object_add_uint (&node, "template_interval",
18288                             ntohl (mp->template_interval));
18289   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18290
18291   vat_json_print (vam->ofp, &node);
18292   vat_json_free (&node);
18293   vam->retval = 0;
18294   vam->result_ready = 1;
18295 }
18296
18297 int
18298 api_ipfix_exporter_dump (vat_main_t * vam)
18299 {
18300   vl_api_ipfix_exporter_dump_t *mp;
18301   int ret;
18302
18303   /* Construct the API message */
18304   M (IPFIX_EXPORTER_DUMP, mp);
18305   mp->context = 0;
18306
18307   S (mp);
18308   W (ret);
18309   return ret;
18310 }
18311
18312 static int
18313 api_ipfix_classify_stream_dump (vat_main_t * vam)
18314 {
18315   vl_api_ipfix_classify_stream_dump_t *mp;
18316   int ret;
18317
18318   /* Construct the API message */
18319   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18320   mp->context = 0;
18321
18322   S (mp);
18323   W (ret);
18324   return ret;
18325   /* NOTREACHED */
18326   return 0;
18327 }
18328
18329 static void
18330   vl_api_ipfix_classify_stream_details_t_handler
18331   (vl_api_ipfix_classify_stream_details_t * mp)
18332 {
18333   vat_main_t *vam = &vat_main;
18334   print (vam->ofp, "domain_id %d, src_port %d",
18335          ntohl (mp->domain_id), ntohs (mp->src_port));
18336   vam->retval = 0;
18337   vam->result_ready = 1;
18338 }
18339
18340 static void
18341   vl_api_ipfix_classify_stream_details_t_handler_json
18342   (vl_api_ipfix_classify_stream_details_t * mp)
18343 {
18344   vat_main_t *vam = &vat_main;
18345   vat_json_node_t node;
18346
18347   vat_json_init_object (&node);
18348   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18349   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18350
18351   vat_json_print (vam->ofp, &node);
18352   vat_json_free (&node);
18353   vam->retval = 0;
18354   vam->result_ready = 1;
18355 }
18356
18357 static int
18358 api_ipfix_classify_table_dump (vat_main_t * vam)
18359 {
18360   vl_api_ipfix_classify_table_dump_t *mp;
18361   vl_api_control_ping_t *mp_ping;
18362   int ret;
18363
18364   if (!vam->json_output)
18365     {
18366       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18367              "transport_protocol");
18368     }
18369
18370   /* Construct the API message */
18371   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18372
18373   /* send it... */
18374   S (mp);
18375
18376   /* Use a control ping for synchronization */
18377   MPING (CONTROL_PING, mp_ping);
18378   S (mp_ping);
18379
18380   W (ret);
18381   return ret;
18382 }
18383
18384 static void
18385   vl_api_ipfix_classify_table_details_t_handler
18386   (vl_api_ipfix_classify_table_details_t * mp)
18387 {
18388   vat_main_t *vam = &vat_main;
18389   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18390          mp->transport_protocol);
18391 }
18392
18393 static void
18394   vl_api_ipfix_classify_table_details_t_handler_json
18395   (vl_api_ipfix_classify_table_details_t * mp)
18396 {
18397   vat_json_node_t *node = NULL;
18398   vat_main_t *vam = &vat_main;
18399
18400   if (VAT_JSON_ARRAY != vam->json_tree.type)
18401     {
18402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18403       vat_json_init_array (&vam->json_tree);
18404     }
18405
18406   node = vat_json_array_add (&vam->json_tree);
18407   vat_json_init_object (node);
18408
18409   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18410   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18411   vat_json_object_add_uint (node, "transport_protocol",
18412                             mp->transport_protocol);
18413 }
18414
18415 static int
18416 api_sw_interface_span_enable_disable (vat_main_t * vam)
18417 {
18418   unformat_input_t *i = vam->input;
18419   vl_api_sw_interface_span_enable_disable_t *mp;
18420   u32 src_sw_if_index = ~0;
18421   u32 dst_sw_if_index = ~0;
18422   u8 state = 3;
18423   int ret;
18424   u8 is_l2 = 0;
18425
18426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18427     {
18428       if (unformat
18429           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18430         ;
18431       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18432         ;
18433       else
18434         if (unformat
18435             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18436         ;
18437       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18438         ;
18439       else if (unformat (i, "disable"))
18440         state = 0;
18441       else if (unformat (i, "rx"))
18442         state = 1;
18443       else if (unformat (i, "tx"))
18444         state = 2;
18445       else if (unformat (i, "both"))
18446         state = 3;
18447       else if (unformat (i, "l2"))
18448         is_l2 = 1;
18449       else
18450         break;
18451     }
18452
18453   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18454
18455   mp->sw_if_index_from = htonl (src_sw_if_index);
18456   mp->sw_if_index_to = htonl (dst_sw_if_index);
18457   mp->state = state;
18458   mp->is_l2 = is_l2;
18459
18460   S (mp);
18461   W (ret);
18462   return ret;
18463 }
18464
18465 static void
18466 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18467                                             * mp)
18468 {
18469   vat_main_t *vam = &vat_main;
18470   u8 *sw_if_from_name = 0;
18471   u8 *sw_if_to_name = 0;
18472   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18473   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18474   char *states[] = { "none", "rx", "tx", "both" };
18475   hash_pair_t *p;
18476
18477   /* *INDENT-OFF* */
18478   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18479   ({
18480     if ((u32) p->value[0] == sw_if_index_from)
18481       {
18482         sw_if_from_name = (u8 *)(p->key);
18483         if (sw_if_to_name)
18484           break;
18485       }
18486     if ((u32) p->value[0] == sw_if_index_to)
18487       {
18488         sw_if_to_name = (u8 *)(p->key);
18489         if (sw_if_from_name)
18490           break;
18491       }
18492   }));
18493   /* *INDENT-ON* */
18494   print (vam->ofp, "%20s => %20s (%s) %s",
18495          sw_if_from_name, sw_if_to_name, states[mp->state],
18496          mp->is_l2 ? "l2" : "device");
18497 }
18498
18499 static void
18500   vl_api_sw_interface_span_details_t_handler_json
18501   (vl_api_sw_interface_span_details_t * mp)
18502 {
18503   vat_main_t *vam = &vat_main;
18504   vat_json_node_t *node = NULL;
18505   u8 *sw_if_from_name = 0;
18506   u8 *sw_if_to_name = 0;
18507   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18508   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18509   hash_pair_t *p;
18510
18511   /* *INDENT-OFF* */
18512   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18513   ({
18514     if ((u32) p->value[0] == sw_if_index_from)
18515       {
18516         sw_if_from_name = (u8 *)(p->key);
18517         if (sw_if_to_name)
18518           break;
18519       }
18520     if ((u32) p->value[0] == sw_if_index_to)
18521       {
18522         sw_if_to_name = (u8 *)(p->key);
18523         if (sw_if_from_name)
18524           break;
18525       }
18526   }));
18527   /* *INDENT-ON* */
18528
18529   if (VAT_JSON_ARRAY != vam->json_tree.type)
18530     {
18531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18532       vat_json_init_array (&vam->json_tree);
18533     }
18534   node = vat_json_array_add (&vam->json_tree);
18535
18536   vat_json_init_object (node);
18537   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18538   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18539   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18540   if (0 != sw_if_to_name)
18541     {
18542       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18543     }
18544   vat_json_object_add_uint (node, "state", mp->state);
18545   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18546 }
18547
18548 static int
18549 api_sw_interface_span_dump (vat_main_t * vam)
18550 {
18551   unformat_input_t *input = vam->input;
18552   vl_api_sw_interface_span_dump_t *mp;
18553   vl_api_control_ping_t *mp_ping;
18554   u8 is_l2 = 0;
18555   int ret;
18556
18557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18558     {
18559       if (unformat (input, "l2"))
18560         is_l2 = 1;
18561       else
18562         break;
18563     }
18564
18565   M (SW_INTERFACE_SPAN_DUMP, mp);
18566   mp->is_l2 = is_l2;
18567   S (mp);
18568
18569   /* Use a control ping for synchronization */
18570   MPING (CONTROL_PING, mp_ping);
18571   S (mp_ping);
18572
18573   W (ret);
18574   return ret;
18575 }
18576
18577 int
18578 api_pg_create_interface (vat_main_t * vam)
18579 {
18580   unformat_input_t *input = vam->input;
18581   vl_api_pg_create_interface_t *mp;
18582
18583   u32 if_id = ~0, gso_size = 0;
18584   u8 gso_enabled = 0;
18585   int ret;
18586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18587     {
18588       if (unformat (input, "if_id %d", &if_id))
18589         ;
18590       else if (unformat (input, "gso-enabled"))
18591         {
18592           gso_enabled = 1;
18593           if (unformat (input, "gso-size %u", &gso_size))
18594             ;
18595           else
18596             {
18597               errmsg ("missing gso-size");
18598               return -99;
18599             }
18600         }
18601       else
18602         break;
18603     }
18604   if (if_id == ~0)
18605     {
18606       errmsg ("missing pg interface index");
18607       return -99;
18608     }
18609
18610   /* Construct the API message */
18611   M (PG_CREATE_INTERFACE, mp);
18612   mp->context = 0;
18613   mp->interface_id = ntohl (if_id);
18614   mp->gso_enabled = gso_enabled;
18615
18616   S (mp);
18617   W (ret);
18618   return ret;
18619 }
18620
18621 int
18622 api_pg_capture (vat_main_t * vam)
18623 {
18624   unformat_input_t *input = vam->input;
18625   vl_api_pg_capture_t *mp;
18626
18627   u32 if_id = ~0;
18628   u8 enable = 1;
18629   u32 count = 1;
18630   u8 pcap_file_set = 0;
18631   u8 *pcap_file = 0;
18632   int ret;
18633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18634     {
18635       if (unformat (input, "if_id %d", &if_id))
18636         ;
18637       else if (unformat (input, "pcap %s", &pcap_file))
18638         pcap_file_set = 1;
18639       else if (unformat (input, "count %d", &count))
18640         ;
18641       else if (unformat (input, "disable"))
18642         enable = 0;
18643       else
18644         break;
18645     }
18646   if (if_id == ~0)
18647     {
18648       errmsg ("missing pg interface index");
18649       return -99;
18650     }
18651   if (pcap_file_set > 0)
18652     {
18653       if (vec_len (pcap_file) > 255)
18654         {
18655           errmsg ("pcap file name is too long");
18656           return -99;
18657         }
18658     }
18659
18660   u32 name_len = vec_len (pcap_file);
18661   /* Construct the API message */
18662   M (PG_CAPTURE, mp);
18663   mp->context = 0;
18664   mp->interface_id = ntohl (if_id);
18665   mp->is_enabled = enable;
18666   mp->count = ntohl (count);
18667   mp->pcap_name_length = ntohl (name_len);
18668   if (pcap_file_set != 0)
18669     {
18670       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18671     }
18672   vec_free (pcap_file);
18673
18674   S (mp);
18675   W (ret);
18676   return ret;
18677 }
18678
18679 int
18680 api_pg_enable_disable (vat_main_t * vam)
18681 {
18682   unformat_input_t *input = vam->input;
18683   vl_api_pg_enable_disable_t *mp;
18684
18685   u8 enable = 1;
18686   u8 stream_name_set = 0;
18687   u8 *stream_name = 0;
18688   int ret;
18689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18690     {
18691       if (unformat (input, "stream %s", &stream_name))
18692         stream_name_set = 1;
18693       else if (unformat (input, "disable"))
18694         enable = 0;
18695       else
18696         break;
18697     }
18698
18699   if (stream_name_set > 0)
18700     {
18701       if (vec_len (stream_name) > 255)
18702         {
18703           errmsg ("stream name too long");
18704           return -99;
18705         }
18706     }
18707
18708   u32 name_len = vec_len (stream_name);
18709   /* Construct the API message */
18710   M (PG_ENABLE_DISABLE, mp);
18711   mp->context = 0;
18712   mp->is_enabled = enable;
18713   if (stream_name_set != 0)
18714     {
18715       mp->stream_name_length = ntohl (name_len);
18716       clib_memcpy (mp->stream_name, stream_name, name_len);
18717     }
18718   vec_free (stream_name);
18719
18720   S (mp);
18721   W (ret);
18722   return ret;
18723 }
18724
18725 int
18726 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18727 {
18728   unformat_input_t *input = vam->input;
18729   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18730
18731   u16 *low_ports = 0;
18732   u16 *high_ports = 0;
18733   u16 this_low;
18734   u16 this_hi;
18735   vl_api_prefix_t prefix;
18736   u32 tmp, tmp2;
18737   u8 prefix_set = 0;
18738   u32 vrf_id = ~0;
18739   u8 is_add = 1;
18740   int ret;
18741
18742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18743     {
18744       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18745         prefix_set = 1;
18746       else if (unformat (input, "vrf %d", &vrf_id))
18747         ;
18748       else if (unformat (input, "del"))
18749         is_add = 0;
18750       else if (unformat (input, "port %d", &tmp))
18751         {
18752           if (tmp == 0 || tmp > 65535)
18753             {
18754               errmsg ("port %d out of range", tmp);
18755               return -99;
18756             }
18757           this_low = tmp;
18758           this_hi = this_low + 1;
18759           vec_add1 (low_ports, this_low);
18760           vec_add1 (high_ports, this_hi);
18761         }
18762       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18763         {
18764           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18765             {
18766               errmsg ("incorrect range parameters");
18767               return -99;
18768             }
18769           this_low = tmp;
18770           /* Note: in debug CLI +1 is added to high before
18771              passing to real fn that does "the work"
18772              (ip_source_and_port_range_check_add_del).
18773              This fn is a wrapper around the binary API fn a
18774              control plane will call, which expects this increment
18775              to have occurred. Hence letting the binary API control
18776              plane fn do the increment for consistency between VAT
18777              and other control planes.
18778            */
18779           this_hi = tmp2;
18780           vec_add1 (low_ports, this_low);
18781           vec_add1 (high_ports, this_hi);
18782         }
18783       else
18784         break;
18785     }
18786
18787   if (prefix_set == 0)
18788     {
18789       errmsg ("<address>/<mask> not specified");
18790       return -99;
18791     }
18792
18793   if (vrf_id == ~0)
18794     {
18795       errmsg ("VRF ID required, not specified");
18796       return -99;
18797     }
18798
18799   if (vrf_id == 0)
18800     {
18801       errmsg
18802         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18803       return -99;
18804     }
18805
18806   if (vec_len (low_ports) == 0)
18807     {
18808       errmsg ("At least one port or port range required");
18809       return -99;
18810     }
18811
18812   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18813
18814   mp->is_add = is_add;
18815
18816   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18817
18818   mp->number_of_ranges = vec_len (low_ports);
18819
18820   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18821   vec_free (low_ports);
18822
18823   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18824   vec_free (high_ports);
18825
18826   mp->vrf_id = ntohl (vrf_id);
18827
18828   S (mp);
18829   W (ret);
18830   return ret;
18831 }
18832
18833 int
18834 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18835 {
18836   unformat_input_t *input = vam->input;
18837   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18838   u32 sw_if_index = ~0;
18839   int vrf_set = 0;
18840   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18841   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18842   u8 is_add = 1;
18843   int ret;
18844
18845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18846     {
18847       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18848         ;
18849       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18850         ;
18851       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18852         vrf_set = 1;
18853       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18854         vrf_set = 1;
18855       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18856         vrf_set = 1;
18857       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18858         vrf_set = 1;
18859       else if (unformat (input, "del"))
18860         is_add = 0;
18861       else
18862         break;
18863     }
18864
18865   if (sw_if_index == ~0)
18866     {
18867       errmsg ("Interface required but not specified");
18868       return -99;
18869     }
18870
18871   if (vrf_set == 0)
18872     {
18873       errmsg ("VRF ID required but not specified");
18874       return -99;
18875     }
18876
18877   if (tcp_out_vrf_id == 0
18878       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18879     {
18880       errmsg
18881         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18882       return -99;
18883     }
18884
18885   /* Construct the API message */
18886   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18887
18888   mp->sw_if_index = ntohl (sw_if_index);
18889   mp->is_add = is_add;
18890   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18891   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18892   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18893   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18894
18895   /* send it... */
18896   S (mp);
18897
18898   /* Wait for a reply... */
18899   W (ret);
18900   return ret;
18901 }
18902
18903 static int
18904 api_set_punt (vat_main_t * vam)
18905 {
18906   unformat_input_t *i = vam->input;
18907   vl_api_address_family_t af;
18908   vl_api_set_punt_t *mp;
18909   u32 protocol = ~0;
18910   u32 port = ~0;
18911   int is_add = 1;
18912   int ret;
18913
18914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18915     {
18916       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18917         ;
18918       else if (unformat (i, "protocol %d", &protocol))
18919         ;
18920       else if (unformat (i, "port %d", &port))
18921         ;
18922       else if (unformat (i, "del"))
18923         is_add = 0;
18924       else
18925         {
18926           clib_warning ("parse error '%U'", format_unformat_error, i);
18927           return -99;
18928         }
18929     }
18930
18931   M (SET_PUNT, mp);
18932
18933   mp->is_add = (u8) is_add;
18934   mp->punt.type = PUNT_API_TYPE_L4;
18935   mp->punt.punt.l4.af = af;
18936   mp->punt.punt.l4.protocol = (u8) protocol;
18937   mp->punt.punt.l4.port = htons ((u16) port);
18938
18939   S (mp);
18940   W (ret);
18941   return ret;
18942 }
18943
18944 static int
18945 api_delete_subif (vat_main_t * vam)
18946 {
18947   unformat_input_t *i = vam->input;
18948   vl_api_delete_subif_t *mp;
18949   u32 sw_if_index = ~0;
18950   int ret;
18951
18952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18953     {
18954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18955         ;
18956       if (unformat (i, "sw_if_index %d", &sw_if_index))
18957         ;
18958       else
18959         break;
18960     }
18961
18962   if (sw_if_index == ~0)
18963     {
18964       errmsg ("missing sw_if_index");
18965       return -99;
18966     }
18967
18968   /* Construct the API message */
18969   M (DELETE_SUBIF, mp);
18970   mp->sw_if_index = ntohl (sw_if_index);
18971
18972   S (mp);
18973   W (ret);
18974   return ret;
18975 }
18976
18977 #define foreach_pbb_vtr_op      \
18978 _("disable",  L2_VTR_DISABLED)  \
18979 _("pop",  L2_VTR_POP_2)         \
18980 _("push",  L2_VTR_PUSH_2)
18981
18982 static int
18983 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18984 {
18985   unformat_input_t *i = vam->input;
18986   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18987   u32 sw_if_index = ~0, vtr_op = ~0;
18988   u16 outer_tag = ~0;
18989   u8 dmac[6], smac[6];
18990   u8 dmac_set = 0, smac_set = 0;
18991   u16 vlanid = 0;
18992   u32 sid = ~0;
18993   u32 tmp;
18994   int ret;
18995
18996   /* Shut up coverity */
18997   clib_memset (dmac, 0, sizeof (dmac));
18998   clib_memset (smac, 0, sizeof (smac));
18999
19000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19001     {
19002       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19003         ;
19004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19005         ;
19006       else if (unformat (i, "vtr_op %d", &vtr_op))
19007         ;
19008 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19009       foreach_pbb_vtr_op
19010 #undef _
19011         else if (unformat (i, "translate_pbb_stag"))
19012         {
19013           if (unformat (i, "%d", &tmp))
19014             {
19015               vtr_op = L2_VTR_TRANSLATE_2_1;
19016               outer_tag = tmp;
19017             }
19018           else
19019             {
19020               errmsg
19021                 ("translate_pbb_stag operation requires outer tag definition");
19022               return -99;
19023             }
19024         }
19025       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19026         dmac_set++;
19027       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19028         smac_set++;
19029       else if (unformat (i, "sid %d", &sid))
19030         ;
19031       else if (unformat (i, "vlanid %d", &tmp))
19032         vlanid = tmp;
19033       else
19034         {
19035           clib_warning ("parse error '%U'", format_unformat_error, i);
19036           return -99;
19037         }
19038     }
19039
19040   if ((sw_if_index == ~0) || (vtr_op == ~0))
19041     {
19042       errmsg ("missing sw_if_index or vtr operation");
19043       return -99;
19044     }
19045   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19046       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19047     {
19048       errmsg
19049         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19050       return -99;
19051     }
19052
19053   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19054   mp->sw_if_index = ntohl (sw_if_index);
19055   mp->vtr_op = ntohl (vtr_op);
19056   mp->outer_tag = ntohs (outer_tag);
19057   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19058   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19059   mp->b_vlanid = ntohs (vlanid);
19060   mp->i_sid = ntohl (sid);
19061
19062   S (mp);
19063   W (ret);
19064   return ret;
19065 }
19066
19067 static int
19068 api_flow_classify_set_interface (vat_main_t * vam)
19069 {
19070   unformat_input_t *i = vam->input;
19071   vl_api_flow_classify_set_interface_t *mp;
19072   u32 sw_if_index;
19073   int sw_if_index_set;
19074   u32 ip4_table_index = ~0;
19075   u32 ip6_table_index = ~0;
19076   u8 is_add = 1;
19077   int ret;
19078
19079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19080     {
19081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19082         sw_if_index_set = 1;
19083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19084         sw_if_index_set = 1;
19085       else if (unformat (i, "del"))
19086         is_add = 0;
19087       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19088         ;
19089       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19090         ;
19091       else
19092         {
19093           clib_warning ("parse error '%U'", format_unformat_error, i);
19094           return -99;
19095         }
19096     }
19097
19098   if (sw_if_index_set == 0)
19099     {
19100       errmsg ("missing interface name or sw_if_index");
19101       return -99;
19102     }
19103
19104   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19105
19106   mp->sw_if_index = ntohl (sw_if_index);
19107   mp->ip4_table_index = ntohl (ip4_table_index);
19108   mp->ip6_table_index = ntohl (ip6_table_index);
19109   mp->is_add = is_add;
19110
19111   S (mp);
19112   W (ret);
19113   return ret;
19114 }
19115
19116 static int
19117 api_flow_classify_dump (vat_main_t * vam)
19118 {
19119   unformat_input_t *i = vam->input;
19120   vl_api_flow_classify_dump_t *mp;
19121   vl_api_control_ping_t *mp_ping;
19122   u8 type = FLOW_CLASSIFY_N_TABLES;
19123   int ret;
19124
19125   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19126     ;
19127   else
19128     {
19129       errmsg ("classify table type must be specified");
19130       return -99;
19131     }
19132
19133   if (!vam->json_output)
19134     {
19135       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19136     }
19137
19138   M (FLOW_CLASSIFY_DUMP, mp);
19139   mp->type = type;
19140   /* send it... */
19141   S (mp);
19142
19143   /* Use a control ping for synchronization */
19144   MPING (CONTROL_PING, mp_ping);
19145   S (mp_ping);
19146
19147   /* Wait for a reply... */
19148   W (ret);
19149   return ret;
19150 }
19151
19152 static int
19153 api_feature_enable_disable (vat_main_t * vam)
19154 {
19155   unformat_input_t *i = vam->input;
19156   vl_api_feature_enable_disable_t *mp;
19157   u8 *arc_name = 0;
19158   u8 *feature_name = 0;
19159   u32 sw_if_index = ~0;
19160   u8 enable = 1;
19161   int ret;
19162
19163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19164     {
19165       if (unformat (i, "arc_name %s", &arc_name))
19166         ;
19167       else if (unformat (i, "feature_name %s", &feature_name))
19168         ;
19169       else
19170         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19171         ;
19172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19173         ;
19174       else if (unformat (i, "disable"))
19175         enable = 0;
19176       else
19177         break;
19178     }
19179
19180   if (arc_name == 0)
19181     {
19182       errmsg ("missing arc name");
19183       return -99;
19184     }
19185   if (vec_len (arc_name) > 63)
19186     {
19187       errmsg ("arc name too long");
19188     }
19189
19190   if (feature_name == 0)
19191     {
19192       errmsg ("missing feature name");
19193       return -99;
19194     }
19195   if (vec_len (feature_name) > 63)
19196     {
19197       errmsg ("feature name too long");
19198     }
19199
19200   if (sw_if_index == ~0)
19201     {
19202       errmsg ("missing interface name or sw_if_index");
19203       return -99;
19204     }
19205
19206   /* Construct the API message */
19207   M (FEATURE_ENABLE_DISABLE, mp);
19208   mp->sw_if_index = ntohl (sw_if_index);
19209   mp->enable = enable;
19210   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19211   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19212   vec_free (arc_name);
19213   vec_free (feature_name);
19214
19215   S (mp);
19216   W (ret);
19217   return ret;
19218 }
19219
19220 static int
19221 api_feature_gso_enable_disable (vat_main_t * vam)
19222 {
19223   unformat_input_t *i = vam->input;
19224   vl_api_feature_gso_enable_disable_t *mp;
19225   u32 sw_if_index = ~0;
19226   u8 enable = 1;
19227   int ret;
19228
19229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19230     {
19231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19232         ;
19233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19234         ;
19235       else if (unformat (i, "enable"))
19236         enable = 1;
19237       else if (unformat (i, "disable"))
19238         enable = 0;
19239       else
19240         break;
19241     }
19242
19243   if (sw_if_index == ~0)
19244     {
19245       errmsg ("missing interface name or sw_if_index");
19246       return -99;
19247     }
19248
19249   /* Construct the API message */
19250   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19251   mp->sw_if_index = ntohl (sw_if_index);
19252   mp->enable_disable = enable;
19253
19254   S (mp);
19255   W (ret);
19256   return ret;
19257 }
19258
19259 static int
19260 api_sw_interface_tag_add_del (vat_main_t * vam)
19261 {
19262   unformat_input_t *i = vam->input;
19263   vl_api_sw_interface_tag_add_del_t *mp;
19264   u32 sw_if_index = ~0;
19265   u8 *tag = 0;
19266   u8 enable = 1;
19267   int ret;
19268
19269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19270     {
19271       if (unformat (i, "tag %s", &tag))
19272         ;
19273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19274         ;
19275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19276         ;
19277       else if (unformat (i, "del"))
19278         enable = 0;
19279       else
19280         break;
19281     }
19282
19283   if (sw_if_index == ~0)
19284     {
19285       errmsg ("missing interface name or sw_if_index");
19286       return -99;
19287     }
19288
19289   if (enable && (tag == 0))
19290     {
19291       errmsg ("no tag specified");
19292       return -99;
19293     }
19294
19295   /* Construct the API message */
19296   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19297   mp->sw_if_index = ntohl (sw_if_index);
19298   mp->is_add = enable;
19299   if (enable)
19300     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19301   vec_free (tag);
19302
19303   S (mp);
19304   W (ret);
19305   return ret;
19306 }
19307
19308 static int
19309 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19310 {
19311   unformat_input_t *i = vam->input;
19312   vl_api_mac_address_t mac = { 0 };
19313   vl_api_sw_interface_add_del_mac_address_t *mp;
19314   u32 sw_if_index = ~0;
19315   u8 is_add = 1;
19316   u8 mac_set = 0;
19317   int ret;
19318
19319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19320     {
19321       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19322         ;
19323       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19324         ;
19325       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19326         mac_set++;
19327       else if (unformat (i, "del"))
19328         is_add = 0;
19329       else
19330         break;
19331     }
19332
19333   if (sw_if_index == ~0)
19334     {
19335       errmsg ("missing interface name or sw_if_index");
19336       return -99;
19337     }
19338
19339   if (!mac_set)
19340     {
19341       errmsg ("missing MAC address");
19342       return -99;
19343     }
19344
19345   /* Construct the API message */
19346   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19347   mp->sw_if_index = ntohl (sw_if_index);
19348   mp->is_add = is_add;
19349   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19350
19351   S (mp);
19352   W (ret);
19353   return ret;
19354 }
19355
19356 static void vl_api_l2_xconnect_details_t_handler
19357   (vl_api_l2_xconnect_details_t * mp)
19358 {
19359   vat_main_t *vam = &vat_main;
19360
19361   print (vam->ofp, "%15d%15d",
19362          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19363 }
19364
19365 static void vl_api_l2_xconnect_details_t_handler_json
19366   (vl_api_l2_xconnect_details_t * mp)
19367 {
19368   vat_main_t *vam = &vat_main;
19369   vat_json_node_t *node = NULL;
19370
19371   if (VAT_JSON_ARRAY != vam->json_tree.type)
19372     {
19373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19374       vat_json_init_array (&vam->json_tree);
19375     }
19376   node = vat_json_array_add (&vam->json_tree);
19377
19378   vat_json_init_object (node);
19379   vat_json_object_add_uint (node, "rx_sw_if_index",
19380                             ntohl (mp->rx_sw_if_index));
19381   vat_json_object_add_uint (node, "tx_sw_if_index",
19382                             ntohl (mp->tx_sw_if_index));
19383 }
19384
19385 static int
19386 api_l2_xconnect_dump (vat_main_t * vam)
19387 {
19388   vl_api_l2_xconnect_dump_t *mp;
19389   vl_api_control_ping_t *mp_ping;
19390   int ret;
19391
19392   if (!vam->json_output)
19393     {
19394       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19395     }
19396
19397   M (L2_XCONNECT_DUMP, mp);
19398
19399   S (mp);
19400
19401   /* Use a control ping for synchronization */
19402   MPING (CONTROL_PING, mp_ping);
19403   S (mp_ping);
19404
19405   W (ret);
19406   return ret;
19407 }
19408
19409 static int
19410 api_hw_interface_set_mtu (vat_main_t * vam)
19411 {
19412   unformat_input_t *i = vam->input;
19413   vl_api_hw_interface_set_mtu_t *mp;
19414   u32 sw_if_index = ~0;
19415   u32 mtu = 0;
19416   int ret;
19417
19418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19419     {
19420       if (unformat (i, "mtu %d", &mtu))
19421         ;
19422       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19423         ;
19424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19425         ;
19426       else
19427         break;
19428     }
19429
19430   if (sw_if_index == ~0)
19431     {
19432       errmsg ("missing interface name or sw_if_index");
19433       return -99;
19434     }
19435
19436   if (mtu == 0)
19437     {
19438       errmsg ("no mtu specified");
19439       return -99;
19440     }
19441
19442   /* Construct the API message */
19443   M (HW_INTERFACE_SET_MTU, mp);
19444   mp->sw_if_index = ntohl (sw_if_index);
19445   mp->mtu = ntohs ((u16) mtu);
19446
19447   S (mp);
19448   W (ret);
19449   return ret;
19450 }
19451
19452 static int
19453 api_p2p_ethernet_add (vat_main_t * vam)
19454 {
19455   unformat_input_t *i = vam->input;
19456   vl_api_p2p_ethernet_add_t *mp;
19457   u32 parent_if_index = ~0;
19458   u32 sub_id = ~0;
19459   u8 remote_mac[6];
19460   u8 mac_set = 0;
19461   int ret;
19462
19463   clib_memset (remote_mac, 0, sizeof (remote_mac));
19464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19465     {
19466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19467         ;
19468       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19469         ;
19470       else
19471         if (unformat
19472             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19473         mac_set++;
19474       else if (unformat (i, "sub_id %d", &sub_id))
19475         ;
19476       else
19477         {
19478           clib_warning ("parse error '%U'", format_unformat_error, i);
19479           return -99;
19480         }
19481     }
19482
19483   if (parent_if_index == ~0)
19484     {
19485       errmsg ("missing interface name or sw_if_index");
19486       return -99;
19487     }
19488   if (mac_set == 0)
19489     {
19490       errmsg ("missing remote mac address");
19491       return -99;
19492     }
19493   if (sub_id == ~0)
19494     {
19495       errmsg ("missing sub-interface id");
19496       return -99;
19497     }
19498
19499   M (P2P_ETHERNET_ADD, mp);
19500   mp->parent_if_index = ntohl (parent_if_index);
19501   mp->subif_id = ntohl (sub_id);
19502   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19503
19504   S (mp);
19505   W (ret);
19506   return ret;
19507 }
19508
19509 static int
19510 api_p2p_ethernet_del (vat_main_t * vam)
19511 {
19512   unformat_input_t *i = vam->input;
19513   vl_api_p2p_ethernet_del_t *mp;
19514   u32 parent_if_index = ~0;
19515   u8 remote_mac[6];
19516   u8 mac_set = 0;
19517   int ret;
19518
19519   clib_memset (remote_mac, 0, sizeof (remote_mac));
19520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19521     {
19522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19523         ;
19524       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19525         ;
19526       else
19527         if (unformat
19528             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19529         mac_set++;
19530       else
19531         {
19532           clib_warning ("parse error '%U'", format_unformat_error, i);
19533           return -99;
19534         }
19535     }
19536
19537   if (parent_if_index == ~0)
19538     {
19539       errmsg ("missing interface name or sw_if_index");
19540       return -99;
19541     }
19542   if (mac_set == 0)
19543     {
19544       errmsg ("missing remote mac address");
19545       return -99;
19546     }
19547
19548   M (P2P_ETHERNET_DEL, mp);
19549   mp->parent_if_index = ntohl (parent_if_index);
19550   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19551
19552   S (mp);
19553   W (ret);
19554   return ret;
19555 }
19556
19557 static int
19558 api_lldp_config (vat_main_t * vam)
19559 {
19560   unformat_input_t *i = vam->input;
19561   vl_api_lldp_config_t *mp;
19562   int tx_hold = 0;
19563   int tx_interval = 0;
19564   u8 *sys_name = NULL;
19565   int ret;
19566
19567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19568     {
19569       if (unformat (i, "system-name %s", &sys_name))
19570         ;
19571       else if (unformat (i, "tx-hold %d", &tx_hold))
19572         ;
19573       else if (unformat (i, "tx-interval %d", &tx_interval))
19574         ;
19575       else
19576         {
19577           clib_warning ("parse error '%U'", format_unformat_error, i);
19578           return -99;
19579         }
19580     }
19581
19582   vec_add1 (sys_name, 0);
19583
19584   M (LLDP_CONFIG, mp);
19585   mp->tx_hold = htonl (tx_hold);
19586   mp->tx_interval = htonl (tx_interval);
19587   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19588   vec_free (sys_name);
19589
19590   S (mp);
19591   W (ret);
19592   return ret;
19593 }
19594
19595 static int
19596 api_sw_interface_set_lldp (vat_main_t * vam)
19597 {
19598   unformat_input_t *i = vam->input;
19599   vl_api_sw_interface_set_lldp_t *mp;
19600   u32 sw_if_index = ~0;
19601   u32 enable = 1;
19602   u8 *port_desc = NULL, *mgmt_oid = NULL;
19603   ip4_address_t ip4_addr;
19604   ip6_address_t ip6_addr;
19605   int ret;
19606
19607   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19608   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19609
19610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19611     {
19612       if (unformat (i, "disable"))
19613         enable = 0;
19614       else
19615         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19616         ;
19617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19618         ;
19619       else if (unformat (i, "port-desc %s", &port_desc))
19620         ;
19621       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19622         ;
19623       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19624         ;
19625       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19626         ;
19627       else
19628         break;
19629     }
19630
19631   if (sw_if_index == ~0)
19632     {
19633       errmsg ("missing interface name or sw_if_index");
19634       return -99;
19635     }
19636
19637   /* Construct the API message */
19638   vec_add1 (port_desc, 0);
19639   vec_add1 (mgmt_oid, 0);
19640   M (SW_INTERFACE_SET_LLDP, mp);
19641   mp->sw_if_index = ntohl (sw_if_index);
19642   mp->enable = enable;
19643   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19644   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19645   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19646   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19647   vec_free (port_desc);
19648   vec_free (mgmt_oid);
19649
19650   S (mp);
19651   W (ret);
19652   return ret;
19653 }
19654
19655 static int
19656 api_tcp_configure_src_addresses (vat_main_t * vam)
19657 {
19658   vl_api_tcp_configure_src_addresses_t *mp;
19659   unformat_input_t *i = vam->input;
19660   vl_api_address_t first, last;
19661   u8 range_set = 0;
19662   u32 vrf_id = 0;
19663   int ret;
19664
19665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19666     {
19667       if (unformat (i, "%U - %U",
19668                     unformat_vl_api_address, &first,
19669                     unformat_vl_api_address, &last))
19670         {
19671           if (range_set)
19672             {
19673               errmsg ("one range per message (range already set)");
19674               return -99;
19675             }
19676           range_set = 1;
19677         }
19678       else if (unformat (i, "vrf %d", &vrf_id))
19679         ;
19680       else
19681         break;
19682     }
19683
19684   if (range_set == 0)
19685     {
19686       errmsg ("address range not set");
19687       return -99;
19688     }
19689
19690   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19691
19692   mp->vrf_id = ntohl (vrf_id);
19693   clib_memcpy (&mp->first_address, &first, sizeof (first));
19694   clib_memcpy (&mp->last_address, &last, sizeof (last));
19695
19696   S (mp);
19697   W (ret);
19698   return ret;
19699 }
19700
19701 static void vl_api_app_namespace_add_del_reply_t_handler
19702   (vl_api_app_namespace_add_del_reply_t * mp)
19703 {
19704   vat_main_t *vam = &vat_main;
19705   i32 retval = ntohl (mp->retval);
19706   if (vam->async_mode)
19707     {
19708       vam->async_errors += (retval < 0);
19709     }
19710   else
19711     {
19712       vam->retval = retval;
19713       if (retval == 0)
19714         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19715       vam->result_ready = 1;
19716     }
19717 }
19718
19719 static void vl_api_app_namespace_add_del_reply_t_handler_json
19720   (vl_api_app_namespace_add_del_reply_t * mp)
19721 {
19722   vat_main_t *vam = &vat_main;
19723   vat_json_node_t node;
19724
19725   vat_json_init_object (&node);
19726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19727   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19728
19729   vat_json_print (vam->ofp, &node);
19730   vat_json_free (&node);
19731
19732   vam->retval = ntohl (mp->retval);
19733   vam->result_ready = 1;
19734 }
19735
19736 static int
19737 api_app_namespace_add_del (vat_main_t * vam)
19738 {
19739   vl_api_app_namespace_add_del_t *mp;
19740   unformat_input_t *i = vam->input;
19741   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19742   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19743   u64 secret;
19744   int ret;
19745
19746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19747     {
19748       if (unformat (i, "id %_%v%_", &ns_id))
19749         ;
19750       else if (unformat (i, "secret %lu", &secret))
19751         secret_set = 1;
19752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19753         sw_if_index_set = 1;
19754       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19755         ;
19756       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19757         ;
19758       else
19759         break;
19760     }
19761   if (!ns_id || !secret_set || !sw_if_index_set)
19762     {
19763       errmsg ("namespace id, secret and sw_if_index must be set");
19764       return -99;
19765     }
19766   if (vec_len (ns_id) > 64)
19767     {
19768       errmsg ("namespace id too long");
19769       return -99;
19770     }
19771   M (APP_NAMESPACE_ADD_DEL, mp);
19772
19773   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19774   mp->namespace_id_len = vec_len (ns_id);
19775   mp->secret = clib_host_to_net_u64 (secret);
19776   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19777   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19778   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19779   vec_free (ns_id);
19780   S (mp);
19781   W (ret);
19782   return ret;
19783 }
19784
19785 static int
19786 api_sock_init_shm (vat_main_t * vam)
19787 {
19788 #if VPP_API_TEST_BUILTIN == 0
19789   unformat_input_t *i = vam->input;
19790   vl_api_shm_elem_config_t *config = 0;
19791   u64 size = 64 << 20;
19792   int rv;
19793
19794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19795     {
19796       if (unformat (i, "size %U", unformat_memory_size, &size))
19797         ;
19798       else
19799         break;
19800     }
19801
19802   /*
19803    * Canned custom ring allocator config.
19804    * Should probably parse all of this
19805    */
19806   vec_validate (config, 6);
19807   config[0].type = VL_API_VLIB_RING;
19808   config[0].size = 256;
19809   config[0].count = 32;
19810
19811   config[1].type = VL_API_VLIB_RING;
19812   config[1].size = 1024;
19813   config[1].count = 16;
19814
19815   config[2].type = VL_API_VLIB_RING;
19816   config[2].size = 4096;
19817   config[2].count = 2;
19818
19819   config[3].type = VL_API_CLIENT_RING;
19820   config[3].size = 256;
19821   config[3].count = 32;
19822
19823   config[4].type = VL_API_CLIENT_RING;
19824   config[4].size = 1024;
19825   config[4].count = 16;
19826
19827   config[5].type = VL_API_CLIENT_RING;
19828   config[5].size = 4096;
19829   config[5].count = 2;
19830
19831   config[6].type = VL_API_QUEUE;
19832   config[6].count = 128;
19833   config[6].size = sizeof (uword);
19834
19835   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19836   if (!rv)
19837     vam->client_index_invalid = 1;
19838   return rv;
19839 #else
19840   return -99;
19841 #endif
19842 }
19843
19844 static void
19845 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19846 {
19847   vat_main_t *vam = &vat_main;
19848
19849   if (mp->is_ip4)
19850     {
19851       print (vam->ofp,
19852              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19853              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19854              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19855              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19856              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19857              clib_net_to_host_u32 (mp->action_index), mp->tag);
19858     }
19859   else
19860     {
19861       print (vam->ofp,
19862              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19863              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19864              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19865              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19866              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19867              clib_net_to_host_u32 (mp->action_index), mp->tag);
19868     }
19869 }
19870
19871 static void
19872 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19873                                              mp)
19874 {
19875   vat_main_t *vam = &vat_main;
19876   vat_json_node_t *node = NULL;
19877   struct in6_addr ip6;
19878   struct in_addr ip4;
19879
19880   if (VAT_JSON_ARRAY != vam->json_tree.type)
19881     {
19882       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19883       vat_json_init_array (&vam->json_tree);
19884     }
19885   node = vat_json_array_add (&vam->json_tree);
19886   vat_json_init_object (node);
19887
19888   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19889   vat_json_object_add_uint (node, "appns_index",
19890                             clib_net_to_host_u32 (mp->appns_index));
19891   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19892   vat_json_object_add_uint (node, "scope", mp->scope);
19893   vat_json_object_add_uint (node, "action_index",
19894                             clib_net_to_host_u32 (mp->action_index));
19895   vat_json_object_add_uint (node, "lcl_port",
19896                             clib_net_to_host_u16 (mp->lcl_port));
19897   vat_json_object_add_uint (node, "rmt_port",
19898                             clib_net_to_host_u16 (mp->rmt_port));
19899   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19900   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19901   vat_json_object_add_string_copy (node, "tag", mp->tag);
19902   if (mp->is_ip4)
19903     {
19904       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19905       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19906       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19907       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19908     }
19909   else
19910     {
19911       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19912       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19913       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19914       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19915     }
19916 }
19917
19918 static int
19919 api_session_rule_add_del (vat_main_t * vam)
19920 {
19921   vl_api_session_rule_add_del_t *mp;
19922   unformat_input_t *i = vam->input;
19923   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19924   u32 appns_index = 0, scope = 0;
19925   ip4_address_t lcl_ip4, rmt_ip4;
19926   ip6_address_t lcl_ip6, rmt_ip6;
19927   u8 is_ip4 = 1, conn_set = 0;
19928   u8 is_add = 1, *tag = 0;
19929   int ret;
19930
19931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19932     {
19933       if (unformat (i, "del"))
19934         is_add = 0;
19935       else if (unformat (i, "add"))
19936         ;
19937       else if (unformat (i, "proto tcp"))
19938         proto = 0;
19939       else if (unformat (i, "proto udp"))
19940         proto = 1;
19941       else if (unformat (i, "appns %d", &appns_index))
19942         ;
19943       else if (unformat (i, "scope %d", &scope))
19944         ;
19945       else if (unformat (i, "tag %_%v%_", &tag))
19946         ;
19947       else
19948         if (unformat
19949             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19950              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19951              &rmt_port))
19952         {
19953           is_ip4 = 1;
19954           conn_set = 1;
19955         }
19956       else
19957         if (unformat
19958             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19959              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19960              &rmt_port))
19961         {
19962           is_ip4 = 0;
19963           conn_set = 1;
19964         }
19965       else if (unformat (i, "action %d", &action))
19966         ;
19967       else
19968         break;
19969     }
19970   if (proto == ~0 || !conn_set || action == ~0)
19971     {
19972       errmsg ("transport proto, connection and action must be set");
19973       return -99;
19974     }
19975
19976   if (scope > 3)
19977     {
19978       errmsg ("scope should be 0-3");
19979       return -99;
19980     }
19981
19982   M (SESSION_RULE_ADD_DEL, mp);
19983
19984   mp->is_ip4 = is_ip4;
19985   mp->transport_proto = proto;
19986   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19987   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19988   mp->lcl_plen = lcl_plen;
19989   mp->rmt_plen = rmt_plen;
19990   mp->action_index = clib_host_to_net_u32 (action);
19991   mp->appns_index = clib_host_to_net_u32 (appns_index);
19992   mp->scope = scope;
19993   mp->is_add = is_add;
19994   if (is_ip4)
19995     {
19996       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
19997       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
19998     }
19999   else
20000     {
20001       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20002       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20003     }
20004   if (tag)
20005     {
20006       clib_memcpy (mp->tag, tag, vec_len (tag));
20007       vec_free (tag);
20008     }
20009
20010   S (mp);
20011   W (ret);
20012   return ret;
20013 }
20014
20015 static int
20016 api_session_rules_dump (vat_main_t * vam)
20017 {
20018   vl_api_session_rules_dump_t *mp;
20019   vl_api_control_ping_t *mp_ping;
20020   int ret;
20021
20022   if (!vam->json_output)
20023     {
20024       print (vam->ofp, "%=20s", "Session Rules");
20025     }
20026
20027   M (SESSION_RULES_DUMP, mp);
20028   /* send it... */
20029   S (mp);
20030
20031   /* Use a control ping for synchronization */
20032   MPING (CONTROL_PING, mp_ping);
20033   S (mp_ping);
20034
20035   /* Wait for a reply... */
20036   W (ret);
20037   return ret;
20038 }
20039
20040 static int
20041 api_ip_container_proxy_add_del (vat_main_t * vam)
20042 {
20043   vl_api_ip_container_proxy_add_del_t *mp;
20044   unformat_input_t *i = vam->input;
20045   u32 sw_if_index = ~0;
20046   vl_api_prefix_t pfx = { };
20047   u8 is_add = 1;
20048   int ret;
20049
20050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20051     {
20052       if (unformat (i, "del"))
20053         is_add = 0;
20054       else if (unformat (i, "add"))
20055         ;
20056       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20057         ;
20058       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20059         ;
20060       else
20061         break;
20062     }
20063   if (sw_if_index == ~0 || pfx.len == 0)
20064     {
20065       errmsg ("address and sw_if_index must be set");
20066       return -99;
20067     }
20068
20069   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20070
20071   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20072   mp->is_add = is_add;
20073   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20074
20075   S (mp);
20076   W (ret);
20077   return ret;
20078 }
20079
20080 static int
20081 api_qos_record_enable_disable (vat_main_t * vam)
20082 {
20083   unformat_input_t *i = vam->input;
20084   vl_api_qos_record_enable_disable_t *mp;
20085   u32 sw_if_index, qs = 0xff;
20086   u8 sw_if_index_set = 0;
20087   u8 enable = 1;
20088   int ret;
20089
20090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20091     {
20092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20093         sw_if_index_set = 1;
20094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20095         sw_if_index_set = 1;
20096       else if (unformat (i, "%U", unformat_qos_source, &qs))
20097         ;
20098       else if (unformat (i, "disable"))
20099         enable = 0;
20100       else
20101         {
20102           clib_warning ("parse error '%U'", format_unformat_error, i);
20103           return -99;
20104         }
20105     }
20106
20107   if (sw_if_index_set == 0)
20108     {
20109       errmsg ("missing interface name or sw_if_index");
20110       return -99;
20111     }
20112   if (qs == 0xff)
20113     {
20114       errmsg ("input location must be specified");
20115       return -99;
20116     }
20117
20118   M (QOS_RECORD_ENABLE_DISABLE, mp);
20119
20120   mp->record.sw_if_index = ntohl (sw_if_index);
20121   mp->record.input_source = qs;
20122   mp->enable = enable;
20123
20124   S (mp);
20125   W (ret);
20126   return ret;
20127 }
20128
20129
20130 static int
20131 q_or_quit (vat_main_t * vam)
20132 {
20133 #if VPP_API_TEST_BUILTIN == 0
20134   longjmp (vam->jump_buf, 1);
20135 #endif
20136   return 0;                     /* not so much */
20137 }
20138
20139 static int
20140 q (vat_main_t * vam)
20141 {
20142   return q_or_quit (vam);
20143 }
20144
20145 static int
20146 quit (vat_main_t * vam)
20147 {
20148   return q_or_quit (vam);
20149 }
20150
20151 static int
20152 comment (vat_main_t * vam)
20153 {
20154   return 0;
20155 }
20156
20157 static int
20158 elog_save (vat_main_t * vam)
20159 {
20160 #if VPP_API_TEST_BUILTIN == 0
20161   elog_main_t *em = &vam->elog_main;
20162   unformat_input_t *i = vam->input;
20163   char *file, *chroot_file;
20164   clib_error_t *error;
20165
20166   if (!unformat (i, "%s", &file))
20167     {
20168       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20169       return 0;
20170     }
20171
20172   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20173   if (strstr (file, "..") || index (file, '/'))
20174     {
20175       errmsg ("illegal characters in filename '%s'", file);
20176       return 0;
20177     }
20178
20179   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20180
20181   vec_free (file);
20182
20183   errmsg ("Saving %wd of %wd events to %s",
20184           elog_n_events_in_buffer (em),
20185           elog_buffer_capacity (em), chroot_file);
20186
20187   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20188   vec_free (chroot_file);
20189
20190   if (error)
20191     clib_error_report (error);
20192 #else
20193   errmsg ("Use the vpp event loger...");
20194 #endif
20195
20196   return 0;
20197 }
20198
20199 static int
20200 elog_setup (vat_main_t * vam)
20201 {
20202 #if VPP_API_TEST_BUILTIN == 0
20203   elog_main_t *em = &vam->elog_main;
20204   unformat_input_t *i = vam->input;
20205   u32 nevents = 128 << 10;
20206
20207   (void) unformat (i, "nevents %d", &nevents);
20208
20209   elog_init (em, nevents);
20210   vl_api_set_elog_main (em);
20211   vl_api_set_elog_trace_api_messages (1);
20212   errmsg ("Event logger initialized with %u events", nevents);
20213 #else
20214   errmsg ("Use the vpp event loger...");
20215 #endif
20216   return 0;
20217 }
20218
20219 static int
20220 elog_enable (vat_main_t * vam)
20221 {
20222 #if VPP_API_TEST_BUILTIN == 0
20223   elog_main_t *em = &vam->elog_main;
20224
20225   elog_enable_disable (em, 1 /* enable */ );
20226   vl_api_set_elog_trace_api_messages (1);
20227   errmsg ("Event logger enabled...");
20228 #else
20229   errmsg ("Use the vpp event loger...");
20230 #endif
20231   return 0;
20232 }
20233
20234 static int
20235 elog_disable (vat_main_t * vam)
20236 {
20237 #if VPP_API_TEST_BUILTIN == 0
20238   elog_main_t *em = &vam->elog_main;
20239
20240   elog_enable_disable (em, 0 /* enable */ );
20241   vl_api_set_elog_trace_api_messages (1);
20242   errmsg ("Event logger disabled...");
20243 #else
20244   errmsg ("Use the vpp event loger...");
20245 #endif
20246   return 0;
20247 }
20248
20249 static int
20250 statseg (vat_main_t * vam)
20251 {
20252   ssvm_private_t *ssvmp = &vam->stat_segment;
20253   ssvm_shared_header_t *shared_header = ssvmp->sh;
20254   vlib_counter_t **counters;
20255   u64 thread0_index1_packets;
20256   u64 thread0_index1_bytes;
20257   f64 vector_rate, input_rate;
20258   uword *p;
20259
20260   uword *counter_vector_by_name;
20261   if (vam->stat_segment_lockp == 0)
20262     {
20263       errmsg ("Stat segment not mapped...");
20264       return -99;
20265     }
20266
20267   /* look up "/if/rx for sw_if_index 1 as a test */
20268
20269   clib_spinlock_lock (vam->stat_segment_lockp);
20270
20271   counter_vector_by_name = (uword *) shared_header->opaque[1];
20272
20273   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20274   if (p == 0)
20275     {
20276       clib_spinlock_unlock (vam->stat_segment_lockp);
20277       errmsg ("/if/tx not found?");
20278       return -99;
20279     }
20280
20281   /* Fish per-thread vector of combined counters from shared memory */
20282   counters = (vlib_counter_t **) p[0];
20283
20284   if (vec_len (counters[0]) < 2)
20285     {
20286       clib_spinlock_unlock (vam->stat_segment_lockp);
20287       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20288       return -99;
20289     }
20290
20291   /* Read thread 0 sw_if_index 1 counter */
20292   thread0_index1_packets = counters[0][1].packets;
20293   thread0_index1_bytes = counters[0][1].bytes;
20294
20295   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20296   if (p == 0)
20297     {
20298       clib_spinlock_unlock (vam->stat_segment_lockp);
20299       errmsg ("vector_rate not found?");
20300       return -99;
20301     }
20302
20303   vector_rate = *(f64 *) (p[0]);
20304   p = hash_get_mem (counter_vector_by_name, "input_rate");
20305   if (p == 0)
20306     {
20307       clib_spinlock_unlock (vam->stat_segment_lockp);
20308       errmsg ("input_rate not found?");
20309       return -99;
20310     }
20311   input_rate = *(f64 *) (p[0]);
20312
20313   clib_spinlock_unlock (vam->stat_segment_lockp);
20314
20315   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20316          vector_rate, input_rate);
20317   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20318          thread0_index1_packets, thread0_index1_bytes);
20319
20320   return 0;
20321 }
20322
20323 static int
20324 cmd_cmp (void *a1, void *a2)
20325 {
20326   u8 **c1 = a1;
20327   u8 **c2 = a2;
20328
20329   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20330 }
20331
20332 static int
20333 help (vat_main_t * vam)
20334 {
20335   u8 **cmds = 0;
20336   u8 *name = 0;
20337   hash_pair_t *p;
20338   unformat_input_t *i = vam->input;
20339   int j;
20340
20341   if (unformat (i, "%s", &name))
20342     {
20343       uword *hs;
20344
20345       vec_add1 (name, 0);
20346
20347       hs = hash_get_mem (vam->help_by_name, name);
20348       if (hs)
20349         print (vam->ofp, "usage: %s %s", name, hs[0]);
20350       else
20351         print (vam->ofp, "No such msg / command '%s'", name);
20352       vec_free (name);
20353       return 0;
20354     }
20355
20356   print (vam->ofp, "Help is available for the following:");
20357
20358     /* *INDENT-OFF* */
20359     hash_foreach_pair (p, vam->function_by_name,
20360     ({
20361       vec_add1 (cmds, (u8 *)(p->key));
20362     }));
20363     /* *INDENT-ON* */
20364
20365   vec_sort_with_function (cmds, cmd_cmp);
20366
20367   for (j = 0; j < vec_len (cmds); j++)
20368     print (vam->ofp, "%s", cmds[j]);
20369
20370   vec_free (cmds);
20371   return 0;
20372 }
20373
20374 static int
20375 set (vat_main_t * vam)
20376 {
20377   u8 *name = 0, *value = 0;
20378   unformat_input_t *i = vam->input;
20379
20380   if (unformat (i, "%s", &name))
20381     {
20382       /* The input buffer is a vector, not a string. */
20383       value = vec_dup (i->buffer);
20384       vec_delete (value, i->index, 0);
20385       /* Almost certainly has a trailing newline */
20386       if (value[vec_len (value) - 1] == '\n')
20387         value[vec_len (value) - 1] = 0;
20388       /* Make sure it's a proper string, one way or the other */
20389       vec_add1 (value, 0);
20390       (void) clib_macro_set_value (&vam->macro_main,
20391                                    (char *) name, (char *) value);
20392     }
20393   else
20394     errmsg ("usage: set <name> <value>");
20395
20396   vec_free (name);
20397   vec_free (value);
20398   return 0;
20399 }
20400
20401 static int
20402 unset (vat_main_t * vam)
20403 {
20404   u8 *name = 0;
20405
20406   if (unformat (vam->input, "%s", &name))
20407     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20408       errmsg ("unset: %s wasn't set", name);
20409   vec_free (name);
20410   return 0;
20411 }
20412
20413 typedef struct
20414 {
20415   u8 *name;
20416   u8 *value;
20417 } macro_sort_t;
20418
20419
20420 static int
20421 macro_sort_cmp (void *a1, void *a2)
20422 {
20423   macro_sort_t *s1 = a1;
20424   macro_sort_t *s2 = a2;
20425
20426   return strcmp ((char *) (s1->name), (char *) (s2->name));
20427 }
20428
20429 static int
20430 dump_macro_table (vat_main_t * vam)
20431 {
20432   macro_sort_t *sort_me = 0, *sm;
20433   int i;
20434   hash_pair_t *p;
20435
20436     /* *INDENT-OFF* */
20437     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20438     ({
20439       vec_add2 (sort_me, sm, 1);
20440       sm->name = (u8 *)(p->key);
20441       sm->value = (u8 *) (p->value[0]);
20442     }));
20443     /* *INDENT-ON* */
20444
20445   vec_sort_with_function (sort_me, macro_sort_cmp);
20446
20447   if (vec_len (sort_me))
20448     print (vam->ofp, "%-15s%s", "Name", "Value");
20449   else
20450     print (vam->ofp, "The macro table is empty...");
20451
20452   for (i = 0; i < vec_len (sort_me); i++)
20453     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20454   return 0;
20455 }
20456
20457 static int
20458 dump_node_table (vat_main_t * vam)
20459 {
20460   int i, j;
20461   vlib_node_t *node, *next_node;
20462
20463   if (vec_len (vam->graph_nodes) == 0)
20464     {
20465       print (vam->ofp, "Node table empty, issue get_node_graph...");
20466       return 0;
20467     }
20468
20469   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20470     {
20471       node = vam->graph_nodes[0][i];
20472       print (vam->ofp, "[%d] %s", i, node->name);
20473       for (j = 0; j < vec_len (node->next_nodes); j++)
20474         {
20475           if (node->next_nodes[j] != ~0)
20476             {
20477               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20478               print (vam->ofp, "  [%d] %s", j, next_node->name);
20479             }
20480         }
20481     }
20482   return 0;
20483 }
20484
20485 static int
20486 value_sort_cmp (void *a1, void *a2)
20487 {
20488   name_sort_t *n1 = a1;
20489   name_sort_t *n2 = a2;
20490
20491   if (n1->value < n2->value)
20492     return -1;
20493   if (n1->value > n2->value)
20494     return 1;
20495   return 0;
20496 }
20497
20498
20499 static int
20500 dump_msg_api_table (vat_main_t * vam)
20501 {
20502   api_main_t *am = vlibapi_get_main ();
20503   name_sort_t *nses = 0, *ns;
20504   hash_pair_t *hp;
20505   int i;
20506
20507   /* *INDENT-OFF* */
20508   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20509   ({
20510     vec_add2 (nses, ns, 1);
20511     ns->name = (u8 *)(hp->key);
20512     ns->value = (u32) hp->value[0];
20513   }));
20514   /* *INDENT-ON* */
20515
20516   vec_sort_with_function (nses, value_sort_cmp);
20517
20518   for (i = 0; i < vec_len (nses); i++)
20519     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20520   vec_free (nses);
20521   return 0;
20522 }
20523
20524 static int
20525 get_msg_id (vat_main_t * vam)
20526 {
20527   u8 *name_and_crc;
20528   u32 message_index;
20529
20530   if (unformat (vam->input, "%s", &name_and_crc))
20531     {
20532       message_index = vl_msg_api_get_msg_index (name_and_crc);
20533       if (message_index == ~0)
20534         {
20535           print (vam->ofp, " '%s' not found", name_and_crc);
20536           return 0;
20537         }
20538       print (vam->ofp, " '%s' has message index %d",
20539              name_and_crc, message_index);
20540       return 0;
20541     }
20542   errmsg ("name_and_crc required...");
20543   return 0;
20544 }
20545
20546 static int
20547 search_node_table (vat_main_t * vam)
20548 {
20549   unformat_input_t *line_input = vam->input;
20550   u8 *node_to_find;
20551   int j;
20552   vlib_node_t *node, *next_node;
20553   uword *p;
20554
20555   if (vam->graph_node_index_by_name == 0)
20556     {
20557       print (vam->ofp, "Node table empty, issue get_node_graph...");
20558       return 0;
20559     }
20560
20561   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20562     {
20563       if (unformat (line_input, "%s", &node_to_find))
20564         {
20565           vec_add1 (node_to_find, 0);
20566           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20567           if (p == 0)
20568             {
20569               print (vam->ofp, "%s not found...", node_to_find);
20570               goto out;
20571             }
20572           node = vam->graph_nodes[0][p[0]];
20573           print (vam->ofp, "[%d] %s", p[0], node->name);
20574           for (j = 0; j < vec_len (node->next_nodes); j++)
20575             {
20576               if (node->next_nodes[j] != ~0)
20577                 {
20578                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20579                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20580                 }
20581             }
20582         }
20583
20584       else
20585         {
20586           clib_warning ("parse error '%U'", format_unformat_error,
20587                         line_input);
20588           return -99;
20589         }
20590
20591     out:
20592       vec_free (node_to_find);
20593
20594     }
20595
20596   return 0;
20597 }
20598
20599
20600 static int
20601 script (vat_main_t * vam)
20602 {
20603 #if (VPP_API_TEST_BUILTIN==0)
20604   u8 *s = 0;
20605   char *save_current_file;
20606   unformat_input_t save_input;
20607   jmp_buf save_jump_buf;
20608   u32 save_line_number;
20609
20610   FILE *new_fp, *save_ifp;
20611
20612   if (unformat (vam->input, "%s", &s))
20613     {
20614       new_fp = fopen ((char *) s, "r");
20615       if (new_fp == 0)
20616         {
20617           errmsg ("Couldn't open script file %s", s);
20618           vec_free (s);
20619           return -99;
20620         }
20621     }
20622   else
20623     {
20624       errmsg ("Missing script name");
20625       return -99;
20626     }
20627
20628   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20629   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20630   save_ifp = vam->ifp;
20631   save_line_number = vam->input_line_number;
20632   save_current_file = (char *) vam->current_file;
20633
20634   vam->input_line_number = 0;
20635   vam->ifp = new_fp;
20636   vam->current_file = s;
20637   do_one_file (vam);
20638
20639   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20640   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20641   vam->ifp = save_ifp;
20642   vam->input_line_number = save_line_number;
20643   vam->current_file = (u8 *) save_current_file;
20644   vec_free (s);
20645
20646   return 0;
20647 #else
20648   clib_warning ("use the exec command...");
20649   return -99;
20650 #endif
20651 }
20652
20653 static int
20654 echo (vat_main_t * vam)
20655 {
20656   print (vam->ofp, "%v", vam->input->buffer);
20657   return 0;
20658 }
20659
20660 /* List of API message constructors, CLI names map to api_xxx */
20661 #define foreach_vpe_api_msg                                             \
20662 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20663 _(sw_interface_dump,"")                                                 \
20664 _(sw_interface_set_flags,                                               \
20665   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20666 _(sw_interface_add_del_address,                                         \
20667   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20668 _(sw_interface_set_rx_mode,                                             \
20669   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20670 _(sw_interface_set_rx_placement,                                        \
20671   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20672 _(sw_interface_rx_placement_dump,                                       \
20673   "[<intfc> | sw_if_index <id>]")                                         \
20674 _(sw_interface_set_table,                                               \
20675   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20676 _(sw_interface_set_mpls_enable,                                         \
20677   "<intfc> | sw_if_index [disable | dis]")                              \
20678 _(sw_interface_set_vpath,                                               \
20679   "<intfc> | sw_if_index <id> enable | disable")                        \
20680 _(sw_interface_set_vxlan_bypass,                                        \
20681   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20682 _(sw_interface_set_geneve_bypass,                                       \
20683   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20684 _(sw_interface_set_l2_xconnect,                                         \
20685   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20686   "enable | disable")                                                   \
20687 _(sw_interface_set_l2_bridge,                                           \
20688   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20689   "[shg <split-horizon-group>] [bvi]\n"                                 \
20690   "enable | disable")                                                   \
20691 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20692 _(bridge_domain_add_del,                                                \
20693   "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") \
20694 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20695 _(l2fib_add_del,                                                        \
20696   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20697 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20698 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20699 _(l2_flags,                                                             \
20700   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20701 _(bridge_flags,                                                         \
20702   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20703 _(tap_create_v2,                                                        \
20704   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
20705 _(tap_delete_v2,                                                        \
20706   "<vpp-if-name> | sw_if_index <id>")                                   \
20707 _(sw_interface_tap_v2_dump, "")                                         \
20708 _(virtio_pci_create,                                                    \
20709   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
20710 _(virtio_pci_delete,                                                    \
20711   "<vpp-if-name> | sw_if_index <id>")                                   \
20712 _(sw_interface_virtio_pci_dump, "")                                     \
20713 _(bond_create,                                                          \
20714   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20715   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20716   "[id <if-id>]")                                                       \
20717 _(bond_delete,                                                          \
20718   "<vpp-if-name> | sw_if_index <id>")                                   \
20719 _(bond_enslave,                                                         \
20720   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20721 _(bond_detach_slave,                                                    \
20722   "sw_if_index <n>")                                                    \
20723  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20724 _(sw_interface_bond_dump, "")                                           \
20725 _(sw_interface_slave_dump,                                              \
20726   "<vpp-if-name> | sw_if_index <id>")                                   \
20727 _(ip_table_add_del,                                                     \
20728   "table <n> [ipv6] [add | del]\n")                                     \
20729 _(ip_route_add_del,                                                     \
20730   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20731   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20732   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20733   "[multipath] [count <n>] [del]")                                      \
20734 _(ip_mroute_add_del,                                                    \
20735   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20736   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20737 _(mpls_table_add_del,                                                   \
20738   "table <n> [add | del]\n")                                            \
20739 _(mpls_route_add_del,                                                   \
20740   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20741   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20742   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20743   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20744   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20745   "[count <n>] [del]")                                                  \
20746 _(mpls_ip_bind_unbind,                                                  \
20747   "<label> <addr/len>")                                                 \
20748 _(mpls_tunnel_add_del,                                                  \
20749   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20750   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20751   "[l2-only]  [out-label <n>]")                                         \
20752 _(sr_mpls_policy_add,                                                   \
20753   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20754 _(sr_mpls_policy_del,                                                   \
20755   "bsid <id>")                                                          \
20756 _(bier_table_add_del,                                                   \
20757   "<label> <sub-domain> <set> <bsl> [del]")                             \
20758 _(bier_route_add_del,                                                   \
20759   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20760   "[<intfc> | sw_if_index <id>]"                                        \
20761   "[weight <n>] [del] [multipath]")                                     \
20762 _(sw_interface_set_unnumbered,                                          \
20763   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20764 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20765 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20766   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20767   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20768   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20769 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20770 _(ip_table_flush, "table <n> [ipv6]")                                   \
20771 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20772 _(set_ip_flow_hash,                                                     \
20773   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20774 _(sw_interface_ip6_enable_disable,                                      \
20775   "<intfc> | sw_if_index <id> enable | disable")                        \
20776 _(l2_patch_add_del,                                                     \
20777   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20778   "enable | disable")                                                   \
20779 _(sr_localsid_add_del,                                                  \
20780   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20781   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20782 _(classify_add_del_table,                                               \
20783   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20784   " [del] [del-chain] mask <mask-value>\n"                              \
20785   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20786   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20787 _(classify_add_del_session,                                             \
20788   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20789   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20790   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20791   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20792 _(classify_set_interface_ip_table,                                      \
20793   "<intfc> | sw_if_index <nn> table <nn>")                              \
20794 _(classify_set_interface_l2_tables,                                     \
20795   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20796   "  [other-table <nn>]")                                               \
20797 _(get_node_index, "node <node-name")                                    \
20798 _(add_node_next, "node <node-name> next <next-node-name>")              \
20799 _(l2tpv3_create_tunnel,                                                 \
20800   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20801   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20802   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20803 _(l2tpv3_set_tunnel_cookies,                                            \
20804   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20805   "[new_remote_cookie <nn>]\n")                                         \
20806 _(l2tpv3_interface_enable_disable,                                      \
20807   "<intfc> | sw_if_index <nn> enable | disable")                        \
20808 _(l2tpv3_set_lookup_key,                                                \
20809   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20810 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20811 _(vxlan_offload_rx,                                                     \
20812   "hw { <interface name> | hw_if_index <nn>} "                          \
20813   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20814 _(vxlan_add_del_tunnel,                                                 \
20815   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20816   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20817   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20818 _(geneve_add_del_tunnel,                                                \
20819   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20820   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20821   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20822 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20823 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20824 _(gre_tunnel_add_del,                                                   \
20825   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20826   "[teb | erspan <session-id>] [del]")                                  \
20827 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20828 _(l2_fib_clear_table, "")                                               \
20829 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20830 _(l2_interface_vlan_tag_rewrite,                                        \
20831   "<intfc> | sw_if_index <nn> \n"                                       \
20832   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20833   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20834 _(create_vhost_user_if,                                                 \
20835         "socket <filename> [server] [renumber <dev_instance>] "         \
20836         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20837         "[mac <mac_address>]")                                          \
20838 _(modify_vhost_user_if,                                                 \
20839         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20840         "[server] [renumber <dev_instance>] [gso]")                     \
20841 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20842 _(sw_interface_vhost_user_dump, "")                                     \
20843 _(show_version, "")                                                     \
20844 _(show_threads, "")                                                     \
20845 _(vxlan_gpe_add_del_tunnel,                                             \
20846   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20847   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20848   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20849   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20850 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20851 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20852 _(interface_name_renumber,                                              \
20853   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20854 _(input_acl_set_interface,                                              \
20855   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20856   "  [l2-table <nn>] [del]")                                            \
20857 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20858 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20859 _(ip_dump, "ipv4 | ipv6")                                               \
20860 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20861 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20862   "  spid_id <n> ")                                                     \
20863 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20864   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20865   "  integ_alg <alg> integ_key <hex>")                                  \
20866 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20867   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20868   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20869   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20870 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20871   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20872   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20873   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20874   "  [instance <n>]")     \
20875 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20876 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20877 _(delete_loopback,"sw_if_index <nn>")                                   \
20878 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20879 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20880 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20881 _(want_interface_events,  "enable|disable")                             \
20882 _(get_first_msg_id, "client <name>")                                    \
20883 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20884 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20885   "fib-id <nn> [ip4][ip6][default]")                                    \
20886 _(get_node_graph, " ")                                                  \
20887 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20888 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20889 _(ioam_disable, "")                                                     \
20890 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20891                             " sw_if_index <sw_if_index> p <priority> "  \
20892                             "w <weight>] [del]")                        \
20893 _(one_add_del_locator, "locator-set <locator_name> "                    \
20894                         "iface <intf> | sw_if_index <sw_if_index> "     \
20895                         "p <priority> w <weight> [del]")                \
20896 _(one_add_del_local_eid,"vni <vni> eid "                                \
20897                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20898                          "locator-set <locator_name> [del]"             \
20899                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20900 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20901 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20902 _(one_enable_disable, "enable|disable")                                 \
20903 _(one_map_register_enable_disable, "enable|disable")                    \
20904 _(one_map_register_fallback_threshold, "<value>")                       \
20905 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20906 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20907                                "[seid <seid>] "                         \
20908                                "rloc <locator> p <prio> "               \
20909                                "w <weight> [rloc <loc> ... ] "          \
20910                                "action <action> [del-all]")             \
20911 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20912                           "<local-eid>")                                \
20913 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20914 _(one_use_petr, "ip-address> | disable")                                \
20915 _(one_map_request_mode, "src-dst|dst-only")                             \
20916 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20917 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20918 _(one_locator_set_dump, "[local | remote]")                             \
20919 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20920 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20921                        "[local] | [remote]")                            \
20922 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20923 _(one_ndp_bd_get, "")                                                   \
20924 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20925 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20926 _(one_l2_arp_bd_get, "")                                                \
20927 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20928 _(one_stats_enable_disable, "enable|disable")                           \
20929 _(show_one_stats_enable_disable, "")                                    \
20930 _(one_eid_table_vni_dump, "")                                           \
20931 _(one_eid_table_map_dump, "l2|l3")                                      \
20932 _(one_map_resolver_dump, "")                                            \
20933 _(one_map_server_dump, "")                                              \
20934 _(one_adjacencies_get, "vni <vni>")                                     \
20935 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20936 _(show_one_rloc_probe_state, "")                                        \
20937 _(show_one_map_register_state, "")                                      \
20938 _(show_one_status, "")                                                  \
20939 _(one_stats_dump, "")                                                   \
20940 _(one_stats_flush, "")                                                  \
20941 _(one_get_map_request_itr_rlocs, "")                                    \
20942 _(one_map_register_set_ttl, "<ttl>")                                    \
20943 _(one_set_transport_protocol, "udp|api")                                \
20944 _(one_get_transport_protocol, "")                                       \
20945 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20946 _(one_show_xtr_mode, "")                                                \
20947 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20948 _(one_show_pitr_mode, "")                                               \
20949 _(one_enable_disable_petr_mode, "enable|disable")                       \
20950 _(one_show_petr_mode, "")                                               \
20951 _(show_one_nsh_mapping, "")                                             \
20952 _(show_one_pitr, "")                                                    \
20953 _(show_one_use_petr, "")                                                \
20954 _(show_one_map_request_mode, "")                                        \
20955 _(show_one_map_register_ttl, "")                                        \
20956 _(show_one_map_register_fallback_threshold, "")                         \
20957 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20958                             " sw_if_index <sw_if_index> p <priority> "  \
20959                             "w <weight>] [del]")                        \
20960 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20961                         "iface <intf> | sw_if_index <sw_if_index> "     \
20962                         "p <priority> w <weight> [del]")                \
20963 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20964                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20965                          "locator-set <locator_name> [del]"             \
20966                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20967 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20968 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20969 _(lisp_enable_disable, "enable|disable")                                \
20970 _(lisp_map_register_enable_disable, "enable|disable")                   \
20971 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20972 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20973                                "[seid <seid>] "                         \
20974                                "rloc <locator> p <prio> "               \
20975                                "w <weight> [rloc <loc> ... ] "          \
20976                                "action <action> [del-all]")             \
20977 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20978                           "<local-eid>")                                \
20979 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20980 _(lisp_use_petr, "<ip-address> | disable")                              \
20981 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20982 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20983 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20984 _(lisp_locator_set_dump, "[local | remote]")                            \
20985 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20986 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20987                        "[local] | [remote]")                            \
20988 _(lisp_eid_table_vni_dump, "")                                          \
20989 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20990 _(lisp_map_resolver_dump, "")                                           \
20991 _(lisp_map_server_dump, "")                                             \
20992 _(lisp_adjacencies_get, "vni <vni>")                                    \
20993 _(gpe_fwd_entry_vnis_get, "")                                           \
20994 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20995 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20996                                 "[table <table-id>]")                   \
20997 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20998 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20999 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21000 _(gpe_get_encap_mode, "")                                               \
21001 _(lisp_gpe_add_del_iface, "up|down")                                    \
21002 _(lisp_gpe_enable_disable, "enable|disable")                            \
21003 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21004   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21005 _(show_lisp_rloc_probe_state, "")                                       \
21006 _(show_lisp_map_register_state, "")                                     \
21007 _(show_lisp_status, "")                                                 \
21008 _(lisp_get_map_request_itr_rlocs, "")                                   \
21009 _(show_lisp_pitr, "")                                                   \
21010 _(show_lisp_use_petr, "")                                               \
21011 _(show_lisp_map_request_mode, "")                                       \
21012 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21013 _(af_packet_delete, "name <host interface name>")                       \
21014 _(af_packet_dump, "")                                                   \
21015 _(policer_add_del, "name <policer name> <params> [del]")                \
21016 _(policer_dump, "[name <policer name>]")                                \
21017 _(policer_classify_set_interface,                                       \
21018   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21019   "  [l2-table <nn>] [del]")                                            \
21020 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21021 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21022     "[master|slave]")                                                   \
21023 _(netmap_delete, "name <interface name>")                               \
21024 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21025 _(mpls_table_dump, "")                                                  \
21026 _(mpls_route_dump, "table-id <ID>")                                     \
21027 _(classify_table_ids, "")                                               \
21028 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21029 _(classify_table_info, "table_id <nn>")                                 \
21030 _(classify_session_dump, "table_id <nn>")                               \
21031 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21032     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21033     "[template_interval <nn>] [udp_checksum]")                          \
21034 _(ipfix_exporter_dump, "")                                              \
21035 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21036 _(ipfix_classify_stream_dump, "")                                       \
21037 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21038 _(ipfix_classify_table_dump, "")                                        \
21039 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21040 _(sw_interface_span_dump, "[l2]")                                           \
21041 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21042 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21043 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21044 _(pg_enable_disable, "[stream <id>] disable")                           \
21045 _(ip_source_and_port_range_check_add_del,                               \
21046   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21047 _(ip_source_and_port_range_check_interface_add_del,                     \
21048   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21049   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21050 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21051 _(l2_interface_pbb_tag_rewrite,                                         \
21052   "<intfc> | sw_if_index <nn> \n"                                       \
21053   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21054   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21055 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21056 _(flow_classify_set_interface,                                          \
21057   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21058 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21059 _(ip_table_dump, "")                                                    \
21060 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21061 _(ip_mtable_dump, "")                                                   \
21062 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21063 _(feature_enable_disable, "arc_name <arc_name> "                        \
21064   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21065 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21066   "[enable | disable] ")                                                \
21067 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21068 "[disable]")                                                            \
21069 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21070   "mac <mac-address> [del]")                                            \
21071 _(l2_xconnect_dump, "")                                                 \
21072 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21073 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21074 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21075 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21076 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21077 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21078   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21079 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21080 _(sock_init_shm, "size <nnn>")                                          \
21081 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21082 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21083   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21084 _(session_rules_dump, "")                                               \
21085 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21086 _(output_acl_set_interface,                                             \
21087   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21088   "  [l2-table <nn>] [del]")                                            \
21089 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21090
21091 /* List of command functions, CLI names map directly to functions */
21092 #define foreach_cli_function                                    \
21093 _(comment, "usage: comment <ignore-rest-of-line>")              \
21094 _(dump_interface_table, "usage: dump_interface_table")          \
21095 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21096 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21097 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21098 _(dump_macro_table, "usage: dump_macro_table ")                 \
21099 _(dump_node_table, "usage: dump_node_table")                    \
21100 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21101 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21102 _(elog_disable, "usage: elog_disable")                          \
21103 _(elog_enable, "usage: elog_enable")                            \
21104 _(elog_save, "usage: elog_save <filename>")                     \
21105 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21106 _(echo, "usage: echo <message>")                                \
21107 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21108 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21109 _(help, "usage: help")                                          \
21110 _(q, "usage: quit")                                             \
21111 _(quit, "usage: quit")                                          \
21112 _(search_node_table, "usage: search_node_table <name>...")      \
21113 _(set, "usage: set <variable-name> <value>")                    \
21114 _(script, "usage: script <file-name>")                          \
21115 _(statseg, "usage: statseg")                                    \
21116 _(unset, "usage: unset <variable-name>")
21117
21118 #define _(N,n)                                  \
21119     static void vl_api_##n##_t_handler_uni      \
21120     (vl_api_##n##_t * mp)                       \
21121     {                                           \
21122         vat_main_t * vam = &vat_main;           \
21123         if (vam->json_output) {                 \
21124             vl_api_##n##_t_handler_json(mp);    \
21125         } else {                                \
21126             vl_api_##n##_t_handler(mp);         \
21127         }                                       \
21128     }
21129 foreach_vpe_api_reply_msg;
21130 #if VPP_API_TEST_BUILTIN == 0
21131 foreach_standalone_reply_msg;
21132 #endif
21133 #undef _
21134
21135 void
21136 vat_api_hookup (vat_main_t * vam)
21137 {
21138 #define _(N,n)                                                  \
21139     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21140                            vl_api_##n##_t_handler_uni,          \
21141                            vl_noop_handler,                     \
21142                            vl_api_##n##_t_endian,               \
21143                            vl_api_##n##_t_print,                \
21144                            sizeof(vl_api_##n##_t), 1);
21145   foreach_vpe_api_reply_msg;
21146 #if VPP_API_TEST_BUILTIN == 0
21147   foreach_standalone_reply_msg;
21148 #endif
21149 #undef _
21150
21151 #if (VPP_API_TEST_BUILTIN==0)
21152   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21153
21154   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21155
21156   vam->function_by_name = hash_create_string (0, sizeof (uword));
21157
21158   vam->help_by_name = hash_create_string (0, sizeof (uword));
21159 #endif
21160
21161   /* API messages we can send */
21162 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21163   foreach_vpe_api_msg;
21164 #undef _
21165
21166   /* Help strings */
21167 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21168   foreach_vpe_api_msg;
21169 #undef _
21170
21171   /* CLI functions */
21172 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21173   foreach_cli_function;
21174 #undef _
21175
21176   /* Help strings */
21177 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21178   foreach_cli_function;
21179 #undef _
21180 }
21181
21182 #if VPP_API_TEST_BUILTIN
21183 static clib_error_t *
21184 vat_api_hookup_shim (vlib_main_t * vm)
21185 {
21186   vat_api_hookup (&vat_main);
21187   return 0;
21188 }
21189
21190 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21191 #endif
21192
21193 /*
21194  * fd.io coding-style-patch-verification: ON
21195  *
21196  * Local Variables:
21197  * eval: (c-set-style "gnu")
21198  * End:
21199  */