misc: deprecate netmap and ixge drivers
[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 _(set_ipfix_exporter_reply)                             \
5113 _(set_ipfix_classify_stream_reply)                      \
5114 _(ipfix_classify_table_add_del_reply)                   \
5115 _(flow_classify_set_interface_reply)                    \
5116 _(sw_interface_span_enable_disable_reply)               \
5117 _(pg_capture_reply)                                     \
5118 _(pg_enable_disable_reply)                              \
5119 _(ip_source_and_port_range_check_add_del_reply)         \
5120 _(ip_source_and_port_range_check_interface_add_del_reply)\
5121 _(delete_subif_reply)                                   \
5122 _(l2_interface_pbb_tag_rewrite_reply)                   \
5123 _(set_punt_reply)                                       \
5124 _(feature_enable_disable_reply)                         \
5125 _(feature_gso_enable_disable_reply)                     \
5126 _(sw_interface_tag_add_del_reply)                       \
5127 _(sw_interface_add_del_mac_address_reply)               \
5128 _(hw_interface_set_mtu_reply)                           \
5129 _(p2p_ethernet_add_reply)                               \
5130 _(p2p_ethernet_del_reply)                               \
5131 _(lldp_config_reply)                                    \
5132 _(sw_interface_set_lldp_reply)                          \
5133 _(tcp_configure_src_addresses_reply)                    \
5134 _(session_rule_add_del_reply)                           \
5135 _(ip_container_proxy_add_del_reply)                     \
5136 _(output_acl_set_interface_reply)                       \
5137 _(qos_record_enable_disable_reply)
5138
5139 #define _(n)                                    \
5140     static void vl_api_##n##_t_handler          \
5141     (vl_api_##n##_t * mp)                       \
5142     {                                           \
5143         vat_main_t * vam = &vat_main;           \
5144         i32 retval = ntohl(mp->retval);         \
5145         if (vam->async_mode) {                  \
5146             vam->async_errors += (retval < 0);  \
5147         } else {                                \
5148             vam->retval = retval;               \
5149             vam->result_ready = 1;              \
5150         }                                       \
5151     }
5152 foreach_standard_reply_retval_handler;
5153 #undef _
5154
5155 #define _(n)                                    \
5156     static void vl_api_##n##_t_handler_json     \
5157     (vl_api_##n##_t * mp)                       \
5158     {                                           \
5159         vat_main_t * vam = &vat_main;           \
5160         vat_json_node_t node;                   \
5161         vat_json_init_object(&node);            \
5162         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5163         vat_json_print(vam->ofp, &node);        \
5164         vam->retval = ntohl(mp->retval);        \
5165         vam->result_ready = 1;                  \
5166     }
5167 foreach_standard_reply_retval_handler;
5168 #undef _
5169
5170 /*
5171  * Table of message reply handlers, must include boilerplate handlers
5172  * we just generated
5173  */
5174
5175 #define foreach_vpe_api_reply_msg                                       \
5176 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5177 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5178 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5179 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5180 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5181 _(CLI_REPLY, cli_reply)                                                 \
5182 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5183 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5184   sw_interface_add_del_address_reply)                                   \
5185 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5186 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5187 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5188 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5189 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5190 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5191 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5192 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5193 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5194 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5195   sw_interface_set_l2_xconnect_reply)                                   \
5196 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5197   sw_interface_set_l2_bridge_reply)                                     \
5198 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5199 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5200 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5201 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5202 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5203 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5204 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5205 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5206 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5207 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5208 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5209 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5210 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5211 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5212 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5213 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5214 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5215 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5216 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5217 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5218 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5219 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5220 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5221 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5222 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5223 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5224 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5225 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5226 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5227 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5228 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5229 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5230 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5231 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5232   sw_interface_set_unnumbered_reply)                                    \
5233 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5234 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5235 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5236 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5237   sw_interface_ip6_enable_disable_reply)                                \
5238 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5239 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5240 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5241 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5242 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5243 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5244 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5245 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5246 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5247 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5248 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5249 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5250 classify_set_interface_ip_table_reply)                                  \
5251 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5252   classify_set_interface_l2_tables_reply)                               \
5253 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5254 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5255 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5256 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5257 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5258   l2tpv3_interface_enable_disable_reply)                                \
5259 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5260 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5261 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5262 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5263 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5264 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5265 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5266 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5267 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5268 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5269 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5270 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5271 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5272 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5273 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5274 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5275 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5276 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5277 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5278 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5279 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5280 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5281 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5282 _(L2_MACS_EVENT, l2_macs_event)                                         \
5283 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5284 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5285 _(IP_DETAILS, ip_details)                                               \
5286 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5287 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5288 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5289 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5290 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5291 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5292 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5293 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5294 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5295 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5296 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5297 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5298 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5299 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5300 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5301 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5302 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5303 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5304 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5305 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5306 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5307 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5308 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5309 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5310 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5311 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5312 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5313 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5314   one_map_register_enable_disable_reply)                                \
5315 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5316 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5317 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5318 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5319   one_map_register_fallback_threshold_reply)                            \
5320 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5321   one_rloc_probe_enable_disable_reply)                                  \
5322 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5323 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5324 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5325 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5326 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5327 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5328 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5329 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5330 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5331 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5332 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5333 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5334 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5335 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5336 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5337 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5338   show_one_stats_enable_disable_reply)                                  \
5339 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5340 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5341 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5342 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5343 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5344 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5345 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5346 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5347   one_enable_disable_pitr_mode_reply)                                   \
5348 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5349   one_enable_disable_petr_mode_reply)                                   \
5350 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5351 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5352 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5353 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5354 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5355 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5356 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5357 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5358 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5359 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5360 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5361 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5362   gpe_add_del_native_fwd_rpath_reply)                                   \
5363 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5364   gpe_fwd_entry_path_details)                                           \
5365 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5366 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5367   one_add_del_map_request_itr_rlocs_reply)                              \
5368 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5369   one_get_map_request_itr_rlocs_reply)                                  \
5370 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5371 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5372 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5373 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5374 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5375 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5376   show_one_map_register_state_reply)                                    \
5377 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5378 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5379   show_one_map_register_fallback_threshold_reply)                       \
5380 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5381 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5382 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5383 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5384 _(POLICER_DETAILS, policer_details)                                     \
5385 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5386 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5387 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5388 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5389 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5390 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5391 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5392 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5393 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5394 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5395 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5396 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5397 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5398 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5399 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5400 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5401 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5402 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5403 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5404 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5405 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5406 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5407 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5408 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5409  ip_source_and_port_range_check_add_del_reply)                          \
5410 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5411  ip_source_and_port_range_check_interface_add_del_reply)                \
5412 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5413 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5414 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5415 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5416 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5417 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5418 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5419 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5420 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5421 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5422 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5423 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5424 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5425 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5426 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5427 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5428 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5429 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5430 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5431 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5432 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5433 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5434 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5435
5436 #define foreach_standalone_reply_msg                                    \
5437 _(SW_INTERFACE_EVENT, sw_interface_event)
5438
5439 typedef struct
5440 {
5441   u8 *name;
5442   u32 value;
5443 } name_sort_t;
5444
5445 #define STR_VTR_OP_CASE(op)     \
5446     case L2_VTR_ ## op:         \
5447         return "" # op;
5448
5449 static const char *
5450 str_vtr_op (u32 vtr_op)
5451 {
5452   switch (vtr_op)
5453     {
5454       STR_VTR_OP_CASE (DISABLED);
5455       STR_VTR_OP_CASE (PUSH_1);
5456       STR_VTR_OP_CASE (PUSH_2);
5457       STR_VTR_OP_CASE (POP_1);
5458       STR_VTR_OP_CASE (POP_2);
5459       STR_VTR_OP_CASE (TRANSLATE_1_1);
5460       STR_VTR_OP_CASE (TRANSLATE_1_2);
5461       STR_VTR_OP_CASE (TRANSLATE_2_1);
5462       STR_VTR_OP_CASE (TRANSLATE_2_2);
5463     }
5464
5465   return "UNKNOWN";
5466 }
5467
5468 static int
5469 dump_sub_interface_table (vat_main_t * vam)
5470 {
5471   const sw_interface_subif_t *sub = NULL;
5472
5473   if (vam->json_output)
5474     {
5475       clib_warning
5476         ("JSON output supported only for VPE API calls and dump_stats_table");
5477       return -99;
5478     }
5479
5480   print (vam->ofp,
5481          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5482          "Interface", "sw_if_index",
5483          "sub id", "dot1ad", "tags", "outer id",
5484          "inner id", "exact", "default", "outer any", "inner any");
5485
5486   vec_foreach (sub, vam->sw_if_subif_table)
5487   {
5488     print (vam->ofp,
5489            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5490            sub->interface_name,
5491            sub->sw_if_index,
5492            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5493            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5494            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5495            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5496     if (sub->vtr_op != L2_VTR_DISABLED)
5497       {
5498         print (vam->ofp,
5499                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5500                "tag1: %d tag2: %d ]",
5501                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5502                sub->vtr_tag1, sub->vtr_tag2);
5503       }
5504   }
5505
5506   return 0;
5507 }
5508
5509 static int
5510 name_sort_cmp (void *a1, void *a2)
5511 {
5512   name_sort_t *n1 = a1;
5513   name_sort_t *n2 = a2;
5514
5515   return strcmp ((char *) n1->name, (char *) n2->name);
5516 }
5517
5518 static int
5519 dump_interface_table (vat_main_t * vam)
5520 {
5521   hash_pair_t *p;
5522   name_sort_t *nses = 0, *ns;
5523
5524   if (vam->json_output)
5525     {
5526       clib_warning
5527         ("JSON output supported only for VPE API calls and dump_stats_table");
5528       return -99;
5529     }
5530
5531   /* *INDENT-OFF* */
5532   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5533   ({
5534     vec_add2 (nses, ns, 1);
5535     ns->name = (u8 *)(p->key);
5536     ns->value = (u32) p->value[0];
5537   }));
5538   /* *INDENT-ON* */
5539
5540   vec_sort_with_function (nses, name_sort_cmp);
5541
5542   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5543   vec_foreach (ns, nses)
5544   {
5545     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5546   }
5547   vec_free (nses);
5548   return 0;
5549 }
5550
5551 static int
5552 dump_ip_table (vat_main_t * vam, int is_ipv6)
5553 {
5554   const ip_details_t *det = NULL;
5555   const ip_address_details_t *address = NULL;
5556   u32 i = ~0;
5557
5558   print (vam->ofp, "%-12s", "sw_if_index");
5559
5560   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5561   {
5562     i++;
5563     if (!det->present)
5564       {
5565         continue;
5566       }
5567     print (vam->ofp, "%-12d", i);
5568     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5569     if (!det->addr)
5570       {
5571         continue;
5572       }
5573     vec_foreach (address, det->addr)
5574     {
5575       print (vam->ofp,
5576              "            %-30U%-13d",
5577              is_ipv6 ? format_ip6_address : format_ip4_address,
5578              address->ip, address->prefix_length);
5579     }
5580   }
5581
5582   return 0;
5583 }
5584
5585 static int
5586 dump_ipv4_table (vat_main_t * vam)
5587 {
5588   if (vam->json_output)
5589     {
5590       clib_warning
5591         ("JSON output supported only for VPE API calls and dump_stats_table");
5592       return -99;
5593     }
5594
5595   return dump_ip_table (vam, 0);
5596 }
5597
5598 static int
5599 dump_ipv6_table (vat_main_t * vam)
5600 {
5601   if (vam->json_output)
5602     {
5603       clib_warning
5604         ("JSON output supported only for VPE API calls and dump_stats_table");
5605       return -99;
5606     }
5607
5608   return dump_ip_table (vam, 1);
5609 }
5610
5611 /*
5612  * Pass CLI buffers directly in the CLI_INBAND API message,
5613  * instead of an additional shared memory area.
5614  */
5615 static int
5616 exec_inband (vat_main_t * vam)
5617 {
5618   vl_api_cli_inband_t *mp;
5619   unformat_input_t *i = vam->input;
5620   int ret;
5621
5622   if (vec_len (i->buffer) == 0)
5623     return -1;
5624
5625   if (vam->exec_mode == 0 && unformat (i, "mode"))
5626     {
5627       vam->exec_mode = 1;
5628       return 0;
5629     }
5630   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5631     {
5632       vam->exec_mode = 0;
5633       return 0;
5634     }
5635
5636   /*
5637    * In order for the CLI command to work, it
5638    * must be a vector ending in \n, not a C-string ending
5639    * in \n\0.
5640    */
5641   u32 len = vec_len (vam->input->buffer);
5642   M2 (CLI_INBAND, mp, len);
5643   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5644
5645   S (mp);
5646   W (ret);
5647   /* json responses may or may not include a useful reply... */
5648   if (vec_len (vam->cmd_reply))
5649     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5650   return ret;
5651 }
5652
5653 int
5654 exec (vat_main_t * vam)
5655 {
5656   return exec_inband (vam);
5657 }
5658
5659 static int
5660 api_create_loopback (vat_main_t * vam)
5661 {
5662   unformat_input_t *i = vam->input;
5663   vl_api_create_loopback_t *mp;
5664   vl_api_create_loopback_instance_t *mp_lbi;
5665   u8 mac_address[6];
5666   u8 mac_set = 0;
5667   u8 is_specified = 0;
5668   u32 user_instance = 0;
5669   int ret;
5670
5671   clib_memset (mac_address, 0, sizeof (mac_address));
5672
5673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5674     {
5675       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5676         mac_set = 1;
5677       if (unformat (i, "instance %d", &user_instance))
5678         is_specified = 1;
5679       else
5680         break;
5681     }
5682
5683   if (is_specified)
5684     {
5685       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5686       mp_lbi->is_specified = is_specified;
5687       if (is_specified)
5688         mp_lbi->user_instance = htonl (user_instance);
5689       if (mac_set)
5690         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5691       S (mp_lbi);
5692     }
5693   else
5694     {
5695       /* Construct the API message */
5696       M (CREATE_LOOPBACK, mp);
5697       if (mac_set)
5698         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5699       S (mp);
5700     }
5701
5702   W (ret);
5703   return ret;
5704 }
5705
5706 static int
5707 api_delete_loopback (vat_main_t * vam)
5708 {
5709   unformat_input_t *i = vam->input;
5710   vl_api_delete_loopback_t *mp;
5711   u32 sw_if_index = ~0;
5712   int ret;
5713
5714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5715     {
5716       if (unformat (i, "sw_if_index %d", &sw_if_index))
5717         ;
5718       else
5719         break;
5720     }
5721
5722   if (sw_if_index == ~0)
5723     {
5724       errmsg ("missing sw_if_index");
5725       return -99;
5726     }
5727
5728   /* Construct the API message */
5729   M (DELETE_LOOPBACK, mp);
5730   mp->sw_if_index = ntohl (sw_if_index);
5731
5732   S (mp);
5733   W (ret);
5734   return ret;
5735 }
5736
5737 static int
5738 api_want_interface_events (vat_main_t * vam)
5739 {
5740   unformat_input_t *i = vam->input;
5741   vl_api_want_interface_events_t *mp;
5742   int enable = -1;
5743   int ret;
5744
5745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5746     {
5747       if (unformat (i, "enable"))
5748         enable = 1;
5749       else if (unformat (i, "disable"))
5750         enable = 0;
5751       else
5752         break;
5753     }
5754
5755   if (enable == -1)
5756     {
5757       errmsg ("missing enable|disable");
5758       return -99;
5759     }
5760
5761   M (WANT_INTERFACE_EVENTS, mp);
5762   mp->enable_disable = enable;
5763
5764   vam->interface_event_display = enable;
5765
5766   S (mp);
5767   W (ret);
5768   return ret;
5769 }
5770
5771
5772 /* Note: non-static, called once to set up the initial intfc table */
5773 int
5774 api_sw_interface_dump (vat_main_t * vam)
5775 {
5776   vl_api_sw_interface_dump_t *mp;
5777   vl_api_control_ping_t *mp_ping;
5778   hash_pair_t *p;
5779   name_sort_t *nses = 0, *ns;
5780   sw_interface_subif_t *sub = NULL;
5781   int ret;
5782
5783   /* Toss the old name table */
5784   /* *INDENT-OFF* */
5785   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5786   ({
5787     vec_add2 (nses, ns, 1);
5788     ns->name = (u8 *)(p->key);
5789     ns->value = (u32) p->value[0];
5790   }));
5791   /* *INDENT-ON* */
5792
5793   hash_free (vam->sw_if_index_by_interface_name);
5794
5795   vec_foreach (ns, nses) vec_free (ns->name);
5796
5797   vec_free (nses);
5798
5799   vec_foreach (sub, vam->sw_if_subif_table)
5800   {
5801     vec_free (sub->interface_name);
5802   }
5803   vec_free (vam->sw_if_subif_table);
5804
5805   /* recreate the interface name hash table */
5806   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5807
5808   /*
5809    * Ask for all interface names. Otherwise, the epic catalog of
5810    * name filters becomes ridiculously long, and vat ends up needing
5811    * to be taught about new interface types.
5812    */
5813   M (SW_INTERFACE_DUMP, mp);
5814   S (mp);
5815
5816   /* Use a control ping for synchronization */
5817   MPING (CONTROL_PING, mp_ping);
5818   S (mp_ping);
5819
5820   W (ret);
5821   return ret;
5822 }
5823
5824 static int
5825 api_sw_interface_set_flags (vat_main_t * vam)
5826 {
5827   unformat_input_t *i = vam->input;
5828   vl_api_sw_interface_set_flags_t *mp;
5829   u32 sw_if_index;
5830   u8 sw_if_index_set = 0;
5831   u8 admin_up = 0;
5832   int ret;
5833
5834   /* Parse args required to build the message */
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "admin-up"))
5838         admin_up = 1;
5839       else if (unformat (i, "admin-down"))
5840         admin_up = 0;
5841       else
5842         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5843         sw_if_index_set = 1;
5844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5845         sw_if_index_set = 1;
5846       else
5847         break;
5848     }
5849
5850   if (sw_if_index_set == 0)
5851     {
5852       errmsg ("missing interface name or sw_if_index");
5853       return -99;
5854     }
5855
5856   /* Construct the API message */
5857   M (SW_INTERFACE_SET_FLAGS, mp);
5858   mp->sw_if_index = ntohl (sw_if_index);
5859   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5860
5861   /* send it... */
5862   S (mp);
5863
5864   /* Wait for a reply, return the good/bad news... */
5865   W (ret);
5866   return ret;
5867 }
5868
5869 static int
5870 api_sw_interface_set_rx_mode (vat_main_t * vam)
5871 {
5872   unformat_input_t *i = vam->input;
5873   vl_api_sw_interface_set_rx_mode_t *mp;
5874   u32 sw_if_index;
5875   u8 sw_if_index_set = 0;
5876   int ret;
5877   u8 queue_id_valid = 0;
5878   u32 queue_id;
5879   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5880
5881   /* Parse args required to build the message */
5882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5883     {
5884       if (unformat (i, "queue %d", &queue_id))
5885         queue_id_valid = 1;
5886       else if (unformat (i, "polling"))
5887         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5888       else if (unformat (i, "interrupt"))
5889         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5890       else if (unformat (i, "adaptive"))
5891         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5892       else
5893         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5894         sw_if_index_set = 1;
5895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5896         sw_if_index_set = 1;
5897       else
5898         break;
5899     }
5900
5901   if (sw_if_index_set == 0)
5902     {
5903       errmsg ("missing interface name or sw_if_index");
5904       return -99;
5905     }
5906   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5907     {
5908       errmsg ("missing rx-mode");
5909       return -99;
5910     }
5911
5912   /* Construct the API message */
5913   M (SW_INTERFACE_SET_RX_MODE, mp);
5914   mp->sw_if_index = ntohl (sw_if_index);
5915   mp->mode = (vl_api_rx_mode_t) mode;
5916   mp->queue_id_valid = queue_id_valid;
5917   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5918
5919   /* send it... */
5920   S (mp);
5921
5922   /* Wait for a reply, return the good/bad news... */
5923   W (ret);
5924   return ret;
5925 }
5926
5927 static int
5928 api_sw_interface_set_rx_placement (vat_main_t * vam)
5929 {
5930   unformat_input_t *i = vam->input;
5931   vl_api_sw_interface_set_rx_placement_t *mp;
5932   u32 sw_if_index;
5933   u8 sw_if_index_set = 0;
5934   int ret;
5935   u8 is_main = 0;
5936   u32 queue_id, thread_index;
5937
5938   /* Parse args required to build the message */
5939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5940     {
5941       if (unformat (i, "queue %d", &queue_id))
5942         ;
5943       else if (unformat (i, "main"))
5944         is_main = 1;
5945       else if (unformat (i, "worker %d", &thread_index))
5946         ;
5947       else
5948         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5949         sw_if_index_set = 1;
5950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5951         sw_if_index_set = 1;
5952       else
5953         break;
5954     }
5955
5956   if (sw_if_index_set == 0)
5957     {
5958       errmsg ("missing interface name or sw_if_index");
5959       return -99;
5960     }
5961
5962   if (is_main)
5963     thread_index = 0;
5964   /* Construct the API message */
5965   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5966   mp->sw_if_index = ntohl (sw_if_index);
5967   mp->worker_id = ntohl (thread_index);
5968   mp->queue_id = ntohl (queue_id);
5969   mp->is_main = is_main;
5970
5971   /* send it... */
5972   S (mp);
5973   /* Wait for a reply, return the good/bad news... */
5974   W (ret);
5975   return ret;
5976 }
5977
5978 static void vl_api_sw_interface_rx_placement_details_t_handler
5979   (vl_api_sw_interface_rx_placement_details_t * mp)
5980 {
5981   vat_main_t *vam = &vat_main;
5982   u32 worker_id = ntohl (mp->worker_id);
5983
5984   print (vam->ofp,
5985          "\n%-11d %-11s %-6d %-5d %-9s",
5986          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5987          worker_id, ntohl (mp->queue_id),
5988          (mp->mode ==
5989           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5990 }
5991
5992 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5993   (vl_api_sw_interface_rx_placement_details_t * mp)
5994 {
5995   vat_main_t *vam = &vat_main;
5996   vat_json_node_t *node = NULL;
5997
5998   if (VAT_JSON_ARRAY != vam->json_tree.type)
5999     {
6000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6001       vat_json_init_array (&vam->json_tree);
6002     }
6003   node = vat_json_array_add (&vam->json_tree);
6004
6005   vat_json_init_object (node);
6006   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6007   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6008   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6009   vat_json_object_add_uint (node, "mode", mp->mode);
6010 }
6011
6012 static int
6013 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6014 {
6015   unformat_input_t *i = vam->input;
6016   vl_api_sw_interface_rx_placement_dump_t *mp;
6017   vl_api_control_ping_t *mp_ping;
6018   int ret;
6019   u32 sw_if_index;
6020   u8 sw_if_index_set = 0;
6021
6022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6023     {
6024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6025         sw_if_index_set++;
6026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6027         sw_if_index_set++;
6028       else
6029         break;
6030     }
6031
6032   print (vam->ofp,
6033          "\n%-11s %-11s %-6s %-5s %-4s",
6034          "sw_if_index", "main/worker", "thread", "queue", "mode");
6035
6036   /* Dump Interface rx placement */
6037   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6038
6039   if (sw_if_index_set)
6040     mp->sw_if_index = htonl (sw_if_index);
6041   else
6042     mp->sw_if_index = ~0;
6043
6044   S (mp);
6045
6046   /* Use a control ping for synchronization */
6047   MPING (CONTROL_PING, mp_ping);
6048   S (mp_ping);
6049
6050   W (ret);
6051   return ret;
6052 }
6053
6054 static int
6055 api_sw_interface_clear_stats (vat_main_t * vam)
6056 {
6057   unformat_input_t *i = vam->input;
6058   vl_api_sw_interface_clear_stats_t *mp;
6059   u32 sw_if_index;
6060   u8 sw_if_index_set = 0;
6061   int ret;
6062
6063   /* Parse args required to build the message */
6064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6065     {
6066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6067         sw_if_index_set = 1;
6068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6069         sw_if_index_set = 1;
6070       else
6071         break;
6072     }
6073
6074   /* Construct the API message */
6075   M (SW_INTERFACE_CLEAR_STATS, mp);
6076
6077   if (sw_if_index_set == 1)
6078     mp->sw_if_index = ntohl (sw_if_index);
6079   else
6080     mp->sw_if_index = ~0;
6081
6082   /* send it... */
6083   S (mp);
6084
6085   /* Wait for a reply, return the good/bad news... */
6086   W (ret);
6087   return ret;
6088 }
6089
6090 static int
6091 api_sw_interface_add_del_address (vat_main_t * vam)
6092 {
6093   unformat_input_t *i = vam->input;
6094   vl_api_sw_interface_add_del_address_t *mp;
6095   u32 sw_if_index;
6096   u8 sw_if_index_set = 0;
6097   u8 is_add = 1, del_all = 0;
6098   u32 address_length = 0;
6099   u8 v4_address_set = 0;
6100   u8 v6_address_set = 0;
6101   ip4_address_t v4address;
6102   ip6_address_t v6address;
6103   int ret;
6104
6105   /* Parse args required to build the message */
6106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6107     {
6108       if (unformat (i, "del-all"))
6109         del_all = 1;
6110       else if (unformat (i, "del"))
6111         is_add = 0;
6112       else
6113         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6114         sw_if_index_set = 1;
6115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6116         sw_if_index_set = 1;
6117       else if (unformat (i, "%U/%d",
6118                          unformat_ip4_address, &v4address, &address_length))
6119         v4_address_set = 1;
6120       else if (unformat (i, "%U/%d",
6121                          unformat_ip6_address, &v6address, &address_length))
6122         v6_address_set = 1;
6123       else
6124         break;
6125     }
6126
6127   if (sw_if_index_set == 0)
6128     {
6129       errmsg ("missing interface name or sw_if_index");
6130       return -99;
6131     }
6132   if (v4_address_set && v6_address_set)
6133     {
6134       errmsg ("both v4 and v6 addresses set");
6135       return -99;
6136     }
6137   if (!v4_address_set && !v6_address_set && !del_all)
6138     {
6139       errmsg ("no addresses set");
6140       return -99;
6141     }
6142
6143   /* Construct the API message */
6144   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6145
6146   mp->sw_if_index = ntohl (sw_if_index);
6147   mp->is_add = is_add;
6148   mp->del_all = del_all;
6149   if (v6_address_set)
6150     {
6151       mp->prefix.address.af = ADDRESS_IP6;
6152       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6153     }
6154   else
6155     {
6156       mp->prefix.address.af = ADDRESS_IP4;
6157       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6158     }
6159   mp->prefix.len = address_length;
6160
6161   /* send it... */
6162   S (mp);
6163
6164   /* Wait for a reply, return good/bad news  */
6165   W (ret);
6166   return ret;
6167 }
6168
6169 static int
6170 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6171 {
6172   unformat_input_t *i = vam->input;
6173   vl_api_sw_interface_set_mpls_enable_t *mp;
6174   u32 sw_if_index;
6175   u8 sw_if_index_set = 0;
6176   u8 enable = 1;
6177   int ret;
6178
6179   /* Parse args required to build the message */
6180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181     {
6182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6183         sw_if_index_set = 1;
6184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6185         sw_if_index_set = 1;
6186       else if (unformat (i, "disable"))
6187         enable = 0;
6188       else if (unformat (i, "dis"))
6189         enable = 0;
6190       else
6191         break;
6192     }
6193
6194   if (sw_if_index_set == 0)
6195     {
6196       errmsg ("missing interface name or sw_if_index");
6197       return -99;
6198     }
6199
6200   /* Construct the API message */
6201   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6202
6203   mp->sw_if_index = ntohl (sw_if_index);
6204   mp->enable = enable;
6205
6206   /* send it... */
6207   S (mp);
6208
6209   /* Wait for a reply... */
6210   W (ret);
6211   return ret;
6212 }
6213
6214 static int
6215 api_sw_interface_set_table (vat_main_t * vam)
6216 {
6217   unformat_input_t *i = vam->input;
6218   vl_api_sw_interface_set_table_t *mp;
6219   u32 sw_if_index, vrf_id = 0;
6220   u8 sw_if_index_set = 0;
6221   u8 is_ipv6 = 0;
6222   int ret;
6223
6224   /* Parse args required to build the message */
6225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6226     {
6227       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6228         sw_if_index_set = 1;
6229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6230         sw_if_index_set = 1;
6231       else if (unformat (i, "vrf %d", &vrf_id))
6232         ;
6233       else if (unformat (i, "ipv6"))
6234         is_ipv6 = 1;
6235       else
6236         break;
6237     }
6238
6239   if (sw_if_index_set == 0)
6240     {
6241       errmsg ("missing interface name or sw_if_index");
6242       return -99;
6243     }
6244
6245   /* Construct the API message */
6246   M (SW_INTERFACE_SET_TABLE, mp);
6247
6248   mp->sw_if_index = ntohl (sw_if_index);
6249   mp->is_ipv6 = is_ipv6;
6250   mp->vrf_id = ntohl (vrf_id);
6251
6252   /* send it... */
6253   S (mp);
6254
6255   /* Wait for a reply... */
6256   W (ret);
6257   return ret;
6258 }
6259
6260 static void vl_api_sw_interface_get_table_reply_t_handler
6261   (vl_api_sw_interface_get_table_reply_t * mp)
6262 {
6263   vat_main_t *vam = &vat_main;
6264
6265   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6266
6267   vam->retval = ntohl (mp->retval);
6268   vam->result_ready = 1;
6269
6270 }
6271
6272 static void vl_api_sw_interface_get_table_reply_t_handler_json
6273   (vl_api_sw_interface_get_table_reply_t * mp)
6274 {
6275   vat_main_t *vam = &vat_main;
6276   vat_json_node_t node;
6277
6278   vat_json_init_object (&node);
6279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6280   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6281
6282   vat_json_print (vam->ofp, &node);
6283   vat_json_free (&node);
6284
6285   vam->retval = ntohl (mp->retval);
6286   vam->result_ready = 1;
6287 }
6288
6289 static int
6290 api_sw_interface_get_table (vat_main_t * vam)
6291 {
6292   unformat_input_t *i = vam->input;
6293   vl_api_sw_interface_get_table_t *mp;
6294   u32 sw_if_index;
6295   u8 sw_if_index_set = 0;
6296   u8 is_ipv6 = 0;
6297   int ret;
6298
6299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6300     {
6301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6302         sw_if_index_set = 1;
6303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6304         sw_if_index_set = 1;
6305       else if (unformat (i, "ipv6"))
6306         is_ipv6 = 1;
6307       else
6308         break;
6309     }
6310
6311   if (sw_if_index_set == 0)
6312     {
6313       errmsg ("missing interface name or sw_if_index");
6314       return -99;
6315     }
6316
6317   M (SW_INTERFACE_GET_TABLE, mp);
6318   mp->sw_if_index = htonl (sw_if_index);
6319   mp->is_ipv6 = is_ipv6;
6320
6321   S (mp);
6322   W (ret);
6323   return ret;
6324 }
6325
6326 static int
6327 api_sw_interface_set_vpath (vat_main_t * vam)
6328 {
6329   unformat_input_t *i = vam->input;
6330   vl_api_sw_interface_set_vpath_t *mp;
6331   u32 sw_if_index = 0;
6332   u8 sw_if_index_set = 0;
6333   u8 is_enable = 0;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "enable"))
6344         is_enable = 1;
6345       else if (unformat (i, "disable"))
6346         is_enable = 0;
6347       else
6348         break;
6349     }
6350
6351   if (sw_if_index_set == 0)
6352     {
6353       errmsg ("missing interface name or sw_if_index");
6354       return -99;
6355     }
6356
6357   /* Construct the API message */
6358   M (SW_INTERFACE_SET_VPATH, mp);
6359
6360   mp->sw_if_index = ntohl (sw_if_index);
6361   mp->enable = is_enable;
6362
6363   /* send it... */
6364   S (mp);
6365
6366   /* Wait for a reply... */
6367   W (ret);
6368   return ret;
6369 }
6370
6371 static int
6372 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6373 {
6374   unformat_input_t *i = vam->input;
6375   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6376   u32 sw_if_index = 0;
6377   u8 sw_if_index_set = 0;
6378   u8 is_enable = 1;
6379   u8 is_ipv6 = 0;
6380   int ret;
6381
6382   /* Parse args required to build the message */
6383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6384     {
6385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6386         sw_if_index_set = 1;
6387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6388         sw_if_index_set = 1;
6389       else if (unformat (i, "enable"))
6390         is_enable = 1;
6391       else if (unformat (i, "disable"))
6392         is_enable = 0;
6393       else if (unformat (i, "ip4"))
6394         is_ipv6 = 0;
6395       else if (unformat (i, "ip6"))
6396         is_ipv6 = 1;
6397       else
6398         break;
6399     }
6400
6401   if (sw_if_index_set == 0)
6402     {
6403       errmsg ("missing interface name or sw_if_index");
6404       return -99;
6405     }
6406
6407   /* Construct the API message */
6408   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6409
6410   mp->sw_if_index = ntohl (sw_if_index);
6411   mp->enable = is_enable;
6412   mp->is_ipv6 = is_ipv6;
6413
6414   /* send it... */
6415   S (mp);
6416
6417   /* Wait for a reply... */
6418   W (ret);
6419   return ret;
6420 }
6421
6422 static int
6423 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6424 {
6425   unformat_input_t *i = vam->input;
6426   vl_api_sw_interface_set_geneve_bypass_t *mp;
6427   u32 sw_if_index = 0;
6428   u8 sw_if_index_set = 0;
6429   u8 is_enable = 1;
6430   u8 is_ipv6 = 0;
6431   int ret;
6432
6433   /* Parse args required to build the message */
6434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6435     {
6436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6437         sw_if_index_set = 1;
6438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6439         sw_if_index_set = 1;
6440       else if (unformat (i, "enable"))
6441         is_enable = 1;
6442       else if (unformat (i, "disable"))
6443         is_enable = 0;
6444       else if (unformat (i, "ip4"))
6445         is_ipv6 = 0;
6446       else if (unformat (i, "ip6"))
6447         is_ipv6 = 1;
6448       else
6449         break;
6450     }
6451
6452   if (sw_if_index_set == 0)
6453     {
6454       errmsg ("missing interface name or sw_if_index");
6455       return -99;
6456     }
6457
6458   /* Construct the API message */
6459   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6460
6461   mp->sw_if_index = ntohl (sw_if_index);
6462   mp->enable = is_enable;
6463   mp->is_ipv6 = is_ipv6;
6464
6465   /* send it... */
6466   S (mp);
6467
6468   /* Wait for a reply... */
6469   W (ret);
6470   return ret;
6471 }
6472
6473 static int
6474 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6475 {
6476   unformat_input_t *i = vam->input;
6477   vl_api_sw_interface_set_l2_xconnect_t *mp;
6478   u32 rx_sw_if_index;
6479   u8 rx_sw_if_index_set = 0;
6480   u32 tx_sw_if_index;
6481   u8 tx_sw_if_index_set = 0;
6482   u8 enable = 1;
6483   int ret;
6484
6485   /* Parse args required to build the message */
6486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6487     {
6488       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6489         rx_sw_if_index_set = 1;
6490       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6491         tx_sw_if_index_set = 1;
6492       else if (unformat (i, "rx"))
6493         {
6494           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6495             {
6496               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6497                             &rx_sw_if_index))
6498                 rx_sw_if_index_set = 1;
6499             }
6500           else
6501             break;
6502         }
6503       else if (unformat (i, "tx"))
6504         {
6505           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506             {
6507               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6508                             &tx_sw_if_index))
6509                 tx_sw_if_index_set = 1;
6510             }
6511           else
6512             break;
6513         }
6514       else if (unformat (i, "enable"))
6515         enable = 1;
6516       else if (unformat (i, "disable"))
6517         enable = 0;
6518       else
6519         break;
6520     }
6521
6522   if (rx_sw_if_index_set == 0)
6523     {
6524       errmsg ("missing rx interface name or rx_sw_if_index");
6525       return -99;
6526     }
6527
6528   if (enable && (tx_sw_if_index_set == 0))
6529     {
6530       errmsg ("missing tx interface name or tx_sw_if_index");
6531       return -99;
6532     }
6533
6534   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6535
6536   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6537   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6538   mp->enable = enable;
6539
6540   S (mp);
6541   W (ret);
6542   return ret;
6543 }
6544
6545 static int
6546 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_sw_interface_set_l2_bridge_t *mp;
6550   vl_api_l2_port_type_t port_type;
6551   u32 rx_sw_if_index;
6552   u8 rx_sw_if_index_set = 0;
6553   u32 bd_id;
6554   u8 bd_id_set = 0;
6555   u32 shg = 0;
6556   u8 enable = 1;
6557   int ret;
6558
6559   port_type = L2_API_PORT_TYPE_NORMAL;
6560
6561   /* Parse args required to build the message */
6562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6563     {
6564       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6565         rx_sw_if_index_set = 1;
6566       else if (unformat (i, "bd_id %d", &bd_id))
6567         bd_id_set = 1;
6568       else
6569         if (unformat
6570             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6571         rx_sw_if_index_set = 1;
6572       else if (unformat (i, "shg %d", &shg))
6573         ;
6574       else if (unformat (i, "bvi"))
6575         port_type = L2_API_PORT_TYPE_BVI;
6576       else if (unformat (i, "uu-fwd"))
6577         port_type = L2_API_PORT_TYPE_UU_FWD;
6578       else if (unformat (i, "enable"))
6579         enable = 1;
6580       else if (unformat (i, "disable"))
6581         enable = 0;
6582       else
6583         break;
6584     }
6585
6586   if (rx_sw_if_index_set == 0)
6587     {
6588       errmsg ("missing rx interface name or sw_if_index");
6589       return -99;
6590     }
6591
6592   if (enable && (bd_id_set == 0))
6593     {
6594       errmsg ("missing bridge domain");
6595       return -99;
6596     }
6597
6598   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6599
6600   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6601   mp->bd_id = ntohl (bd_id);
6602   mp->shg = (u8) shg;
6603   mp->port_type = ntohl (port_type);
6604   mp->enable = enable;
6605
6606   S (mp);
6607   W (ret);
6608   return ret;
6609 }
6610
6611 static int
6612 api_bridge_domain_dump (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_bridge_domain_dump_t *mp;
6616   vl_api_control_ping_t *mp_ping;
6617   u32 bd_id = ~0;
6618   int ret;
6619
6620   /* Parse args required to build the message */
6621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6622     {
6623       if (unformat (i, "bd_id %d", &bd_id))
6624         ;
6625       else
6626         break;
6627     }
6628
6629   M (BRIDGE_DOMAIN_DUMP, mp);
6630   mp->bd_id = ntohl (bd_id);
6631   S (mp);
6632
6633   /* Use a control ping for synchronization */
6634   MPING (CONTROL_PING, mp_ping);
6635   S (mp_ping);
6636
6637   W (ret);
6638   return ret;
6639 }
6640
6641 static int
6642 api_bridge_domain_add_del (vat_main_t * vam)
6643 {
6644   unformat_input_t *i = vam->input;
6645   vl_api_bridge_domain_add_del_t *mp;
6646   u32 bd_id = ~0;
6647   u8 is_add = 1;
6648   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6649   u8 *bd_tag = NULL;
6650   u32 mac_age = 0;
6651   int ret;
6652
6653   /* Parse args required to build the message */
6654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6655     {
6656       if (unformat (i, "bd_id %d", &bd_id))
6657         ;
6658       else if (unformat (i, "flood %d", &flood))
6659         ;
6660       else if (unformat (i, "uu-flood %d", &uu_flood))
6661         ;
6662       else if (unformat (i, "forward %d", &forward))
6663         ;
6664       else if (unformat (i, "learn %d", &learn))
6665         ;
6666       else if (unformat (i, "arp-term %d", &arp_term))
6667         ;
6668       else if (unformat (i, "mac-age %d", &mac_age))
6669         ;
6670       else if (unformat (i, "bd-tag %s", &bd_tag))
6671         ;
6672       else if (unformat (i, "del"))
6673         {
6674           is_add = 0;
6675           flood = uu_flood = forward = learn = 0;
6676         }
6677       else
6678         break;
6679     }
6680
6681   if (bd_id == ~0)
6682     {
6683       errmsg ("missing bridge domain");
6684       ret = -99;
6685       goto done;
6686     }
6687
6688   if (mac_age > 255)
6689     {
6690       errmsg ("mac age must be less than 256 ");
6691       ret = -99;
6692       goto done;
6693     }
6694
6695   if ((bd_tag) && (vec_len (bd_tag) > 63))
6696     {
6697       errmsg ("bd-tag cannot be longer than 63");
6698       ret = -99;
6699       goto done;
6700     }
6701
6702   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6703
6704   mp->bd_id = ntohl (bd_id);
6705   mp->flood = flood;
6706   mp->uu_flood = uu_flood;
6707   mp->forward = forward;
6708   mp->learn = learn;
6709   mp->arp_term = arp_term;
6710   mp->is_add = is_add;
6711   mp->mac_age = (u8) mac_age;
6712   if (bd_tag)
6713     {
6714       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6715       mp->bd_tag[vec_len (bd_tag)] = 0;
6716     }
6717   S (mp);
6718   W (ret);
6719
6720 done:
6721   vec_free (bd_tag);
6722   return ret;
6723 }
6724
6725 static int
6726 api_l2fib_flush_bd (vat_main_t * vam)
6727 {
6728   unformat_input_t *i = vam->input;
6729   vl_api_l2fib_flush_bd_t *mp;
6730   u32 bd_id = ~0;
6731   int ret;
6732
6733   /* Parse args required to build the message */
6734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735     {
6736       if (unformat (i, "bd_id %d", &bd_id));
6737       else
6738         break;
6739     }
6740
6741   if (bd_id == ~0)
6742     {
6743       errmsg ("missing bridge domain");
6744       return -99;
6745     }
6746
6747   M (L2FIB_FLUSH_BD, mp);
6748
6749   mp->bd_id = htonl (bd_id);
6750
6751   S (mp);
6752   W (ret);
6753   return ret;
6754 }
6755
6756 static int
6757 api_l2fib_flush_int (vat_main_t * vam)
6758 {
6759   unformat_input_t *i = vam->input;
6760   vl_api_l2fib_flush_int_t *mp;
6761   u32 sw_if_index = ~0;
6762   int ret;
6763
6764   /* Parse args required to build the message */
6765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6766     {
6767       if (unformat (i, "sw_if_index %d", &sw_if_index));
6768       else
6769         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6770       else
6771         break;
6772     }
6773
6774   if (sw_if_index == ~0)
6775     {
6776       errmsg ("missing interface name or sw_if_index");
6777       return -99;
6778     }
6779
6780   M (L2FIB_FLUSH_INT, mp);
6781
6782   mp->sw_if_index = ntohl (sw_if_index);
6783
6784   S (mp);
6785   W (ret);
6786   return ret;
6787 }
6788
6789 static int
6790 api_l2fib_add_del (vat_main_t * vam)
6791 {
6792   unformat_input_t *i = vam->input;
6793   vl_api_l2fib_add_del_t *mp;
6794   f64 timeout;
6795   u8 mac[6] = { 0 };
6796   u8 mac_set = 0;
6797   u32 bd_id;
6798   u8 bd_id_set = 0;
6799   u32 sw_if_index = 0;
6800   u8 sw_if_index_set = 0;
6801   u8 is_add = 1;
6802   u8 static_mac = 0;
6803   u8 filter_mac = 0;
6804   u8 bvi_mac = 0;
6805   int count = 1;
6806   f64 before = 0;
6807   int j;
6808
6809   /* Parse args required to build the message */
6810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6811     {
6812       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6813         mac_set = 1;
6814       else if (unformat (i, "bd_id %d", &bd_id))
6815         bd_id_set = 1;
6816       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6817         sw_if_index_set = 1;
6818       else if (unformat (i, "sw_if"))
6819         {
6820           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6821             {
6822               if (unformat
6823                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6824                 sw_if_index_set = 1;
6825             }
6826           else
6827             break;
6828         }
6829       else if (unformat (i, "static"))
6830         static_mac = 1;
6831       else if (unformat (i, "filter"))
6832         {
6833           filter_mac = 1;
6834           static_mac = 1;
6835         }
6836       else if (unformat (i, "bvi"))
6837         {
6838           bvi_mac = 1;
6839           static_mac = 1;
6840         }
6841       else if (unformat (i, "del"))
6842         is_add = 0;
6843       else if (unformat (i, "count %d", &count))
6844         ;
6845       else
6846         break;
6847     }
6848
6849   if (mac_set == 0)
6850     {
6851       errmsg ("missing mac address");
6852       return -99;
6853     }
6854
6855   if (bd_id_set == 0)
6856     {
6857       errmsg ("missing bridge domain");
6858       return -99;
6859     }
6860
6861   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6862     {
6863       errmsg ("missing interface name or sw_if_index");
6864       return -99;
6865     }
6866
6867   if (count > 1)
6868     {
6869       /* Turn on async mode */
6870       vam->async_mode = 1;
6871       vam->async_errors = 0;
6872       before = vat_time_now (vam);
6873     }
6874
6875   for (j = 0; j < count; j++)
6876     {
6877       M (L2FIB_ADD_DEL, mp);
6878
6879       clib_memcpy (mp->mac, mac, 6);
6880       mp->bd_id = ntohl (bd_id);
6881       mp->is_add = is_add;
6882       mp->sw_if_index = ntohl (sw_if_index);
6883
6884       if (is_add)
6885         {
6886           mp->static_mac = static_mac;
6887           mp->filter_mac = filter_mac;
6888           mp->bvi_mac = bvi_mac;
6889         }
6890       increment_mac_address (mac);
6891       /* send it... */
6892       S (mp);
6893     }
6894
6895   if (count > 1)
6896     {
6897       vl_api_control_ping_t *mp_ping;
6898       f64 after;
6899
6900       /* Shut off async mode */
6901       vam->async_mode = 0;
6902
6903       MPING (CONTROL_PING, mp_ping);
6904       S (mp_ping);
6905
6906       timeout = vat_time_now (vam) + 1.0;
6907       while (vat_time_now (vam) < timeout)
6908         if (vam->result_ready == 1)
6909           goto out;
6910       vam->retval = -99;
6911
6912     out:
6913       if (vam->retval == -99)
6914         errmsg ("timeout");
6915
6916       if (vam->async_errors > 0)
6917         {
6918           errmsg ("%d asynchronous errors", vam->async_errors);
6919           vam->retval = -98;
6920         }
6921       vam->async_errors = 0;
6922       after = vat_time_now (vam);
6923
6924       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6925              count, after - before, count / (after - before));
6926     }
6927   else
6928     {
6929       int ret;
6930
6931       /* Wait for a reply... */
6932       W (ret);
6933       return ret;
6934     }
6935   /* Return the good/bad news */
6936   return (vam->retval);
6937 }
6938
6939 static int
6940 api_bridge_domain_set_mac_age (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_bridge_domain_set_mac_age_t *mp;
6944   u32 bd_id = ~0;
6945   u32 mac_age = 0;
6946   int ret;
6947
6948   /* Parse args required to build the message */
6949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950     {
6951       if (unformat (i, "bd_id %d", &bd_id));
6952       else if (unformat (i, "mac-age %d", &mac_age));
6953       else
6954         break;
6955     }
6956
6957   if (bd_id == ~0)
6958     {
6959       errmsg ("missing bridge domain");
6960       return -99;
6961     }
6962
6963   if (mac_age > 255)
6964     {
6965       errmsg ("mac age must be less than 256 ");
6966       return -99;
6967     }
6968
6969   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6970
6971   mp->bd_id = htonl (bd_id);
6972   mp->mac_age = (u8) mac_age;
6973
6974   S (mp);
6975   W (ret);
6976   return ret;
6977 }
6978
6979 static int
6980 api_l2_flags (vat_main_t * vam)
6981 {
6982   unformat_input_t *i = vam->input;
6983   vl_api_l2_flags_t *mp;
6984   u32 sw_if_index;
6985   u32 flags = 0;
6986   u8 sw_if_index_set = 0;
6987   u8 is_set = 0;
6988   int ret;
6989
6990   /* Parse args required to build the message */
6991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6992     {
6993       if (unformat (i, "sw_if_index %d", &sw_if_index))
6994         sw_if_index_set = 1;
6995       else if (unformat (i, "sw_if"))
6996         {
6997           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6998             {
6999               if (unformat
7000                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7001                 sw_if_index_set = 1;
7002             }
7003           else
7004             break;
7005         }
7006       else if (unformat (i, "learn"))
7007         flags |= L2_LEARN;
7008       else if (unformat (i, "forward"))
7009         flags |= L2_FWD;
7010       else if (unformat (i, "flood"))
7011         flags |= L2_FLOOD;
7012       else if (unformat (i, "uu-flood"))
7013         flags |= L2_UU_FLOOD;
7014       else if (unformat (i, "arp-term"))
7015         flags |= L2_ARP_TERM;
7016       else if (unformat (i, "off"))
7017         is_set = 0;
7018       else if (unformat (i, "disable"))
7019         is_set = 0;
7020       else
7021         break;
7022     }
7023
7024   if (sw_if_index_set == 0)
7025     {
7026       errmsg ("missing interface name or sw_if_index");
7027       return -99;
7028     }
7029
7030   M (L2_FLAGS, mp);
7031
7032   mp->sw_if_index = ntohl (sw_if_index);
7033   mp->feature_bitmap = ntohl (flags);
7034   mp->is_set = is_set;
7035
7036   S (mp);
7037   W (ret);
7038   return ret;
7039 }
7040
7041 static int
7042 api_bridge_flags (vat_main_t * vam)
7043 {
7044   unformat_input_t *i = vam->input;
7045   vl_api_bridge_flags_t *mp;
7046   u32 bd_id;
7047   u8 bd_id_set = 0;
7048   u8 is_set = 1;
7049   bd_flags_t flags = 0;
7050   int ret;
7051
7052   /* Parse args required to build the message */
7053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7054     {
7055       if (unformat (i, "bd_id %d", &bd_id))
7056         bd_id_set = 1;
7057       else if (unformat (i, "learn"))
7058         flags |= BRIDGE_API_FLAG_LEARN;
7059       else if (unformat (i, "forward"))
7060         flags |= BRIDGE_API_FLAG_FWD;
7061       else if (unformat (i, "flood"))
7062         flags |= BRIDGE_API_FLAG_FLOOD;
7063       else if (unformat (i, "uu-flood"))
7064         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7065       else if (unformat (i, "arp-term"))
7066         flags |= BRIDGE_API_FLAG_ARP_TERM;
7067       else if (unformat (i, "off"))
7068         is_set = 0;
7069       else if (unformat (i, "disable"))
7070         is_set = 0;
7071       else
7072         break;
7073     }
7074
7075   if (bd_id_set == 0)
7076     {
7077       errmsg ("missing bridge domain");
7078       return -99;
7079     }
7080
7081   M (BRIDGE_FLAGS, mp);
7082
7083   mp->bd_id = ntohl (bd_id);
7084   mp->flags = ntohl (flags);
7085   mp->is_set = is_set;
7086
7087   S (mp);
7088   W (ret);
7089   return ret;
7090 }
7091
7092 static int
7093 api_bd_ip_mac_add_del (vat_main_t * vam)
7094 {
7095   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7096   vl_api_mac_address_t mac = { 0 };
7097   unformat_input_t *i = vam->input;
7098   vl_api_bd_ip_mac_add_del_t *mp;
7099   u32 bd_id;
7100   u8 is_add = 1;
7101   u8 bd_id_set = 0;
7102   u8 ip_set = 0;
7103   u8 mac_set = 0;
7104   int ret;
7105
7106
7107   /* Parse args required to build the message */
7108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7109     {
7110       if (unformat (i, "bd_id %d", &bd_id))
7111         {
7112           bd_id_set++;
7113         }
7114       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7115         {
7116           ip_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7119         {
7120           mac_set++;
7121         }
7122       else if (unformat (i, "del"))
7123         is_add = 0;
7124       else
7125         break;
7126     }
7127
7128   if (bd_id_set == 0)
7129     {
7130       errmsg ("missing bridge domain");
7131       return -99;
7132     }
7133   else if (ip_set == 0)
7134     {
7135       errmsg ("missing IP address");
7136       return -99;
7137     }
7138   else if (mac_set == 0)
7139     {
7140       errmsg ("missing MAC address");
7141       return -99;
7142     }
7143
7144   M (BD_IP_MAC_ADD_DEL, mp);
7145
7146   mp->entry.bd_id = ntohl (bd_id);
7147   mp->is_add = is_add;
7148
7149   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7150   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7151
7152   S (mp);
7153   W (ret);
7154   return ret;
7155 }
7156
7157 static int
7158 api_bd_ip_mac_flush (vat_main_t * vam)
7159 {
7160   unformat_input_t *i = vam->input;
7161   vl_api_bd_ip_mac_flush_t *mp;
7162   u32 bd_id;
7163   u8 bd_id_set = 0;
7164   int ret;
7165
7166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167     {
7168       if (unformat (i, "bd_id %d", &bd_id))
7169         {
7170           bd_id_set++;
7171         }
7172       else
7173         break;
7174     }
7175
7176   if (bd_id_set == 0)
7177     {
7178       errmsg ("missing bridge domain");
7179       return -99;
7180     }
7181
7182   M (BD_IP_MAC_FLUSH, mp);
7183
7184   mp->bd_id = ntohl (bd_id);
7185
7186   S (mp);
7187   W (ret);
7188   return ret;
7189 }
7190
7191 static void vl_api_bd_ip_mac_details_t_handler
7192   (vl_api_bd_ip_mac_details_t * mp)
7193 {
7194   vat_main_t *vam = &vat_main;
7195
7196   print (vam->ofp,
7197          "\n%-5d %U %U",
7198          ntohl (mp->entry.bd_id),
7199          format_vl_api_mac_address, mp->entry.mac,
7200          format_vl_api_address, &mp->entry.ip);
7201 }
7202
7203 static void vl_api_bd_ip_mac_details_t_handler_json
7204   (vl_api_bd_ip_mac_details_t * mp)
7205 {
7206   vat_main_t *vam = &vat_main;
7207   vat_json_node_t *node = NULL;
7208
7209   if (VAT_JSON_ARRAY != vam->json_tree.type)
7210     {
7211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7212       vat_json_init_array (&vam->json_tree);
7213     }
7214   node = vat_json_array_add (&vam->json_tree);
7215
7216   vat_json_init_object (node);
7217   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7218   vat_json_object_add_string_copy (node, "mac_address",
7219                                    format (0, "%U", format_vl_api_mac_address,
7220                                            &mp->entry.mac));
7221   u8 *ip = 0;
7222
7223   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7224   vat_json_object_add_string_copy (node, "ip_address", ip);
7225   vec_free (ip);
7226 }
7227
7228 static int
7229 api_bd_ip_mac_dump (vat_main_t * vam)
7230 {
7231   unformat_input_t *i = vam->input;
7232   vl_api_bd_ip_mac_dump_t *mp;
7233   vl_api_control_ping_t *mp_ping;
7234   int ret;
7235   u32 bd_id;
7236   u8 bd_id_set = 0;
7237
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "bd_id %d", &bd_id))
7241         {
7242           bd_id_set++;
7243         }
7244       else
7245         break;
7246     }
7247
7248   print (vam->ofp,
7249          "\n%-5s %-7s %-20s %-30s",
7250          "bd_id", "is_ipv6", "mac_address", "ip_address");
7251
7252   /* Dump Bridge Domain Ip to Mac entries */
7253   M (BD_IP_MAC_DUMP, mp);
7254
7255   if (bd_id_set)
7256     mp->bd_id = htonl (bd_id);
7257   else
7258     mp->bd_id = ~0;
7259
7260   S (mp);
7261
7262   /* Use a control ping for synchronization */
7263   MPING (CONTROL_PING, mp_ping);
7264   S (mp_ping);
7265
7266   W (ret);
7267   return ret;
7268 }
7269
7270 static int
7271 api_tap_create_v2 (vat_main_t * vam)
7272 {
7273   unformat_input_t *i = vam->input;
7274   vl_api_tap_create_v2_t *mp;
7275 #define TAP_FLAG_GSO (1 << 0)
7276   u8 mac_address[6];
7277   u8 random_mac = 1;
7278   u32 id = ~0;
7279   u8 *host_if_name = 0;
7280   u8 *host_ns = 0;
7281   u8 host_mac_addr[6];
7282   u8 host_mac_addr_set = 0;
7283   u8 *host_bridge = 0;
7284   ip4_address_t host_ip4_addr;
7285   ip4_address_t host_ip4_gw;
7286   u8 host_ip4_gw_set = 0;
7287   u32 host_ip4_prefix_len = 0;
7288   ip6_address_t host_ip6_addr;
7289   ip6_address_t host_ip6_gw;
7290   u8 host_ip6_gw_set = 0;
7291   u32 host_ip6_prefix_len = 0;
7292   u8 host_mtu_set = 0;
7293   u32 host_mtu_size = 0;
7294   u32 tap_flags = 0;
7295   int ret;
7296   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7297
7298   clib_memset (mac_address, 0, sizeof (mac_address));
7299
7300   /* Parse args required to build the message */
7301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7302     {
7303       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7304         {
7305           random_mac = 0;
7306         }
7307       else if (unformat (i, "id %u", &id))
7308         ;
7309       else if (unformat (i, "host-if-name %s", &host_if_name))
7310         ;
7311       else if (unformat (i, "host-ns %s", &host_ns))
7312         ;
7313       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7314                          host_mac_addr))
7315         host_mac_addr_set = 1;
7316       else if (unformat (i, "host-bridge %s", &host_bridge))
7317         ;
7318       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7319                          &host_ip4_addr, &host_ip4_prefix_len))
7320         ;
7321       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7322                          &host_ip6_addr, &host_ip6_prefix_len))
7323         ;
7324       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7325                          &host_ip4_gw))
7326         host_ip4_gw_set = 1;
7327       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7328                          &host_ip6_gw))
7329         host_ip6_gw_set = 1;
7330       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7331         ;
7332       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7333         ;
7334       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7335         host_mtu_set = 1;
7336       else if (unformat (i, "no-gso"))
7337         tap_flags &= ~TAP_FLAG_GSO;
7338       else if (unformat (i, "gso"))
7339         tap_flags |= TAP_FLAG_GSO;
7340       else if (unformat (i, "csum-offload"))
7341         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7342       else
7343         break;
7344     }
7345
7346   if (vec_len (host_if_name) > 63)
7347     {
7348       errmsg ("tap name too long. ");
7349       return -99;
7350     }
7351   if (vec_len (host_ns) > 63)
7352     {
7353       errmsg ("host name space too long. ");
7354       return -99;
7355     }
7356   if (vec_len (host_bridge) > 63)
7357     {
7358       errmsg ("host bridge name too long. ");
7359       return -99;
7360     }
7361   if (host_ip4_prefix_len > 32)
7362     {
7363       errmsg ("host ip4 prefix length not valid. ");
7364       return -99;
7365     }
7366   if (host_ip6_prefix_len > 128)
7367     {
7368       errmsg ("host ip6 prefix length not valid. ");
7369       return -99;
7370     }
7371   if (!is_pow2 (rx_ring_sz))
7372     {
7373       errmsg ("rx ring size must be power of 2. ");
7374       return -99;
7375     }
7376   if (rx_ring_sz > 32768)
7377     {
7378       errmsg ("rx ring size must be 32768 or lower. ");
7379       return -99;
7380     }
7381   if (!is_pow2 (tx_ring_sz))
7382     {
7383       errmsg ("tx ring size must be power of 2. ");
7384       return -99;
7385     }
7386   if (tx_ring_sz > 32768)
7387     {
7388       errmsg ("tx ring size must be 32768 or lower. ");
7389       return -99;
7390     }
7391   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7392     {
7393       errmsg ("host MTU size must be in between 64 and 65355. ");
7394       return -99;
7395     }
7396
7397   /* Construct the API message */
7398   M (TAP_CREATE_V2, mp);
7399
7400   mp->use_random_mac = random_mac;
7401
7402   mp->id = ntohl (id);
7403   mp->host_namespace_set = host_ns != 0;
7404   mp->host_bridge_set = host_bridge != 0;
7405   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7406   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7407   mp->rx_ring_sz = ntohs (rx_ring_sz);
7408   mp->tx_ring_sz = ntohs (tx_ring_sz);
7409   mp->host_mtu_set = host_mtu_set;
7410   mp->host_mtu_size = ntohl (host_mtu_size);
7411   mp->tap_flags = ntohl (tap_flags);
7412
7413   if (random_mac == 0)
7414     clib_memcpy (mp->mac_address, mac_address, 6);
7415   if (host_mac_addr_set)
7416     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7417   if (host_if_name)
7418     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7419   if (host_ns)
7420     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7421   if (host_bridge)
7422     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7423   if (host_ip4_prefix_len)
7424     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7425   if (host_ip6_prefix_len)
7426     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7427   if (host_ip4_gw_set)
7428     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7429   if (host_ip6_gw_set)
7430     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7431
7432   vec_free (host_ns);
7433   vec_free (host_if_name);
7434   vec_free (host_bridge);
7435
7436   /* send it... */
7437   S (mp);
7438
7439   /* Wait for a reply... */
7440   W (ret);
7441   return ret;
7442 }
7443
7444 static int
7445 api_tap_delete_v2 (vat_main_t * vam)
7446 {
7447   unformat_input_t *i = vam->input;
7448   vl_api_tap_delete_v2_t *mp;
7449   u32 sw_if_index = ~0;
7450   u8 sw_if_index_set = 0;
7451   int ret;
7452
7453   /* Parse args required to build the message */
7454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7455     {
7456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7457         sw_if_index_set = 1;
7458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7459         sw_if_index_set = 1;
7460       else
7461         break;
7462     }
7463
7464   if (sw_if_index_set == 0)
7465     {
7466       errmsg ("missing vpp interface name. ");
7467       return -99;
7468     }
7469
7470   /* Construct the API message */
7471   M (TAP_DELETE_V2, mp);
7472
7473   mp->sw_if_index = ntohl (sw_if_index);
7474
7475   /* send it... */
7476   S (mp);
7477
7478   /* Wait for a reply... */
7479   W (ret);
7480   return ret;
7481 }
7482
7483 uword
7484 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7485 {
7486   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7487   u32 x[4];
7488
7489   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7490     return 0;
7491
7492   addr->domain = x[0];
7493   addr->bus = x[1];
7494   addr->slot = x[2];
7495   addr->function = x[3];
7496
7497   return 1;
7498 }
7499
7500 static int
7501 api_virtio_pci_create (vat_main_t * vam)
7502 {
7503   unformat_input_t *i = vam->input;
7504   vl_api_virtio_pci_create_t *mp;
7505   u8 mac_address[6];
7506   u8 random_mac = 1;
7507   u8 gso_enabled = 0;
7508   u8 checksum_offload_enabled = 0;
7509   u32 pci_addr = 0;
7510   u64 features = (u64) ~ (0ULL);
7511   int ret;
7512
7513   clib_memset (mac_address, 0, sizeof (mac_address));
7514
7515   /* Parse args required to build the message */
7516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7517     {
7518       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7519         {
7520           random_mac = 0;
7521         }
7522       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7523         ;
7524       else if (unformat (i, "features 0x%llx", &features))
7525         ;
7526       else if (unformat (i, "gso-enabled"))
7527         gso_enabled = 1;
7528       else if (unformat (i, "csum-offload-enabled"))
7529         checksum_offload_enabled = 1;
7530       else
7531         break;
7532     }
7533
7534   if (pci_addr == 0)
7535     {
7536       errmsg ("pci address must be non zero. ");
7537       return -99;
7538     }
7539
7540   /* Construct the API message */
7541   M (VIRTIO_PCI_CREATE, mp);
7542
7543   mp->use_random_mac = random_mac;
7544
7545   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7546   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7547   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7548   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7549
7550   mp->features = clib_host_to_net_u64 (features);
7551   mp->gso_enabled = gso_enabled;
7552   mp->checksum_offload_enabled = checksum_offload_enabled;
7553
7554   if (random_mac == 0)
7555     clib_memcpy (mp->mac_address, mac_address, 6);
7556
7557   /* send it... */
7558   S (mp);
7559
7560   /* Wait for a reply... */
7561   W (ret);
7562   return ret;
7563 }
7564
7565 static int
7566 api_virtio_pci_delete (vat_main_t * vam)
7567 {
7568   unformat_input_t *i = vam->input;
7569   vl_api_virtio_pci_delete_t *mp;
7570   u32 sw_if_index = ~0;
7571   u8 sw_if_index_set = 0;
7572   int ret;
7573
7574   /* Parse args required to build the message */
7575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7576     {
7577       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7578         sw_if_index_set = 1;
7579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7580         sw_if_index_set = 1;
7581       else
7582         break;
7583     }
7584
7585   if (sw_if_index_set == 0)
7586     {
7587       errmsg ("missing vpp interface name. ");
7588       return -99;
7589     }
7590
7591   /* Construct the API message */
7592   M (VIRTIO_PCI_DELETE, mp);
7593
7594   mp->sw_if_index = htonl (sw_if_index);
7595
7596   /* send it... */
7597   S (mp);
7598
7599   /* Wait for a reply... */
7600   W (ret);
7601   return ret;
7602 }
7603
7604 static int
7605 api_bond_create (vat_main_t * vam)
7606 {
7607   unformat_input_t *i = vam->input;
7608   vl_api_bond_create_t *mp;
7609   u8 mac_address[6];
7610   u8 custom_mac = 0;
7611   int ret;
7612   u8 mode;
7613   u8 lb;
7614   u8 mode_is_set = 0;
7615   u32 id = ~0;
7616   u8 numa_only = 0;
7617
7618   clib_memset (mac_address, 0, sizeof (mac_address));
7619   lb = BOND_LB_L2;
7620
7621   /* Parse args required to build the message */
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7625         mode_is_set = 1;
7626       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7627                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7628         ;
7629       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7630                          mac_address))
7631         custom_mac = 1;
7632       else if (unformat (i, "numa-only"))
7633         numa_only = 1;
7634       else if (unformat (i, "id %u", &id))
7635         ;
7636       else
7637         break;
7638     }
7639
7640   if (mode_is_set == 0)
7641     {
7642       errmsg ("Missing bond mode. ");
7643       return -99;
7644     }
7645
7646   /* Construct the API message */
7647   M (BOND_CREATE, mp);
7648
7649   mp->use_custom_mac = custom_mac;
7650
7651   mp->mode = htonl (mode);
7652   mp->lb = htonl (lb);
7653   mp->id = htonl (id);
7654   mp->numa_only = numa_only;
7655
7656   if (custom_mac)
7657     clib_memcpy (mp->mac_address, mac_address, 6);
7658
7659   /* send it... */
7660   S (mp);
7661
7662   /* Wait for a reply... */
7663   W (ret);
7664   return ret;
7665 }
7666
7667 static int
7668 api_bond_delete (vat_main_t * vam)
7669 {
7670   unformat_input_t *i = vam->input;
7671   vl_api_bond_delete_t *mp;
7672   u32 sw_if_index = ~0;
7673   u8 sw_if_index_set = 0;
7674   int ret;
7675
7676   /* Parse args required to build the message */
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7680         sw_if_index_set = 1;
7681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7682         sw_if_index_set = 1;
7683       else
7684         break;
7685     }
7686
7687   if (sw_if_index_set == 0)
7688     {
7689       errmsg ("missing vpp interface name. ");
7690       return -99;
7691     }
7692
7693   /* Construct the API message */
7694   M (BOND_DELETE, mp);
7695
7696   mp->sw_if_index = ntohl (sw_if_index);
7697
7698   /* send it... */
7699   S (mp);
7700
7701   /* Wait for a reply... */
7702   W (ret);
7703   return ret;
7704 }
7705
7706 static int
7707 api_bond_enslave (vat_main_t * vam)
7708 {
7709   unformat_input_t *i = vam->input;
7710   vl_api_bond_enslave_t *mp;
7711   u32 bond_sw_if_index;
7712   int ret;
7713   u8 is_passive;
7714   u8 is_long_timeout;
7715   u32 bond_sw_if_index_is_set = 0;
7716   u32 sw_if_index;
7717   u8 sw_if_index_is_set = 0;
7718
7719   /* Parse args required to build the message */
7720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7721     {
7722       if (unformat (i, "sw_if_index %d", &sw_if_index))
7723         sw_if_index_is_set = 1;
7724       else if (unformat (i, "bond %u", &bond_sw_if_index))
7725         bond_sw_if_index_is_set = 1;
7726       else if (unformat (i, "passive %d", &is_passive))
7727         ;
7728       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7729         ;
7730       else
7731         break;
7732     }
7733
7734   if (bond_sw_if_index_is_set == 0)
7735     {
7736       errmsg ("Missing bond sw_if_index. ");
7737       return -99;
7738     }
7739   if (sw_if_index_is_set == 0)
7740     {
7741       errmsg ("Missing slave sw_if_index. ");
7742       return -99;
7743     }
7744
7745   /* Construct the API message */
7746   M (BOND_ENSLAVE, mp);
7747
7748   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7749   mp->sw_if_index = ntohl (sw_if_index);
7750   mp->is_long_timeout = is_long_timeout;
7751   mp->is_passive = is_passive;
7752
7753   /* send it... */
7754   S (mp);
7755
7756   /* Wait for a reply... */
7757   W (ret);
7758   return ret;
7759 }
7760
7761 static int
7762 api_bond_detach_slave (vat_main_t * vam)
7763 {
7764   unformat_input_t *i = vam->input;
7765   vl_api_bond_detach_slave_t *mp;
7766   u32 sw_if_index = ~0;
7767   u8 sw_if_index_set = 0;
7768   int ret;
7769
7770   /* Parse args required to build the message */
7771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7772     {
7773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7774         sw_if_index_set = 1;
7775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7776         sw_if_index_set = 1;
7777       else
7778         break;
7779     }
7780
7781   if (sw_if_index_set == 0)
7782     {
7783       errmsg ("missing vpp interface name. ");
7784       return -99;
7785     }
7786
7787   /* Construct the API message */
7788   M (BOND_DETACH_SLAVE, mp);
7789
7790   mp->sw_if_index = ntohl (sw_if_index);
7791
7792   /* send it... */
7793   S (mp);
7794
7795   /* Wait for a reply... */
7796   W (ret);
7797   return ret;
7798 }
7799
7800 static int
7801 api_ip_table_add_del (vat_main_t * vam)
7802 {
7803   unformat_input_t *i = vam->input;
7804   vl_api_ip_table_add_del_t *mp;
7805   u32 table_id = ~0;
7806   u8 is_ipv6 = 0;
7807   u8 is_add = 1;
7808   int ret = 0;
7809
7810   /* Parse args required to build the message */
7811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7812     {
7813       if (unformat (i, "ipv6"))
7814         is_ipv6 = 1;
7815       else if (unformat (i, "del"))
7816         is_add = 0;
7817       else if (unformat (i, "add"))
7818         is_add = 1;
7819       else if (unformat (i, "table %d", &table_id))
7820         ;
7821       else
7822         {
7823           clib_warning ("parse error '%U'", format_unformat_error, i);
7824           return -99;
7825         }
7826     }
7827
7828   if (~0 == table_id)
7829     {
7830       errmsg ("missing table-ID");
7831       return -99;
7832     }
7833
7834   /* Construct the API message */
7835   M (IP_TABLE_ADD_DEL, mp);
7836
7837   mp->table.table_id = ntohl (table_id);
7838   mp->table.is_ip6 = is_ipv6;
7839   mp->is_add = is_add;
7840
7841   /* send it... */
7842   S (mp);
7843
7844   /* Wait for a reply... */
7845   W (ret);
7846
7847   return ret;
7848 }
7849
7850 uword
7851 unformat_fib_path (unformat_input_t * input, va_list * args)
7852 {
7853   vat_main_t *vam = va_arg (*args, vat_main_t *);
7854   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7855   u32 weight, preference;
7856   mpls_label_t out_label;
7857
7858   clib_memset (path, 0, sizeof (*path));
7859   path->weight = 1;
7860   path->sw_if_index = ~0;
7861   path->rpf_id = ~0;
7862   path->n_labels = 0;
7863
7864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7865     {
7866       if (unformat (input, "%U %U",
7867                     unformat_vl_api_ip4_address,
7868                     &path->nh.address.ip4,
7869                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7870         {
7871           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7872         }
7873       else if (unformat (input, "%U %U",
7874                          unformat_vl_api_ip6_address,
7875                          &path->nh.address.ip6,
7876                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7877         {
7878           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7879         }
7880       else if (unformat (input, "weight %u", &weight))
7881         {
7882           path->weight = weight;
7883         }
7884       else if (unformat (input, "preference %u", &preference))
7885         {
7886           path->preference = preference;
7887         }
7888       else if (unformat (input, "%U next-hop-table %d",
7889                          unformat_vl_api_ip4_address,
7890                          &path->nh.address.ip4, &path->table_id))
7891         {
7892           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7893         }
7894       else if (unformat (input, "%U next-hop-table %d",
7895                          unformat_vl_api_ip6_address,
7896                          &path->nh.address.ip6, &path->table_id))
7897         {
7898           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7899         }
7900       else if (unformat (input, "%U",
7901                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7902         {
7903           /*
7904            * the recursive next-hops are by default in the default table
7905            */
7906           path->table_id = 0;
7907           path->sw_if_index = ~0;
7908           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7909         }
7910       else if (unformat (input, "%U",
7911                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7912         {
7913           /*
7914            * the recursive next-hops are by default in the default table
7915            */
7916           path->table_id = 0;
7917           path->sw_if_index = ~0;
7918           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7919         }
7920       else if (unformat (input, "resolve-via-host"))
7921         {
7922           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7923         }
7924       else if (unformat (input, "resolve-via-attached"))
7925         {
7926           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7927         }
7928       else if (unformat (input, "ip4-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_IP4;
7933         }
7934       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7935         {
7936           path->type = FIB_API_PATH_TYPE_LOCAL;
7937           path->sw_if_index = ~0;
7938           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7939         }
7940       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7941         ;
7942       else if (unformat (input, "via-label %d", &path->nh.via_label))
7943         {
7944           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7945           path->sw_if_index = ~0;
7946         }
7947       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7948         {
7949           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7950           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7951         }
7952       else if (unformat (input, "local"))
7953         {
7954           path->type = FIB_API_PATH_TYPE_LOCAL;
7955         }
7956       else if (unformat (input, "out-labels"))
7957         {
7958           while (unformat (input, "%d", &out_label))
7959             {
7960               path->label_stack[path->n_labels].label = out_label;
7961               path->label_stack[path->n_labels].is_uniform = 0;
7962               path->label_stack[path->n_labels].ttl = 64;
7963               path->n_labels++;
7964             }
7965         }
7966       else if (unformat (input, "via"))
7967         {
7968           /* new path, back up and return */
7969           unformat_put_input (input);
7970           unformat_put_input (input);
7971           unformat_put_input (input);
7972           unformat_put_input (input);
7973           break;
7974         }
7975       else
7976         {
7977           return (0);
7978         }
7979     }
7980
7981   path->proto = ntohl (path->proto);
7982   path->type = ntohl (path->type);
7983   path->flags = ntohl (path->flags);
7984   path->table_id = ntohl (path->table_id);
7985   path->sw_if_index = ntohl (path->sw_if_index);
7986
7987   return (1);
7988 }
7989
7990 static int
7991 api_ip_route_add_del (vat_main_t * vam)
7992 {
7993   unformat_input_t *i = vam->input;
7994   vl_api_ip_route_add_del_t *mp;
7995   u32 vrf_id = 0;
7996   u8 is_add = 1;
7997   u8 is_multipath = 0;
7998   u8 prefix_set = 0;
7999   u8 path_count = 0;
8000   vl_api_prefix_t pfx = { };
8001   vl_api_fib_path_t paths[8];
8002   int count = 1;
8003   int j;
8004   f64 before = 0;
8005   u32 random_add_del = 0;
8006   u32 *random_vector = 0;
8007   u32 random_seed = 0xdeaddabe;
8008
8009   /* Parse args required to build the message */
8010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8011     {
8012       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8013         prefix_set = 1;
8014       else if (unformat (i, "del"))
8015         is_add = 0;
8016       else if (unformat (i, "add"))
8017         is_add = 1;
8018       else if (unformat (i, "vrf %d", &vrf_id))
8019         ;
8020       else if (unformat (i, "count %d", &count))
8021         ;
8022       else if (unformat (i, "random"))
8023         random_add_del = 1;
8024       else if (unformat (i, "multipath"))
8025         is_multipath = 1;
8026       else if (unformat (i, "seed %d", &random_seed))
8027         ;
8028       else
8029         if (unformat
8030             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8031         {
8032           path_count++;
8033           if (8 == path_count)
8034             {
8035               errmsg ("max 8 paths");
8036               return -99;
8037             }
8038         }
8039       else
8040         {
8041           clib_warning ("parse error '%U'", format_unformat_error, i);
8042           return -99;
8043         }
8044     }
8045
8046   if (!path_count)
8047     {
8048       errmsg ("specify a path; via ...");
8049       return -99;
8050     }
8051   if (prefix_set == 0)
8052     {
8053       errmsg ("missing prefix");
8054       return -99;
8055     }
8056
8057   /* Generate a pile of unique, random routes */
8058   if (random_add_del)
8059     {
8060       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8061       u32 this_random_address;
8062       uword *random_hash;
8063
8064       random_hash = hash_create (count, sizeof (uword));
8065
8066       hash_set (random_hash, i->as_u32, 1);
8067       for (j = 0; j <= count; j++)
8068         {
8069           do
8070             {
8071               this_random_address = random_u32 (&random_seed);
8072               this_random_address =
8073                 clib_host_to_net_u32 (this_random_address);
8074             }
8075           while (hash_get (random_hash, this_random_address));
8076           vec_add1 (random_vector, this_random_address);
8077           hash_set (random_hash, this_random_address, 1);
8078         }
8079       hash_free (random_hash);
8080       set_ip4_address (&pfx.address, random_vector[0]);
8081     }
8082
8083   if (count > 1)
8084     {
8085       /* Turn on async mode */
8086       vam->async_mode = 1;
8087       vam->async_errors = 0;
8088       before = vat_time_now (vam);
8089     }
8090
8091   for (j = 0; j < count; j++)
8092     {
8093       /* Construct the API message */
8094       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8095
8096       mp->is_add = is_add;
8097       mp->is_multipath = is_multipath;
8098
8099       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8100       mp->route.table_id = ntohl (vrf_id);
8101       mp->route.n_paths = path_count;
8102
8103       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8104
8105       if (random_add_del)
8106         set_ip4_address (&pfx.address, random_vector[j + 1]);
8107       else
8108         increment_address (&pfx.address);
8109       /* send it... */
8110       S (mp);
8111       /* If we receive SIGTERM, stop now... */
8112       if (vam->do_exit)
8113         break;
8114     }
8115
8116   /* When testing multiple add/del ops, use a control-ping to sync */
8117   if (count > 1)
8118     {
8119       vl_api_control_ping_t *mp_ping;
8120       f64 after;
8121       f64 timeout;
8122
8123       /* Shut off async mode */
8124       vam->async_mode = 0;
8125
8126       MPING (CONTROL_PING, mp_ping);
8127       S (mp_ping);
8128
8129       timeout = vat_time_now (vam) + 1.0;
8130       while (vat_time_now (vam) < timeout)
8131         if (vam->result_ready == 1)
8132           goto out;
8133       vam->retval = -99;
8134
8135     out:
8136       if (vam->retval == -99)
8137         errmsg ("timeout");
8138
8139       if (vam->async_errors > 0)
8140         {
8141           errmsg ("%d asynchronous errors", vam->async_errors);
8142           vam->retval = -98;
8143         }
8144       vam->async_errors = 0;
8145       after = vat_time_now (vam);
8146
8147       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8148       if (j > 0)
8149         count = j;
8150
8151       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8152              count, after - before, count / (after - before));
8153     }
8154   else
8155     {
8156       int ret;
8157
8158       /* Wait for a reply... */
8159       W (ret);
8160       return ret;
8161     }
8162
8163   /* Return the good/bad news */
8164   return (vam->retval);
8165 }
8166
8167 static int
8168 api_ip_mroute_add_del (vat_main_t * vam)
8169 {
8170   unformat_input_t *i = vam->input;
8171   u8 path_set = 0, prefix_set = 0, is_add = 1;
8172   vl_api_ip_mroute_add_del_t *mp;
8173   mfib_entry_flags_t eflags = 0;
8174   vl_api_mfib_path_t path;
8175   vl_api_mprefix_t pfx = { };
8176   u32 vrf_id = 0;
8177   int ret;
8178
8179   /* Parse args required to build the message */
8180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8181     {
8182       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8183         {
8184           prefix_set = 1;
8185           pfx.grp_address_length = htons (pfx.grp_address_length);
8186         }
8187       else if (unformat (i, "del"))
8188         is_add = 0;
8189       else if (unformat (i, "add"))
8190         is_add = 1;
8191       else if (unformat (i, "vrf %d", &vrf_id))
8192         ;
8193       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8194         path.itf_flags = htonl (path.itf_flags);
8195       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8196         ;
8197       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8198         path_set = 1;
8199       else
8200         {
8201           clib_warning ("parse error '%U'", format_unformat_error, i);
8202           return -99;
8203         }
8204     }
8205
8206   if (prefix_set == 0)
8207     {
8208       errmsg ("missing addresses\n");
8209       return -99;
8210     }
8211   if (path_set == 0)
8212     {
8213       errmsg ("missing path\n");
8214       return -99;
8215     }
8216
8217   /* Construct the API message */
8218   M (IP_MROUTE_ADD_DEL, mp);
8219
8220   mp->is_add = is_add;
8221   mp->is_multipath = 1;
8222
8223   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8224   mp->route.table_id = htonl (vrf_id);
8225   mp->route.n_paths = 1;
8226   mp->route.entry_flags = htonl (eflags);
8227
8228   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8229
8230   /* send it... */
8231   S (mp);
8232   /* Wait for a reply... */
8233   W (ret);
8234   return ret;
8235 }
8236
8237 static int
8238 api_mpls_table_add_del (vat_main_t * vam)
8239 {
8240   unformat_input_t *i = vam->input;
8241   vl_api_mpls_table_add_del_t *mp;
8242   u32 table_id = ~0;
8243   u8 is_add = 1;
8244   int ret = 0;
8245
8246   /* Parse args required to build the message */
8247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8248     {
8249       if (unformat (i, "table %d", &table_id))
8250         ;
8251       else if (unformat (i, "del"))
8252         is_add = 0;
8253       else if (unformat (i, "add"))
8254         is_add = 1;
8255       else
8256         {
8257           clib_warning ("parse error '%U'", format_unformat_error, i);
8258           return -99;
8259         }
8260     }
8261
8262   if (~0 == table_id)
8263     {
8264       errmsg ("missing table-ID");
8265       return -99;
8266     }
8267
8268   /* Construct the API message */
8269   M (MPLS_TABLE_ADD_DEL, mp);
8270
8271   mp->mt_table.mt_table_id = ntohl (table_id);
8272   mp->mt_is_add = is_add;
8273
8274   /* send it... */
8275   S (mp);
8276
8277   /* Wait for a reply... */
8278   W (ret);
8279
8280   return ret;
8281 }
8282
8283 static int
8284 api_mpls_route_add_del (vat_main_t * vam)
8285 {
8286   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8287   mpls_label_t local_label = MPLS_LABEL_INVALID;
8288   unformat_input_t *i = vam->input;
8289   vl_api_mpls_route_add_del_t *mp;
8290   vl_api_fib_path_t paths[8];
8291   int count = 1, j;
8292   f64 before = 0;
8293
8294   /* Parse args required to build the message */
8295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8296     {
8297       if (unformat (i, "%d", &local_label))
8298         ;
8299       else if (unformat (i, "eos"))
8300         is_eos = 1;
8301       else if (unformat (i, "non-eos"))
8302         is_eos = 0;
8303       else if (unformat (i, "del"))
8304         is_add = 0;
8305       else if (unformat (i, "add"))
8306         is_add = 1;
8307       else if (unformat (i, "multipath"))
8308         is_multipath = 1;
8309       else if (unformat (i, "count %d", &count))
8310         ;
8311       else
8312         if (unformat
8313             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8314         {
8315           path_count++;
8316           if (8 == path_count)
8317             {
8318               errmsg ("max 8 paths");
8319               return -99;
8320             }
8321         }
8322       else
8323         {
8324           clib_warning ("parse error '%U'", format_unformat_error, i);
8325           return -99;
8326         }
8327     }
8328
8329   if (!path_count)
8330     {
8331       errmsg ("specify a path; via ...");
8332       return -99;
8333     }
8334
8335   if (MPLS_LABEL_INVALID == local_label)
8336     {
8337       errmsg ("missing label");
8338       return -99;
8339     }
8340
8341   if (count > 1)
8342     {
8343       /* Turn on async mode */
8344       vam->async_mode = 1;
8345       vam->async_errors = 0;
8346       before = vat_time_now (vam);
8347     }
8348
8349   for (j = 0; j < count; j++)
8350     {
8351       /* Construct the API message */
8352       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8353
8354       mp->mr_is_add = is_add;
8355       mp->mr_is_multipath = is_multipath;
8356
8357       mp->mr_route.mr_label = local_label;
8358       mp->mr_route.mr_eos = is_eos;
8359       mp->mr_route.mr_table_id = 0;
8360       mp->mr_route.mr_n_paths = path_count;
8361
8362       clib_memcpy (&mp->mr_route.mr_paths, paths,
8363                    sizeof (paths[0]) * path_count);
8364
8365       local_label++;
8366
8367       /* send it... */
8368       S (mp);
8369       /* If we receive SIGTERM, stop now... */
8370       if (vam->do_exit)
8371         break;
8372     }
8373
8374   /* When testing multiple add/del ops, use a control-ping to sync */
8375   if (count > 1)
8376     {
8377       vl_api_control_ping_t *mp_ping;
8378       f64 after;
8379       f64 timeout;
8380
8381       /* Shut off async mode */
8382       vam->async_mode = 0;
8383
8384       MPING (CONTROL_PING, mp_ping);
8385       S (mp_ping);
8386
8387       timeout = vat_time_now (vam) + 1.0;
8388       while (vat_time_now (vam) < timeout)
8389         if (vam->result_ready == 1)
8390           goto out;
8391       vam->retval = -99;
8392
8393     out:
8394       if (vam->retval == -99)
8395         errmsg ("timeout");
8396
8397       if (vam->async_errors > 0)
8398         {
8399           errmsg ("%d asynchronous errors", vam->async_errors);
8400           vam->retval = -98;
8401         }
8402       vam->async_errors = 0;
8403       after = vat_time_now (vam);
8404
8405       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8406       if (j > 0)
8407         count = j;
8408
8409       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8410              count, after - before, count / (after - before));
8411     }
8412   else
8413     {
8414       int ret;
8415
8416       /* Wait for a reply... */
8417       W (ret);
8418       return ret;
8419     }
8420
8421   /* Return the good/bad news */
8422   return (vam->retval);
8423   return (0);
8424 }
8425
8426 static int
8427 api_mpls_ip_bind_unbind (vat_main_t * vam)
8428 {
8429   unformat_input_t *i = vam->input;
8430   vl_api_mpls_ip_bind_unbind_t *mp;
8431   u32 ip_table_id = 0;
8432   u8 is_bind = 1;
8433   vl_api_prefix_t pfx;
8434   u8 prefix_set = 0;
8435   mpls_label_t local_label = MPLS_LABEL_INVALID;
8436   int ret;
8437
8438   /* Parse args required to build the message */
8439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8440     {
8441       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8442         prefix_set = 1;
8443       else if (unformat (i, "%d", &local_label))
8444         ;
8445       else if (unformat (i, "table-id %d", &ip_table_id))
8446         ;
8447       else if (unformat (i, "unbind"))
8448         is_bind = 0;
8449       else if (unformat (i, "bind"))
8450         is_bind = 1;
8451       else
8452         {
8453           clib_warning ("parse error '%U'", format_unformat_error, i);
8454           return -99;
8455         }
8456     }
8457
8458   if (!prefix_set)
8459     {
8460       errmsg ("IP prefix not set");
8461       return -99;
8462     }
8463
8464   if (MPLS_LABEL_INVALID == local_label)
8465     {
8466       errmsg ("missing label");
8467       return -99;
8468     }
8469
8470   /* Construct the API message */
8471   M (MPLS_IP_BIND_UNBIND, mp);
8472
8473   mp->mb_is_bind = is_bind;
8474   mp->mb_ip_table_id = ntohl (ip_table_id);
8475   mp->mb_mpls_table_id = 0;
8476   mp->mb_label = ntohl (local_label);
8477   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8478
8479   /* send it... */
8480   S (mp);
8481
8482   /* Wait for a reply... */
8483   W (ret);
8484   return ret;
8485   return (0);
8486 }
8487
8488 static int
8489 api_sr_mpls_policy_add (vat_main_t * vam)
8490 {
8491   unformat_input_t *i = vam->input;
8492   vl_api_sr_mpls_policy_add_t *mp;
8493   u32 bsid = 0;
8494   u32 weight = 1;
8495   u8 type = 0;
8496   u8 n_segments = 0;
8497   u32 sid;
8498   u32 *segments = NULL;
8499   int ret;
8500
8501   /* Parse args required to build the message */
8502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8503     {
8504       if (unformat (i, "bsid %d", &bsid))
8505         ;
8506       else if (unformat (i, "weight %d", &weight))
8507         ;
8508       else if (unformat (i, "spray"))
8509         type = 1;
8510       else if (unformat (i, "next %d", &sid))
8511         {
8512           n_segments += 1;
8513           vec_add1 (segments, htonl (sid));
8514         }
8515       else
8516         {
8517           clib_warning ("parse error '%U'", format_unformat_error, i);
8518           return -99;
8519         }
8520     }
8521
8522   if (bsid == 0)
8523     {
8524       errmsg ("bsid not set");
8525       return -99;
8526     }
8527
8528   if (n_segments == 0)
8529     {
8530       errmsg ("no sid in segment stack");
8531       return -99;
8532     }
8533
8534   /* Construct the API message */
8535   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8536
8537   mp->bsid = htonl (bsid);
8538   mp->weight = htonl (weight);
8539   mp->type = type;
8540   mp->n_segments = n_segments;
8541   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8542   vec_free (segments);
8543
8544   /* send it... */
8545   S (mp);
8546
8547   /* Wait for a reply... */
8548   W (ret);
8549   return ret;
8550 }
8551
8552 static int
8553 api_sr_mpls_policy_del (vat_main_t * vam)
8554 {
8555   unformat_input_t *i = vam->input;
8556   vl_api_sr_mpls_policy_del_t *mp;
8557   u32 bsid = 0;
8558   int ret;
8559
8560   /* Parse args required to build the message */
8561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8562     {
8563       if (unformat (i, "bsid %d", &bsid))
8564         ;
8565       else
8566         {
8567           clib_warning ("parse error '%U'", format_unformat_error, i);
8568           return -99;
8569         }
8570     }
8571
8572   if (bsid == 0)
8573     {
8574       errmsg ("bsid not set");
8575       return -99;
8576     }
8577
8578   /* Construct the API message */
8579   M (SR_MPLS_POLICY_DEL, mp);
8580
8581   mp->bsid = htonl (bsid);
8582
8583   /* send it... */
8584   S (mp);
8585
8586   /* Wait for a reply... */
8587   W (ret);
8588   return ret;
8589 }
8590
8591 static int
8592 api_bier_table_add_del (vat_main_t * vam)
8593 {
8594   unformat_input_t *i = vam->input;
8595   vl_api_bier_table_add_del_t *mp;
8596   u8 is_add = 1;
8597   u32 set = 0, sub_domain = 0, hdr_len = 3;
8598   mpls_label_t local_label = MPLS_LABEL_INVALID;
8599   int ret;
8600
8601   /* Parse args required to build the message */
8602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8603     {
8604       if (unformat (i, "sub-domain %d", &sub_domain))
8605         ;
8606       else if (unformat (i, "set %d", &set))
8607         ;
8608       else if (unformat (i, "label %d", &local_label))
8609         ;
8610       else if (unformat (i, "hdr-len %d", &hdr_len))
8611         ;
8612       else if (unformat (i, "add"))
8613         is_add = 1;
8614       else if (unformat (i, "del"))
8615         is_add = 0;
8616       else
8617         {
8618           clib_warning ("parse error '%U'", format_unformat_error, i);
8619           return -99;
8620         }
8621     }
8622
8623   if (MPLS_LABEL_INVALID == local_label)
8624     {
8625       errmsg ("missing label\n");
8626       return -99;
8627     }
8628
8629   /* Construct the API message */
8630   M (BIER_TABLE_ADD_DEL, mp);
8631
8632   mp->bt_is_add = is_add;
8633   mp->bt_label = ntohl (local_label);
8634   mp->bt_tbl_id.bt_set = set;
8635   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8636   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8637
8638   /* send it... */
8639   S (mp);
8640
8641   /* Wait for a reply... */
8642   W (ret);
8643
8644   return (ret);
8645 }
8646
8647 static int
8648 api_bier_route_add_del (vat_main_t * vam)
8649 {
8650   unformat_input_t *i = vam->input;
8651   vl_api_bier_route_add_del_t *mp;
8652   u8 is_add = 1;
8653   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8654   ip4_address_t v4_next_hop_address;
8655   ip6_address_t v6_next_hop_address;
8656   u8 next_hop_set = 0;
8657   u8 next_hop_proto_is_ip4 = 1;
8658   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8659   int ret;
8660
8661   /* Parse args required to build the message */
8662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8663     {
8664       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8665         {
8666           next_hop_proto_is_ip4 = 1;
8667           next_hop_set = 1;
8668         }
8669       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8670         {
8671           next_hop_proto_is_ip4 = 0;
8672           next_hop_set = 1;
8673         }
8674       if (unformat (i, "sub-domain %d", &sub_domain))
8675         ;
8676       else if (unformat (i, "set %d", &set))
8677         ;
8678       else if (unformat (i, "hdr-len %d", &hdr_len))
8679         ;
8680       else if (unformat (i, "bp %d", &bp))
8681         ;
8682       else if (unformat (i, "add"))
8683         is_add = 1;
8684       else if (unformat (i, "del"))
8685         is_add = 0;
8686       else if (unformat (i, "out-label %d", &next_hop_out_label))
8687         ;
8688       else
8689         {
8690           clib_warning ("parse error '%U'", format_unformat_error, i);
8691           return -99;
8692         }
8693     }
8694
8695   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8696     {
8697       errmsg ("next hop / label set\n");
8698       return -99;
8699     }
8700   if (0 == bp)
8701     {
8702       errmsg ("bit=position not set\n");
8703       return -99;
8704     }
8705
8706   /* Construct the API message */
8707   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8708
8709   mp->br_is_add = is_add;
8710   mp->br_route.br_tbl_id.bt_set = set;
8711   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8712   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8713   mp->br_route.br_bp = ntohs (bp);
8714   mp->br_route.br_n_paths = 1;
8715   mp->br_route.br_paths[0].n_labels = 1;
8716   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8717   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8718                                     FIB_API_PATH_NH_PROTO_IP4 :
8719                                     FIB_API_PATH_NH_PROTO_IP6);
8720
8721   if (next_hop_proto_is_ip4)
8722     {
8723       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8724                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8725     }
8726   else
8727     {
8728       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8729                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8730     }
8731
8732   /* send it... */
8733   S (mp);
8734
8735   /* Wait for a reply... */
8736   W (ret);
8737
8738   return (ret);
8739 }
8740
8741 static int
8742 api_mpls_tunnel_add_del (vat_main_t * vam)
8743 {
8744   unformat_input_t *i = vam->input;
8745   vl_api_mpls_tunnel_add_del_t *mp;
8746
8747   vl_api_fib_path_t paths[8];
8748   u32 sw_if_index = ~0;
8749   u8 path_count = 0;
8750   u8 l2_only = 0;
8751   u8 is_add = 1;
8752   int ret;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "add"))
8757         is_add = 1;
8758       else
8759         if (unformat
8760             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8761         is_add = 0;
8762       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8763         is_add = 0;
8764       else if (unformat (i, "l2-only"))
8765         l2_only = 1;
8766       else
8767         if (unformat
8768             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8769         {
8770           path_count++;
8771           if (8 == path_count)
8772             {
8773               errmsg ("max 8 paths");
8774               return -99;
8775             }
8776         }
8777       else
8778         {
8779           clib_warning ("parse error '%U'", format_unformat_error, i);
8780           return -99;
8781         }
8782     }
8783
8784   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8785
8786   mp->mt_is_add = is_add;
8787   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8788   mp->mt_tunnel.mt_l2_only = l2_only;
8789   mp->mt_tunnel.mt_is_multicast = 0;
8790   mp->mt_tunnel.mt_n_paths = path_count;
8791
8792   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8793                sizeof (paths[0]) * path_count);
8794
8795   S (mp);
8796   W (ret);
8797   return ret;
8798 }
8799
8800 static int
8801 api_sw_interface_set_unnumbered (vat_main_t * vam)
8802 {
8803   unformat_input_t *i = vam->input;
8804   vl_api_sw_interface_set_unnumbered_t *mp;
8805   u32 sw_if_index;
8806   u32 unnum_sw_index = ~0;
8807   u8 is_add = 1;
8808   u8 sw_if_index_set = 0;
8809   int ret;
8810
8811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8814         sw_if_index_set = 1;
8815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8816         sw_if_index_set = 1;
8817       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8818         ;
8819       else if (unformat (i, "del"))
8820         is_add = 0;
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   if (sw_if_index_set == 0)
8829     {
8830       errmsg ("missing interface name or sw_if_index");
8831       return -99;
8832     }
8833
8834   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8835
8836   mp->sw_if_index = ntohl (sw_if_index);
8837   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8838   mp->is_add = is_add;
8839
8840   S (mp);
8841   W (ret);
8842   return ret;
8843 }
8844
8845
8846 static int
8847 api_create_vlan_subif (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_create_vlan_subif_t *mp;
8851   u32 sw_if_index;
8852   u8 sw_if_index_set = 0;
8853   u32 vlan_id;
8854   u8 vlan_id_set = 0;
8855   int ret;
8856
8857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8858     {
8859       if (unformat (i, "sw_if_index %d", &sw_if_index))
8860         sw_if_index_set = 1;
8861       else
8862         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8863         sw_if_index_set = 1;
8864       else if (unformat (i, "vlan %d", &vlan_id))
8865         vlan_id_set = 1;
8866       else
8867         {
8868           clib_warning ("parse error '%U'", format_unformat_error, i);
8869           return -99;
8870         }
8871     }
8872
8873   if (sw_if_index_set == 0)
8874     {
8875       errmsg ("missing interface name or sw_if_index");
8876       return -99;
8877     }
8878
8879   if (vlan_id_set == 0)
8880     {
8881       errmsg ("missing vlan_id");
8882       return -99;
8883     }
8884   M (CREATE_VLAN_SUBIF, mp);
8885
8886   mp->sw_if_index = ntohl (sw_if_index);
8887   mp->vlan_id = ntohl (vlan_id);
8888
8889   S (mp);
8890   W (ret);
8891   return ret;
8892 }
8893
8894 #define foreach_create_subif_bit                \
8895 _(no_tags)                                      \
8896 _(one_tag)                                      \
8897 _(two_tags)                                     \
8898 _(dot1ad)                                       \
8899 _(exact_match)                                  \
8900 _(default_sub)                                  \
8901 _(outer_vlan_id_any)                            \
8902 _(inner_vlan_id_any)
8903
8904 #define foreach_create_subif_flag               \
8905 _(0, "no_tags")                                 \
8906 _(1, "one_tag")                                 \
8907 _(2, "two_tags")                                \
8908 _(3, "dot1ad")                                  \
8909 _(4, "exact_match")                             \
8910 _(5, "default_sub")                             \
8911 _(6, "outer_vlan_id_any")                       \
8912 _(7, "inner_vlan_id_any")
8913
8914 static int
8915 api_create_subif (vat_main_t * vam)
8916 {
8917   unformat_input_t *i = vam->input;
8918   vl_api_create_subif_t *mp;
8919   u32 sw_if_index;
8920   u8 sw_if_index_set = 0;
8921   u32 sub_id;
8922   u8 sub_id_set = 0;
8923   u32 __attribute__ ((unused)) no_tags = 0;
8924   u32 __attribute__ ((unused)) one_tag = 0;
8925   u32 __attribute__ ((unused)) two_tags = 0;
8926   u32 __attribute__ ((unused)) dot1ad = 0;
8927   u32 __attribute__ ((unused)) exact_match = 0;
8928   u32 __attribute__ ((unused)) default_sub = 0;
8929   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8930   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8931   u32 tmp;
8932   u16 outer_vlan_id = 0;
8933   u16 inner_vlan_id = 0;
8934   int ret;
8935
8936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8937     {
8938       if (unformat (i, "sw_if_index %d", &sw_if_index))
8939         sw_if_index_set = 1;
8940       else
8941         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8942         sw_if_index_set = 1;
8943       else if (unformat (i, "sub_id %d", &sub_id))
8944         sub_id_set = 1;
8945       else if (unformat (i, "outer_vlan_id %d", &tmp))
8946         outer_vlan_id = tmp;
8947       else if (unformat (i, "inner_vlan_id %d", &tmp))
8948         inner_vlan_id = tmp;
8949
8950 #define _(a) else if (unformat (i, #a)) a = 1 ;
8951       foreach_create_subif_bit
8952 #undef _
8953         else
8954         {
8955           clib_warning ("parse error '%U'", format_unformat_error, i);
8956           return -99;
8957         }
8958     }
8959
8960   if (sw_if_index_set == 0)
8961     {
8962       errmsg ("missing interface name or sw_if_index");
8963       return -99;
8964     }
8965
8966   if (sub_id_set == 0)
8967     {
8968       errmsg ("missing sub_id");
8969       return -99;
8970     }
8971   M (CREATE_SUBIF, mp);
8972
8973   mp->sw_if_index = ntohl (sw_if_index);
8974   mp->sub_id = ntohl (sub_id);
8975
8976 #define _(a,b) mp->sub_if_flags |= (1 << a);
8977   foreach_create_subif_flag;
8978 #undef _
8979
8980   mp->outer_vlan_id = ntohs (outer_vlan_id);
8981   mp->inner_vlan_id = ntohs (inner_vlan_id);
8982
8983   S (mp);
8984   W (ret);
8985   return ret;
8986 }
8987
8988 static int
8989 api_ip_table_replace_begin (vat_main_t * vam)
8990 {
8991   unformat_input_t *i = vam->input;
8992   vl_api_ip_table_replace_begin_t *mp;
8993   u32 table_id = 0;
8994   u8 is_ipv6 = 0;
8995
8996   int ret;
8997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8998     {
8999       if (unformat (i, "table %d", &table_id))
9000         ;
9001       else if (unformat (i, "ipv6"))
9002         is_ipv6 = 1;
9003       else
9004         {
9005           clib_warning ("parse error '%U'", format_unformat_error, i);
9006           return -99;
9007         }
9008     }
9009
9010   M (IP_TABLE_REPLACE_BEGIN, mp);
9011
9012   mp->table.table_id = ntohl (table_id);
9013   mp->table.is_ip6 = is_ipv6;
9014
9015   S (mp);
9016   W (ret);
9017   return ret;
9018 }
9019
9020 static int
9021 api_ip_table_flush (vat_main_t * vam)
9022 {
9023   unformat_input_t *i = vam->input;
9024   vl_api_ip_table_flush_t *mp;
9025   u32 table_id = 0;
9026   u8 is_ipv6 = 0;
9027
9028   int ret;
9029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9030     {
9031       if (unformat (i, "table %d", &table_id))
9032         ;
9033       else if (unformat (i, "ipv6"))
9034         is_ipv6 = 1;
9035       else
9036         {
9037           clib_warning ("parse error '%U'", format_unformat_error, i);
9038           return -99;
9039         }
9040     }
9041
9042   M (IP_TABLE_FLUSH, mp);
9043
9044   mp->table.table_id = ntohl (table_id);
9045   mp->table.is_ip6 = is_ipv6;
9046
9047   S (mp);
9048   W (ret);
9049   return ret;
9050 }
9051
9052 static int
9053 api_ip_table_replace_end (vat_main_t * vam)
9054 {
9055   unformat_input_t *i = vam->input;
9056   vl_api_ip_table_replace_end_t *mp;
9057   u32 table_id = 0;
9058   u8 is_ipv6 = 0;
9059
9060   int ret;
9061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9062     {
9063       if (unformat (i, "table %d", &table_id))
9064         ;
9065       else if (unformat (i, "ipv6"))
9066         is_ipv6 = 1;
9067       else
9068         {
9069           clib_warning ("parse error '%U'", format_unformat_error, i);
9070           return -99;
9071         }
9072     }
9073
9074   M (IP_TABLE_REPLACE_END, mp);
9075
9076   mp->table.table_id = ntohl (table_id);
9077   mp->table.is_ip6 = is_ipv6;
9078
9079   S (mp);
9080   W (ret);
9081   return ret;
9082 }
9083
9084 static int
9085 api_set_ip_flow_hash (vat_main_t * vam)
9086 {
9087   unformat_input_t *i = vam->input;
9088   vl_api_set_ip_flow_hash_t *mp;
9089   u32 vrf_id = 0;
9090   u8 is_ipv6 = 0;
9091   u8 vrf_id_set = 0;
9092   u8 src = 0;
9093   u8 dst = 0;
9094   u8 sport = 0;
9095   u8 dport = 0;
9096   u8 proto = 0;
9097   u8 reverse = 0;
9098   int ret;
9099
9100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9101     {
9102       if (unformat (i, "vrf %d", &vrf_id))
9103         vrf_id_set = 1;
9104       else if (unformat (i, "ipv6"))
9105         is_ipv6 = 1;
9106       else if (unformat (i, "src"))
9107         src = 1;
9108       else if (unformat (i, "dst"))
9109         dst = 1;
9110       else if (unformat (i, "sport"))
9111         sport = 1;
9112       else if (unformat (i, "dport"))
9113         dport = 1;
9114       else if (unformat (i, "proto"))
9115         proto = 1;
9116       else if (unformat (i, "reverse"))
9117         reverse = 1;
9118
9119       else
9120         {
9121           clib_warning ("parse error '%U'", format_unformat_error, i);
9122           return -99;
9123         }
9124     }
9125
9126   if (vrf_id_set == 0)
9127     {
9128       errmsg ("missing vrf id");
9129       return -99;
9130     }
9131
9132   M (SET_IP_FLOW_HASH, mp);
9133   mp->src = src;
9134   mp->dst = dst;
9135   mp->sport = sport;
9136   mp->dport = dport;
9137   mp->proto = proto;
9138   mp->reverse = reverse;
9139   mp->vrf_id = ntohl (vrf_id);
9140   mp->is_ipv6 = is_ipv6;
9141
9142   S (mp);
9143   W (ret);
9144   return ret;
9145 }
9146
9147 static int
9148 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9149 {
9150   unformat_input_t *i = vam->input;
9151   vl_api_sw_interface_ip6_enable_disable_t *mp;
9152   u32 sw_if_index;
9153   u8 sw_if_index_set = 0;
9154   u8 enable = 0;
9155   int ret;
9156
9157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9158     {
9159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9160         sw_if_index_set = 1;
9161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9162         sw_if_index_set = 1;
9163       else if (unformat (i, "enable"))
9164         enable = 1;
9165       else if (unformat (i, "disable"))
9166         enable = 0;
9167       else
9168         {
9169           clib_warning ("parse error '%U'", format_unformat_error, i);
9170           return -99;
9171         }
9172     }
9173
9174   if (sw_if_index_set == 0)
9175     {
9176       errmsg ("missing interface name or sw_if_index");
9177       return -99;
9178     }
9179
9180   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9181
9182   mp->sw_if_index = ntohl (sw_if_index);
9183   mp->enable = enable;
9184
9185   S (mp);
9186   W (ret);
9187   return ret;
9188 }
9189
9190
9191 static int
9192 api_l2_patch_add_del (vat_main_t * vam)
9193 {
9194   unformat_input_t *i = vam->input;
9195   vl_api_l2_patch_add_del_t *mp;
9196   u32 rx_sw_if_index;
9197   u8 rx_sw_if_index_set = 0;
9198   u32 tx_sw_if_index;
9199   u8 tx_sw_if_index_set = 0;
9200   u8 is_add = 1;
9201   int ret;
9202
9203   /* Parse args required to build the message */
9204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9205     {
9206       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9207         rx_sw_if_index_set = 1;
9208       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9209         tx_sw_if_index_set = 1;
9210       else if (unformat (i, "rx"))
9211         {
9212           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9213             {
9214               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9215                             &rx_sw_if_index))
9216                 rx_sw_if_index_set = 1;
9217             }
9218           else
9219             break;
9220         }
9221       else if (unformat (i, "tx"))
9222         {
9223           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9224             {
9225               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9226                             &tx_sw_if_index))
9227                 tx_sw_if_index_set = 1;
9228             }
9229           else
9230             break;
9231         }
9232       else if (unformat (i, "del"))
9233         is_add = 0;
9234       else
9235         break;
9236     }
9237
9238   if (rx_sw_if_index_set == 0)
9239     {
9240       errmsg ("missing rx interface name or rx_sw_if_index");
9241       return -99;
9242     }
9243
9244   if (tx_sw_if_index_set == 0)
9245     {
9246       errmsg ("missing tx interface name or tx_sw_if_index");
9247       return -99;
9248     }
9249
9250   M (L2_PATCH_ADD_DEL, mp);
9251
9252   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9253   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9254   mp->is_add = is_add;
9255
9256   S (mp);
9257   W (ret);
9258   return ret;
9259 }
9260
9261 u8 is_del;
9262 u8 localsid_addr[16];
9263 u8 end_psp;
9264 u8 behavior;
9265 u32 sw_if_index;
9266 u32 vlan_index;
9267 u32 fib_table;
9268 u8 nh_addr[16];
9269
9270 static int
9271 api_sr_localsid_add_del (vat_main_t * vam)
9272 {
9273   unformat_input_t *i = vam->input;
9274   vl_api_sr_localsid_add_del_t *mp;
9275
9276   u8 is_del;
9277   ip6_address_t localsid;
9278   u8 end_psp = 0;
9279   u8 behavior = ~0;
9280   u32 sw_if_index;
9281   u32 fib_table = ~(u32) 0;
9282   ip6_address_t nh_addr6;
9283   ip4_address_t nh_addr4;
9284   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9285   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9286
9287   bool nexthop_set = 0;
9288
9289   int ret;
9290
9291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9292     {
9293       if (unformat (i, "del"))
9294         is_del = 1;
9295       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9296       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9297         nexthop_set = 1;
9298       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9299         nexthop_set = 1;
9300       else if (unformat (i, "behavior %u", &behavior));
9301       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9302       else if (unformat (i, "fib-table %u", &fib_table));
9303       else if (unformat (i, "end.psp %u", &behavior));
9304       else
9305         break;
9306     }
9307
9308   M (SR_LOCALSID_ADD_DEL, mp);
9309
9310   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9311
9312   if (nexthop_set)
9313     {
9314       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9315       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9316     }
9317   mp->behavior = behavior;
9318   mp->sw_if_index = ntohl (sw_if_index);
9319   mp->fib_table = ntohl (fib_table);
9320   mp->end_psp = end_psp;
9321   mp->is_del = is_del;
9322
9323   S (mp);
9324   W (ret);
9325   return ret;
9326 }
9327
9328 static int
9329 api_ioam_enable (vat_main_t * vam)
9330 {
9331   unformat_input_t *input = vam->input;
9332   vl_api_ioam_enable_t *mp;
9333   u32 id = 0;
9334   int has_trace_option = 0;
9335   int has_pot_option = 0;
9336   int has_seqno_option = 0;
9337   int has_analyse_option = 0;
9338   int ret;
9339
9340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9341     {
9342       if (unformat (input, "trace"))
9343         has_trace_option = 1;
9344       else if (unformat (input, "pot"))
9345         has_pot_option = 1;
9346       else if (unformat (input, "seqno"))
9347         has_seqno_option = 1;
9348       else if (unformat (input, "analyse"))
9349         has_analyse_option = 1;
9350       else
9351         break;
9352     }
9353   M (IOAM_ENABLE, mp);
9354   mp->id = htons (id);
9355   mp->seqno = has_seqno_option;
9356   mp->analyse = has_analyse_option;
9357   mp->pot_enable = has_pot_option;
9358   mp->trace_enable = has_trace_option;
9359
9360   S (mp);
9361   W (ret);
9362   return ret;
9363 }
9364
9365
9366 static int
9367 api_ioam_disable (vat_main_t * vam)
9368 {
9369   vl_api_ioam_disable_t *mp;
9370   int ret;
9371
9372   M (IOAM_DISABLE, mp);
9373   S (mp);
9374   W (ret);
9375   return ret;
9376 }
9377
9378 #define foreach_tcp_proto_field                 \
9379 _(src_port)                                     \
9380 _(dst_port)
9381
9382 #define foreach_udp_proto_field                 \
9383 _(src_port)                                     \
9384 _(dst_port)
9385
9386 #define foreach_ip4_proto_field                 \
9387 _(src_address)                                  \
9388 _(dst_address)                                  \
9389 _(tos)                                          \
9390 _(length)                                       \
9391 _(fragment_id)                                  \
9392 _(ttl)                                          \
9393 _(protocol)                                     \
9394 _(checksum)
9395
9396 typedef struct
9397 {
9398   u16 src_port, dst_port;
9399 } tcpudp_header_t;
9400
9401 #if VPP_API_TEST_BUILTIN == 0
9402 uword
9403 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9404 {
9405   u8 **maskp = va_arg (*args, u8 **);
9406   u8 *mask = 0;
9407   u8 found_something = 0;
9408   tcp_header_t *tcp;
9409
9410 #define _(a) u8 a=0;
9411   foreach_tcp_proto_field;
9412 #undef _
9413
9414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9415     {
9416       if (0);
9417 #define _(a) else if (unformat (input, #a)) a=1;
9418       foreach_tcp_proto_field
9419 #undef _
9420         else
9421         break;
9422     }
9423
9424 #define _(a) found_something += a;
9425   foreach_tcp_proto_field;
9426 #undef _
9427
9428   if (found_something == 0)
9429     return 0;
9430
9431   vec_validate (mask, sizeof (*tcp) - 1);
9432
9433   tcp = (tcp_header_t *) mask;
9434
9435 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9436   foreach_tcp_proto_field;
9437 #undef _
9438
9439   *maskp = mask;
9440   return 1;
9441 }
9442
9443 uword
9444 unformat_udp_mask (unformat_input_t * input, va_list * args)
9445 {
9446   u8 **maskp = va_arg (*args, u8 **);
9447   u8 *mask = 0;
9448   u8 found_something = 0;
9449   udp_header_t *udp;
9450
9451 #define _(a) u8 a=0;
9452   foreach_udp_proto_field;
9453 #undef _
9454
9455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9456     {
9457       if (0);
9458 #define _(a) else if (unformat (input, #a)) a=1;
9459       foreach_udp_proto_field
9460 #undef _
9461         else
9462         break;
9463     }
9464
9465 #define _(a) found_something += a;
9466   foreach_udp_proto_field;
9467 #undef _
9468
9469   if (found_something == 0)
9470     return 0;
9471
9472   vec_validate (mask, sizeof (*udp) - 1);
9473
9474   udp = (udp_header_t *) mask;
9475
9476 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9477   foreach_udp_proto_field;
9478 #undef _
9479
9480   *maskp = mask;
9481   return 1;
9482 }
9483
9484 uword
9485 unformat_l4_mask (unformat_input_t * input, va_list * args)
9486 {
9487   u8 **maskp = va_arg (*args, u8 **);
9488   u16 src_port = 0, dst_port = 0;
9489   tcpudp_header_t *tcpudp;
9490
9491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9492     {
9493       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9494         return 1;
9495       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9496         return 1;
9497       else if (unformat (input, "src_port"))
9498         src_port = 0xFFFF;
9499       else if (unformat (input, "dst_port"))
9500         dst_port = 0xFFFF;
9501       else
9502         return 0;
9503     }
9504
9505   if (!src_port && !dst_port)
9506     return 0;
9507
9508   u8 *mask = 0;
9509   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9510
9511   tcpudp = (tcpudp_header_t *) mask;
9512   tcpudp->src_port = src_port;
9513   tcpudp->dst_port = dst_port;
9514
9515   *maskp = mask;
9516
9517   return 1;
9518 }
9519
9520 uword
9521 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9522 {
9523   u8 **maskp = va_arg (*args, u8 **);
9524   u8 *mask = 0;
9525   u8 found_something = 0;
9526   ip4_header_t *ip;
9527
9528 #define _(a) u8 a=0;
9529   foreach_ip4_proto_field;
9530 #undef _
9531   u8 version = 0;
9532   u8 hdr_length = 0;
9533
9534
9535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9536     {
9537       if (unformat (input, "version"))
9538         version = 1;
9539       else if (unformat (input, "hdr_length"))
9540         hdr_length = 1;
9541       else if (unformat (input, "src"))
9542         src_address = 1;
9543       else if (unformat (input, "dst"))
9544         dst_address = 1;
9545       else if (unformat (input, "proto"))
9546         protocol = 1;
9547
9548 #define _(a) else if (unformat (input, #a)) a=1;
9549       foreach_ip4_proto_field
9550 #undef _
9551         else
9552         break;
9553     }
9554
9555 #define _(a) found_something += a;
9556   foreach_ip4_proto_field;
9557 #undef _
9558
9559   if (found_something == 0)
9560     return 0;
9561
9562   vec_validate (mask, sizeof (*ip) - 1);
9563
9564   ip = (ip4_header_t *) mask;
9565
9566 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9567   foreach_ip4_proto_field;
9568 #undef _
9569
9570   ip->ip_version_and_header_length = 0;
9571
9572   if (version)
9573     ip->ip_version_and_header_length |= 0xF0;
9574
9575   if (hdr_length)
9576     ip->ip_version_and_header_length |= 0x0F;
9577
9578   *maskp = mask;
9579   return 1;
9580 }
9581
9582 #define foreach_ip6_proto_field                 \
9583 _(src_address)                                  \
9584 _(dst_address)                                  \
9585 _(payload_length)                               \
9586 _(hop_limit)                                    \
9587 _(protocol)
9588
9589 uword
9590 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9591 {
9592   u8 **maskp = va_arg (*args, u8 **);
9593   u8 *mask = 0;
9594   u8 found_something = 0;
9595   ip6_header_t *ip;
9596   u32 ip_version_traffic_class_and_flow_label;
9597
9598 #define _(a) u8 a=0;
9599   foreach_ip6_proto_field;
9600 #undef _
9601   u8 version = 0;
9602   u8 traffic_class = 0;
9603   u8 flow_label = 0;
9604
9605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9606     {
9607       if (unformat (input, "version"))
9608         version = 1;
9609       else if (unformat (input, "traffic-class"))
9610         traffic_class = 1;
9611       else if (unformat (input, "flow-label"))
9612         flow_label = 1;
9613       else if (unformat (input, "src"))
9614         src_address = 1;
9615       else if (unformat (input, "dst"))
9616         dst_address = 1;
9617       else if (unformat (input, "proto"))
9618         protocol = 1;
9619
9620 #define _(a) else if (unformat (input, #a)) a=1;
9621       foreach_ip6_proto_field
9622 #undef _
9623         else
9624         break;
9625     }
9626
9627 #define _(a) found_something += a;
9628   foreach_ip6_proto_field;
9629 #undef _
9630
9631   if (found_something == 0)
9632     return 0;
9633
9634   vec_validate (mask, sizeof (*ip) - 1);
9635
9636   ip = (ip6_header_t *) mask;
9637
9638 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9639   foreach_ip6_proto_field;
9640 #undef _
9641
9642   ip_version_traffic_class_and_flow_label = 0;
9643
9644   if (version)
9645     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9646
9647   if (traffic_class)
9648     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9649
9650   if (flow_label)
9651     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9652
9653   ip->ip_version_traffic_class_and_flow_label =
9654     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9655
9656   *maskp = mask;
9657   return 1;
9658 }
9659
9660 uword
9661 unformat_l3_mask (unformat_input_t * input, va_list * args)
9662 {
9663   u8 **maskp = va_arg (*args, u8 **);
9664
9665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9666     {
9667       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9668         return 1;
9669       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9670         return 1;
9671       else
9672         break;
9673     }
9674   return 0;
9675 }
9676
9677 uword
9678 unformat_l2_mask (unformat_input_t * input, va_list * args)
9679 {
9680   u8 **maskp = va_arg (*args, u8 **);
9681   u8 *mask = 0;
9682   u8 src = 0;
9683   u8 dst = 0;
9684   u8 proto = 0;
9685   u8 tag1 = 0;
9686   u8 tag2 = 0;
9687   u8 ignore_tag1 = 0;
9688   u8 ignore_tag2 = 0;
9689   u8 cos1 = 0;
9690   u8 cos2 = 0;
9691   u8 dot1q = 0;
9692   u8 dot1ad = 0;
9693   int len = 14;
9694
9695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (input, "src"))
9698         src = 1;
9699       else if (unformat (input, "dst"))
9700         dst = 1;
9701       else if (unformat (input, "proto"))
9702         proto = 1;
9703       else if (unformat (input, "tag1"))
9704         tag1 = 1;
9705       else if (unformat (input, "tag2"))
9706         tag2 = 1;
9707       else if (unformat (input, "ignore-tag1"))
9708         ignore_tag1 = 1;
9709       else if (unformat (input, "ignore-tag2"))
9710         ignore_tag2 = 1;
9711       else if (unformat (input, "cos1"))
9712         cos1 = 1;
9713       else if (unformat (input, "cos2"))
9714         cos2 = 1;
9715       else if (unformat (input, "dot1q"))
9716         dot1q = 1;
9717       else if (unformat (input, "dot1ad"))
9718         dot1ad = 1;
9719       else
9720         break;
9721     }
9722   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9723        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9724     return 0;
9725
9726   if (tag1 || ignore_tag1 || cos1 || dot1q)
9727     len = 18;
9728   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9729     len = 22;
9730
9731   vec_validate (mask, len - 1);
9732
9733   if (dst)
9734     clib_memset (mask, 0xff, 6);
9735
9736   if (src)
9737     clib_memset (mask + 6, 0xff, 6);
9738
9739   if (tag2 || dot1ad)
9740     {
9741       /* inner vlan tag */
9742       if (tag2)
9743         {
9744           mask[19] = 0xff;
9745           mask[18] = 0x0f;
9746         }
9747       if (cos2)
9748         mask[18] |= 0xe0;
9749       if (proto)
9750         mask[21] = mask[20] = 0xff;
9751       if (tag1)
9752         {
9753           mask[15] = 0xff;
9754           mask[14] = 0x0f;
9755         }
9756       if (cos1)
9757         mask[14] |= 0xe0;
9758       *maskp = mask;
9759       return 1;
9760     }
9761   if (tag1 | dot1q)
9762     {
9763       if (tag1)
9764         {
9765           mask[15] = 0xff;
9766           mask[14] = 0x0f;
9767         }
9768       if (cos1)
9769         mask[14] |= 0xe0;
9770       if (proto)
9771         mask[16] = mask[17] = 0xff;
9772
9773       *maskp = mask;
9774       return 1;
9775     }
9776   if (cos2)
9777     mask[18] |= 0xe0;
9778   if (cos1)
9779     mask[14] |= 0xe0;
9780   if (proto)
9781     mask[12] = mask[13] = 0xff;
9782
9783   *maskp = mask;
9784   return 1;
9785 }
9786
9787 uword
9788 unformat_classify_mask (unformat_input_t * input, va_list * args)
9789 {
9790   u8 **maskp = va_arg (*args, u8 **);
9791   u32 *skipp = va_arg (*args, u32 *);
9792   u32 *matchp = va_arg (*args, u32 *);
9793   u32 match;
9794   u8 *mask = 0;
9795   u8 *l2 = 0;
9796   u8 *l3 = 0;
9797   u8 *l4 = 0;
9798   int i;
9799
9800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9801     {
9802       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9803         ;
9804       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9805         ;
9806       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9807         ;
9808       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9809         ;
9810       else
9811         break;
9812     }
9813
9814   if (l4 && !l3)
9815     {
9816       vec_free (mask);
9817       vec_free (l2);
9818       vec_free (l4);
9819       return 0;
9820     }
9821
9822   if (mask || l2 || l3 || l4)
9823     {
9824       if (l2 || l3 || l4)
9825         {
9826           /* "With a free Ethernet header in every package" */
9827           if (l2 == 0)
9828             vec_validate (l2, 13);
9829           mask = l2;
9830           if (vec_len (l3))
9831             {
9832               vec_append (mask, l3);
9833               vec_free (l3);
9834             }
9835           if (vec_len (l4))
9836             {
9837               vec_append (mask, l4);
9838               vec_free (l4);
9839             }
9840         }
9841
9842       /* Scan forward looking for the first significant mask octet */
9843       for (i = 0; i < vec_len (mask); i++)
9844         if (mask[i])
9845           break;
9846
9847       /* compute (skip, match) params */
9848       *skipp = i / sizeof (u32x4);
9849       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9850
9851       /* Pad mask to an even multiple of the vector size */
9852       while (vec_len (mask) % sizeof (u32x4))
9853         vec_add1 (mask, 0);
9854
9855       match = vec_len (mask) / sizeof (u32x4);
9856
9857       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9858         {
9859           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9860           if (*tmp || *(tmp + 1))
9861             break;
9862           match--;
9863         }
9864       if (match == 0)
9865         clib_warning ("BUG: match 0");
9866
9867       _vec_len (mask) = match * sizeof (u32x4);
9868
9869       *matchp = match;
9870       *maskp = mask;
9871
9872       return 1;
9873     }
9874
9875   return 0;
9876 }
9877 #endif /* VPP_API_TEST_BUILTIN */
9878
9879 #define foreach_l2_next                         \
9880 _(drop, DROP)                                   \
9881 _(ethernet, ETHERNET_INPUT)                     \
9882 _(ip4, IP4_INPUT)                               \
9883 _(ip6, IP6_INPUT)
9884
9885 uword
9886 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9887 {
9888   u32 *miss_next_indexp = va_arg (*args, u32 *);
9889   u32 next_index = 0;
9890   u32 tmp;
9891
9892 #define _(n,N) \
9893   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9894   foreach_l2_next;
9895 #undef _
9896
9897   if (unformat (input, "%d", &tmp))
9898     {
9899       next_index = tmp;
9900       goto out;
9901     }
9902
9903   return 0;
9904
9905 out:
9906   *miss_next_indexp = next_index;
9907   return 1;
9908 }
9909
9910 #define foreach_ip_next                         \
9911 _(drop, DROP)                                   \
9912 _(local, LOCAL)                                 \
9913 _(rewrite, REWRITE)
9914
9915 uword
9916 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9917 {
9918   u32 *miss_next_indexp = va_arg (*args, u32 *);
9919   u32 next_index = 0;
9920   u32 tmp;
9921
9922 #define _(n,N) \
9923   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9924   foreach_ip_next;
9925 #undef _
9926
9927   if (unformat (input, "%d", &tmp))
9928     {
9929       next_index = tmp;
9930       goto out;
9931     }
9932
9933   return 0;
9934
9935 out:
9936   *miss_next_indexp = next_index;
9937   return 1;
9938 }
9939
9940 #define foreach_acl_next                        \
9941 _(deny, DENY)
9942
9943 uword
9944 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9945 {
9946   u32 *miss_next_indexp = va_arg (*args, u32 *);
9947   u32 next_index = 0;
9948   u32 tmp;
9949
9950 #define _(n,N) \
9951   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9952   foreach_acl_next;
9953 #undef _
9954
9955   if (unformat (input, "permit"))
9956     {
9957       next_index = ~0;
9958       goto out;
9959     }
9960   else if (unformat (input, "%d", &tmp))
9961     {
9962       next_index = tmp;
9963       goto out;
9964     }
9965
9966   return 0;
9967
9968 out:
9969   *miss_next_indexp = next_index;
9970   return 1;
9971 }
9972
9973 uword
9974 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9975 {
9976   u32 *r = va_arg (*args, u32 *);
9977
9978   if (unformat (input, "conform-color"))
9979     *r = POLICE_CONFORM;
9980   else if (unformat (input, "exceed-color"))
9981     *r = POLICE_EXCEED;
9982   else
9983     return 0;
9984
9985   return 1;
9986 }
9987
9988 static int
9989 api_classify_add_del_table (vat_main_t * vam)
9990 {
9991   unformat_input_t *i = vam->input;
9992   vl_api_classify_add_del_table_t *mp;
9993
9994   u32 nbuckets = 2;
9995   u32 skip = ~0;
9996   u32 match = ~0;
9997   int is_add = 1;
9998   int del_chain = 0;
9999   u32 table_index = ~0;
10000   u32 next_table_index = ~0;
10001   u32 miss_next_index = ~0;
10002   u32 memory_size = 32 << 20;
10003   u8 *mask = 0;
10004   u32 current_data_flag = 0;
10005   int current_data_offset = 0;
10006   int ret;
10007
10008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10009     {
10010       if (unformat (i, "del"))
10011         is_add = 0;
10012       else if (unformat (i, "del-chain"))
10013         {
10014           is_add = 0;
10015           del_chain = 1;
10016         }
10017       else if (unformat (i, "buckets %d", &nbuckets))
10018         ;
10019       else if (unformat (i, "memory_size %d", &memory_size))
10020         ;
10021       else if (unformat (i, "skip %d", &skip))
10022         ;
10023       else if (unformat (i, "match %d", &match))
10024         ;
10025       else if (unformat (i, "table %d", &table_index))
10026         ;
10027       else if (unformat (i, "mask %U", unformat_classify_mask,
10028                          &mask, &skip, &match))
10029         ;
10030       else if (unformat (i, "next-table %d", &next_table_index))
10031         ;
10032       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10033                          &miss_next_index))
10034         ;
10035       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10036                          &miss_next_index))
10037         ;
10038       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10039                          &miss_next_index))
10040         ;
10041       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10042         ;
10043       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10044         ;
10045       else
10046         break;
10047     }
10048
10049   if (is_add && mask == 0)
10050     {
10051       errmsg ("Mask required");
10052       return -99;
10053     }
10054
10055   if (is_add && skip == ~0)
10056     {
10057       errmsg ("skip count required");
10058       return -99;
10059     }
10060
10061   if (is_add && match == ~0)
10062     {
10063       errmsg ("match count required");
10064       return -99;
10065     }
10066
10067   if (!is_add && table_index == ~0)
10068     {
10069       errmsg ("table index required for delete");
10070       return -99;
10071     }
10072
10073   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10074
10075   mp->is_add = is_add;
10076   mp->del_chain = del_chain;
10077   mp->table_index = ntohl (table_index);
10078   mp->nbuckets = ntohl (nbuckets);
10079   mp->memory_size = ntohl (memory_size);
10080   mp->skip_n_vectors = ntohl (skip);
10081   mp->match_n_vectors = ntohl (match);
10082   mp->next_table_index = ntohl (next_table_index);
10083   mp->miss_next_index = ntohl (miss_next_index);
10084   mp->current_data_flag = ntohl (current_data_flag);
10085   mp->current_data_offset = ntohl (current_data_offset);
10086   mp->mask_len = ntohl (vec_len (mask));
10087   clib_memcpy (mp->mask, mask, vec_len (mask));
10088
10089   vec_free (mask);
10090
10091   S (mp);
10092   W (ret);
10093   return ret;
10094 }
10095
10096 #if VPP_API_TEST_BUILTIN == 0
10097 uword
10098 unformat_l4_match (unformat_input_t * input, va_list * args)
10099 {
10100   u8 **matchp = va_arg (*args, u8 **);
10101
10102   u8 *proto_header = 0;
10103   int src_port = 0;
10104   int dst_port = 0;
10105
10106   tcpudp_header_t h;
10107
10108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10109     {
10110       if (unformat (input, "src_port %d", &src_port))
10111         ;
10112       else if (unformat (input, "dst_port %d", &dst_port))
10113         ;
10114       else
10115         return 0;
10116     }
10117
10118   h.src_port = clib_host_to_net_u16 (src_port);
10119   h.dst_port = clib_host_to_net_u16 (dst_port);
10120   vec_validate (proto_header, sizeof (h) - 1);
10121   memcpy (proto_header, &h, sizeof (h));
10122
10123   *matchp = proto_header;
10124
10125   return 1;
10126 }
10127
10128 uword
10129 unformat_ip4_match (unformat_input_t * input, va_list * args)
10130 {
10131   u8 **matchp = va_arg (*args, u8 **);
10132   u8 *match = 0;
10133   ip4_header_t *ip;
10134   int version = 0;
10135   u32 version_val;
10136   int hdr_length = 0;
10137   u32 hdr_length_val;
10138   int src = 0, dst = 0;
10139   ip4_address_t src_val, dst_val;
10140   int proto = 0;
10141   u32 proto_val;
10142   int tos = 0;
10143   u32 tos_val;
10144   int length = 0;
10145   u32 length_val;
10146   int fragment_id = 0;
10147   u32 fragment_id_val;
10148   int ttl = 0;
10149   int ttl_val;
10150   int checksum = 0;
10151   u32 checksum_val;
10152
10153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10154     {
10155       if (unformat (input, "version %d", &version_val))
10156         version = 1;
10157       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10158         hdr_length = 1;
10159       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10160         src = 1;
10161       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10162         dst = 1;
10163       else if (unformat (input, "proto %d", &proto_val))
10164         proto = 1;
10165       else if (unformat (input, "tos %d", &tos_val))
10166         tos = 1;
10167       else if (unformat (input, "length %d", &length_val))
10168         length = 1;
10169       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10170         fragment_id = 1;
10171       else if (unformat (input, "ttl %d", &ttl_val))
10172         ttl = 1;
10173       else if (unformat (input, "checksum %d", &checksum_val))
10174         checksum = 1;
10175       else
10176         break;
10177     }
10178
10179   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10180       + ttl + checksum == 0)
10181     return 0;
10182
10183   /*
10184    * Aligned because we use the real comparison functions
10185    */
10186   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10187
10188   ip = (ip4_header_t *) match;
10189
10190   /* These are realistically matched in practice */
10191   if (src)
10192     ip->src_address.as_u32 = src_val.as_u32;
10193
10194   if (dst)
10195     ip->dst_address.as_u32 = dst_val.as_u32;
10196
10197   if (proto)
10198     ip->protocol = proto_val;
10199
10200
10201   /* These are not, but they're included for completeness */
10202   if (version)
10203     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10204
10205   if (hdr_length)
10206     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10207
10208   if (tos)
10209     ip->tos = tos_val;
10210
10211   if (length)
10212     ip->length = clib_host_to_net_u16 (length_val);
10213
10214   if (ttl)
10215     ip->ttl = ttl_val;
10216
10217   if (checksum)
10218     ip->checksum = clib_host_to_net_u16 (checksum_val);
10219
10220   *matchp = match;
10221   return 1;
10222 }
10223
10224 uword
10225 unformat_ip6_match (unformat_input_t * input, va_list * args)
10226 {
10227   u8 **matchp = va_arg (*args, u8 **);
10228   u8 *match = 0;
10229   ip6_header_t *ip;
10230   int version = 0;
10231   u32 version_val;
10232   u8 traffic_class = 0;
10233   u32 traffic_class_val = 0;
10234   u8 flow_label = 0;
10235   u8 flow_label_val;
10236   int src = 0, dst = 0;
10237   ip6_address_t src_val, dst_val;
10238   int proto = 0;
10239   u32 proto_val;
10240   int payload_length = 0;
10241   u32 payload_length_val;
10242   int hop_limit = 0;
10243   int hop_limit_val;
10244   u32 ip_version_traffic_class_and_flow_label;
10245
10246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10247     {
10248       if (unformat (input, "version %d", &version_val))
10249         version = 1;
10250       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10251         traffic_class = 1;
10252       else if (unformat (input, "flow_label %d", &flow_label_val))
10253         flow_label = 1;
10254       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10255         src = 1;
10256       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10257         dst = 1;
10258       else if (unformat (input, "proto %d", &proto_val))
10259         proto = 1;
10260       else if (unformat (input, "payload_length %d", &payload_length_val))
10261         payload_length = 1;
10262       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10263         hop_limit = 1;
10264       else
10265         break;
10266     }
10267
10268   if (version + traffic_class + flow_label + src + dst + proto +
10269       payload_length + hop_limit == 0)
10270     return 0;
10271
10272   /*
10273    * Aligned because we use the real comparison functions
10274    */
10275   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10276
10277   ip = (ip6_header_t *) match;
10278
10279   if (src)
10280     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10281
10282   if (dst)
10283     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10284
10285   if (proto)
10286     ip->protocol = proto_val;
10287
10288   ip_version_traffic_class_and_flow_label = 0;
10289
10290   if (version)
10291     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10292
10293   if (traffic_class)
10294     ip_version_traffic_class_and_flow_label |=
10295       (traffic_class_val & 0xFF) << 20;
10296
10297   if (flow_label)
10298     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10299
10300   ip->ip_version_traffic_class_and_flow_label =
10301     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10302
10303   if (payload_length)
10304     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10305
10306   if (hop_limit)
10307     ip->hop_limit = hop_limit_val;
10308
10309   *matchp = match;
10310   return 1;
10311 }
10312
10313 uword
10314 unformat_l3_match (unformat_input_t * input, va_list * args)
10315 {
10316   u8 **matchp = va_arg (*args, u8 **);
10317
10318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10319     {
10320       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10321         return 1;
10322       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10323         return 1;
10324       else
10325         break;
10326     }
10327   return 0;
10328 }
10329
10330 uword
10331 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10332 {
10333   u8 *tagp = va_arg (*args, u8 *);
10334   u32 tag;
10335
10336   if (unformat (input, "%d", &tag))
10337     {
10338       tagp[0] = (tag >> 8) & 0x0F;
10339       tagp[1] = tag & 0xFF;
10340       return 1;
10341     }
10342
10343   return 0;
10344 }
10345
10346 uword
10347 unformat_l2_match (unformat_input_t * input, va_list * args)
10348 {
10349   u8 **matchp = va_arg (*args, u8 **);
10350   u8 *match = 0;
10351   u8 src = 0;
10352   u8 src_val[6];
10353   u8 dst = 0;
10354   u8 dst_val[6];
10355   u8 proto = 0;
10356   u16 proto_val;
10357   u8 tag1 = 0;
10358   u8 tag1_val[2];
10359   u8 tag2 = 0;
10360   u8 tag2_val[2];
10361   int len = 14;
10362   u8 ignore_tag1 = 0;
10363   u8 ignore_tag2 = 0;
10364   u8 cos1 = 0;
10365   u8 cos2 = 0;
10366   u32 cos1_val = 0;
10367   u32 cos2_val = 0;
10368
10369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10372         src = 1;
10373       else
10374         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10375         dst = 1;
10376       else if (unformat (input, "proto %U",
10377                          unformat_ethernet_type_host_byte_order, &proto_val))
10378         proto = 1;
10379       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10380         tag1 = 1;
10381       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10382         tag2 = 1;
10383       else if (unformat (input, "ignore-tag1"))
10384         ignore_tag1 = 1;
10385       else if (unformat (input, "ignore-tag2"))
10386         ignore_tag2 = 1;
10387       else if (unformat (input, "cos1 %d", &cos1_val))
10388         cos1 = 1;
10389       else if (unformat (input, "cos2 %d", &cos2_val))
10390         cos2 = 1;
10391       else
10392         break;
10393     }
10394   if ((src + dst + proto + tag1 + tag2 +
10395        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10396     return 0;
10397
10398   if (tag1 || ignore_tag1 || cos1)
10399     len = 18;
10400   if (tag2 || ignore_tag2 || cos2)
10401     len = 22;
10402
10403   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10404
10405   if (dst)
10406     clib_memcpy (match, dst_val, 6);
10407
10408   if (src)
10409     clib_memcpy (match + 6, src_val, 6);
10410
10411   if (tag2)
10412     {
10413       /* inner vlan tag */
10414       match[19] = tag2_val[1];
10415       match[18] = tag2_val[0];
10416       if (cos2)
10417         match[18] |= (cos2_val & 0x7) << 5;
10418       if (proto)
10419         {
10420           match[21] = proto_val & 0xff;
10421           match[20] = proto_val >> 8;
10422         }
10423       if (tag1)
10424         {
10425           match[15] = tag1_val[1];
10426           match[14] = tag1_val[0];
10427         }
10428       if (cos1)
10429         match[14] |= (cos1_val & 0x7) << 5;
10430       *matchp = match;
10431       return 1;
10432     }
10433   if (tag1)
10434     {
10435       match[15] = tag1_val[1];
10436       match[14] = tag1_val[0];
10437       if (proto)
10438         {
10439           match[17] = proto_val & 0xff;
10440           match[16] = proto_val >> 8;
10441         }
10442       if (cos1)
10443         match[14] |= (cos1_val & 0x7) << 5;
10444
10445       *matchp = match;
10446       return 1;
10447     }
10448   if (cos2)
10449     match[18] |= (cos2_val & 0x7) << 5;
10450   if (cos1)
10451     match[14] |= (cos1_val & 0x7) << 5;
10452   if (proto)
10453     {
10454       match[13] = proto_val & 0xff;
10455       match[12] = proto_val >> 8;
10456     }
10457
10458   *matchp = match;
10459   return 1;
10460 }
10461
10462 uword
10463 unformat_qos_source (unformat_input_t * input, va_list * args)
10464 {
10465   int *qs = va_arg (*args, int *);
10466
10467   if (unformat (input, "ip"))
10468     *qs = QOS_SOURCE_IP;
10469   else if (unformat (input, "mpls"))
10470     *qs = QOS_SOURCE_MPLS;
10471   else if (unformat (input, "ext"))
10472     *qs = QOS_SOURCE_EXT;
10473   else if (unformat (input, "vlan"))
10474     *qs = QOS_SOURCE_VLAN;
10475   else
10476     return 0;
10477
10478   return 1;
10479 }
10480 #endif
10481
10482 uword
10483 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10484 {
10485   u8 **matchp = va_arg (*args, u8 **);
10486   u32 skip_n_vectors = va_arg (*args, u32);
10487   u32 match_n_vectors = va_arg (*args, u32);
10488
10489   u8 *match = 0;
10490   u8 *l2 = 0;
10491   u8 *l3 = 0;
10492   u8 *l4 = 0;
10493
10494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10495     {
10496       if (unformat (input, "hex %U", unformat_hex_string, &match))
10497         ;
10498       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10499         ;
10500       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10501         ;
10502       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10503         ;
10504       else
10505         break;
10506     }
10507
10508   if (l4 && !l3)
10509     {
10510       vec_free (match);
10511       vec_free (l2);
10512       vec_free (l4);
10513       return 0;
10514     }
10515
10516   if (match || l2 || l3 || l4)
10517     {
10518       if (l2 || l3 || l4)
10519         {
10520           /* "Win a free Ethernet header in every packet" */
10521           if (l2 == 0)
10522             vec_validate_aligned (l2, 13, sizeof (u32x4));
10523           match = l2;
10524           if (vec_len (l3))
10525             {
10526               vec_append_aligned (match, l3, sizeof (u32x4));
10527               vec_free (l3);
10528             }
10529           if (vec_len (l4))
10530             {
10531               vec_append_aligned (match, l4, sizeof (u32x4));
10532               vec_free (l4);
10533             }
10534         }
10535
10536       /* Make sure the vector is big enough even if key is all 0's */
10537       vec_validate_aligned
10538         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10539          sizeof (u32x4));
10540
10541       /* Set size, include skipped vectors */
10542       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10543
10544       *matchp = match;
10545
10546       return 1;
10547     }
10548
10549   return 0;
10550 }
10551
10552 static int
10553 api_classify_add_del_session (vat_main_t * vam)
10554 {
10555   unformat_input_t *i = vam->input;
10556   vl_api_classify_add_del_session_t *mp;
10557   int is_add = 1;
10558   u32 table_index = ~0;
10559   u32 hit_next_index = ~0;
10560   u32 opaque_index = ~0;
10561   u8 *match = 0;
10562   i32 advance = 0;
10563   u32 skip_n_vectors = 0;
10564   u32 match_n_vectors = 0;
10565   u32 action = 0;
10566   u32 metadata = 0;
10567   int ret;
10568
10569   /*
10570    * Warning: you have to supply skip_n and match_n
10571    * because the API client cant simply look at the classify
10572    * table object.
10573    */
10574
10575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10576     {
10577       if (unformat (i, "del"))
10578         is_add = 0;
10579       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10580                          &hit_next_index))
10581         ;
10582       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10583                          &hit_next_index))
10584         ;
10585       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10586                          &hit_next_index))
10587         ;
10588       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10589         ;
10590       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10591         ;
10592       else if (unformat (i, "opaque-index %d", &opaque_index))
10593         ;
10594       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10595         ;
10596       else if (unformat (i, "match_n %d", &match_n_vectors))
10597         ;
10598       else if (unformat (i, "match %U", api_unformat_classify_match,
10599                          &match, skip_n_vectors, match_n_vectors))
10600         ;
10601       else if (unformat (i, "advance %d", &advance))
10602         ;
10603       else if (unformat (i, "table-index %d", &table_index))
10604         ;
10605       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10606         action = 1;
10607       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10608         action = 2;
10609       else if (unformat (i, "action %d", &action))
10610         ;
10611       else if (unformat (i, "metadata %d", &metadata))
10612         ;
10613       else
10614         break;
10615     }
10616
10617   if (table_index == ~0)
10618     {
10619       errmsg ("Table index required");
10620       return -99;
10621     }
10622
10623   if (is_add && match == 0)
10624     {
10625       errmsg ("Match value required");
10626       return -99;
10627     }
10628
10629   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10630
10631   mp->is_add = is_add;
10632   mp->table_index = ntohl (table_index);
10633   mp->hit_next_index = ntohl (hit_next_index);
10634   mp->opaque_index = ntohl (opaque_index);
10635   mp->advance = ntohl (advance);
10636   mp->action = action;
10637   mp->metadata = ntohl (metadata);
10638   mp->match_len = ntohl (vec_len (match));
10639   clib_memcpy (mp->match, match, vec_len (match));
10640   vec_free (match);
10641
10642   S (mp);
10643   W (ret);
10644   return ret;
10645 }
10646
10647 static int
10648 api_classify_set_interface_ip_table (vat_main_t * vam)
10649 {
10650   unformat_input_t *i = vam->input;
10651   vl_api_classify_set_interface_ip_table_t *mp;
10652   u32 sw_if_index;
10653   int sw_if_index_set;
10654   u32 table_index = ~0;
10655   u8 is_ipv6 = 0;
10656   int ret;
10657
10658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10659     {
10660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10661         sw_if_index_set = 1;
10662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10663         sw_if_index_set = 1;
10664       else if (unformat (i, "table %d", &table_index))
10665         ;
10666       else
10667         {
10668           clib_warning ("parse error '%U'", format_unformat_error, i);
10669           return -99;
10670         }
10671     }
10672
10673   if (sw_if_index_set == 0)
10674     {
10675       errmsg ("missing interface name or sw_if_index");
10676       return -99;
10677     }
10678
10679
10680   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10681
10682   mp->sw_if_index = ntohl (sw_if_index);
10683   mp->table_index = ntohl (table_index);
10684   mp->is_ipv6 = is_ipv6;
10685
10686   S (mp);
10687   W (ret);
10688   return ret;
10689 }
10690
10691 static int
10692 api_classify_set_interface_l2_tables (vat_main_t * vam)
10693 {
10694   unformat_input_t *i = vam->input;
10695   vl_api_classify_set_interface_l2_tables_t *mp;
10696   u32 sw_if_index;
10697   int sw_if_index_set;
10698   u32 ip4_table_index = ~0;
10699   u32 ip6_table_index = ~0;
10700   u32 other_table_index = ~0;
10701   u32 is_input = 1;
10702   int ret;
10703
10704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10709         sw_if_index_set = 1;
10710       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10711         ;
10712       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10713         ;
10714       else if (unformat (i, "other-table %d", &other_table_index))
10715         ;
10716       else if (unformat (i, "is-input %d", &is_input))
10717         ;
10718       else
10719         {
10720           clib_warning ("parse error '%U'", format_unformat_error, i);
10721           return -99;
10722         }
10723     }
10724
10725   if (sw_if_index_set == 0)
10726     {
10727       errmsg ("missing interface name or sw_if_index");
10728       return -99;
10729     }
10730
10731
10732   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10733
10734   mp->sw_if_index = ntohl (sw_if_index);
10735   mp->ip4_table_index = ntohl (ip4_table_index);
10736   mp->ip6_table_index = ntohl (ip6_table_index);
10737   mp->other_table_index = ntohl (other_table_index);
10738   mp->is_input = (u8) is_input;
10739
10740   S (mp);
10741   W (ret);
10742   return ret;
10743 }
10744
10745 static int
10746 api_set_ipfix_exporter (vat_main_t * vam)
10747 {
10748   unformat_input_t *i = vam->input;
10749   vl_api_set_ipfix_exporter_t *mp;
10750   ip4_address_t collector_address;
10751   u8 collector_address_set = 0;
10752   u32 collector_port = ~0;
10753   ip4_address_t src_address;
10754   u8 src_address_set = 0;
10755   u32 vrf_id = ~0;
10756   u32 path_mtu = ~0;
10757   u32 template_interval = ~0;
10758   u8 udp_checksum = 0;
10759   int ret;
10760
10761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10762     {
10763       if (unformat (i, "collector_address %U", unformat_ip4_address,
10764                     &collector_address))
10765         collector_address_set = 1;
10766       else if (unformat (i, "collector_port %d", &collector_port))
10767         ;
10768       else if (unformat (i, "src_address %U", unformat_ip4_address,
10769                          &src_address))
10770         src_address_set = 1;
10771       else if (unformat (i, "vrf_id %d", &vrf_id))
10772         ;
10773       else if (unformat (i, "path_mtu %d", &path_mtu))
10774         ;
10775       else if (unformat (i, "template_interval %d", &template_interval))
10776         ;
10777       else if (unformat (i, "udp_checksum"))
10778         udp_checksum = 1;
10779       else
10780         break;
10781     }
10782
10783   if (collector_address_set == 0)
10784     {
10785       errmsg ("collector_address required");
10786       return -99;
10787     }
10788
10789   if (src_address_set == 0)
10790     {
10791       errmsg ("src_address required");
10792       return -99;
10793     }
10794
10795   M (SET_IPFIX_EXPORTER, mp);
10796
10797   memcpy (mp->collector_address.un.ip4, collector_address.data,
10798           sizeof (collector_address.data));
10799   mp->collector_port = htons ((u16) collector_port);
10800   memcpy (mp->src_address.un.ip4, src_address.data,
10801           sizeof (src_address.data));
10802   mp->vrf_id = htonl (vrf_id);
10803   mp->path_mtu = htonl (path_mtu);
10804   mp->template_interval = htonl (template_interval);
10805   mp->udp_checksum = udp_checksum;
10806
10807   S (mp);
10808   W (ret);
10809   return ret;
10810 }
10811
10812 static int
10813 api_set_ipfix_classify_stream (vat_main_t * vam)
10814 {
10815   unformat_input_t *i = vam->input;
10816   vl_api_set_ipfix_classify_stream_t *mp;
10817   u32 domain_id = 0;
10818   u32 src_port = UDP_DST_PORT_ipfix;
10819   int ret;
10820
10821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10822     {
10823       if (unformat (i, "domain %d", &domain_id))
10824         ;
10825       else if (unformat (i, "src_port %d", &src_port))
10826         ;
10827       else
10828         {
10829           errmsg ("unknown input `%U'", format_unformat_error, i);
10830           return -99;
10831         }
10832     }
10833
10834   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10835
10836   mp->domain_id = htonl (domain_id);
10837   mp->src_port = htons ((u16) src_port);
10838
10839   S (mp);
10840   W (ret);
10841   return ret;
10842 }
10843
10844 static int
10845 api_ipfix_classify_table_add_del (vat_main_t * vam)
10846 {
10847   unformat_input_t *i = vam->input;
10848   vl_api_ipfix_classify_table_add_del_t *mp;
10849   int is_add = -1;
10850   u32 classify_table_index = ~0;
10851   u8 ip_version = 0;
10852   u8 transport_protocol = 255;
10853   int ret;
10854
10855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10856     {
10857       if (unformat (i, "add"))
10858         is_add = 1;
10859       else if (unformat (i, "del"))
10860         is_add = 0;
10861       else if (unformat (i, "table %d", &classify_table_index))
10862         ;
10863       else if (unformat (i, "ip4"))
10864         ip_version = 4;
10865       else if (unformat (i, "ip6"))
10866         ip_version = 6;
10867       else if (unformat (i, "tcp"))
10868         transport_protocol = 6;
10869       else if (unformat (i, "udp"))
10870         transport_protocol = 17;
10871       else
10872         {
10873           errmsg ("unknown input `%U'", format_unformat_error, i);
10874           return -99;
10875         }
10876     }
10877
10878   if (is_add == -1)
10879     {
10880       errmsg ("expecting: add|del");
10881       return -99;
10882     }
10883   if (classify_table_index == ~0)
10884     {
10885       errmsg ("classifier table not specified");
10886       return -99;
10887     }
10888   if (ip_version == 0)
10889     {
10890       errmsg ("IP version not specified");
10891       return -99;
10892     }
10893
10894   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10895
10896   mp->is_add = is_add;
10897   mp->table_id = htonl (classify_table_index);
10898   mp->ip_version = ip_version;
10899   mp->transport_protocol = transport_protocol;
10900
10901   S (mp);
10902   W (ret);
10903   return ret;
10904 }
10905
10906 static int
10907 api_get_node_index (vat_main_t * vam)
10908 {
10909   unformat_input_t *i = vam->input;
10910   vl_api_get_node_index_t *mp;
10911   u8 *name = 0;
10912   int ret;
10913
10914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10915     {
10916       if (unformat (i, "node %s", &name))
10917         ;
10918       else
10919         break;
10920     }
10921   if (name == 0)
10922     {
10923       errmsg ("node name required");
10924       return -99;
10925     }
10926   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10927     {
10928       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10929       return -99;
10930     }
10931
10932   M (GET_NODE_INDEX, mp);
10933   clib_memcpy (mp->node_name, name, vec_len (name));
10934   vec_free (name);
10935
10936   S (mp);
10937   W (ret);
10938   return ret;
10939 }
10940
10941 static int
10942 api_get_next_index (vat_main_t * vam)
10943 {
10944   unformat_input_t *i = vam->input;
10945   vl_api_get_next_index_t *mp;
10946   u8 *node_name = 0, *next_node_name = 0;
10947   int ret;
10948
10949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10950     {
10951       if (unformat (i, "node-name %s", &node_name))
10952         ;
10953       else if (unformat (i, "next-node-name %s", &next_node_name))
10954         break;
10955     }
10956
10957   if (node_name == 0)
10958     {
10959       errmsg ("node name required");
10960       return -99;
10961     }
10962   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10963     {
10964       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10965       return -99;
10966     }
10967
10968   if (next_node_name == 0)
10969     {
10970       errmsg ("next node name required");
10971       return -99;
10972     }
10973   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10974     {
10975       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10976       return -99;
10977     }
10978
10979   M (GET_NEXT_INDEX, mp);
10980   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10981   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10982   vec_free (node_name);
10983   vec_free (next_node_name);
10984
10985   S (mp);
10986   W (ret);
10987   return ret;
10988 }
10989
10990 static int
10991 api_add_node_next (vat_main_t * vam)
10992 {
10993   unformat_input_t *i = vam->input;
10994   vl_api_add_node_next_t *mp;
10995   u8 *name = 0;
10996   u8 *next = 0;
10997   int ret;
10998
10999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11000     {
11001       if (unformat (i, "node %s", &name))
11002         ;
11003       else if (unformat (i, "next %s", &next))
11004         ;
11005       else
11006         break;
11007     }
11008   if (name == 0)
11009     {
11010       errmsg ("node name required");
11011       return -99;
11012     }
11013   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11014     {
11015       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11016       return -99;
11017     }
11018   if (next == 0)
11019     {
11020       errmsg ("next node required");
11021       return -99;
11022     }
11023   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11024     {
11025       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11026       return -99;
11027     }
11028
11029   M (ADD_NODE_NEXT, mp);
11030   clib_memcpy (mp->node_name, name, vec_len (name));
11031   clib_memcpy (mp->next_name, next, vec_len (next));
11032   vec_free (name);
11033   vec_free (next);
11034
11035   S (mp);
11036   W (ret);
11037   return ret;
11038 }
11039
11040 static int
11041 api_l2tpv3_create_tunnel (vat_main_t * vam)
11042 {
11043   unformat_input_t *i = vam->input;
11044   ip6_address_t client_address, our_address;
11045   int client_address_set = 0;
11046   int our_address_set = 0;
11047   u32 local_session_id = 0;
11048   u32 remote_session_id = 0;
11049   u64 local_cookie = 0;
11050   u64 remote_cookie = 0;
11051   u8 l2_sublayer_present = 0;
11052   vl_api_l2tpv3_create_tunnel_t *mp;
11053   int ret;
11054
11055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11056     {
11057       if (unformat (i, "client_address %U", unformat_ip6_address,
11058                     &client_address))
11059         client_address_set = 1;
11060       else if (unformat (i, "our_address %U", unformat_ip6_address,
11061                          &our_address))
11062         our_address_set = 1;
11063       else if (unformat (i, "local_session_id %d", &local_session_id))
11064         ;
11065       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11066         ;
11067       else if (unformat (i, "local_cookie %lld", &local_cookie))
11068         ;
11069       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11070         ;
11071       else if (unformat (i, "l2-sublayer-present"))
11072         l2_sublayer_present = 1;
11073       else
11074         break;
11075     }
11076
11077   if (client_address_set == 0)
11078     {
11079       errmsg ("client_address required");
11080       return -99;
11081     }
11082
11083   if (our_address_set == 0)
11084     {
11085       errmsg ("our_address required");
11086       return -99;
11087     }
11088
11089   M (L2TPV3_CREATE_TUNNEL, mp);
11090
11091   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11092                sizeof (ip6_address_t));
11093
11094   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11095                sizeof (ip6_address_t));
11096
11097   mp->local_session_id = ntohl (local_session_id);
11098   mp->remote_session_id = ntohl (remote_session_id);
11099   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11100   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11101   mp->l2_sublayer_present = l2_sublayer_present;
11102
11103   S (mp);
11104   W (ret);
11105   return ret;
11106 }
11107
11108 static int
11109 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   u32 sw_if_index;
11113   u8 sw_if_index_set = 0;
11114   u64 new_local_cookie = 0;
11115   u64 new_remote_cookie = 0;
11116   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11117   int ret;
11118
11119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11122         sw_if_index_set = 1;
11123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11126         ;
11127       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11128         ;
11129       else
11130         break;
11131     }
11132
11133   if (sw_if_index_set == 0)
11134     {
11135       errmsg ("missing interface name or sw_if_index");
11136       return -99;
11137     }
11138
11139   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11140
11141   mp->sw_if_index = ntohl (sw_if_index);
11142   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11143   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11144
11145   S (mp);
11146   W (ret);
11147   return ret;
11148 }
11149
11150 static int
11151 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11152 {
11153   unformat_input_t *i = vam->input;
11154   vl_api_l2tpv3_interface_enable_disable_t *mp;
11155   u32 sw_if_index;
11156   u8 sw_if_index_set = 0;
11157   u8 enable_disable = 1;
11158   int ret;
11159
11160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11161     {
11162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11163         sw_if_index_set = 1;
11164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11165         sw_if_index_set = 1;
11166       else if (unformat (i, "enable"))
11167         enable_disable = 1;
11168       else if (unformat (i, "disable"))
11169         enable_disable = 0;
11170       else
11171         break;
11172     }
11173
11174   if (sw_if_index_set == 0)
11175     {
11176       errmsg ("missing interface name or sw_if_index");
11177       return -99;
11178     }
11179
11180   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11181
11182   mp->sw_if_index = ntohl (sw_if_index);
11183   mp->enable_disable = enable_disable;
11184
11185   S (mp);
11186   W (ret);
11187   return ret;
11188 }
11189
11190 static int
11191 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11192 {
11193   unformat_input_t *i = vam->input;
11194   vl_api_l2tpv3_set_lookup_key_t *mp;
11195   u8 key = ~0;
11196   int ret;
11197
11198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11199     {
11200       if (unformat (i, "lookup_v6_src"))
11201         key = L2T_LOOKUP_SRC_ADDRESS;
11202       else if (unformat (i, "lookup_v6_dst"))
11203         key = L2T_LOOKUP_DST_ADDRESS;
11204       else if (unformat (i, "lookup_session_id"))
11205         key = L2T_LOOKUP_SESSION_ID;
11206       else
11207         break;
11208     }
11209
11210   if (key == (u8) ~ 0)
11211     {
11212       errmsg ("l2tp session lookup key unset");
11213       return -99;
11214     }
11215
11216   M (L2TPV3_SET_LOOKUP_KEY, mp);
11217
11218   mp->key = key;
11219
11220   S (mp);
11221   W (ret);
11222   return ret;
11223 }
11224
11225 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11226   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11227 {
11228   vat_main_t *vam = &vat_main;
11229
11230   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11231          format_ip6_address, mp->our_address,
11232          format_ip6_address, mp->client_address,
11233          clib_net_to_host_u32 (mp->sw_if_index));
11234
11235   print (vam->ofp,
11236          "   local cookies %016llx %016llx remote cookie %016llx",
11237          clib_net_to_host_u64 (mp->local_cookie[0]),
11238          clib_net_to_host_u64 (mp->local_cookie[1]),
11239          clib_net_to_host_u64 (mp->remote_cookie));
11240
11241   print (vam->ofp, "   local session-id %d remote session-id %d",
11242          clib_net_to_host_u32 (mp->local_session_id),
11243          clib_net_to_host_u32 (mp->remote_session_id));
11244
11245   print (vam->ofp, "   l2 specific sublayer %s\n",
11246          mp->l2_sublayer_present ? "preset" : "absent");
11247
11248 }
11249
11250 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11251   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11252 {
11253   vat_main_t *vam = &vat_main;
11254   vat_json_node_t *node = NULL;
11255   struct in6_addr addr;
11256
11257   if (VAT_JSON_ARRAY != vam->json_tree.type)
11258     {
11259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11260       vat_json_init_array (&vam->json_tree);
11261     }
11262   node = vat_json_array_add (&vam->json_tree);
11263
11264   vat_json_init_object (node);
11265
11266   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11267   vat_json_object_add_ip6 (node, "our_address", addr);
11268   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11269   vat_json_object_add_ip6 (node, "client_address", addr);
11270
11271   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11272   vat_json_init_array (lc);
11273   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11274   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11275   vat_json_object_add_uint (node, "remote_cookie",
11276                             clib_net_to_host_u64 (mp->remote_cookie));
11277
11278   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11279   vat_json_object_add_uint (node, "local_session_id",
11280                             clib_net_to_host_u32 (mp->local_session_id));
11281   vat_json_object_add_uint (node, "remote_session_id",
11282                             clib_net_to_host_u32 (mp->remote_session_id));
11283   vat_json_object_add_string_copy (node, "l2_sublayer",
11284                                    mp->l2_sublayer_present ? (u8 *) "present"
11285                                    : (u8 *) "absent");
11286 }
11287
11288 static int
11289 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11290 {
11291   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11292   vl_api_control_ping_t *mp_ping;
11293   int ret;
11294
11295   /* Get list of l2tpv3-tunnel interfaces */
11296   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11297   S (mp);
11298
11299   /* Use a control ping for synchronization */
11300   MPING (CONTROL_PING, mp_ping);
11301   S (mp_ping);
11302
11303   W (ret);
11304   return ret;
11305 }
11306
11307
11308 static void vl_api_sw_interface_tap_v2_details_t_handler
11309   (vl_api_sw_interface_tap_v2_details_t * mp)
11310 {
11311   vat_main_t *vam = &vat_main;
11312
11313   u8 *ip4 =
11314     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11315             mp->host_ip4_prefix.len);
11316   u8 *ip6 =
11317     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11318             mp->host_ip6_prefix.len);
11319
11320   print (vam->ofp,
11321          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11322          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11323          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11324          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11325          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11326
11327   vec_free (ip4);
11328   vec_free (ip6);
11329 }
11330
11331 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11332   (vl_api_sw_interface_tap_v2_details_t * mp)
11333 {
11334   vat_main_t *vam = &vat_main;
11335   vat_json_node_t *node = NULL;
11336
11337   if (VAT_JSON_ARRAY != vam->json_tree.type)
11338     {
11339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11340       vat_json_init_array (&vam->json_tree);
11341     }
11342   node = vat_json_array_add (&vam->json_tree);
11343
11344   vat_json_init_object (node);
11345   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11347   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11348   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11349   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11350   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11351   vat_json_object_add_string_copy (node, "host_mac_addr",
11352                                    format (0, "%U", format_ethernet_address,
11353                                            &mp->host_mac_addr));
11354   vat_json_object_add_string_copy (node, "host_namespace",
11355                                    mp->host_namespace);
11356   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11357   vat_json_object_add_string_copy (node, "host_ip4_addr",
11358                                    format (0, "%U/%d", format_ip4_address,
11359                                            mp->host_ip4_prefix.address,
11360                                            mp->host_ip4_prefix.len));
11361   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11362                                    format (0, "%U/%d", format_ip6_address,
11363                                            mp->host_ip6_prefix.address,
11364                                            mp->host_ip6_prefix.len));
11365
11366 }
11367
11368 static int
11369 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11370 {
11371   vl_api_sw_interface_tap_v2_dump_t *mp;
11372   vl_api_control_ping_t *mp_ping;
11373   int ret;
11374
11375   print (vam->ofp,
11376          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11377          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11378          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11379          "host_ip6_addr");
11380
11381   /* Get list of tap interfaces */
11382   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11383   S (mp);
11384
11385   /* Use a control ping for synchronization */
11386   MPING (CONTROL_PING, mp_ping);
11387   S (mp_ping);
11388
11389   W (ret);
11390   return ret;
11391 }
11392
11393 static void vl_api_sw_interface_virtio_pci_details_t_handler
11394   (vl_api_sw_interface_virtio_pci_details_t * mp)
11395 {
11396   vat_main_t *vam = &vat_main;
11397
11398   typedef union
11399   {
11400     struct
11401     {
11402       u16 domain;
11403       u8 bus;
11404       u8 slot:5;
11405       u8 function:3;
11406     };
11407     u32 as_u32;
11408   } pci_addr_t;
11409   pci_addr_t addr;
11410
11411   addr.domain = ntohs (mp->pci_addr.domain);
11412   addr.bus = mp->pci_addr.bus;
11413   addr.slot = mp->pci_addr.slot;
11414   addr.function = mp->pci_addr.function;
11415
11416   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11417                          addr.slot, addr.function);
11418
11419   print (vam->ofp,
11420          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11421          pci_addr, ntohl (mp->sw_if_index),
11422          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11423          format_ethernet_address, mp->mac_addr,
11424          clib_net_to_host_u64 (mp->features));
11425   vec_free (pci_addr);
11426 }
11427
11428 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11429   (vl_api_sw_interface_virtio_pci_details_t * mp)
11430 {
11431   vat_main_t *vam = &vat_main;
11432   vat_json_node_t *node = NULL;
11433   vlib_pci_addr_t pci_addr;
11434
11435   if (VAT_JSON_ARRAY != vam->json_tree.type)
11436     {
11437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11438       vat_json_init_array (&vam->json_tree);
11439     }
11440   node = vat_json_array_add (&vam->json_tree);
11441
11442   pci_addr.domain = ntohs (mp->pci_addr.domain);
11443   pci_addr.bus = mp->pci_addr.bus;
11444   pci_addr.slot = mp->pci_addr.slot;
11445   pci_addr.function = mp->pci_addr.function;
11446
11447   vat_json_init_object (node);
11448   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11449   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11450   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11451   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11452   vat_json_object_add_uint (node, "features",
11453                             clib_net_to_host_u64 (mp->features));
11454   vat_json_object_add_string_copy (node, "mac_addr",
11455                                    format (0, "%U", format_ethernet_address,
11456                                            &mp->mac_addr));
11457 }
11458
11459 static int
11460 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11461 {
11462   vl_api_sw_interface_virtio_pci_dump_t *mp;
11463   vl_api_control_ping_t *mp_ping;
11464   int ret;
11465
11466   print (vam->ofp,
11467          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11468          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11469          "mac_addr", "features");
11470
11471   /* Get list of tap interfaces */
11472   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11473   S (mp);
11474
11475   /* Use a control ping for synchronization */
11476   MPING (CONTROL_PING, mp_ping);
11477   S (mp_ping);
11478
11479   W (ret);
11480   return ret;
11481 }
11482
11483 static int
11484 api_vxlan_offload_rx (vat_main_t * vam)
11485 {
11486   unformat_input_t *line_input = vam->input;
11487   vl_api_vxlan_offload_rx_t *mp;
11488   u32 hw_if_index = ~0, rx_if_index = ~0;
11489   u8 is_add = 1;
11490   int ret;
11491
11492   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11493     {
11494       if (unformat (line_input, "del"))
11495         is_add = 0;
11496       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11497                          &hw_if_index))
11498         ;
11499       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11500         ;
11501       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11502                          &rx_if_index))
11503         ;
11504       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11505         ;
11506       else
11507         {
11508           errmsg ("parse error '%U'", format_unformat_error, line_input);
11509           return -99;
11510         }
11511     }
11512
11513   if (hw_if_index == ~0)
11514     {
11515       errmsg ("no hw interface");
11516       return -99;
11517     }
11518
11519   if (rx_if_index == ~0)
11520     {
11521       errmsg ("no rx tunnel");
11522       return -99;
11523     }
11524
11525   M (VXLAN_OFFLOAD_RX, mp);
11526
11527   mp->hw_if_index = ntohl (hw_if_index);
11528   mp->sw_if_index = ntohl (rx_if_index);
11529   mp->enable = is_add;
11530
11531   S (mp);
11532   W (ret);
11533   return ret;
11534 }
11535
11536 static uword unformat_vxlan_decap_next
11537   (unformat_input_t * input, va_list * args)
11538 {
11539   u32 *result = va_arg (*args, u32 *);
11540   u32 tmp;
11541
11542   if (unformat (input, "l2"))
11543     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11544   else if (unformat (input, "%d", &tmp))
11545     *result = tmp;
11546   else
11547     return 0;
11548   return 1;
11549 }
11550
11551 static int
11552 api_vxlan_add_del_tunnel (vat_main_t * vam)
11553 {
11554   unformat_input_t *line_input = vam->input;
11555   vl_api_vxlan_add_del_tunnel_t *mp;
11556   ip46_address_t src, dst;
11557   u8 is_add = 1;
11558   u8 ipv4_set = 0, ipv6_set = 0;
11559   u8 src_set = 0;
11560   u8 dst_set = 0;
11561   u8 grp_set = 0;
11562   u32 instance = ~0;
11563   u32 mcast_sw_if_index = ~0;
11564   u32 encap_vrf_id = 0;
11565   u32 decap_next_index = ~0;
11566   u32 vni = 0;
11567   int ret;
11568
11569   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11570   clib_memset (&src, 0, sizeof src);
11571   clib_memset (&dst, 0, sizeof dst);
11572
11573   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11574     {
11575       if (unformat (line_input, "del"))
11576         is_add = 0;
11577       else if (unformat (line_input, "instance %d", &instance))
11578         ;
11579       else
11580         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11581         {
11582           ipv4_set = 1;
11583           src_set = 1;
11584         }
11585       else
11586         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11587         {
11588           ipv4_set = 1;
11589           dst_set = 1;
11590         }
11591       else
11592         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11593         {
11594           ipv6_set = 1;
11595           src_set = 1;
11596         }
11597       else
11598         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11599         {
11600           ipv6_set = 1;
11601           dst_set = 1;
11602         }
11603       else if (unformat (line_input, "group %U %U",
11604                          unformat_ip4_address, &dst.ip4,
11605                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11606         {
11607           grp_set = dst_set = 1;
11608           ipv4_set = 1;
11609         }
11610       else if (unformat (line_input, "group %U",
11611                          unformat_ip4_address, &dst.ip4))
11612         {
11613           grp_set = dst_set = 1;
11614           ipv4_set = 1;
11615         }
11616       else if (unformat (line_input, "group %U %U",
11617                          unformat_ip6_address, &dst.ip6,
11618                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11619         {
11620           grp_set = dst_set = 1;
11621           ipv6_set = 1;
11622         }
11623       else if (unformat (line_input, "group %U",
11624                          unformat_ip6_address, &dst.ip6))
11625         {
11626           grp_set = dst_set = 1;
11627           ipv6_set = 1;
11628         }
11629       else
11630         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11631         ;
11632       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11633         ;
11634       else if (unformat (line_input, "decap-next %U",
11635                          unformat_vxlan_decap_next, &decap_next_index))
11636         ;
11637       else if (unformat (line_input, "vni %d", &vni))
11638         ;
11639       else
11640         {
11641           errmsg ("parse error '%U'", format_unformat_error, line_input);
11642           return -99;
11643         }
11644     }
11645
11646   if (src_set == 0)
11647     {
11648       errmsg ("tunnel src address not specified");
11649       return -99;
11650     }
11651   if (dst_set == 0)
11652     {
11653       errmsg ("tunnel dst address not specified");
11654       return -99;
11655     }
11656
11657   if (grp_set && !ip46_address_is_multicast (&dst))
11658     {
11659       errmsg ("tunnel group address not multicast");
11660       return -99;
11661     }
11662   if (grp_set && mcast_sw_if_index == ~0)
11663     {
11664       errmsg ("tunnel nonexistent multicast device");
11665       return -99;
11666     }
11667   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11668     {
11669       errmsg ("tunnel dst address must be unicast");
11670       return -99;
11671     }
11672
11673
11674   if (ipv4_set && ipv6_set)
11675     {
11676       errmsg ("both IPv4 and IPv6 addresses specified");
11677       return -99;
11678     }
11679
11680   if ((vni == 0) || (vni >> 24))
11681     {
11682       errmsg ("vni not specified or out of range");
11683       return -99;
11684     }
11685
11686   M (VXLAN_ADD_DEL_TUNNEL, mp);
11687
11688   if (ipv6_set)
11689     {
11690       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11691       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11692     }
11693   else
11694     {
11695       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11696       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11697     }
11698
11699   mp->instance = htonl (instance);
11700   mp->encap_vrf_id = ntohl (encap_vrf_id);
11701   mp->decap_next_index = ntohl (decap_next_index);
11702   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11703   mp->vni = ntohl (vni);
11704   mp->is_add = is_add;
11705   mp->is_ipv6 = ipv6_set;
11706
11707   S (mp);
11708   W (ret);
11709   return ret;
11710 }
11711
11712 static void vl_api_vxlan_tunnel_details_t_handler
11713   (vl_api_vxlan_tunnel_details_t * mp)
11714 {
11715   vat_main_t *vam = &vat_main;
11716   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11717   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11718
11719   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11720          ntohl (mp->sw_if_index),
11721          ntohl (mp->instance),
11722          format_ip46_address, &src, IP46_TYPE_ANY,
11723          format_ip46_address, &dst, IP46_TYPE_ANY,
11724          ntohl (mp->encap_vrf_id),
11725          ntohl (mp->decap_next_index), ntohl (mp->vni),
11726          ntohl (mp->mcast_sw_if_index));
11727 }
11728
11729 static void vl_api_vxlan_tunnel_details_t_handler_json
11730   (vl_api_vxlan_tunnel_details_t * mp)
11731 {
11732   vat_main_t *vam = &vat_main;
11733   vat_json_node_t *node = NULL;
11734
11735   if (VAT_JSON_ARRAY != vam->json_tree.type)
11736     {
11737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11738       vat_json_init_array (&vam->json_tree);
11739     }
11740   node = vat_json_array_add (&vam->json_tree);
11741
11742   vat_json_init_object (node);
11743   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11744
11745   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11746
11747   if (mp->is_ipv6)
11748     {
11749       struct in6_addr ip6;
11750
11751       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11752       vat_json_object_add_ip6 (node, "src_address", ip6);
11753       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11754       vat_json_object_add_ip6 (node, "dst_address", ip6);
11755     }
11756   else
11757     {
11758       struct in_addr ip4;
11759
11760       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11761       vat_json_object_add_ip4 (node, "src_address", ip4);
11762       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11763       vat_json_object_add_ip4 (node, "dst_address", ip4);
11764     }
11765   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11766   vat_json_object_add_uint (node, "decap_next_index",
11767                             ntohl (mp->decap_next_index));
11768   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11769   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11770   vat_json_object_add_uint (node, "mcast_sw_if_index",
11771                             ntohl (mp->mcast_sw_if_index));
11772 }
11773
11774 static int
11775 api_vxlan_tunnel_dump (vat_main_t * vam)
11776 {
11777   unformat_input_t *i = vam->input;
11778   vl_api_vxlan_tunnel_dump_t *mp;
11779   vl_api_control_ping_t *mp_ping;
11780   u32 sw_if_index;
11781   u8 sw_if_index_set = 0;
11782   int ret;
11783
11784   /* Parse args required to build the message */
11785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11786     {
11787       if (unformat (i, "sw_if_index %d", &sw_if_index))
11788         sw_if_index_set = 1;
11789       else
11790         break;
11791     }
11792
11793   if (sw_if_index_set == 0)
11794     {
11795       sw_if_index = ~0;
11796     }
11797
11798   if (!vam->json_output)
11799     {
11800       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11801              "sw_if_index", "instance", "src_address", "dst_address",
11802              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11803     }
11804
11805   /* Get list of vxlan-tunnel interfaces */
11806   M (VXLAN_TUNNEL_DUMP, mp);
11807
11808   mp->sw_if_index = htonl (sw_if_index);
11809
11810   S (mp);
11811
11812   /* Use a control ping for synchronization */
11813   MPING (CONTROL_PING, mp_ping);
11814   S (mp_ping);
11815
11816   W (ret);
11817   return ret;
11818 }
11819
11820 static uword unformat_geneve_decap_next
11821   (unformat_input_t * input, va_list * args)
11822 {
11823   u32 *result = va_arg (*args, u32 *);
11824   u32 tmp;
11825
11826   if (unformat (input, "l2"))
11827     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11828   else if (unformat (input, "%d", &tmp))
11829     *result = tmp;
11830   else
11831     return 0;
11832   return 1;
11833 }
11834
11835 static int
11836 api_geneve_add_del_tunnel (vat_main_t * vam)
11837 {
11838   unformat_input_t *line_input = vam->input;
11839   vl_api_geneve_add_del_tunnel_t *mp;
11840   ip46_address_t src, dst;
11841   u8 is_add = 1;
11842   u8 ipv4_set = 0, ipv6_set = 0;
11843   u8 src_set = 0;
11844   u8 dst_set = 0;
11845   u8 grp_set = 0;
11846   u32 mcast_sw_if_index = ~0;
11847   u32 encap_vrf_id = 0;
11848   u32 decap_next_index = ~0;
11849   u32 vni = 0;
11850   int ret;
11851
11852   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11853   clib_memset (&src, 0, sizeof src);
11854   clib_memset (&dst, 0, sizeof dst);
11855
11856   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11857     {
11858       if (unformat (line_input, "del"))
11859         is_add = 0;
11860       else
11861         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11862         {
11863           ipv4_set = 1;
11864           src_set = 1;
11865         }
11866       else
11867         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11868         {
11869           ipv4_set = 1;
11870           dst_set = 1;
11871         }
11872       else
11873         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11874         {
11875           ipv6_set = 1;
11876           src_set = 1;
11877         }
11878       else
11879         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11880         {
11881           ipv6_set = 1;
11882           dst_set = 1;
11883         }
11884       else if (unformat (line_input, "group %U %U",
11885                          unformat_ip4_address, &dst.ip4,
11886                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11887         {
11888           grp_set = dst_set = 1;
11889           ipv4_set = 1;
11890         }
11891       else if (unformat (line_input, "group %U",
11892                          unformat_ip4_address, &dst.ip4))
11893         {
11894           grp_set = dst_set = 1;
11895           ipv4_set = 1;
11896         }
11897       else if (unformat (line_input, "group %U %U",
11898                          unformat_ip6_address, &dst.ip6,
11899                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11900         {
11901           grp_set = dst_set = 1;
11902           ipv6_set = 1;
11903         }
11904       else if (unformat (line_input, "group %U",
11905                          unformat_ip6_address, &dst.ip6))
11906         {
11907           grp_set = dst_set = 1;
11908           ipv6_set = 1;
11909         }
11910       else
11911         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11912         ;
11913       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11914         ;
11915       else if (unformat (line_input, "decap-next %U",
11916                          unformat_geneve_decap_next, &decap_next_index))
11917         ;
11918       else if (unformat (line_input, "vni %d", &vni))
11919         ;
11920       else
11921         {
11922           errmsg ("parse error '%U'", format_unformat_error, line_input);
11923           return -99;
11924         }
11925     }
11926
11927   if (src_set == 0)
11928     {
11929       errmsg ("tunnel src address not specified");
11930       return -99;
11931     }
11932   if (dst_set == 0)
11933     {
11934       errmsg ("tunnel dst address not specified");
11935       return -99;
11936     }
11937
11938   if (grp_set && !ip46_address_is_multicast (&dst))
11939     {
11940       errmsg ("tunnel group address not multicast");
11941       return -99;
11942     }
11943   if (grp_set && mcast_sw_if_index == ~0)
11944     {
11945       errmsg ("tunnel nonexistent multicast device");
11946       return -99;
11947     }
11948   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11949     {
11950       errmsg ("tunnel dst address must be unicast");
11951       return -99;
11952     }
11953
11954
11955   if (ipv4_set && ipv6_set)
11956     {
11957       errmsg ("both IPv4 and IPv6 addresses specified");
11958       return -99;
11959     }
11960
11961   if ((vni == 0) || (vni >> 24))
11962     {
11963       errmsg ("vni not specified or out of range");
11964       return -99;
11965     }
11966
11967   M (GENEVE_ADD_DEL_TUNNEL, mp);
11968
11969   if (ipv6_set)
11970     {
11971       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11972       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11973     }
11974   else
11975     {
11976       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11977       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11978     }
11979   mp->encap_vrf_id = ntohl (encap_vrf_id);
11980   mp->decap_next_index = ntohl (decap_next_index);
11981   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11982   mp->vni = ntohl (vni);
11983   mp->is_add = is_add;
11984
11985   S (mp);
11986   W (ret);
11987   return ret;
11988 }
11989
11990 static void vl_api_geneve_tunnel_details_t_handler
11991   (vl_api_geneve_tunnel_details_t * mp)
11992 {
11993   vat_main_t *vam = &vat_main;
11994   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
11995   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
11996
11997   if (mp->src_address.af == ADDRESS_IP6)
11998     {
11999       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12000       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12001     }
12002   else
12003     {
12004       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12005       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12006     }
12007
12008   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12009          ntohl (mp->sw_if_index),
12010          format_ip46_address, &src, IP46_TYPE_ANY,
12011          format_ip46_address, &dst, IP46_TYPE_ANY,
12012          ntohl (mp->encap_vrf_id),
12013          ntohl (mp->decap_next_index), ntohl (mp->vni),
12014          ntohl (mp->mcast_sw_if_index));
12015 }
12016
12017 static void vl_api_geneve_tunnel_details_t_handler_json
12018   (vl_api_geneve_tunnel_details_t * mp)
12019 {
12020   vat_main_t *vam = &vat_main;
12021   vat_json_node_t *node = NULL;
12022   bool is_ipv6;
12023
12024   if (VAT_JSON_ARRAY != vam->json_tree.type)
12025     {
12026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12027       vat_json_init_array (&vam->json_tree);
12028     }
12029   node = vat_json_array_add (&vam->json_tree);
12030
12031   vat_json_init_object (node);
12032   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12033   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12034   if (is_ipv6)
12035     {
12036       struct in6_addr ip6;
12037
12038       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12039       vat_json_object_add_ip6 (node, "src_address", ip6);
12040       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12041       vat_json_object_add_ip6 (node, "dst_address", ip6);
12042     }
12043   else
12044     {
12045       struct in_addr ip4;
12046
12047       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12048       vat_json_object_add_ip4 (node, "src_address", ip4);
12049       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12050       vat_json_object_add_ip4 (node, "dst_address", ip4);
12051     }
12052   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12053   vat_json_object_add_uint (node, "decap_next_index",
12054                             ntohl (mp->decap_next_index));
12055   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12056   vat_json_object_add_uint (node, "mcast_sw_if_index",
12057                             ntohl (mp->mcast_sw_if_index));
12058 }
12059
12060 static int
12061 api_geneve_tunnel_dump (vat_main_t * vam)
12062 {
12063   unformat_input_t *i = vam->input;
12064   vl_api_geneve_tunnel_dump_t *mp;
12065   vl_api_control_ping_t *mp_ping;
12066   u32 sw_if_index;
12067   u8 sw_if_index_set = 0;
12068   int ret;
12069
12070   /* Parse args required to build the message */
12071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12072     {
12073       if (unformat (i, "sw_if_index %d", &sw_if_index))
12074         sw_if_index_set = 1;
12075       else
12076         break;
12077     }
12078
12079   if (sw_if_index_set == 0)
12080     {
12081       sw_if_index = ~0;
12082     }
12083
12084   if (!vam->json_output)
12085     {
12086       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12087              "sw_if_index", "local_address", "remote_address",
12088              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12089     }
12090
12091   /* Get list of geneve-tunnel interfaces */
12092   M (GENEVE_TUNNEL_DUMP, mp);
12093
12094   mp->sw_if_index = htonl (sw_if_index);
12095
12096   S (mp);
12097
12098   /* Use a control ping for synchronization */
12099   M (CONTROL_PING, mp_ping);
12100   S (mp_ping);
12101
12102   W (ret);
12103   return ret;
12104 }
12105
12106 static int
12107 api_gre_tunnel_add_del (vat_main_t * vam)
12108 {
12109   unformat_input_t *line_input = vam->input;
12110   vl_api_address_t src = { }, dst =
12111   {
12112   };
12113   vl_api_gre_tunnel_add_del_t *mp;
12114   vl_api_gre_tunnel_type_t t_type;
12115   u8 is_add = 1;
12116   u8 src_set = 0;
12117   u8 dst_set = 0;
12118   u32 outer_table_id = 0;
12119   u32 session_id = 0;
12120   u32 instance = ~0;
12121   int ret;
12122
12123   t_type = GRE_API_TUNNEL_TYPE_L3;
12124
12125   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12126     {
12127       if (unformat (line_input, "del"))
12128         is_add = 0;
12129       else if (unformat (line_input, "instance %d", &instance))
12130         ;
12131       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12132         {
12133           src_set = 1;
12134         }
12135       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12136         {
12137           dst_set = 1;
12138         }
12139       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12140         ;
12141       else if (unformat (line_input, "teb"))
12142         t_type = GRE_API_TUNNEL_TYPE_TEB;
12143       else if (unformat (line_input, "erspan %d", &session_id))
12144         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12145       else
12146         {
12147           errmsg ("parse error '%U'", format_unformat_error, line_input);
12148           return -99;
12149         }
12150     }
12151
12152   if (src_set == 0)
12153     {
12154       errmsg ("tunnel src address not specified");
12155       return -99;
12156     }
12157   if (dst_set == 0)
12158     {
12159       errmsg ("tunnel dst address not specified");
12160       return -99;
12161     }
12162
12163   M (GRE_TUNNEL_ADD_DEL, mp);
12164
12165   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12166   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12167
12168   mp->tunnel.instance = htonl (instance);
12169   mp->tunnel.outer_table_id = htonl (outer_table_id);
12170   mp->is_add = is_add;
12171   mp->tunnel.session_id = htons ((u16) session_id);
12172   mp->tunnel.type = htonl (t_type);
12173
12174   S (mp);
12175   W (ret);
12176   return ret;
12177 }
12178
12179 static void vl_api_gre_tunnel_details_t_handler
12180   (vl_api_gre_tunnel_details_t * mp)
12181 {
12182   vat_main_t *vam = &vat_main;
12183
12184   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12185          ntohl (mp->tunnel.sw_if_index),
12186          ntohl (mp->tunnel.instance),
12187          format_vl_api_address, &mp->tunnel.src,
12188          format_vl_api_address, &mp->tunnel.dst,
12189          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12190          ntohl (mp->tunnel.session_id));
12191 }
12192
12193 static void vl_api_gre_tunnel_details_t_handler_json
12194   (vl_api_gre_tunnel_details_t * mp)
12195 {
12196   vat_main_t *vam = &vat_main;
12197   vat_json_node_t *node = NULL;
12198
12199   if (VAT_JSON_ARRAY != vam->json_tree.type)
12200     {
12201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12202       vat_json_init_array (&vam->json_tree);
12203     }
12204   node = vat_json_array_add (&vam->json_tree);
12205
12206   vat_json_init_object (node);
12207   vat_json_object_add_uint (node, "sw_if_index",
12208                             ntohl (mp->tunnel.sw_if_index));
12209   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12210
12211   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12212   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12213   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12214   vat_json_object_add_uint (node, "outer_table_id",
12215                             ntohl (mp->tunnel.outer_table_id));
12216   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12217 }
12218
12219 static int
12220 api_gre_tunnel_dump (vat_main_t * vam)
12221 {
12222   unformat_input_t *i = vam->input;
12223   vl_api_gre_tunnel_dump_t *mp;
12224   vl_api_control_ping_t *mp_ping;
12225   u32 sw_if_index;
12226   u8 sw_if_index_set = 0;
12227   int ret;
12228
12229   /* Parse args required to build the message */
12230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12231     {
12232       if (unformat (i, "sw_if_index %d", &sw_if_index))
12233         sw_if_index_set = 1;
12234       else
12235         break;
12236     }
12237
12238   if (sw_if_index_set == 0)
12239     {
12240       sw_if_index = ~0;
12241     }
12242
12243   if (!vam->json_output)
12244     {
12245       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12246              "sw_if_index", "instance", "src_address", "dst_address",
12247              "tunnel_type", "outer_fib_id", "session_id");
12248     }
12249
12250   /* Get list of gre-tunnel interfaces */
12251   M (GRE_TUNNEL_DUMP, mp);
12252
12253   mp->sw_if_index = htonl (sw_if_index);
12254
12255   S (mp);
12256
12257   /* Use a control ping for synchronization */
12258   MPING (CONTROL_PING, mp_ping);
12259   S (mp_ping);
12260
12261   W (ret);
12262   return ret;
12263 }
12264
12265 static int
12266 api_l2_fib_clear_table (vat_main_t * vam)
12267 {
12268 //  unformat_input_t * i = vam->input;
12269   vl_api_l2_fib_clear_table_t *mp;
12270   int ret;
12271
12272   M (L2_FIB_CLEAR_TABLE, mp);
12273
12274   S (mp);
12275   W (ret);
12276   return ret;
12277 }
12278
12279 static int
12280 api_l2_interface_efp_filter (vat_main_t * vam)
12281 {
12282   unformat_input_t *i = vam->input;
12283   vl_api_l2_interface_efp_filter_t *mp;
12284   u32 sw_if_index;
12285   u8 enable = 1;
12286   u8 sw_if_index_set = 0;
12287   int ret;
12288
12289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12290     {
12291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12292         sw_if_index_set = 1;
12293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12294         sw_if_index_set = 1;
12295       else if (unformat (i, "enable"))
12296         enable = 1;
12297       else if (unformat (i, "disable"))
12298         enable = 0;
12299       else
12300         {
12301           clib_warning ("parse error '%U'", format_unformat_error, i);
12302           return -99;
12303         }
12304     }
12305
12306   if (sw_if_index_set == 0)
12307     {
12308       errmsg ("missing sw_if_index");
12309       return -99;
12310     }
12311
12312   M (L2_INTERFACE_EFP_FILTER, mp);
12313
12314   mp->sw_if_index = ntohl (sw_if_index);
12315   mp->enable_disable = enable;
12316
12317   S (mp);
12318   W (ret);
12319   return ret;
12320 }
12321
12322 #define foreach_vtr_op                          \
12323 _("disable",  L2_VTR_DISABLED)                  \
12324 _("push-1",  L2_VTR_PUSH_1)                     \
12325 _("push-2",  L2_VTR_PUSH_2)                     \
12326 _("pop-1",  L2_VTR_POP_1)                       \
12327 _("pop-2",  L2_VTR_POP_2)                       \
12328 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12329 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12330 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12331 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12332
12333 static int
12334 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12335 {
12336   unformat_input_t *i = vam->input;
12337   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12338   u32 sw_if_index;
12339   u8 sw_if_index_set = 0;
12340   u8 vtr_op_set = 0;
12341   u32 vtr_op = 0;
12342   u32 push_dot1q = 1;
12343   u32 tag1 = ~0;
12344   u32 tag2 = ~0;
12345   int ret;
12346
12347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12348     {
12349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12350         sw_if_index_set = 1;
12351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12352         sw_if_index_set = 1;
12353       else if (unformat (i, "vtr_op %d", &vtr_op))
12354         vtr_op_set = 1;
12355 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12356       foreach_vtr_op
12357 #undef _
12358         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12359         ;
12360       else if (unformat (i, "tag1 %d", &tag1))
12361         ;
12362       else if (unformat (i, "tag2 %d", &tag2))
12363         ;
12364       else
12365         {
12366           clib_warning ("parse error '%U'", format_unformat_error, i);
12367           return -99;
12368         }
12369     }
12370
12371   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12372     {
12373       errmsg ("missing vtr operation or sw_if_index");
12374       return -99;
12375     }
12376
12377   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12378   mp->sw_if_index = ntohl (sw_if_index);
12379   mp->vtr_op = ntohl (vtr_op);
12380   mp->push_dot1q = ntohl (push_dot1q);
12381   mp->tag1 = ntohl (tag1);
12382   mp->tag2 = ntohl (tag2);
12383
12384   S (mp);
12385   W (ret);
12386   return ret;
12387 }
12388
12389 static int
12390 api_create_vhost_user_if (vat_main_t * vam)
12391 {
12392   unformat_input_t *i = vam->input;
12393   vl_api_create_vhost_user_if_t *mp;
12394   u8 *file_name;
12395   u8 is_server = 0;
12396   u8 file_name_set = 0;
12397   u32 custom_dev_instance = ~0;
12398   u8 hwaddr[6];
12399   u8 use_custom_mac = 0;
12400   u8 disable_mrg_rxbuf = 0;
12401   u8 disable_indirect_desc = 0;
12402   u8 *tag = 0;
12403   u8 enable_gso = 0;
12404   int ret;
12405
12406   /* Shut up coverity */
12407   clib_memset (hwaddr, 0, sizeof (hwaddr));
12408
12409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12410     {
12411       if (unformat (i, "socket %s", &file_name))
12412         {
12413           file_name_set = 1;
12414         }
12415       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12416         ;
12417       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12418         use_custom_mac = 1;
12419       else if (unformat (i, "server"))
12420         is_server = 1;
12421       else if (unformat (i, "disable_mrg_rxbuf"))
12422         disable_mrg_rxbuf = 1;
12423       else if (unformat (i, "disable_indirect_desc"))
12424         disable_indirect_desc = 1;
12425       else if (unformat (i, "gso"))
12426         enable_gso = 1;
12427       else if (unformat (i, "tag %s", &tag))
12428         ;
12429       else
12430         break;
12431     }
12432
12433   if (file_name_set == 0)
12434     {
12435       errmsg ("missing socket file name");
12436       return -99;
12437     }
12438
12439   if (vec_len (file_name) > 255)
12440     {
12441       errmsg ("socket file name too long");
12442       return -99;
12443     }
12444   vec_add1 (file_name, 0);
12445
12446   M (CREATE_VHOST_USER_IF, mp);
12447
12448   mp->is_server = is_server;
12449   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12450   mp->disable_indirect_desc = disable_indirect_desc;
12451   mp->enable_gso = enable_gso;
12452   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12453   vec_free (file_name);
12454   if (custom_dev_instance != ~0)
12455     {
12456       mp->renumber = 1;
12457       mp->custom_dev_instance = ntohl (custom_dev_instance);
12458     }
12459
12460   mp->use_custom_mac = use_custom_mac;
12461   clib_memcpy (mp->mac_address, hwaddr, 6);
12462   if (tag)
12463     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12464   vec_free (tag);
12465
12466   S (mp);
12467   W (ret);
12468   return ret;
12469 }
12470
12471 static int
12472 api_modify_vhost_user_if (vat_main_t * vam)
12473 {
12474   unformat_input_t *i = vam->input;
12475   vl_api_modify_vhost_user_if_t *mp;
12476   u8 *file_name;
12477   u8 is_server = 0;
12478   u8 file_name_set = 0;
12479   u32 custom_dev_instance = ~0;
12480   u8 sw_if_index_set = 0;
12481   u32 sw_if_index = (u32) ~ 0;
12482   u8 enable_gso = 0;
12483   int ret;
12484
12485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12488         sw_if_index_set = 1;
12489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12490         sw_if_index_set = 1;
12491       else if (unformat (i, "socket %s", &file_name))
12492         {
12493           file_name_set = 1;
12494         }
12495       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12496         ;
12497       else if (unformat (i, "server"))
12498         is_server = 1;
12499       else if (unformat (i, "gso"))
12500         enable_gso = 1;
12501       else
12502         break;
12503     }
12504
12505   if (sw_if_index_set == 0)
12506     {
12507       errmsg ("missing sw_if_index or interface name");
12508       return -99;
12509     }
12510
12511   if (file_name_set == 0)
12512     {
12513       errmsg ("missing socket file name");
12514       return -99;
12515     }
12516
12517   if (vec_len (file_name) > 255)
12518     {
12519       errmsg ("socket file name too long");
12520       return -99;
12521     }
12522   vec_add1 (file_name, 0);
12523
12524   M (MODIFY_VHOST_USER_IF, mp);
12525
12526   mp->sw_if_index = ntohl (sw_if_index);
12527   mp->is_server = is_server;
12528   mp->enable_gso = enable_gso;
12529   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12530   vec_free (file_name);
12531   if (custom_dev_instance != ~0)
12532     {
12533       mp->renumber = 1;
12534       mp->custom_dev_instance = ntohl (custom_dev_instance);
12535     }
12536
12537   S (mp);
12538   W (ret);
12539   return ret;
12540 }
12541
12542 static int
12543 api_delete_vhost_user_if (vat_main_t * vam)
12544 {
12545   unformat_input_t *i = vam->input;
12546   vl_api_delete_vhost_user_if_t *mp;
12547   u32 sw_if_index = ~0;
12548   u8 sw_if_index_set = 0;
12549   int ret;
12550
12551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12552     {
12553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12554         sw_if_index_set = 1;
12555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12556         sw_if_index_set = 1;
12557       else
12558         break;
12559     }
12560
12561   if (sw_if_index_set == 0)
12562     {
12563       errmsg ("missing sw_if_index or interface name");
12564       return -99;
12565     }
12566
12567
12568   M (DELETE_VHOST_USER_IF, mp);
12569
12570   mp->sw_if_index = ntohl (sw_if_index);
12571
12572   S (mp);
12573   W (ret);
12574   return ret;
12575 }
12576
12577 static void vl_api_sw_interface_vhost_user_details_t_handler
12578   (vl_api_sw_interface_vhost_user_details_t * mp)
12579 {
12580   vat_main_t *vam = &vat_main;
12581   u64 features;
12582
12583   features =
12584     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12585                                                     clib_net_to_host_u32
12586                                                     (mp->features_last_32) <<
12587                                                     32);
12588
12589   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12590          (char *) mp->interface_name,
12591          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12592          features, mp->is_server,
12593          ntohl (mp->num_regions), (char *) mp->sock_filename);
12594   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12595 }
12596
12597 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12598   (vl_api_sw_interface_vhost_user_details_t * mp)
12599 {
12600   vat_main_t *vam = &vat_main;
12601   vat_json_node_t *node = NULL;
12602
12603   if (VAT_JSON_ARRAY != vam->json_tree.type)
12604     {
12605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12606       vat_json_init_array (&vam->json_tree);
12607     }
12608   node = vat_json_array_add (&vam->json_tree);
12609
12610   vat_json_init_object (node);
12611   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12612   vat_json_object_add_string_copy (node, "interface_name",
12613                                    mp->interface_name);
12614   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12615                             ntohl (mp->virtio_net_hdr_sz));
12616   vat_json_object_add_uint (node, "features_first_32",
12617                             clib_net_to_host_u32 (mp->features_first_32));
12618   vat_json_object_add_uint (node, "features_last_32",
12619                             clib_net_to_host_u32 (mp->features_last_32));
12620   vat_json_object_add_uint (node, "is_server", mp->is_server);
12621   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12622   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12623   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12624 }
12625
12626 static int
12627 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12628 {
12629   vl_api_sw_interface_vhost_user_dump_t *mp;
12630   vl_api_control_ping_t *mp_ping;
12631   int ret;
12632   print (vam->ofp,
12633          "Interface name            idx hdr_sz features server regions filename");
12634
12635   /* Get list of vhost-user interfaces */
12636   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12637   mp->sw_if_index = ntohl (~0);
12638   S (mp);
12639
12640   /* Use a control ping for synchronization */
12641   MPING (CONTROL_PING, mp_ping);
12642   S (mp_ping);
12643
12644   W (ret);
12645   return ret;
12646 }
12647
12648 static int
12649 api_show_version (vat_main_t * vam)
12650 {
12651   vl_api_show_version_t *mp;
12652   int ret;
12653
12654   M (SHOW_VERSION, mp);
12655
12656   S (mp);
12657   W (ret);
12658   return ret;
12659 }
12660
12661
12662 static int
12663 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12664 {
12665   unformat_input_t *line_input = vam->input;
12666   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12667   ip4_address_t local4, remote4;
12668   ip6_address_t local6, remote6;
12669   u8 is_add = 1;
12670   u8 ipv4_set = 0, ipv6_set = 0;
12671   u8 local_set = 0;
12672   u8 remote_set = 0;
12673   u8 grp_set = 0;
12674   u32 mcast_sw_if_index = ~0;
12675   u32 encap_vrf_id = 0;
12676   u32 decap_vrf_id = 0;
12677   u8 protocol = ~0;
12678   u32 vni;
12679   u8 vni_set = 0;
12680   int ret;
12681
12682   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12683   clib_memset (&local4, 0, sizeof local4);
12684   clib_memset (&remote4, 0, sizeof remote4);
12685   clib_memset (&local6, 0, sizeof local6);
12686   clib_memset (&remote6, 0, sizeof remote6);
12687
12688   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (line_input, "del"))
12691         is_add = 0;
12692       else if (unformat (line_input, "local %U",
12693                          unformat_ip4_address, &local4))
12694         {
12695           local_set = 1;
12696           ipv4_set = 1;
12697         }
12698       else if (unformat (line_input, "remote %U",
12699                          unformat_ip4_address, &remote4))
12700         {
12701           remote_set = 1;
12702           ipv4_set = 1;
12703         }
12704       else if (unformat (line_input, "local %U",
12705                          unformat_ip6_address, &local6))
12706         {
12707           local_set = 1;
12708           ipv6_set = 1;
12709         }
12710       else if (unformat (line_input, "remote %U",
12711                          unformat_ip6_address, &remote6))
12712         {
12713           remote_set = 1;
12714           ipv6_set = 1;
12715         }
12716       else if (unformat (line_input, "group %U %U",
12717                          unformat_ip4_address, &remote4,
12718                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12719         {
12720           grp_set = remote_set = 1;
12721           ipv4_set = 1;
12722         }
12723       else if (unformat (line_input, "group %U",
12724                          unformat_ip4_address, &remote4))
12725         {
12726           grp_set = remote_set = 1;
12727           ipv4_set = 1;
12728         }
12729       else if (unformat (line_input, "group %U %U",
12730                          unformat_ip6_address, &remote6,
12731                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12732         {
12733           grp_set = remote_set = 1;
12734           ipv6_set = 1;
12735         }
12736       else if (unformat (line_input, "group %U",
12737                          unformat_ip6_address, &remote6))
12738         {
12739           grp_set = remote_set = 1;
12740           ipv6_set = 1;
12741         }
12742       else
12743         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12744         ;
12745       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12746         ;
12747       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12748         ;
12749       else if (unformat (line_input, "vni %d", &vni))
12750         vni_set = 1;
12751       else if (unformat (line_input, "next-ip4"))
12752         protocol = 1;
12753       else if (unformat (line_input, "next-ip6"))
12754         protocol = 2;
12755       else if (unformat (line_input, "next-ethernet"))
12756         protocol = 3;
12757       else if (unformat (line_input, "next-nsh"))
12758         protocol = 4;
12759       else
12760         {
12761           errmsg ("parse error '%U'", format_unformat_error, line_input);
12762           return -99;
12763         }
12764     }
12765
12766   if (local_set == 0)
12767     {
12768       errmsg ("tunnel local address not specified");
12769       return -99;
12770     }
12771   if (remote_set == 0)
12772     {
12773       errmsg ("tunnel remote address not specified");
12774       return -99;
12775     }
12776   if (grp_set && mcast_sw_if_index == ~0)
12777     {
12778       errmsg ("tunnel nonexistent multicast device");
12779       return -99;
12780     }
12781   if (ipv4_set && ipv6_set)
12782     {
12783       errmsg ("both IPv4 and IPv6 addresses specified");
12784       return -99;
12785     }
12786
12787   if (vni_set == 0)
12788     {
12789       errmsg ("vni not specified");
12790       return -99;
12791     }
12792
12793   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12794
12795
12796   if (ipv6_set)
12797     {
12798       clib_memcpy (&mp->local, &local6, sizeof (local6));
12799       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12800     }
12801   else
12802     {
12803       clib_memcpy (&mp->local, &local4, sizeof (local4));
12804       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12805     }
12806
12807   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12808   mp->encap_vrf_id = ntohl (encap_vrf_id);
12809   mp->decap_vrf_id = ntohl (decap_vrf_id);
12810   mp->protocol = protocol;
12811   mp->vni = ntohl (vni);
12812   mp->is_add = is_add;
12813   mp->is_ipv6 = ipv6_set;
12814
12815   S (mp);
12816   W (ret);
12817   return ret;
12818 }
12819
12820 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12821   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12822 {
12823   vat_main_t *vam = &vat_main;
12824   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12825   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12826
12827   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12828          ntohl (mp->sw_if_index),
12829          format_ip46_address, &local, IP46_TYPE_ANY,
12830          format_ip46_address, &remote, IP46_TYPE_ANY,
12831          ntohl (mp->vni), mp->protocol,
12832          ntohl (mp->mcast_sw_if_index),
12833          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12834 }
12835
12836
12837 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12838   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12839 {
12840   vat_main_t *vam = &vat_main;
12841   vat_json_node_t *node = NULL;
12842   struct in_addr ip4;
12843   struct in6_addr ip6;
12844
12845   if (VAT_JSON_ARRAY != vam->json_tree.type)
12846     {
12847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12848       vat_json_init_array (&vam->json_tree);
12849     }
12850   node = vat_json_array_add (&vam->json_tree);
12851
12852   vat_json_init_object (node);
12853   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12854   if (mp->is_ipv6)
12855     {
12856       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12857       vat_json_object_add_ip6 (node, "local", ip6);
12858       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12859       vat_json_object_add_ip6 (node, "remote", ip6);
12860     }
12861   else
12862     {
12863       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12864       vat_json_object_add_ip4 (node, "local", ip4);
12865       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12866       vat_json_object_add_ip4 (node, "remote", ip4);
12867     }
12868   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12869   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12870   vat_json_object_add_uint (node, "mcast_sw_if_index",
12871                             ntohl (mp->mcast_sw_if_index));
12872   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12873   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12874   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12875 }
12876
12877 static int
12878 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12879 {
12880   unformat_input_t *i = vam->input;
12881   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12882   vl_api_control_ping_t *mp_ping;
12883   u32 sw_if_index;
12884   u8 sw_if_index_set = 0;
12885   int ret;
12886
12887   /* Parse args required to build the message */
12888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12889     {
12890       if (unformat (i, "sw_if_index %d", &sw_if_index))
12891         sw_if_index_set = 1;
12892       else
12893         break;
12894     }
12895
12896   if (sw_if_index_set == 0)
12897     {
12898       sw_if_index = ~0;
12899     }
12900
12901   if (!vam->json_output)
12902     {
12903       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12904              "sw_if_index", "local", "remote", "vni",
12905              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12906     }
12907
12908   /* Get list of vxlan-tunnel interfaces */
12909   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12910
12911   mp->sw_if_index = htonl (sw_if_index);
12912
12913   S (mp);
12914
12915   /* Use a control ping for synchronization */
12916   MPING (CONTROL_PING, mp_ping);
12917   S (mp_ping);
12918
12919   W (ret);
12920   return ret;
12921 }
12922
12923 static void vl_api_l2_fib_table_details_t_handler
12924   (vl_api_l2_fib_table_details_t * mp)
12925 {
12926   vat_main_t *vam = &vat_main;
12927
12928   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12929          "       %d       %d     %d",
12930          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12931          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12932          mp->bvi_mac);
12933 }
12934
12935 static void vl_api_l2_fib_table_details_t_handler_json
12936   (vl_api_l2_fib_table_details_t * mp)
12937 {
12938   vat_main_t *vam = &vat_main;
12939   vat_json_node_t *node = NULL;
12940
12941   if (VAT_JSON_ARRAY != vam->json_tree.type)
12942     {
12943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12944       vat_json_init_array (&vam->json_tree);
12945     }
12946   node = vat_json_array_add (&vam->json_tree);
12947
12948   vat_json_init_object (node);
12949   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12950   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12951   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12952   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12953   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12954   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12955 }
12956
12957 static int
12958 api_l2_fib_table_dump (vat_main_t * vam)
12959 {
12960   unformat_input_t *i = vam->input;
12961   vl_api_l2_fib_table_dump_t *mp;
12962   vl_api_control_ping_t *mp_ping;
12963   u32 bd_id;
12964   u8 bd_id_set = 0;
12965   int ret;
12966
12967   /* Parse args required to build the message */
12968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12969     {
12970       if (unformat (i, "bd_id %d", &bd_id))
12971         bd_id_set = 1;
12972       else
12973         break;
12974     }
12975
12976   if (bd_id_set == 0)
12977     {
12978       errmsg ("missing bridge domain");
12979       return -99;
12980     }
12981
12982   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12983
12984   /* Get list of l2 fib entries */
12985   M (L2_FIB_TABLE_DUMP, mp);
12986
12987   mp->bd_id = ntohl (bd_id);
12988   S (mp);
12989
12990   /* Use a control ping for synchronization */
12991   MPING (CONTROL_PING, mp_ping);
12992   S (mp_ping);
12993
12994   W (ret);
12995   return ret;
12996 }
12997
12998
12999 static int
13000 api_interface_name_renumber (vat_main_t * vam)
13001 {
13002   unformat_input_t *line_input = vam->input;
13003   vl_api_interface_name_renumber_t *mp;
13004   u32 sw_if_index = ~0;
13005   u32 new_show_dev_instance = ~0;
13006   int ret;
13007
13008   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13009     {
13010       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13011                     &sw_if_index))
13012         ;
13013       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13014         ;
13015       else if (unformat (line_input, "new_show_dev_instance %d",
13016                          &new_show_dev_instance))
13017         ;
13018       else
13019         break;
13020     }
13021
13022   if (sw_if_index == ~0)
13023     {
13024       errmsg ("missing interface name or sw_if_index");
13025       return -99;
13026     }
13027
13028   if (new_show_dev_instance == ~0)
13029     {
13030       errmsg ("missing new_show_dev_instance");
13031       return -99;
13032     }
13033
13034   M (INTERFACE_NAME_RENUMBER, mp);
13035
13036   mp->sw_if_index = ntohl (sw_if_index);
13037   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13038
13039   S (mp);
13040   W (ret);
13041   return ret;
13042 }
13043
13044 static int
13045 api_want_l2_macs_events (vat_main_t * vam)
13046 {
13047   unformat_input_t *line_input = vam->input;
13048   vl_api_want_l2_macs_events_t *mp;
13049   u8 enable_disable = 1;
13050   u32 scan_delay = 0;
13051   u32 max_macs_in_event = 0;
13052   u32 learn_limit = 0;
13053   int ret;
13054
13055   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13056     {
13057       if (unformat (line_input, "learn-limit %d", &learn_limit))
13058         ;
13059       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13060         ;
13061       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13062         ;
13063       else if (unformat (line_input, "disable"))
13064         enable_disable = 0;
13065       else
13066         break;
13067     }
13068
13069   M (WANT_L2_MACS_EVENTS, mp);
13070   mp->enable_disable = enable_disable;
13071   mp->pid = htonl (getpid ());
13072   mp->learn_limit = htonl (learn_limit);
13073   mp->scan_delay = (u8) scan_delay;
13074   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13075   S (mp);
13076   W (ret);
13077   return ret;
13078 }
13079
13080 static int
13081 api_input_acl_set_interface (vat_main_t * vam)
13082 {
13083   unformat_input_t *i = vam->input;
13084   vl_api_input_acl_set_interface_t *mp;
13085   u32 sw_if_index;
13086   int sw_if_index_set;
13087   u32 ip4_table_index = ~0;
13088   u32 ip6_table_index = ~0;
13089   u32 l2_table_index = ~0;
13090   u8 is_add = 1;
13091   int ret;
13092
13093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13094     {
13095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13096         sw_if_index_set = 1;
13097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13098         sw_if_index_set = 1;
13099       else if (unformat (i, "del"))
13100         is_add = 0;
13101       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13102         ;
13103       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13104         ;
13105       else if (unformat (i, "l2-table %d", &l2_table_index))
13106         ;
13107       else
13108         {
13109           clib_warning ("parse error '%U'", format_unformat_error, i);
13110           return -99;
13111         }
13112     }
13113
13114   if (sw_if_index_set == 0)
13115     {
13116       errmsg ("missing interface name or sw_if_index");
13117       return -99;
13118     }
13119
13120   M (INPUT_ACL_SET_INTERFACE, mp);
13121
13122   mp->sw_if_index = ntohl (sw_if_index);
13123   mp->ip4_table_index = ntohl (ip4_table_index);
13124   mp->ip6_table_index = ntohl (ip6_table_index);
13125   mp->l2_table_index = ntohl (l2_table_index);
13126   mp->is_add = is_add;
13127
13128   S (mp);
13129   W (ret);
13130   return ret;
13131 }
13132
13133 static int
13134 api_output_acl_set_interface (vat_main_t * vam)
13135 {
13136   unformat_input_t *i = vam->input;
13137   vl_api_output_acl_set_interface_t *mp;
13138   u32 sw_if_index;
13139   int sw_if_index_set;
13140   u32 ip4_table_index = ~0;
13141   u32 ip6_table_index = ~0;
13142   u32 l2_table_index = ~0;
13143   u8 is_add = 1;
13144   int ret;
13145
13146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13147     {
13148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13149         sw_if_index_set = 1;
13150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13151         sw_if_index_set = 1;
13152       else if (unformat (i, "del"))
13153         is_add = 0;
13154       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13155         ;
13156       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13157         ;
13158       else if (unformat (i, "l2-table %d", &l2_table_index))
13159         ;
13160       else
13161         {
13162           clib_warning ("parse error '%U'", format_unformat_error, i);
13163           return -99;
13164         }
13165     }
13166
13167   if (sw_if_index_set == 0)
13168     {
13169       errmsg ("missing interface name or sw_if_index");
13170       return -99;
13171     }
13172
13173   M (OUTPUT_ACL_SET_INTERFACE, mp);
13174
13175   mp->sw_if_index = ntohl (sw_if_index);
13176   mp->ip4_table_index = ntohl (ip4_table_index);
13177   mp->ip6_table_index = ntohl (ip6_table_index);
13178   mp->l2_table_index = ntohl (l2_table_index);
13179   mp->is_add = is_add;
13180
13181   S (mp);
13182   W (ret);
13183   return ret;
13184 }
13185
13186 static int
13187 api_ip_address_dump (vat_main_t * vam)
13188 {
13189   unformat_input_t *i = vam->input;
13190   vl_api_ip_address_dump_t *mp;
13191   vl_api_control_ping_t *mp_ping;
13192   u32 sw_if_index = ~0;
13193   u8 sw_if_index_set = 0;
13194   u8 ipv4_set = 0;
13195   u8 ipv6_set = 0;
13196   int ret;
13197
13198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13199     {
13200       if (unformat (i, "sw_if_index %d", &sw_if_index))
13201         sw_if_index_set = 1;
13202       else
13203         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13204         sw_if_index_set = 1;
13205       else if (unformat (i, "ipv4"))
13206         ipv4_set = 1;
13207       else if (unformat (i, "ipv6"))
13208         ipv6_set = 1;
13209       else
13210         break;
13211     }
13212
13213   if (ipv4_set && ipv6_set)
13214     {
13215       errmsg ("ipv4 and ipv6 flags cannot be both set");
13216       return -99;
13217     }
13218
13219   if ((!ipv4_set) && (!ipv6_set))
13220     {
13221       errmsg ("no ipv4 nor ipv6 flag set");
13222       return -99;
13223     }
13224
13225   if (sw_if_index_set == 0)
13226     {
13227       errmsg ("missing interface name or sw_if_index");
13228       return -99;
13229     }
13230
13231   vam->current_sw_if_index = sw_if_index;
13232   vam->is_ipv6 = ipv6_set;
13233
13234   M (IP_ADDRESS_DUMP, mp);
13235   mp->sw_if_index = ntohl (sw_if_index);
13236   mp->is_ipv6 = ipv6_set;
13237   S (mp);
13238
13239   /* Use a control ping for synchronization */
13240   MPING (CONTROL_PING, mp_ping);
13241   S (mp_ping);
13242
13243   W (ret);
13244   return ret;
13245 }
13246
13247 static int
13248 api_ip_dump (vat_main_t * vam)
13249 {
13250   vl_api_ip_dump_t *mp;
13251   vl_api_control_ping_t *mp_ping;
13252   unformat_input_t *in = vam->input;
13253   int ipv4_set = 0;
13254   int ipv6_set = 0;
13255   int is_ipv6;
13256   int i;
13257   int ret;
13258
13259   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13260     {
13261       if (unformat (in, "ipv4"))
13262         ipv4_set = 1;
13263       else if (unformat (in, "ipv6"))
13264         ipv6_set = 1;
13265       else
13266         break;
13267     }
13268
13269   if (ipv4_set && ipv6_set)
13270     {
13271       errmsg ("ipv4 and ipv6 flags cannot be both set");
13272       return -99;
13273     }
13274
13275   if ((!ipv4_set) && (!ipv6_set))
13276     {
13277       errmsg ("no ipv4 nor ipv6 flag set");
13278       return -99;
13279     }
13280
13281   is_ipv6 = ipv6_set;
13282   vam->is_ipv6 = is_ipv6;
13283
13284   /* free old data */
13285   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13286     {
13287       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13288     }
13289   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13290
13291   M (IP_DUMP, mp);
13292   mp->is_ipv6 = ipv6_set;
13293   S (mp);
13294
13295   /* Use a control ping for synchronization */
13296   MPING (CONTROL_PING, mp_ping);
13297   S (mp_ping);
13298
13299   W (ret);
13300   return ret;
13301 }
13302
13303 static int
13304 api_ipsec_spd_add_del (vat_main_t * vam)
13305 {
13306   unformat_input_t *i = vam->input;
13307   vl_api_ipsec_spd_add_del_t *mp;
13308   u32 spd_id = ~0;
13309   u8 is_add = 1;
13310   int ret;
13311
13312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13313     {
13314       if (unformat (i, "spd_id %d", &spd_id))
13315         ;
13316       else if (unformat (i, "del"))
13317         is_add = 0;
13318       else
13319         {
13320           clib_warning ("parse error '%U'", format_unformat_error, i);
13321           return -99;
13322         }
13323     }
13324   if (spd_id == ~0)
13325     {
13326       errmsg ("spd_id must be set");
13327       return -99;
13328     }
13329
13330   M (IPSEC_SPD_ADD_DEL, mp);
13331
13332   mp->spd_id = ntohl (spd_id);
13333   mp->is_add = is_add;
13334
13335   S (mp);
13336   W (ret);
13337   return ret;
13338 }
13339
13340 static int
13341 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13342 {
13343   unformat_input_t *i = vam->input;
13344   vl_api_ipsec_interface_add_del_spd_t *mp;
13345   u32 sw_if_index;
13346   u8 sw_if_index_set = 0;
13347   u32 spd_id = (u32) ~ 0;
13348   u8 is_add = 1;
13349   int ret;
13350
13351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13352     {
13353       if (unformat (i, "del"))
13354         is_add = 0;
13355       else if (unformat (i, "spd_id %d", &spd_id))
13356         ;
13357       else
13358         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13359         sw_if_index_set = 1;
13360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13361         sw_if_index_set = 1;
13362       else
13363         {
13364           clib_warning ("parse error '%U'", format_unformat_error, i);
13365           return -99;
13366         }
13367
13368     }
13369
13370   if (spd_id == (u32) ~ 0)
13371     {
13372       errmsg ("spd_id must be set");
13373       return -99;
13374     }
13375
13376   if (sw_if_index_set == 0)
13377     {
13378       errmsg ("missing interface name or sw_if_index");
13379       return -99;
13380     }
13381
13382   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13383
13384   mp->spd_id = ntohl (spd_id);
13385   mp->sw_if_index = ntohl (sw_if_index);
13386   mp->is_add = is_add;
13387
13388   S (mp);
13389   W (ret);
13390   return ret;
13391 }
13392
13393 static int
13394 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13395 {
13396   unformat_input_t *i = vam->input;
13397   vl_api_ipsec_spd_entry_add_del_t *mp;
13398   u8 is_add = 1, is_outbound = 0;
13399   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13400   i32 priority = 0;
13401   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13402   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13403   vl_api_address_t laddr_start = { }, laddr_stop =
13404   {
13405   }, raddr_start =
13406   {
13407   }, raddr_stop =
13408   {
13409   };
13410   int ret;
13411
13412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13413     {
13414       if (unformat (i, "del"))
13415         is_add = 0;
13416       if (unformat (i, "outbound"))
13417         is_outbound = 1;
13418       if (unformat (i, "inbound"))
13419         is_outbound = 0;
13420       else if (unformat (i, "spd_id %d", &spd_id))
13421         ;
13422       else if (unformat (i, "sa_id %d", &sa_id))
13423         ;
13424       else if (unformat (i, "priority %d", &priority))
13425         ;
13426       else if (unformat (i, "protocol %d", &protocol))
13427         ;
13428       else if (unformat (i, "lport_start %d", &lport_start))
13429         ;
13430       else if (unformat (i, "lport_stop %d", &lport_stop))
13431         ;
13432       else if (unformat (i, "rport_start %d", &rport_start))
13433         ;
13434       else if (unformat (i, "rport_stop %d", &rport_stop))
13435         ;
13436       else if (unformat (i, "laddr_start %U",
13437                          unformat_vl_api_address, &laddr_start))
13438         ;
13439       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13440                          &laddr_stop))
13441         ;
13442       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13443                          &raddr_start))
13444         ;
13445       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13446                          &raddr_stop))
13447         ;
13448       else
13449         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13450         {
13451           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13452             {
13453               clib_warning ("unsupported action: 'resolve'");
13454               return -99;
13455             }
13456         }
13457       else
13458         {
13459           clib_warning ("parse error '%U'", format_unformat_error, i);
13460           return -99;
13461         }
13462
13463     }
13464
13465   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13466
13467   mp->is_add = is_add;
13468
13469   mp->entry.spd_id = ntohl (spd_id);
13470   mp->entry.priority = ntohl (priority);
13471   mp->entry.is_outbound = is_outbound;
13472
13473   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13474                sizeof (vl_api_address_t));
13475   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13476                sizeof (vl_api_address_t));
13477   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13478                sizeof (vl_api_address_t));
13479   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13480                sizeof (vl_api_address_t));
13481
13482   mp->entry.protocol = (u8) protocol;
13483   mp->entry.local_port_start = ntohs ((u16) lport_start);
13484   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13485   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13486   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13487   mp->entry.policy = (u8) policy;
13488   mp->entry.sa_id = ntohl (sa_id);
13489
13490   S (mp);
13491   W (ret);
13492   return ret;
13493 }
13494
13495 static int
13496 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13497 {
13498   unformat_input_t *i = vam->input;
13499   vl_api_ipsec_sad_entry_add_del_t *mp;
13500   u32 sad_id = 0, spi = 0;
13501   u8 *ck = 0, *ik = 0;
13502   u8 is_add = 1;
13503
13504   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13505   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13506   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13507   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13508   vl_api_address_t tun_src, tun_dst;
13509   int ret;
13510
13511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13512     {
13513       if (unformat (i, "del"))
13514         is_add = 0;
13515       else if (unformat (i, "sad_id %d", &sad_id))
13516         ;
13517       else if (unformat (i, "spi %d", &spi))
13518         ;
13519       else if (unformat (i, "esp"))
13520         protocol = IPSEC_API_PROTO_ESP;
13521       else
13522         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13523         {
13524           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13525           if (ADDRESS_IP6 == tun_src.af)
13526             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13527         }
13528       else
13529         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13530         {
13531           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13532           if (ADDRESS_IP6 == tun_src.af)
13533             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13534         }
13535       else
13536         if (unformat (i, "crypto_alg %U",
13537                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13538         ;
13539       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13540         ;
13541       else if (unformat (i, "integ_alg %U",
13542                          unformat_ipsec_api_integ_alg, &integ_alg))
13543         ;
13544       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13545         ;
13546       else
13547         {
13548           clib_warning ("parse error '%U'", format_unformat_error, i);
13549           return -99;
13550         }
13551
13552     }
13553
13554   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13555
13556   mp->is_add = is_add;
13557   mp->entry.sad_id = ntohl (sad_id);
13558   mp->entry.protocol = protocol;
13559   mp->entry.spi = ntohl (spi);
13560   mp->entry.flags = flags;
13561
13562   mp->entry.crypto_algorithm = crypto_alg;
13563   mp->entry.integrity_algorithm = integ_alg;
13564   mp->entry.crypto_key.length = vec_len (ck);
13565   mp->entry.integrity_key.length = vec_len (ik);
13566
13567   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13568     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13569
13570   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13571     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13572
13573   if (ck)
13574     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13575   if (ik)
13576     clib_memcpy (mp->entry.integrity_key.data, ik,
13577                  mp->entry.integrity_key.length);
13578
13579   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13580     {
13581       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13582                    sizeof (mp->entry.tunnel_src));
13583       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13584                    sizeof (mp->entry.tunnel_dst));
13585     }
13586
13587   S (mp);
13588   W (ret);
13589   return ret;
13590 }
13591
13592 static int
13593 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13594 {
13595   unformat_input_t *i = vam->input;
13596   vl_api_ipsec_tunnel_if_add_del_t *mp;
13597   u32 local_spi = 0, remote_spi = 0;
13598   u32 crypto_alg = 0, integ_alg = 0;
13599   u8 *lck = NULL, *rck = NULL;
13600   u8 *lik = NULL, *rik = NULL;
13601   vl_api_address_t local_ip = { 0 };
13602   vl_api_address_t remote_ip = { 0 };
13603   f64 before = 0;
13604   u8 is_add = 1;
13605   u8 esn = 0;
13606   u8 anti_replay = 0;
13607   u8 renumber = 0;
13608   u32 instance = ~0;
13609   u32 count = 1, jj;
13610   int ret = -1;
13611
13612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13613     {
13614       if (unformat (i, "del"))
13615         is_add = 0;
13616       else if (unformat (i, "esn"))
13617         esn = 1;
13618       else if (unformat (i, "anti-replay"))
13619         anti_replay = 1;
13620       else if (unformat (i, "count %d", &count))
13621         ;
13622       else if (unformat (i, "local_spi %d", &local_spi))
13623         ;
13624       else if (unformat (i, "remote_spi %d", &remote_spi))
13625         ;
13626       else
13627         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13628         ;
13629       else
13630         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13631         ;
13632       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13633         ;
13634       else
13635         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13636         ;
13637       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13638         ;
13639       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13640         ;
13641       else
13642         if (unformat
13643             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13644         {
13645           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13646             {
13647               errmsg ("unsupported crypto-alg: '%U'\n",
13648                       format_ipsec_crypto_alg, crypto_alg);
13649               return -99;
13650             }
13651         }
13652       else
13653         if (unformat
13654             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13655         {
13656           if (integ_alg >= IPSEC_INTEG_N_ALG)
13657             {
13658               errmsg ("unsupported integ-alg: '%U'\n",
13659                       format_ipsec_integ_alg, integ_alg);
13660               return -99;
13661             }
13662         }
13663       else if (unformat (i, "instance %u", &instance))
13664         renumber = 1;
13665       else
13666         {
13667           errmsg ("parse error '%U'\n", format_unformat_error, i);
13668           return -99;
13669         }
13670     }
13671
13672   if (count > 1)
13673     {
13674       /* Turn on async mode */
13675       vam->async_mode = 1;
13676       vam->async_errors = 0;
13677       before = vat_time_now (vam);
13678     }
13679
13680   for (jj = 0; jj < count; jj++)
13681     {
13682       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13683
13684       mp->is_add = is_add;
13685       mp->esn = esn;
13686       mp->anti_replay = anti_replay;
13687
13688       if (jj > 0)
13689         increment_address (&remote_ip);
13690
13691       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13692       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13693
13694       mp->local_spi = htonl (local_spi + jj);
13695       mp->remote_spi = htonl (remote_spi + jj);
13696       mp->crypto_alg = (u8) crypto_alg;
13697
13698       mp->local_crypto_key_len = 0;
13699       if (lck)
13700         {
13701           mp->local_crypto_key_len = vec_len (lck);
13702           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13703             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13704           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13705         }
13706
13707       mp->remote_crypto_key_len = 0;
13708       if (rck)
13709         {
13710           mp->remote_crypto_key_len = vec_len (rck);
13711           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13712             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13713           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13714         }
13715
13716       mp->integ_alg = (u8) integ_alg;
13717
13718       mp->local_integ_key_len = 0;
13719       if (lik)
13720         {
13721           mp->local_integ_key_len = vec_len (lik);
13722           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13723             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13724           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13725         }
13726
13727       mp->remote_integ_key_len = 0;
13728       if (rik)
13729         {
13730           mp->remote_integ_key_len = vec_len (rik);
13731           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13732             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13733           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13734         }
13735
13736       if (renumber)
13737         {
13738           mp->renumber = renumber;
13739           mp->show_instance = ntohl (instance);
13740         }
13741       S (mp);
13742     }
13743
13744   /* When testing multiple add/del ops, use a control-ping to sync */
13745   if (count > 1)
13746     {
13747       vl_api_control_ping_t *mp_ping;
13748       f64 after;
13749       f64 timeout;
13750
13751       /* Shut off async mode */
13752       vam->async_mode = 0;
13753
13754       MPING (CONTROL_PING, mp_ping);
13755       S (mp_ping);
13756
13757       timeout = vat_time_now (vam) + 1.0;
13758       while (vat_time_now (vam) < timeout)
13759         if (vam->result_ready == 1)
13760           goto out;
13761       vam->retval = -99;
13762
13763     out:
13764       if (vam->retval == -99)
13765         errmsg ("timeout");
13766
13767       if (vam->async_errors > 0)
13768         {
13769           errmsg ("%d asynchronous errors", vam->async_errors);
13770           vam->retval = -98;
13771         }
13772       vam->async_errors = 0;
13773       after = vat_time_now (vam);
13774
13775       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13776       if (jj > 0)
13777         count = jj;
13778
13779       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13780              count, after - before, count / (after - before));
13781     }
13782   else
13783     {
13784       /* Wait for a reply... */
13785       W (ret);
13786       return ret;
13787     }
13788
13789   return ret;
13790 }
13791
13792 static void
13793 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13794 {
13795   vat_main_t *vam = &vat_main;
13796
13797   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13798          "crypto_key %U integ_alg %u integ_key %U flags %x "
13799          "tunnel_src_addr %U tunnel_dst_addr %U "
13800          "salt %u seq_outbound %lu last_seq_inbound %lu "
13801          "replay_window %lu\n",
13802          ntohl (mp->entry.sad_id),
13803          ntohl (mp->sw_if_index),
13804          ntohl (mp->entry.spi),
13805          ntohl (mp->entry.protocol),
13806          ntohl (mp->entry.crypto_algorithm),
13807          format_hex_bytes, mp->entry.crypto_key.data,
13808          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13809          format_hex_bytes, mp->entry.integrity_key.data,
13810          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13811          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13812          &mp->entry.tunnel_dst, ntohl (mp->salt),
13813          clib_net_to_host_u64 (mp->seq_outbound),
13814          clib_net_to_host_u64 (mp->last_seq_inbound),
13815          clib_net_to_host_u64 (mp->replay_window));
13816 }
13817
13818 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13819 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13820
13821 static void vl_api_ipsec_sa_details_t_handler_json
13822   (vl_api_ipsec_sa_details_t * mp)
13823 {
13824   vat_main_t *vam = &vat_main;
13825   vat_json_node_t *node = NULL;
13826   vl_api_ipsec_sad_flags_t flags;
13827
13828   if (VAT_JSON_ARRAY != vam->json_tree.type)
13829     {
13830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13831       vat_json_init_array (&vam->json_tree);
13832     }
13833   node = vat_json_array_add (&vam->json_tree);
13834
13835   vat_json_init_object (node);
13836   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13837   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13838   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13839   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13840   vat_json_object_add_uint (node, "crypto_alg",
13841                             ntohl (mp->entry.crypto_algorithm));
13842   vat_json_object_add_uint (node, "integ_alg",
13843                             ntohl (mp->entry.integrity_algorithm));
13844   flags = ntohl (mp->entry.flags);
13845   vat_json_object_add_uint (node, "use_esn",
13846                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13847   vat_json_object_add_uint (node, "use_anti_replay",
13848                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13849   vat_json_object_add_uint (node, "is_tunnel",
13850                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13851   vat_json_object_add_uint (node, "is_tunnel_ip6",
13852                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13853   vat_json_object_add_uint (node, "udp_encap",
13854                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13855   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13856                              mp->entry.crypto_key.length);
13857   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13858                              mp->entry.integrity_key.length);
13859   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13860   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13861   vat_json_object_add_uint (node, "replay_window",
13862                             clib_net_to_host_u64 (mp->replay_window));
13863 }
13864
13865 static int
13866 api_ipsec_sa_dump (vat_main_t * vam)
13867 {
13868   unformat_input_t *i = vam->input;
13869   vl_api_ipsec_sa_dump_t *mp;
13870   vl_api_control_ping_t *mp_ping;
13871   u32 sa_id = ~0;
13872   int ret;
13873
13874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13875     {
13876       if (unformat (i, "sa_id %d", &sa_id))
13877         ;
13878       else
13879         {
13880           clib_warning ("parse error '%U'", format_unformat_error, i);
13881           return -99;
13882         }
13883     }
13884
13885   M (IPSEC_SA_DUMP, mp);
13886
13887   mp->sa_id = ntohl (sa_id);
13888
13889   S (mp);
13890
13891   /* Use a control ping for synchronization */
13892   M (CONTROL_PING, mp_ping);
13893   S (mp_ping);
13894
13895   W (ret);
13896   return ret;
13897 }
13898
13899 static int
13900 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13901 {
13902   unformat_input_t *i = vam->input;
13903   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13904   u32 sw_if_index = ~0;
13905   u32 sa_id = ~0;
13906   u8 is_outbound = (u8) ~ 0;
13907   int ret;
13908
13909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13910     {
13911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13912         ;
13913       else if (unformat (i, "sa_id %d", &sa_id))
13914         ;
13915       else if (unformat (i, "outbound"))
13916         is_outbound = 1;
13917       else if (unformat (i, "inbound"))
13918         is_outbound = 0;
13919       else
13920         {
13921           clib_warning ("parse error '%U'", format_unformat_error, i);
13922           return -99;
13923         }
13924     }
13925
13926   if (sw_if_index == ~0)
13927     {
13928       errmsg ("interface must be specified");
13929       return -99;
13930     }
13931
13932   if (sa_id == ~0)
13933     {
13934       errmsg ("SA ID must be specified");
13935       return -99;
13936     }
13937
13938   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13939
13940   mp->sw_if_index = htonl (sw_if_index);
13941   mp->sa_id = htonl (sa_id);
13942   mp->is_outbound = is_outbound;
13943
13944   S (mp);
13945   W (ret);
13946
13947   return ret;
13948 }
13949
13950 static int
13951 api_get_first_msg_id (vat_main_t * vam)
13952 {
13953   vl_api_get_first_msg_id_t *mp;
13954   unformat_input_t *i = vam->input;
13955   u8 *name;
13956   u8 name_set = 0;
13957   int ret;
13958
13959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13960     {
13961       if (unformat (i, "client %s", &name))
13962         name_set = 1;
13963       else
13964         break;
13965     }
13966
13967   if (name_set == 0)
13968     {
13969       errmsg ("missing client name");
13970       return -99;
13971     }
13972   vec_add1 (name, 0);
13973
13974   if (vec_len (name) > 63)
13975     {
13976       errmsg ("client name too long");
13977       return -99;
13978     }
13979
13980   M (GET_FIRST_MSG_ID, mp);
13981   clib_memcpy (mp->name, name, vec_len (name));
13982   S (mp);
13983   W (ret);
13984   return ret;
13985 }
13986
13987 static int
13988 api_cop_interface_enable_disable (vat_main_t * vam)
13989 {
13990   unformat_input_t *line_input = vam->input;
13991   vl_api_cop_interface_enable_disable_t *mp;
13992   u32 sw_if_index = ~0;
13993   u8 enable_disable = 1;
13994   int ret;
13995
13996   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13997     {
13998       if (unformat (line_input, "disable"))
13999         enable_disable = 0;
14000       if (unformat (line_input, "enable"))
14001         enable_disable = 1;
14002       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14003                          vam, &sw_if_index))
14004         ;
14005       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14006         ;
14007       else
14008         break;
14009     }
14010
14011   if (sw_if_index == ~0)
14012     {
14013       errmsg ("missing interface name or sw_if_index");
14014       return -99;
14015     }
14016
14017   /* Construct the API message */
14018   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14019   mp->sw_if_index = ntohl (sw_if_index);
14020   mp->enable_disable = enable_disable;
14021
14022   /* send it... */
14023   S (mp);
14024   /* Wait for the reply */
14025   W (ret);
14026   return ret;
14027 }
14028
14029 static int
14030 api_cop_whitelist_enable_disable (vat_main_t * vam)
14031 {
14032   unformat_input_t *line_input = vam->input;
14033   vl_api_cop_whitelist_enable_disable_t *mp;
14034   u32 sw_if_index = ~0;
14035   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14036   u32 fib_id = 0;
14037   int ret;
14038
14039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14040     {
14041       if (unformat (line_input, "ip4"))
14042         ip4 = 1;
14043       else if (unformat (line_input, "ip6"))
14044         ip6 = 1;
14045       else if (unformat (line_input, "default"))
14046         default_cop = 1;
14047       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14048                          vam, &sw_if_index))
14049         ;
14050       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14051         ;
14052       else if (unformat (line_input, "fib-id %d", &fib_id))
14053         ;
14054       else
14055         break;
14056     }
14057
14058   if (sw_if_index == ~0)
14059     {
14060       errmsg ("missing interface name or sw_if_index");
14061       return -99;
14062     }
14063
14064   /* Construct the API message */
14065   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14066   mp->sw_if_index = ntohl (sw_if_index);
14067   mp->fib_id = ntohl (fib_id);
14068   mp->ip4 = ip4;
14069   mp->ip6 = ip6;
14070   mp->default_cop = default_cop;
14071
14072   /* send it... */
14073   S (mp);
14074   /* Wait for the reply */
14075   W (ret);
14076   return ret;
14077 }
14078
14079 static int
14080 api_get_node_graph (vat_main_t * vam)
14081 {
14082   vl_api_get_node_graph_t *mp;
14083   int ret;
14084
14085   M (GET_NODE_GRAPH, mp);
14086
14087   /* send it... */
14088   S (mp);
14089   /* Wait for the reply */
14090   W (ret);
14091   return ret;
14092 }
14093
14094 /* *INDENT-OFF* */
14095 /** Used for parsing LISP eids */
14096 typedef CLIB_PACKED(struct{
14097   u8 addr[16];   /**< eid address */
14098   u32 len;       /**< prefix length if IP */
14099   u8 type;      /**< type of eid */
14100 }) lisp_eid_vat_t;
14101 /* *INDENT-ON* */
14102
14103 static uword
14104 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14105 {
14106   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14107
14108   clib_memset (a, 0, sizeof (a[0]));
14109
14110   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14111     {
14112       a->type = 0;              /* ipv4 type */
14113     }
14114   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14115     {
14116       a->type = 1;              /* ipv6 type */
14117     }
14118   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14119     {
14120       a->type = 2;              /* mac type */
14121     }
14122   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14123     {
14124       a->type = 3;              /* NSH type */
14125       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14126       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14127     }
14128   else
14129     {
14130       return 0;
14131     }
14132
14133   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14134     {
14135       return 0;
14136     }
14137
14138   return 1;
14139 }
14140
14141 static int
14142 lisp_eid_size_vat (u8 type)
14143 {
14144   switch (type)
14145     {
14146     case 0:
14147       return 4;
14148     case 1:
14149       return 16;
14150     case 2:
14151       return 6;
14152     case 3:
14153       return 5;
14154     }
14155   return 0;
14156 }
14157
14158 static void
14159 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14160 {
14161   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14162 }
14163
14164 static int
14165 api_one_add_del_locator_set (vat_main_t * vam)
14166 {
14167   unformat_input_t *input = vam->input;
14168   vl_api_one_add_del_locator_set_t *mp;
14169   u8 is_add = 1;
14170   u8 *locator_set_name = NULL;
14171   u8 locator_set_name_set = 0;
14172   vl_api_local_locator_t locator, *locators = 0;
14173   u32 sw_if_index, priority, weight;
14174   u32 data_len = 0;
14175
14176   int ret;
14177   /* Parse args required to build the message */
14178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14179     {
14180       if (unformat (input, "del"))
14181         {
14182           is_add = 0;
14183         }
14184       else if (unformat (input, "locator-set %s", &locator_set_name))
14185         {
14186           locator_set_name_set = 1;
14187         }
14188       else if (unformat (input, "sw_if_index %u p %u w %u",
14189                          &sw_if_index, &priority, &weight))
14190         {
14191           locator.sw_if_index = htonl (sw_if_index);
14192           locator.priority = priority;
14193           locator.weight = weight;
14194           vec_add1 (locators, locator);
14195         }
14196       else
14197         if (unformat
14198             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14199              &sw_if_index, &priority, &weight))
14200         {
14201           locator.sw_if_index = htonl (sw_if_index);
14202           locator.priority = priority;
14203           locator.weight = weight;
14204           vec_add1 (locators, locator);
14205         }
14206       else
14207         break;
14208     }
14209
14210   if (locator_set_name_set == 0)
14211     {
14212       errmsg ("missing locator-set name");
14213       vec_free (locators);
14214       return -99;
14215     }
14216
14217   if (vec_len (locator_set_name) > 64)
14218     {
14219       errmsg ("locator-set name too long");
14220       vec_free (locator_set_name);
14221       vec_free (locators);
14222       return -99;
14223     }
14224   vec_add1 (locator_set_name, 0);
14225
14226   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14227
14228   /* Construct the API message */
14229   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14230
14231   mp->is_add = is_add;
14232   clib_memcpy (mp->locator_set_name, locator_set_name,
14233                vec_len (locator_set_name));
14234   vec_free (locator_set_name);
14235
14236   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14237   if (locators)
14238     clib_memcpy (mp->locators, locators, data_len);
14239   vec_free (locators);
14240
14241   /* send it... */
14242   S (mp);
14243
14244   /* Wait for a reply... */
14245   W (ret);
14246   return ret;
14247 }
14248
14249 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14250
14251 static int
14252 api_one_add_del_locator (vat_main_t * vam)
14253 {
14254   unformat_input_t *input = vam->input;
14255   vl_api_one_add_del_locator_t *mp;
14256   u32 tmp_if_index = ~0;
14257   u32 sw_if_index = ~0;
14258   u8 sw_if_index_set = 0;
14259   u8 sw_if_index_if_name_set = 0;
14260   u32 priority = ~0;
14261   u8 priority_set = 0;
14262   u32 weight = ~0;
14263   u8 weight_set = 0;
14264   u8 is_add = 1;
14265   u8 *locator_set_name = NULL;
14266   u8 locator_set_name_set = 0;
14267   int ret;
14268
14269   /* Parse args required to build the message */
14270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14271     {
14272       if (unformat (input, "del"))
14273         {
14274           is_add = 0;
14275         }
14276       else if (unformat (input, "locator-set %s", &locator_set_name))
14277         {
14278           locator_set_name_set = 1;
14279         }
14280       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14281                          &tmp_if_index))
14282         {
14283           sw_if_index_if_name_set = 1;
14284           sw_if_index = tmp_if_index;
14285         }
14286       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14287         {
14288           sw_if_index_set = 1;
14289           sw_if_index = tmp_if_index;
14290         }
14291       else if (unformat (input, "p %d", &priority))
14292         {
14293           priority_set = 1;
14294         }
14295       else if (unformat (input, "w %d", &weight))
14296         {
14297           weight_set = 1;
14298         }
14299       else
14300         break;
14301     }
14302
14303   if (locator_set_name_set == 0)
14304     {
14305       errmsg ("missing locator-set name");
14306       return -99;
14307     }
14308
14309   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14310     {
14311       errmsg ("missing sw_if_index");
14312       vec_free (locator_set_name);
14313       return -99;
14314     }
14315
14316   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14317     {
14318       errmsg ("cannot use both params interface name and sw_if_index");
14319       vec_free (locator_set_name);
14320       return -99;
14321     }
14322
14323   if (priority_set == 0)
14324     {
14325       errmsg ("missing locator-set priority");
14326       vec_free (locator_set_name);
14327       return -99;
14328     }
14329
14330   if (weight_set == 0)
14331     {
14332       errmsg ("missing locator-set weight");
14333       vec_free (locator_set_name);
14334       return -99;
14335     }
14336
14337   if (vec_len (locator_set_name) > 64)
14338     {
14339       errmsg ("locator-set name too long");
14340       vec_free (locator_set_name);
14341       return -99;
14342     }
14343   vec_add1 (locator_set_name, 0);
14344
14345   /* Construct the API message */
14346   M (ONE_ADD_DEL_LOCATOR, mp);
14347
14348   mp->is_add = is_add;
14349   mp->sw_if_index = ntohl (sw_if_index);
14350   mp->priority = priority;
14351   mp->weight = weight;
14352   clib_memcpy (mp->locator_set_name, locator_set_name,
14353                vec_len (locator_set_name));
14354   vec_free (locator_set_name);
14355
14356   /* send it... */
14357   S (mp);
14358
14359   /* Wait for a reply... */
14360   W (ret);
14361   return ret;
14362 }
14363
14364 #define api_lisp_add_del_locator api_one_add_del_locator
14365
14366 uword
14367 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14368 {
14369   u32 *key_id = va_arg (*args, u32 *);
14370   u8 *s = 0;
14371
14372   if (unformat (input, "%s", &s))
14373     {
14374       if (!strcmp ((char *) s, "sha1"))
14375         key_id[0] = HMAC_SHA_1_96;
14376       else if (!strcmp ((char *) s, "sha256"))
14377         key_id[0] = HMAC_SHA_256_128;
14378       else
14379         {
14380           clib_warning ("invalid key_id: '%s'", s);
14381           key_id[0] = HMAC_NO_KEY;
14382         }
14383     }
14384   else
14385     return 0;
14386
14387   vec_free (s);
14388   return 1;
14389 }
14390
14391 static int
14392 api_one_add_del_local_eid (vat_main_t * vam)
14393 {
14394   unformat_input_t *input = vam->input;
14395   vl_api_one_add_del_local_eid_t *mp;
14396   u8 is_add = 1;
14397   u8 eid_set = 0;
14398   lisp_eid_vat_t _eid, *eid = &_eid;
14399   u8 *locator_set_name = 0;
14400   u8 locator_set_name_set = 0;
14401   u32 vni = 0;
14402   u16 key_id = 0;
14403   u8 *key = 0;
14404   int ret;
14405
14406   /* Parse args required to build the message */
14407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14408     {
14409       if (unformat (input, "del"))
14410         {
14411           is_add = 0;
14412         }
14413       else if (unformat (input, "vni %d", &vni))
14414         {
14415           ;
14416         }
14417       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14418         {
14419           eid_set = 1;
14420         }
14421       else if (unformat (input, "locator-set %s", &locator_set_name))
14422         {
14423           locator_set_name_set = 1;
14424         }
14425       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14426         ;
14427       else if (unformat (input, "secret-key %_%v%_", &key))
14428         ;
14429       else
14430         break;
14431     }
14432
14433   if (locator_set_name_set == 0)
14434     {
14435       errmsg ("missing locator-set name");
14436       return -99;
14437     }
14438
14439   if (0 == eid_set)
14440     {
14441       errmsg ("EID address not set!");
14442       vec_free (locator_set_name);
14443       return -99;
14444     }
14445
14446   if (key && (0 == key_id))
14447     {
14448       errmsg ("invalid key_id!");
14449       return -99;
14450     }
14451
14452   if (vec_len (key) > 64)
14453     {
14454       errmsg ("key too long");
14455       vec_free (key);
14456       return -99;
14457     }
14458
14459   if (vec_len (locator_set_name) > 64)
14460     {
14461       errmsg ("locator-set name too long");
14462       vec_free (locator_set_name);
14463       return -99;
14464     }
14465   vec_add1 (locator_set_name, 0);
14466
14467   /* Construct the API message */
14468   M (ONE_ADD_DEL_LOCAL_EID, mp);
14469
14470   mp->is_add = is_add;
14471   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14472   mp->eid_type = eid->type;
14473   mp->prefix_len = eid->len;
14474   mp->vni = clib_host_to_net_u32 (vni);
14475   mp->key_id = clib_host_to_net_u16 (key_id);
14476   clib_memcpy (mp->locator_set_name, locator_set_name,
14477                vec_len (locator_set_name));
14478   clib_memcpy (mp->key, key, vec_len (key));
14479
14480   vec_free (locator_set_name);
14481   vec_free (key);
14482
14483   /* send it... */
14484   S (mp);
14485
14486   /* Wait for a reply... */
14487   W (ret);
14488   return ret;
14489 }
14490
14491 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14492
14493 static int
14494 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14495 {
14496   u32 dp_table = 0, vni = 0;;
14497   unformat_input_t *input = vam->input;
14498   vl_api_gpe_add_del_fwd_entry_t *mp;
14499   u8 is_add = 1;
14500   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14501   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14502   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14503   u32 action = ~0, w;
14504   ip4_address_t rmt_rloc4, lcl_rloc4;
14505   ip6_address_t rmt_rloc6, lcl_rloc6;
14506   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14507   int ret;
14508
14509   clib_memset (&rloc, 0, sizeof (rloc));
14510
14511   /* Parse args required to build the message */
14512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14513     {
14514       if (unformat (input, "del"))
14515         is_add = 0;
14516       else if (unformat (input, "add"))
14517         is_add = 1;
14518       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14519         {
14520           rmt_eid_set = 1;
14521         }
14522       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14523         {
14524           lcl_eid_set = 1;
14525         }
14526       else if (unformat (input, "vrf %d", &dp_table))
14527         ;
14528       else if (unformat (input, "bd %d", &dp_table))
14529         ;
14530       else if (unformat (input, "vni %d", &vni))
14531         ;
14532       else if (unformat (input, "w %d", &w))
14533         {
14534           if (!curr_rloc)
14535             {
14536               errmsg ("No RLOC configured for setting priority/weight!");
14537               return -99;
14538             }
14539           curr_rloc->weight = w;
14540         }
14541       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14542                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14543         {
14544           rloc.is_ip4 = 1;
14545
14546           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14547           rloc.weight = 0;
14548           vec_add1 (lcl_locs, rloc);
14549
14550           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14551           vec_add1 (rmt_locs, rloc);
14552           /* weight saved in rmt loc */
14553           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14554         }
14555       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14556                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14557         {
14558           rloc.is_ip4 = 0;
14559           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14560           rloc.weight = 0;
14561           vec_add1 (lcl_locs, rloc);
14562
14563           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14564           vec_add1 (rmt_locs, rloc);
14565           /* weight saved in rmt loc */
14566           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14567         }
14568       else if (unformat (input, "action %d", &action))
14569         {
14570           ;
14571         }
14572       else
14573         {
14574           clib_warning ("parse error '%U'", format_unformat_error, input);
14575           return -99;
14576         }
14577     }
14578
14579   if (!rmt_eid_set)
14580     {
14581       errmsg ("remote eid addresses not set");
14582       return -99;
14583     }
14584
14585   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14586     {
14587       errmsg ("eid types don't match");
14588       return -99;
14589     }
14590
14591   if (0 == rmt_locs && (u32) ~ 0 == action)
14592     {
14593       errmsg ("action not set for negative mapping");
14594       return -99;
14595     }
14596
14597   /* Construct the API message */
14598   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14599       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14600
14601   mp->is_add = is_add;
14602   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14603   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14604   mp->eid_type = rmt_eid->type;
14605   mp->dp_table = clib_host_to_net_u32 (dp_table);
14606   mp->vni = clib_host_to_net_u32 (vni);
14607   mp->rmt_len = rmt_eid->len;
14608   mp->lcl_len = lcl_eid->len;
14609   mp->action = action;
14610
14611   if (0 != rmt_locs && 0 != lcl_locs)
14612     {
14613       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14614       clib_memcpy (mp->locs, lcl_locs,
14615                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14616
14617       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14618       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14619                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14620     }
14621   vec_free (lcl_locs);
14622   vec_free (rmt_locs);
14623
14624   /* send it... */
14625   S (mp);
14626
14627   /* Wait for a reply... */
14628   W (ret);
14629   return ret;
14630 }
14631
14632 static int
14633 api_one_add_del_map_server (vat_main_t * vam)
14634 {
14635   unformat_input_t *input = vam->input;
14636   vl_api_one_add_del_map_server_t *mp;
14637   u8 is_add = 1;
14638   u8 ipv4_set = 0;
14639   u8 ipv6_set = 0;
14640   ip4_address_t ipv4;
14641   ip6_address_t ipv6;
14642   int ret;
14643
14644   /* Parse args required to build the message */
14645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14646     {
14647       if (unformat (input, "del"))
14648         {
14649           is_add = 0;
14650         }
14651       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14652         {
14653           ipv4_set = 1;
14654         }
14655       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14656         {
14657           ipv6_set = 1;
14658         }
14659       else
14660         break;
14661     }
14662
14663   if (ipv4_set && ipv6_set)
14664     {
14665       errmsg ("both eid v4 and v6 addresses set");
14666       return -99;
14667     }
14668
14669   if (!ipv4_set && !ipv6_set)
14670     {
14671       errmsg ("eid addresses not set");
14672       return -99;
14673     }
14674
14675   /* Construct the API message */
14676   M (ONE_ADD_DEL_MAP_SERVER, mp);
14677
14678   mp->is_add = is_add;
14679   if (ipv6_set)
14680     {
14681       mp->is_ipv6 = 1;
14682       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14683     }
14684   else
14685     {
14686       mp->is_ipv6 = 0;
14687       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14688     }
14689
14690   /* send it... */
14691   S (mp);
14692
14693   /* Wait for a reply... */
14694   W (ret);
14695   return ret;
14696 }
14697
14698 #define api_lisp_add_del_map_server api_one_add_del_map_server
14699
14700 static int
14701 api_one_add_del_map_resolver (vat_main_t * vam)
14702 {
14703   unformat_input_t *input = vam->input;
14704   vl_api_one_add_del_map_resolver_t *mp;
14705   u8 is_add = 1;
14706   u8 ipv4_set = 0;
14707   u8 ipv6_set = 0;
14708   ip4_address_t ipv4;
14709   ip6_address_t ipv6;
14710   int ret;
14711
14712   /* Parse args required to build the message */
14713   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14714     {
14715       if (unformat (input, "del"))
14716         {
14717           is_add = 0;
14718         }
14719       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14720         {
14721           ipv4_set = 1;
14722         }
14723       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14724         {
14725           ipv6_set = 1;
14726         }
14727       else
14728         break;
14729     }
14730
14731   if (ipv4_set && ipv6_set)
14732     {
14733       errmsg ("both eid v4 and v6 addresses set");
14734       return -99;
14735     }
14736
14737   if (!ipv4_set && !ipv6_set)
14738     {
14739       errmsg ("eid addresses not set");
14740       return -99;
14741     }
14742
14743   /* Construct the API message */
14744   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14745
14746   mp->is_add = is_add;
14747   if (ipv6_set)
14748     {
14749       mp->is_ipv6 = 1;
14750       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14751     }
14752   else
14753     {
14754       mp->is_ipv6 = 0;
14755       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14756     }
14757
14758   /* send it... */
14759   S (mp);
14760
14761   /* Wait for a reply... */
14762   W (ret);
14763   return ret;
14764 }
14765
14766 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14767
14768 static int
14769 api_lisp_gpe_enable_disable (vat_main_t * vam)
14770 {
14771   unformat_input_t *input = vam->input;
14772   vl_api_gpe_enable_disable_t *mp;
14773   u8 is_set = 0;
14774   u8 is_en = 1;
14775   int ret;
14776
14777   /* Parse args required to build the message */
14778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14779     {
14780       if (unformat (input, "enable"))
14781         {
14782           is_set = 1;
14783           is_en = 1;
14784         }
14785       else if (unformat (input, "disable"))
14786         {
14787           is_set = 1;
14788           is_en = 0;
14789         }
14790       else
14791         break;
14792     }
14793
14794   if (is_set == 0)
14795     {
14796       errmsg ("Value not set");
14797       return -99;
14798     }
14799
14800   /* Construct the API message */
14801   M (GPE_ENABLE_DISABLE, mp);
14802
14803   mp->is_en = is_en;
14804
14805   /* send it... */
14806   S (mp);
14807
14808   /* Wait for a reply... */
14809   W (ret);
14810   return ret;
14811 }
14812
14813 static int
14814 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14815 {
14816   unformat_input_t *input = vam->input;
14817   vl_api_one_rloc_probe_enable_disable_t *mp;
14818   u8 is_set = 0;
14819   u8 is_en = 0;
14820   int ret;
14821
14822   /* Parse args required to build the message */
14823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14824     {
14825       if (unformat (input, "enable"))
14826         {
14827           is_set = 1;
14828           is_en = 1;
14829         }
14830       else if (unformat (input, "disable"))
14831         is_set = 1;
14832       else
14833         break;
14834     }
14835
14836   if (!is_set)
14837     {
14838       errmsg ("Value not set");
14839       return -99;
14840     }
14841
14842   /* Construct the API message */
14843   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14844
14845   mp->is_enabled = is_en;
14846
14847   /* send it... */
14848   S (mp);
14849
14850   /* Wait for a reply... */
14851   W (ret);
14852   return ret;
14853 }
14854
14855 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14856
14857 static int
14858 api_one_map_register_enable_disable (vat_main_t * vam)
14859 {
14860   unformat_input_t *input = vam->input;
14861   vl_api_one_map_register_enable_disable_t *mp;
14862   u8 is_set = 0;
14863   u8 is_en = 0;
14864   int ret;
14865
14866   /* Parse args required to build the message */
14867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14868     {
14869       if (unformat (input, "enable"))
14870         {
14871           is_set = 1;
14872           is_en = 1;
14873         }
14874       else if (unformat (input, "disable"))
14875         is_set = 1;
14876       else
14877         break;
14878     }
14879
14880   if (!is_set)
14881     {
14882       errmsg ("Value not set");
14883       return -99;
14884     }
14885
14886   /* Construct the API message */
14887   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14888
14889   mp->is_enabled = is_en;
14890
14891   /* send it... */
14892   S (mp);
14893
14894   /* Wait for a reply... */
14895   W (ret);
14896   return ret;
14897 }
14898
14899 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14900
14901 static int
14902 api_one_enable_disable (vat_main_t * vam)
14903 {
14904   unformat_input_t *input = vam->input;
14905   vl_api_one_enable_disable_t *mp;
14906   u8 is_set = 0;
14907   u8 is_en = 0;
14908   int ret;
14909
14910   /* Parse args required to build the message */
14911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14912     {
14913       if (unformat (input, "enable"))
14914         {
14915           is_set = 1;
14916           is_en = 1;
14917         }
14918       else if (unformat (input, "disable"))
14919         {
14920           is_set = 1;
14921         }
14922       else
14923         break;
14924     }
14925
14926   if (!is_set)
14927     {
14928       errmsg ("Value not set");
14929       return -99;
14930     }
14931
14932   /* Construct the API message */
14933   M (ONE_ENABLE_DISABLE, mp);
14934
14935   mp->is_en = is_en;
14936
14937   /* send it... */
14938   S (mp);
14939
14940   /* Wait for a reply... */
14941   W (ret);
14942   return ret;
14943 }
14944
14945 #define api_lisp_enable_disable api_one_enable_disable
14946
14947 static int
14948 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14949 {
14950   unformat_input_t *input = vam->input;
14951   vl_api_one_enable_disable_xtr_mode_t *mp;
14952   u8 is_set = 0;
14953   u8 is_en = 0;
14954   int ret;
14955
14956   /* Parse args required to build the message */
14957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14958     {
14959       if (unformat (input, "enable"))
14960         {
14961           is_set = 1;
14962           is_en = 1;
14963         }
14964       else if (unformat (input, "disable"))
14965         {
14966           is_set = 1;
14967         }
14968       else
14969         break;
14970     }
14971
14972   if (!is_set)
14973     {
14974       errmsg ("Value not set");
14975       return -99;
14976     }
14977
14978   /* Construct the API message */
14979   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14980
14981   mp->is_en = is_en;
14982
14983   /* send it... */
14984   S (mp);
14985
14986   /* Wait for a reply... */
14987   W (ret);
14988   return ret;
14989 }
14990
14991 static int
14992 api_one_show_xtr_mode (vat_main_t * vam)
14993 {
14994   vl_api_one_show_xtr_mode_t *mp;
14995   int ret;
14996
14997   /* Construct the API message */
14998   M (ONE_SHOW_XTR_MODE, mp);
14999
15000   /* send it... */
15001   S (mp);
15002
15003   /* Wait for a reply... */
15004   W (ret);
15005   return ret;
15006 }
15007
15008 static int
15009 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15010 {
15011   unformat_input_t *input = vam->input;
15012   vl_api_one_enable_disable_pitr_mode_t *mp;
15013   u8 is_set = 0;
15014   u8 is_en = 0;
15015   int ret;
15016
15017   /* Parse args required to build the message */
15018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15019     {
15020       if (unformat (input, "enable"))
15021         {
15022           is_set = 1;
15023           is_en = 1;
15024         }
15025       else if (unformat (input, "disable"))
15026         {
15027           is_set = 1;
15028         }
15029       else
15030         break;
15031     }
15032
15033   if (!is_set)
15034     {
15035       errmsg ("Value not set");
15036       return -99;
15037     }
15038
15039   /* Construct the API message */
15040   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15041
15042   mp->is_en = is_en;
15043
15044   /* send it... */
15045   S (mp);
15046
15047   /* Wait for a reply... */
15048   W (ret);
15049   return ret;
15050 }
15051
15052 static int
15053 api_one_show_pitr_mode (vat_main_t * vam)
15054 {
15055   vl_api_one_show_pitr_mode_t *mp;
15056   int ret;
15057
15058   /* Construct the API message */
15059   M (ONE_SHOW_PITR_MODE, mp);
15060
15061   /* send it... */
15062   S (mp);
15063
15064   /* Wait for a reply... */
15065   W (ret);
15066   return ret;
15067 }
15068
15069 static int
15070 api_one_enable_disable_petr_mode (vat_main_t * vam)
15071 {
15072   unformat_input_t *input = vam->input;
15073   vl_api_one_enable_disable_petr_mode_t *mp;
15074   u8 is_set = 0;
15075   u8 is_en = 0;
15076   int ret;
15077
15078   /* Parse args required to build the message */
15079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15080     {
15081       if (unformat (input, "enable"))
15082         {
15083           is_set = 1;
15084           is_en = 1;
15085         }
15086       else if (unformat (input, "disable"))
15087         {
15088           is_set = 1;
15089         }
15090       else
15091         break;
15092     }
15093
15094   if (!is_set)
15095     {
15096       errmsg ("Value not set");
15097       return -99;
15098     }
15099
15100   /* Construct the API message */
15101   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15102
15103   mp->is_en = is_en;
15104
15105   /* send it... */
15106   S (mp);
15107
15108   /* Wait for a reply... */
15109   W (ret);
15110   return ret;
15111 }
15112
15113 static int
15114 api_one_show_petr_mode (vat_main_t * vam)
15115 {
15116   vl_api_one_show_petr_mode_t *mp;
15117   int ret;
15118
15119   /* Construct the API message */
15120   M (ONE_SHOW_PETR_MODE, mp);
15121
15122   /* send it... */
15123   S (mp);
15124
15125   /* Wait for a reply... */
15126   W (ret);
15127   return ret;
15128 }
15129
15130 static int
15131 api_show_one_map_register_state (vat_main_t * vam)
15132 {
15133   vl_api_show_one_map_register_state_t *mp;
15134   int ret;
15135
15136   M (SHOW_ONE_MAP_REGISTER_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_map_register_state api_show_one_map_register_state
15147
15148 static int
15149 api_show_one_rloc_probe_state (vat_main_t * vam)
15150 {
15151   vl_api_show_one_rloc_probe_state_t *mp;
15152   int ret;
15153
15154   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15155
15156   /* send */
15157   S (mp);
15158
15159   /* wait for reply */
15160   W (ret);
15161   return ret;
15162 }
15163
15164 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15165
15166 static int
15167 api_one_add_del_ndp_entry (vat_main_t * vam)
15168 {
15169   vl_api_one_add_del_ndp_entry_t *mp;
15170   unformat_input_t *input = vam->input;
15171   u8 is_add = 1;
15172   u8 mac_set = 0;
15173   u8 bd_set = 0;
15174   u8 ip_set = 0;
15175   u8 mac[6] = { 0, };
15176   u8 ip6[16] = { 0, };
15177   u32 bd = ~0;
15178   int ret;
15179
15180   /* Parse args required to build the message */
15181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15182     {
15183       if (unformat (input, "del"))
15184         is_add = 0;
15185       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15186         mac_set = 1;
15187       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15188         ip_set = 1;
15189       else if (unformat (input, "bd %d", &bd))
15190         bd_set = 1;
15191       else
15192         {
15193           errmsg ("parse error '%U'", format_unformat_error, input);
15194           return -99;
15195         }
15196     }
15197
15198   if (!bd_set || !ip_set || (!mac_set && is_add))
15199     {
15200       errmsg ("Missing BD, IP or MAC!");
15201       return -99;
15202     }
15203
15204   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15205   mp->is_add = is_add;
15206   clib_memcpy (mp->mac, mac, 6);
15207   mp->bd = clib_host_to_net_u32 (bd);
15208   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15209
15210   /* send */
15211   S (mp);
15212
15213   /* wait for reply */
15214   W (ret);
15215   return ret;
15216 }
15217
15218 static int
15219 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15220 {
15221   vl_api_one_add_del_l2_arp_entry_t *mp;
15222   unformat_input_t *input = vam->input;
15223   u8 is_add = 1;
15224   u8 mac_set = 0;
15225   u8 bd_set = 0;
15226   u8 ip_set = 0;
15227   u8 mac[6] = { 0, };
15228   u32 ip4 = 0, bd = ~0;
15229   int ret;
15230
15231   /* Parse args required to build the message */
15232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15233     {
15234       if (unformat (input, "del"))
15235         is_add = 0;
15236       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15237         mac_set = 1;
15238       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15239         ip_set = 1;
15240       else if (unformat (input, "bd %d", &bd))
15241         bd_set = 1;
15242       else
15243         {
15244           errmsg ("parse error '%U'", format_unformat_error, input);
15245           return -99;
15246         }
15247     }
15248
15249   if (!bd_set || !ip_set || (!mac_set && is_add))
15250     {
15251       errmsg ("Missing BD, IP or MAC!");
15252       return -99;
15253     }
15254
15255   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15256   mp->is_add = is_add;
15257   clib_memcpy (mp->mac, mac, 6);
15258   mp->bd = clib_host_to_net_u32 (bd);
15259   mp->ip4 = ip4;
15260
15261   /* send */
15262   S (mp);
15263
15264   /* wait for reply */
15265   W (ret);
15266   return ret;
15267 }
15268
15269 static int
15270 api_one_ndp_bd_get (vat_main_t * vam)
15271 {
15272   vl_api_one_ndp_bd_get_t *mp;
15273   int ret;
15274
15275   M (ONE_NDP_BD_GET, mp);
15276
15277   /* send */
15278   S (mp);
15279
15280   /* wait for reply */
15281   W (ret);
15282   return ret;
15283 }
15284
15285 static int
15286 api_one_ndp_entries_get (vat_main_t * vam)
15287 {
15288   vl_api_one_ndp_entries_get_t *mp;
15289   unformat_input_t *input = vam->input;
15290   u8 bd_set = 0;
15291   u32 bd = ~0;
15292   int ret;
15293
15294   /* Parse args required to build the message */
15295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15296     {
15297       if (unformat (input, "bd %d", &bd))
15298         bd_set = 1;
15299       else
15300         {
15301           errmsg ("parse error '%U'", format_unformat_error, input);
15302           return -99;
15303         }
15304     }
15305
15306   if (!bd_set)
15307     {
15308       errmsg ("Expected bridge domain!");
15309       return -99;
15310     }
15311
15312   M (ONE_NDP_ENTRIES_GET, mp);
15313   mp->bd = clib_host_to_net_u32 (bd);
15314
15315   /* send */
15316   S (mp);
15317
15318   /* wait for reply */
15319   W (ret);
15320   return ret;
15321 }
15322
15323 static int
15324 api_one_l2_arp_bd_get (vat_main_t * vam)
15325 {
15326   vl_api_one_l2_arp_bd_get_t *mp;
15327   int ret;
15328
15329   M (ONE_L2_ARP_BD_GET, mp);
15330
15331   /* send */
15332   S (mp);
15333
15334   /* wait for reply */
15335   W (ret);
15336   return ret;
15337 }
15338
15339 static int
15340 api_one_l2_arp_entries_get (vat_main_t * vam)
15341 {
15342   vl_api_one_l2_arp_entries_get_t *mp;
15343   unformat_input_t *input = vam->input;
15344   u8 bd_set = 0;
15345   u32 bd = ~0;
15346   int ret;
15347
15348   /* Parse args required to build the message */
15349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15350     {
15351       if (unformat (input, "bd %d", &bd))
15352         bd_set = 1;
15353       else
15354         {
15355           errmsg ("parse error '%U'", format_unformat_error, input);
15356           return -99;
15357         }
15358     }
15359
15360   if (!bd_set)
15361     {
15362       errmsg ("Expected bridge domain!");
15363       return -99;
15364     }
15365
15366   M (ONE_L2_ARP_ENTRIES_GET, mp);
15367   mp->bd = clib_host_to_net_u32 (bd);
15368
15369   /* send */
15370   S (mp);
15371
15372   /* wait for reply */
15373   W (ret);
15374   return ret;
15375 }
15376
15377 static int
15378 api_one_stats_enable_disable (vat_main_t * vam)
15379 {
15380   vl_api_one_stats_enable_disable_t *mp;
15381   unformat_input_t *input = vam->input;
15382   u8 is_set = 0;
15383   u8 is_en = 0;
15384   int ret;
15385
15386   /* Parse args required to build the message */
15387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15388     {
15389       if (unformat (input, "enable"))
15390         {
15391           is_set = 1;
15392           is_en = 1;
15393         }
15394       else if (unformat (input, "disable"))
15395         {
15396           is_set = 1;
15397         }
15398       else
15399         break;
15400     }
15401
15402   if (!is_set)
15403     {
15404       errmsg ("Value not set");
15405       return -99;
15406     }
15407
15408   M (ONE_STATS_ENABLE_DISABLE, mp);
15409   mp->is_en = is_en;
15410
15411   /* send */
15412   S (mp);
15413
15414   /* wait for reply */
15415   W (ret);
15416   return ret;
15417 }
15418
15419 static int
15420 api_show_one_stats_enable_disable (vat_main_t * vam)
15421 {
15422   vl_api_show_one_stats_enable_disable_t *mp;
15423   int ret;
15424
15425   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15426
15427   /* send */
15428   S (mp);
15429
15430   /* wait for reply */
15431   W (ret);
15432   return ret;
15433 }
15434
15435 static int
15436 api_show_one_map_request_mode (vat_main_t * vam)
15437 {
15438   vl_api_show_one_map_request_mode_t *mp;
15439   int ret;
15440
15441   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15442
15443   /* send */
15444   S (mp);
15445
15446   /* wait for reply */
15447   W (ret);
15448   return ret;
15449 }
15450
15451 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15452
15453 static int
15454 api_one_map_request_mode (vat_main_t * vam)
15455 {
15456   unformat_input_t *input = vam->input;
15457   vl_api_one_map_request_mode_t *mp;
15458   u8 mode = 0;
15459   int ret;
15460
15461   /* Parse args required to build the message */
15462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15463     {
15464       if (unformat (input, "dst-only"))
15465         mode = 0;
15466       else if (unformat (input, "src-dst"))
15467         mode = 1;
15468       else
15469         {
15470           errmsg ("parse error '%U'", format_unformat_error, input);
15471           return -99;
15472         }
15473     }
15474
15475   M (ONE_MAP_REQUEST_MODE, mp);
15476
15477   mp->mode = mode;
15478
15479   /* send */
15480   S (mp);
15481
15482   /* wait for reply */
15483   W (ret);
15484   return ret;
15485 }
15486
15487 #define api_lisp_map_request_mode api_one_map_request_mode
15488
15489 /**
15490  * Enable/disable ONE proxy ITR.
15491  *
15492  * @param vam vpp API test context
15493  * @return return code
15494  */
15495 static int
15496 api_one_pitr_set_locator_set (vat_main_t * vam)
15497 {
15498   u8 ls_name_set = 0;
15499   unformat_input_t *input = vam->input;
15500   vl_api_one_pitr_set_locator_set_t *mp;
15501   u8 is_add = 1;
15502   u8 *ls_name = 0;
15503   int ret;
15504
15505   /* Parse args required to build the message */
15506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15507     {
15508       if (unformat (input, "del"))
15509         is_add = 0;
15510       else if (unformat (input, "locator-set %s", &ls_name))
15511         ls_name_set = 1;
15512       else
15513         {
15514           errmsg ("parse error '%U'", format_unformat_error, input);
15515           return -99;
15516         }
15517     }
15518
15519   if (!ls_name_set)
15520     {
15521       errmsg ("locator-set name not set!");
15522       return -99;
15523     }
15524
15525   M (ONE_PITR_SET_LOCATOR_SET, mp);
15526
15527   mp->is_add = is_add;
15528   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15529   vec_free (ls_name);
15530
15531   /* send */
15532   S (mp);
15533
15534   /* wait for reply */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15540
15541 static int
15542 api_one_nsh_set_locator_set (vat_main_t * vam)
15543 {
15544   u8 ls_name_set = 0;
15545   unformat_input_t *input = vam->input;
15546   vl_api_one_nsh_set_locator_set_t *mp;
15547   u8 is_add = 1;
15548   u8 *ls_name = 0;
15549   int ret;
15550
15551   /* Parse args required to build the message */
15552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15553     {
15554       if (unformat (input, "del"))
15555         is_add = 0;
15556       else if (unformat (input, "ls %s", &ls_name))
15557         ls_name_set = 1;
15558       else
15559         {
15560           errmsg ("parse error '%U'", format_unformat_error, input);
15561           return -99;
15562         }
15563     }
15564
15565   if (!ls_name_set && is_add)
15566     {
15567       errmsg ("locator-set name not set!");
15568       return -99;
15569     }
15570
15571   M (ONE_NSH_SET_LOCATOR_SET, mp);
15572
15573   mp->is_add = is_add;
15574   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15575   vec_free (ls_name);
15576
15577   /* send */
15578   S (mp);
15579
15580   /* wait for reply */
15581   W (ret);
15582   return ret;
15583 }
15584
15585 static int
15586 api_show_one_pitr (vat_main_t * vam)
15587 {
15588   vl_api_show_one_pitr_t *mp;
15589   int ret;
15590
15591   if (!vam->json_output)
15592     {
15593       print (vam->ofp, "%=20s", "lisp status:");
15594     }
15595
15596   M (SHOW_ONE_PITR, mp);
15597   /* send it... */
15598   S (mp);
15599
15600   /* Wait for a reply... */
15601   W (ret);
15602   return ret;
15603 }
15604
15605 #define api_show_lisp_pitr api_show_one_pitr
15606
15607 static int
15608 api_one_use_petr (vat_main_t * vam)
15609 {
15610   unformat_input_t *input = vam->input;
15611   vl_api_one_use_petr_t *mp;
15612   u8 is_add = 0;
15613   ip_address_t ip;
15614   int ret;
15615
15616   clib_memset (&ip, 0, sizeof (ip));
15617
15618   /* Parse args required to build the message */
15619   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15620     {
15621       if (unformat (input, "disable"))
15622         is_add = 0;
15623       else
15624         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15625         {
15626           is_add = 1;
15627           ip_addr_version (&ip) = AF_IP4;
15628         }
15629       else
15630         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15631         {
15632           is_add = 1;
15633           ip_addr_version (&ip) = AF_IP6;
15634         }
15635       else
15636         {
15637           errmsg ("parse error '%U'", format_unformat_error, input);
15638           return -99;
15639         }
15640     }
15641
15642   M (ONE_USE_PETR, mp);
15643
15644   mp->is_add = is_add;
15645   if (is_add)
15646     {
15647       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15648       if (mp->is_ip4)
15649         clib_memcpy (mp->address, &ip, 4);
15650       else
15651         clib_memcpy (mp->address, &ip, 16);
15652     }
15653
15654   /* send */
15655   S (mp);
15656
15657   /* wait for reply */
15658   W (ret);
15659   return ret;
15660 }
15661
15662 #define api_lisp_use_petr api_one_use_petr
15663
15664 static int
15665 api_show_one_nsh_mapping (vat_main_t * vam)
15666 {
15667   vl_api_show_one_use_petr_t *mp;
15668   int ret;
15669
15670   if (!vam->json_output)
15671     {
15672       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15673     }
15674
15675   M (SHOW_ONE_NSH_MAPPING, mp);
15676   /* send it... */
15677   S (mp);
15678
15679   /* Wait for a reply... */
15680   W (ret);
15681   return ret;
15682 }
15683
15684 static int
15685 api_show_one_use_petr (vat_main_t * vam)
15686 {
15687   vl_api_show_one_use_petr_t *mp;
15688   int ret;
15689
15690   if (!vam->json_output)
15691     {
15692       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15693     }
15694
15695   M (SHOW_ONE_USE_PETR, mp);
15696   /* send it... */
15697   S (mp);
15698
15699   /* Wait for a reply... */
15700   W (ret);
15701   return ret;
15702 }
15703
15704 #define api_show_lisp_use_petr api_show_one_use_petr
15705
15706 /**
15707  * Add/delete mapping between vni and vrf
15708  */
15709 static int
15710 api_one_eid_table_add_del_map (vat_main_t * vam)
15711 {
15712   unformat_input_t *input = vam->input;
15713   vl_api_one_eid_table_add_del_map_t *mp;
15714   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15715   u32 vni, vrf, bd_index;
15716   int ret;
15717
15718   /* Parse args required to build the message */
15719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15720     {
15721       if (unformat (input, "del"))
15722         is_add = 0;
15723       else if (unformat (input, "vrf %d", &vrf))
15724         vrf_set = 1;
15725       else if (unformat (input, "bd_index %d", &bd_index))
15726         bd_index_set = 1;
15727       else if (unformat (input, "vni %d", &vni))
15728         vni_set = 1;
15729       else
15730         break;
15731     }
15732
15733   if (!vni_set || (!vrf_set && !bd_index_set))
15734     {
15735       errmsg ("missing arguments!");
15736       return -99;
15737     }
15738
15739   if (vrf_set && bd_index_set)
15740     {
15741       errmsg ("error: both vrf and bd entered!");
15742       return -99;
15743     }
15744
15745   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15746
15747   mp->is_add = is_add;
15748   mp->vni = htonl (vni);
15749   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15750   mp->is_l2 = bd_index_set;
15751
15752   /* send */
15753   S (mp);
15754
15755   /* wait for reply */
15756   W (ret);
15757   return ret;
15758 }
15759
15760 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15761
15762 uword
15763 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15764 {
15765   u32 *action = va_arg (*args, u32 *);
15766   u8 *s = 0;
15767
15768   if (unformat (input, "%s", &s))
15769     {
15770       if (!strcmp ((char *) s, "no-action"))
15771         action[0] = 0;
15772       else if (!strcmp ((char *) s, "natively-forward"))
15773         action[0] = 1;
15774       else if (!strcmp ((char *) s, "send-map-request"))
15775         action[0] = 2;
15776       else if (!strcmp ((char *) s, "drop"))
15777         action[0] = 3;
15778       else
15779         {
15780           clib_warning ("invalid action: '%s'", s);
15781           action[0] = 3;
15782         }
15783     }
15784   else
15785     return 0;
15786
15787   vec_free (s);
15788   return 1;
15789 }
15790
15791 /**
15792  * Add/del remote mapping to/from ONE control plane
15793  *
15794  * @param vam vpp API test context
15795  * @return return code
15796  */
15797 static int
15798 api_one_add_del_remote_mapping (vat_main_t * vam)
15799 {
15800   unformat_input_t *input = vam->input;
15801   vl_api_one_add_del_remote_mapping_t *mp;
15802   u32 vni = 0;
15803   lisp_eid_vat_t _eid, *eid = &_eid;
15804   lisp_eid_vat_t _seid, *seid = &_seid;
15805   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15806   u32 action = ~0, p, w, data_len;
15807   ip4_address_t rloc4;
15808   ip6_address_t rloc6;
15809   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15810   int ret;
15811
15812   clib_memset (&rloc, 0, sizeof (rloc));
15813
15814   /* Parse args required to build the message */
15815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15816     {
15817       if (unformat (input, "del-all"))
15818         {
15819           del_all = 1;
15820         }
15821       else if (unformat (input, "del"))
15822         {
15823           is_add = 0;
15824         }
15825       else if (unformat (input, "add"))
15826         {
15827           is_add = 1;
15828         }
15829       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15830         {
15831           eid_set = 1;
15832         }
15833       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15834         {
15835           seid_set = 1;
15836         }
15837       else if (unformat (input, "vni %d", &vni))
15838         {
15839           ;
15840         }
15841       else if (unformat (input, "p %d w %d", &p, &w))
15842         {
15843           if (!curr_rloc)
15844             {
15845               errmsg ("No RLOC configured for setting priority/weight!");
15846               return -99;
15847             }
15848           curr_rloc->priority = p;
15849           curr_rloc->weight = w;
15850         }
15851       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15852         {
15853           rloc.is_ip4 = 1;
15854           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15855           vec_add1 (rlocs, rloc);
15856           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15857         }
15858       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15859         {
15860           rloc.is_ip4 = 0;
15861           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15862           vec_add1 (rlocs, rloc);
15863           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15864         }
15865       else if (unformat (input, "action %U",
15866                          unformat_negative_mapping_action, &action))
15867         {
15868           ;
15869         }
15870       else
15871         {
15872           clib_warning ("parse error '%U'", format_unformat_error, input);
15873           return -99;
15874         }
15875     }
15876
15877   if (0 == eid_set)
15878     {
15879       errmsg ("missing params!");
15880       return -99;
15881     }
15882
15883   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15884     {
15885       errmsg ("no action set for negative map-reply!");
15886       return -99;
15887     }
15888
15889   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15890
15891   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15892   mp->is_add = is_add;
15893   mp->vni = htonl (vni);
15894   mp->action = (u8) action;
15895   mp->is_src_dst = seid_set;
15896   mp->eid_len = eid->len;
15897   mp->seid_len = seid->len;
15898   mp->del_all = del_all;
15899   mp->eid_type = eid->type;
15900   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15901   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15902
15903   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15904   clib_memcpy (mp->rlocs, rlocs, data_len);
15905   vec_free (rlocs);
15906
15907   /* send it... */
15908   S (mp);
15909
15910   /* Wait for a reply... */
15911   W (ret);
15912   return ret;
15913 }
15914
15915 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15916
15917 /**
15918  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15919  * forwarding entries in data-plane accordingly.
15920  *
15921  * @param vam vpp API test context
15922  * @return return code
15923  */
15924 static int
15925 api_one_add_del_adjacency (vat_main_t * vam)
15926 {
15927   unformat_input_t *input = vam->input;
15928   vl_api_one_add_del_adjacency_t *mp;
15929   u32 vni = 0;
15930   ip4_address_t leid4, reid4;
15931   ip6_address_t leid6, reid6;
15932   u8 reid_mac[6] = { 0 };
15933   u8 leid_mac[6] = { 0 };
15934   u8 reid_type, leid_type;
15935   u32 leid_len = 0, reid_len = 0, len;
15936   u8 is_add = 1;
15937   int ret;
15938
15939   leid_type = reid_type = (u8) ~ 0;
15940
15941   /* Parse args required to build the message */
15942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15943     {
15944       if (unformat (input, "del"))
15945         {
15946           is_add = 0;
15947         }
15948       else if (unformat (input, "add"))
15949         {
15950           is_add = 1;
15951         }
15952       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15953                          &reid4, &len))
15954         {
15955           reid_type = 0;        /* ipv4 */
15956           reid_len = len;
15957         }
15958       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15959                          &reid6, &len))
15960         {
15961           reid_type = 1;        /* ipv6 */
15962           reid_len = len;
15963         }
15964       else if (unformat (input, "reid %U", unformat_ethernet_address,
15965                          reid_mac))
15966         {
15967           reid_type = 2;        /* mac */
15968         }
15969       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15970                          &leid4, &len))
15971         {
15972           leid_type = 0;        /* ipv4 */
15973           leid_len = len;
15974         }
15975       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15976                          &leid6, &len))
15977         {
15978           leid_type = 1;        /* ipv6 */
15979           leid_len = len;
15980         }
15981       else if (unformat (input, "leid %U", unformat_ethernet_address,
15982                          leid_mac))
15983         {
15984           leid_type = 2;        /* mac */
15985         }
15986       else if (unformat (input, "vni %d", &vni))
15987         {
15988           ;
15989         }
15990       else
15991         {
15992           errmsg ("parse error '%U'", format_unformat_error, input);
15993           return -99;
15994         }
15995     }
15996
15997   if ((u8) ~ 0 == reid_type)
15998     {
15999       errmsg ("missing params!");
16000       return -99;
16001     }
16002
16003   if (leid_type != reid_type)
16004     {
16005       errmsg ("remote and local EIDs are of different types!");
16006       return -99;
16007     }
16008
16009   M (ONE_ADD_DEL_ADJACENCY, mp);
16010   mp->is_add = is_add;
16011   mp->vni = htonl (vni);
16012   mp->leid_len = leid_len;
16013   mp->reid_len = reid_len;
16014   mp->eid_type = reid_type;
16015
16016   switch (mp->eid_type)
16017     {
16018     case 0:
16019       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16020       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16021       break;
16022     case 1:
16023       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16024       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16025       break;
16026     case 2:
16027       clib_memcpy (mp->leid, leid_mac, 6);
16028       clib_memcpy (mp->reid, reid_mac, 6);
16029       break;
16030     default:
16031       errmsg ("unknown EID type %d!", mp->eid_type);
16032       return 0;
16033     }
16034
16035   /* send it... */
16036   S (mp);
16037
16038   /* Wait for a reply... */
16039   W (ret);
16040   return ret;
16041 }
16042
16043 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16044
16045 uword
16046 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16047 {
16048   u32 *mode = va_arg (*args, u32 *);
16049
16050   if (unformat (input, "lisp"))
16051     *mode = 0;
16052   else if (unformat (input, "vxlan"))
16053     *mode = 1;
16054   else
16055     return 0;
16056
16057   return 1;
16058 }
16059
16060 static int
16061 api_gpe_get_encap_mode (vat_main_t * vam)
16062 {
16063   vl_api_gpe_get_encap_mode_t *mp;
16064   int ret;
16065
16066   /* Construct the API message */
16067   M (GPE_GET_ENCAP_MODE, mp);
16068
16069   /* send it... */
16070   S (mp);
16071
16072   /* Wait for a reply... */
16073   W (ret);
16074   return ret;
16075 }
16076
16077 static int
16078 api_gpe_set_encap_mode (vat_main_t * vam)
16079 {
16080   unformat_input_t *input = vam->input;
16081   vl_api_gpe_set_encap_mode_t *mp;
16082   int ret;
16083   u32 mode = 0;
16084
16085   /* Parse args required to build the message */
16086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16087     {
16088       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16089         ;
16090       else
16091         break;
16092     }
16093
16094   /* Construct the API message */
16095   M (GPE_SET_ENCAP_MODE, mp);
16096
16097   mp->mode = mode;
16098
16099   /* send it... */
16100   S (mp);
16101
16102   /* Wait for a reply... */
16103   W (ret);
16104   return ret;
16105 }
16106
16107 static int
16108 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16109 {
16110   unformat_input_t *input = vam->input;
16111   vl_api_gpe_add_del_iface_t *mp;
16112   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16113   u32 dp_table = 0, vni = 0;
16114   int ret;
16115
16116   /* Parse args required to build the message */
16117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16118     {
16119       if (unformat (input, "up"))
16120         {
16121           action_set = 1;
16122           is_add = 1;
16123         }
16124       else if (unformat (input, "down"))
16125         {
16126           action_set = 1;
16127           is_add = 0;
16128         }
16129       else if (unformat (input, "table_id %d", &dp_table))
16130         {
16131           dp_table_set = 1;
16132         }
16133       else if (unformat (input, "bd_id %d", &dp_table))
16134         {
16135           dp_table_set = 1;
16136           is_l2 = 1;
16137         }
16138       else if (unformat (input, "vni %d", &vni))
16139         {
16140           vni_set = 1;
16141         }
16142       else
16143         break;
16144     }
16145
16146   if (action_set == 0)
16147     {
16148       errmsg ("Action not set");
16149       return -99;
16150     }
16151   if (dp_table_set == 0 || vni_set == 0)
16152     {
16153       errmsg ("vni and dp_table must be set");
16154       return -99;
16155     }
16156
16157   /* Construct the API message */
16158   M (GPE_ADD_DEL_IFACE, mp);
16159
16160   mp->is_add = is_add;
16161   mp->dp_table = clib_host_to_net_u32 (dp_table);
16162   mp->is_l2 = is_l2;
16163   mp->vni = clib_host_to_net_u32 (vni);
16164
16165   /* send it... */
16166   S (mp);
16167
16168   /* Wait for a reply... */
16169   W (ret);
16170   return ret;
16171 }
16172
16173 static int
16174 api_one_map_register_fallback_threshold (vat_main_t * vam)
16175 {
16176   unformat_input_t *input = vam->input;
16177   vl_api_one_map_register_fallback_threshold_t *mp;
16178   u32 value = 0;
16179   u8 is_set = 0;
16180   int ret;
16181
16182   /* Parse args required to build the message */
16183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16184     {
16185       if (unformat (input, "%u", &value))
16186         is_set = 1;
16187       else
16188         {
16189           clib_warning ("parse error '%U'", format_unformat_error, input);
16190           return -99;
16191         }
16192     }
16193
16194   if (!is_set)
16195     {
16196       errmsg ("fallback threshold value is missing!");
16197       return -99;
16198     }
16199
16200   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16201   mp->value = clib_host_to_net_u32 (value);
16202
16203   /* send it... */
16204   S (mp);
16205
16206   /* Wait for a reply... */
16207   W (ret);
16208   return ret;
16209 }
16210
16211 static int
16212 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16213 {
16214   vl_api_show_one_map_register_fallback_threshold_t *mp;
16215   int ret;
16216
16217   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16218
16219   /* send it... */
16220   S (mp);
16221
16222   /* Wait for a reply... */
16223   W (ret);
16224   return ret;
16225 }
16226
16227 uword
16228 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16229 {
16230   u32 *proto = va_arg (*args, u32 *);
16231
16232   if (unformat (input, "udp"))
16233     *proto = 1;
16234   else if (unformat (input, "api"))
16235     *proto = 2;
16236   else
16237     return 0;
16238
16239   return 1;
16240 }
16241
16242 static int
16243 api_one_set_transport_protocol (vat_main_t * vam)
16244 {
16245   unformat_input_t *input = vam->input;
16246   vl_api_one_set_transport_protocol_t *mp;
16247   u8 is_set = 0;
16248   u32 protocol = 0;
16249   int ret;
16250
16251   /* Parse args required to build the message */
16252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16253     {
16254       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16255         is_set = 1;
16256       else
16257         {
16258           clib_warning ("parse error '%U'", format_unformat_error, input);
16259           return -99;
16260         }
16261     }
16262
16263   if (!is_set)
16264     {
16265       errmsg ("Transport protocol missing!");
16266       return -99;
16267     }
16268
16269   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16270   mp->protocol = (u8) protocol;
16271
16272   /* send it... */
16273   S (mp);
16274
16275   /* Wait for a reply... */
16276   W (ret);
16277   return ret;
16278 }
16279
16280 static int
16281 api_one_get_transport_protocol (vat_main_t * vam)
16282 {
16283   vl_api_one_get_transport_protocol_t *mp;
16284   int ret;
16285
16286   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16287
16288   /* send it... */
16289   S (mp);
16290
16291   /* Wait for a reply... */
16292   W (ret);
16293   return ret;
16294 }
16295
16296 static int
16297 api_one_map_register_set_ttl (vat_main_t * vam)
16298 {
16299   unformat_input_t *input = vam->input;
16300   vl_api_one_map_register_set_ttl_t *mp;
16301   u32 ttl = 0;
16302   u8 is_set = 0;
16303   int ret;
16304
16305   /* Parse args required to build the message */
16306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (input, "%u", &ttl))
16309         is_set = 1;
16310       else
16311         {
16312           clib_warning ("parse error '%U'", format_unformat_error, input);
16313           return -99;
16314         }
16315     }
16316
16317   if (!is_set)
16318     {
16319       errmsg ("TTL value missing!");
16320       return -99;
16321     }
16322
16323   M (ONE_MAP_REGISTER_SET_TTL, mp);
16324   mp->ttl = clib_host_to_net_u32 (ttl);
16325
16326   /* send it... */
16327   S (mp);
16328
16329   /* Wait for a reply... */
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_show_one_map_register_ttl (vat_main_t * vam)
16336 {
16337   vl_api_show_one_map_register_ttl_t *mp;
16338   int ret;
16339
16340   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16341
16342   /* send it... */
16343   S (mp);
16344
16345   /* Wait for a reply... */
16346   W (ret);
16347   return ret;
16348 }
16349
16350 /**
16351  * Add/del map request itr rlocs from ONE control plane and updates
16352  *
16353  * @param vam vpp API test context
16354  * @return return code
16355  */
16356 static int
16357 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16358 {
16359   unformat_input_t *input = vam->input;
16360   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16361   u8 *locator_set_name = 0;
16362   u8 locator_set_name_set = 0;
16363   u8 is_add = 1;
16364   int ret;
16365
16366   /* Parse args required to build the message */
16367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16368     {
16369       if (unformat (input, "del"))
16370         {
16371           is_add = 0;
16372         }
16373       else if (unformat (input, "%_%v%_", &locator_set_name))
16374         {
16375           locator_set_name_set = 1;
16376         }
16377       else
16378         {
16379           clib_warning ("parse error '%U'", format_unformat_error, input);
16380           return -99;
16381         }
16382     }
16383
16384   if (is_add && !locator_set_name_set)
16385     {
16386       errmsg ("itr-rloc is not set!");
16387       return -99;
16388     }
16389
16390   if (is_add && vec_len (locator_set_name) > 64)
16391     {
16392       errmsg ("itr-rloc locator-set name too long");
16393       vec_free (locator_set_name);
16394       return -99;
16395     }
16396
16397   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16398   mp->is_add = is_add;
16399   if (is_add)
16400     {
16401       clib_memcpy (mp->locator_set_name, locator_set_name,
16402                    vec_len (locator_set_name));
16403     }
16404   else
16405     {
16406       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16407     }
16408   vec_free (locator_set_name);
16409
16410   /* send it... */
16411   S (mp);
16412
16413   /* Wait for a reply... */
16414   W (ret);
16415   return ret;
16416 }
16417
16418 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16419
16420 static int
16421 api_one_locator_dump (vat_main_t * vam)
16422 {
16423   unformat_input_t *input = vam->input;
16424   vl_api_one_locator_dump_t *mp;
16425   vl_api_control_ping_t *mp_ping;
16426   u8 is_index_set = 0, is_name_set = 0;
16427   u8 *ls_name = 0;
16428   u32 ls_index = ~0;
16429   int ret;
16430
16431   /* Parse args required to build the message */
16432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16433     {
16434       if (unformat (input, "ls_name %_%v%_", &ls_name))
16435         {
16436           is_name_set = 1;
16437         }
16438       else if (unformat (input, "ls_index %d", &ls_index))
16439         {
16440           is_index_set = 1;
16441         }
16442       else
16443         {
16444           errmsg ("parse error '%U'", format_unformat_error, input);
16445           return -99;
16446         }
16447     }
16448
16449   if (!is_index_set && !is_name_set)
16450     {
16451       errmsg ("error: expected one of index or name!");
16452       return -99;
16453     }
16454
16455   if (is_index_set && is_name_set)
16456     {
16457       errmsg ("error: only one param expected!");
16458       return -99;
16459     }
16460
16461   if (vec_len (ls_name) > 62)
16462     {
16463       errmsg ("error: locator set name too long!");
16464       return -99;
16465     }
16466
16467   if (!vam->json_output)
16468     {
16469       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16470     }
16471
16472   M (ONE_LOCATOR_DUMP, mp);
16473   mp->is_index_set = is_index_set;
16474
16475   if (is_index_set)
16476     mp->ls_index = clib_host_to_net_u32 (ls_index);
16477   else
16478     {
16479       vec_add1 (ls_name, 0);
16480       strncpy ((char *) mp->ls_name, (char *) ls_name,
16481                sizeof (mp->ls_name) - 1);
16482     }
16483
16484   /* send it... */
16485   S (mp);
16486
16487   /* Use a control ping for synchronization */
16488   MPING (CONTROL_PING, mp_ping);
16489   S (mp_ping);
16490
16491   /* Wait for a reply... */
16492   W (ret);
16493   return ret;
16494 }
16495
16496 #define api_lisp_locator_dump api_one_locator_dump
16497
16498 static int
16499 api_one_locator_set_dump (vat_main_t * vam)
16500 {
16501   vl_api_one_locator_set_dump_t *mp;
16502   vl_api_control_ping_t *mp_ping;
16503   unformat_input_t *input = vam->input;
16504   u8 filter = 0;
16505   int ret;
16506
16507   /* Parse args required to build the message */
16508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16509     {
16510       if (unformat (input, "local"))
16511         {
16512           filter = 1;
16513         }
16514       else if (unformat (input, "remote"))
16515         {
16516           filter = 2;
16517         }
16518       else
16519         {
16520           errmsg ("parse error '%U'", format_unformat_error, input);
16521           return -99;
16522         }
16523     }
16524
16525   if (!vam->json_output)
16526     {
16527       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16528     }
16529
16530   M (ONE_LOCATOR_SET_DUMP, mp);
16531
16532   mp->filter = filter;
16533
16534   /* send it... */
16535   S (mp);
16536
16537   /* Use a control ping for synchronization */
16538   MPING (CONTROL_PING, mp_ping);
16539   S (mp_ping);
16540
16541   /* Wait for a reply... */
16542   W (ret);
16543   return ret;
16544 }
16545
16546 #define api_lisp_locator_set_dump api_one_locator_set_dump
16547
16548 static int
16549 api_one_eid_table_map_dump (vat_main_t * vam)
16550 {
16551   u8 is_l2 = 0;
16552   u8 mode_set = 0;
16553   unformat_input_t *input = vam->input;
16554   vl_api_one_eid_table_map_dump_t *mp;
16555   vl_api_control_ping_t *mp_ping;
16556   int ret;
16557
16558   /* Parse args required to build the message */
16559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16560     {
16561       if (unformat (input, "l2"))
16562         {
16563           is_l2 = 1;
16564           mode_set = 1;
16565         }
16566       else if (unformat (input, "l3"))
16567         {
16568           is_l2 = 0;
16569           mode_set = 1;
16570         }
16571       else
16572         {
16573           errmsg ("parse error '%U'", format_unformat_error, input);
16574           return -99;
16575         }
16576     }
16577
16578   if (!mode_set)
16579     {
16580       errmsg ("expected one of 'l2' or 'l3' parameter!");
16581       return -99;
16582     }
16583
16584   if (!vam->json_output)
16585     {
16586       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16587     }
16588
16589   M (ONE_EID_TABLE_MAP_DUMP, mp);
16590   mp->is_l2 = is_l2;
16591
16592   /* send it... */
16593   S (mp);
16594
16595   /* Use a control ping for synchronization */
16596   MPING (CONTROL_PING, mp_ping);
16597   S (mp_ping);
16598
16599   /* Wait for a reply... */
16600   W (ret);
16601   return ret;
16602 }
16603
16604 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16605
16606 static int
16607 api_one_eid_table_vni_dump (vat_main_t * vam)
16608 {
16609   vl_api_one_eid_table_vni_dump_t *mp;
16610   vl_api_control_ping_t *mp_ping;
16611   int ret;
16612
16613   if (!vam->json_output)
16614     {
16615       print (vam->ofp, "VNI");
16616     }
16617
16618   M (ONE_EID_TABLE_VNI_DUMP, mp);
16619
16620   /* send it... */
16621   S (mp);
16622
16623   /* Use a control ping for synchronization */
16624   MPING (CONTROL_PING, mp_ping);
16625   S (mp_ping);
16626
16627   /* Wait for a reply... */
16628   W (ret);
16629   return ret;
16630 }
16631
16632 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16633
16634 static int
16635 api_one_eid_table_dump (vat_main_t * vam)
16636 {
16637   unformat_input_t *i = vam->input;
16638   vl_api_one_eid_table_dump_t *mp;
16639   vl_api_control_ping_t *mp_ping;
16640   struct in_addr ip4;
16641   struct in6_addr ip6;
16642   u8 mac[6];
16643   u8 eid_type = ~0, eid_set = 0;
16644   u32 prefix_length = ~0, t, vni = 0;
16645   u8 filter = 0;
16646   int ret;
16647   lisp_nsh_api_t nsh;
16648
16649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16650     {
16651       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16652         {
16653           eid_set = 1;
16654           eid_type = 0;
16655           prefix_length = t;
16656         }
16657       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16658         {
16659           eid_set = 1;
16660           eid_type = 1;
16661           prefix_length = t;
16662         }
16663       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16664         {
16665           eid_set = 1;
16666           eid_type = 2;
16667         }
16668       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16669         {
16670           eid_set = 1;
16671           eid_type = 3;
16672         }
16673       else if (unformat (i, "vni %d", &t))
16674         {
16675           vni = t;
16676         }
16677       else if (unformat (i, "local"))
16678         {
16679           filter = 1;
16680         }
16681       else if (unformat (i, "remote"))
16682         {
16683           filter = 2;
16684         }
16685       else
16686         {
16687           errmsg ("parse error '%U'", format_unformat_error, i);
16688           return -99;
16689         }
16690     }
16691
16692   if (!vam->json_output)
16693     {
16694       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16695              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16696     }
16697
16698   M (ONE_EID_TABLE_DUMP, mp);
16699
16700   mp->filter = filter;
16701   if (eid_set)
16702     {
16703       mp->eid_set = 1;
16704       mp->vni = htonl (vni);
16705       mp->eid_type = eid_type;
16706       switch (eid_type)
16707         {
16708         case 0:
16709           mp->prefix_length = prefix_length;
16710           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16711           break;
16712         case 1:
16713           mp->prefix_length = prefix_length;
16714           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16715           break;
16716         case 2:
16717           clib_memcpy (mp->eid, mac, sizeof (mac));
16718           break;
16719         case 3:
16720           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16721           break;
16722         default:
16723           errmsg ("unknown EID type %d!", eid_type);
16724           return -99;
16725         }
16726     }
16727
16728   /* send it... */
16729   S (mp);
16730
16731   /* Use a control ping for synchronization */
16732   MPING (CONTROL_PING, mp_ping);
16733   S (mp_ping);
16734
16735   /* Wait for a reply... */
16736   W (ret);
16737   return ret;
16738 }
16739
16740 #define api_lisp_eid_table_dump api_one_eid_table_dump
16741
16742 static int
16743 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16744 {
16745   unformat_input_t *i = vam->input;
16746   vl_api_gpe_fwd_entries_get_t *mp;
16747   u8 vni_set = 0;
16748   u32 vni = ~0;
16749   int ret;
16750
16751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16752     {
16753       if (unformat (i, "vni %d", &vni))
16754         {
16755           vni_set = 1;
16756         }
16757       else
16758         {
16759           errmsg ("parse error '%U'", format_unformat_error, i);
16760           return -99;
16761         }
16762     }
16763
16764   if (!vni_set)
16765     {
16766       errmsg ("vni not set!");
16767       return -99;
16768     }
16769
16770   if (!vam->json_output)
16771     {
16772       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16773              "leid", "reid");
16774     }
16775
16776   M (GPE_FWD_ENTRIES_GET, mp);
16777   mp->vni = clib_host_to_net_u32 (vni);
16778
16779   /* send it... */
16780   S (mp);
16781
16782   /* Wait for a reply... */
16783   W (ret);
16784   return ret;
16785 }
16786
16787 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16788 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16789 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16790 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16791 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16792 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16793 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16794 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16795
16796 static int
16797 api_one_adjacencies_get (vat_main_t * vam)
16798 {
16799   unformat_input_t *i = vam->input;
16800   vl_api_one_adjacencies_get_t *mp;
16801   u8 vni_set = 0;
16802   u32 vni = ~0;
16803   int ret;
16804
16805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16806     {
16807       if (unformat (i, "vni %d", &vni))
16808         {
16809           vni_set = 1;
16810         }
16811       else
16812         {
16813           errmsg ("parse error '%U'", format_unformat_error, i);
16814           return -99;
16815         }
16816     }
16817
16818   if (!vni_set)
16819     {
16820       errmsg ("vni not set!");
16821       return -99;
16822     }
16823
16824   if (!vam->json_output)
16825     {
16826       print (vam->ofp, "%s %40s", "leid", "reid");
16827     }
16828
16829   M (ONE_ADJACENCIES_GET, mp);
16830   mp->vni = clib_host_to_net_u32 (vni);
16831
16832   /* send it... */
16833   S (mp);
16834
16835   /* Wait for a reply... */
16836   W (ret);
16837   return ret;
16838 }
16839
16840 #define api_lisp_adjacencies_get api_one_adjacencies_get
16841
16842 static int
16843 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16844 {
16845   unformat_input_t *i = vam->input;
16846   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16847   int ret;
16848   u8 ip_family_set = 0, is_ip4 = 1;
16849
16850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16851     {
16852       if (unformat (i, "ip4"))
16853         {
16854           ip_family_set = 1;
16855           is_ip4 = 1;
16856         }
16857       else if (unformat (i, "ip6"))
16858         {
16859           ip_family_set = 1;
16860           is_ip4 = 0;
16861         }
16862       else
16863         {
16864           errmsg ("parse error '%U'", format_unformat_error, i);
16865           return -99;
16866         }
16867     }
16868
16869   if (!ip_family_set)
16870     {
16871       errmsg ("ip family not set!");
16872       return -99;
16873     }
16874
16875   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16876   mp->is_ip4 = is_ip4;
16877
16878   /* send it... */
16879   S (mp);
16880
16881   /* Wait for a reply... */
16882   W (ret);
16883   return ret;
16884 }
16885
16886 static int
16887 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16888 {
16889   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16890   int ret;
16891
16892   if (!vam->json_output)
16893     {
16894       print (vam->ofp, "VNIs");
16895     }
16896
16897   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16898
16899   /* send it... */
16900   S (mp);
16901
16902   /* Wait for a reply... */
16903   W (ret);
16904   return ret;
16905 }
16906
16907 static int
16908 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16909 {
16910   unformat_input_t *i = vam->input;
16911   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16912   int ret = 0;
16913   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16914   struct in_addr ip4;
16915   struct in6_addr ip6;
16916   u32 table_id = 0, nh_sw_if_index = ~0;
16917
16918   clib_memset (&ip4, 0, sizeof (ip4));
16919   clib_memset (&ip6, 0, sizeof (ip6));
16920
16921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16922     {
16923       if (unformat (i, "del"))
16924         is_add = 0;
16925       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16926                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16927         {
16928           ip_set = 1;
16929           is_ip4 = 1;
16930         }
16931       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16932                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16933         {
16934           ip_set = 1;
16935           is_ip4 = 0;
16936         }
16937       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16938         {
16939           ip_set = 1;
16940           is_ip4 = 1;
16941           nh_sw_if_index = ~0;
16942         }
16943       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16944         {
16945           ip_set = 1;
16946           is_ip4 = 0;
16947           nh_sw_if_index = ~0;
16948         }
16949       else if (unformat (i, "table %d", &table_id))
16950         ;
16951       else
16952         {
16953           errmsg ("parse error '%U'", format_unformat_error, i);
16954           return -99;
16955         }
16956     }
16957
16958   if (!ip_set)
16959     {
16960       errmsg ("nh addr not set!");
16961       return -99;
16962     }
16963
16964   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16965   mp->is_add = is_add;
16966   mp->table_id = clib_host_to_net_u32 (table_id);
16967   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16968   mp->is_ip4 = is_ip4;
16969   if (is_ip4)
16970     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16971   else
16972     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16973
16974   /* send it... */
16975   S (mp);
16976
16977   /* Wait for a reply... */
16978   W (ret);
16979   return ret;
16980 }
16981
16982 static int
16983 api_one_map_server_dump (vat_main_t * vam)
16984 {
16985   vl_api_one_map_server_dump_t *mp;
16986   vl_api_control_ping_t *mp_ping;
16987   int ret;
16988
16989   if (!vam->json_output)
16990     {
16991       print (vam->ofp, "%=20s", "Map server");
16992     }
16993
16994   M (ONE_MAP_SERVER_DUMP, mp);
16995   /* send it... */
16996   S (mp);
16997
16998   /* Use a control ping for synchronization */
16999   MPING (CONTROL_PING, mp_ping);
17000   S (mp_ping);
17001
17002   /* Wait for a reply... */
17003   W (ret);
17004   return ret;
17005 }
17006
17007 #define api_lisp_map_server_dump api_one_map_server_dump
17008
17009 static int
17010 api_one_map_resolver_dump (vat_main_t * vam)
17011 {
17012   vl_api_one_map_resolver_dump_t *mp;
17013   vl_api_control_ping_t *mp_ping;
17014   int ret;
17015
17016   if (!vam->json_output)
17017     {
17018       print (vam->ofp, "%=20s", "Map resolver");
17019     }
17020
17021   M (ONE_MAP_RESOLVER_DUMP, mp);
17022   /* send it... */
17023   S (mp);
17024
17025   /* Use a control ping for synchronization */
17026   MPING (CONTROL_PING, mp_ping);
17027   S (mp_ping);
17028
17029   /* Wait for a reply... */
17030   W (ret);
17031   return ret;
17032 }
17033
17034 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17035
17036 static int
17037 api_one_stats_flush (vat_main_t * vam)
17038 {
17039   vl_api_one_stats_flush_t *mp;
17040   int ret = 0;
17041
17042   M (ONE_STATS_FLUSH, mp);
17043   S (mp);
17044   W (ret);
17045   return ret;
17046 }
17047
17048 static int
17049 api_one_stats_dump (vat_main_t * vam)
17050 {
17051   vl_api_one_stats_dump_t *mp;
17052   vl_api_control_ping_t *mp_ping;
17053   int ret;
17054
17055   M (ONE_STATS_DUMP, mp);
17056   /* send it... */
17057   S (mp);
17058
17059   /* Use a control ping for synchronization */
17060   MPING (CONTROL_PING, mp_ping);
17061   S (mp_ping);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 static int
17069 api_show_one_status (vat_main_t * vam)
17070 {
17071   vl_api_show_one_status_t *mp;
17072   int ret;
17073
17074   if (!vam->json_output)
17075     {
17076       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17077     }
17078
17079   M (SHOW_ONE_STATUS, mp);
17080   /* send it... */
17081   S (mp);
17082   /* Wait for a reply... */
17083   W (ret);
17084   return ret;
17085 }
17086
17087 #define api_show_lisp_status api_show_one_status
17088
17089 static int
17090 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17091 {
17092   vl_api_gpe_fwd_entry_path_dump_t *mp;
17093   vl_api_control_ping_t *mp_ping;
17094   unformat_input_t *i = vam->input;
17095   u32 fwd_entry_index = ~0;
17096   int ret;
17097
17098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17099     {
17100       if (unformat (i, "index %d", &fwd_entry_index))
17101         ;
17102       else
17103         break;
17104     }
17105
17106   if (~0 == fwd_entry_index)
17107     {
17108       errmsg ("no index specified!");
17109       return -99;
17110     }
17111
17112   if (!vam->json_output)
17113     {
17114       print (vam->ofp, "first line");
17115     }
17116
17117   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17118
17119   /* send it... */
17120   S (mp);
17121   /* Use a control ping for synchronization */
17122   MPING (CONTROL_PING, mp_ping);
17123   S (mp_ping);
17124
17125   /* Wait for a reply... */
17126   W (ret);
17127   return ret;
17128 }
17129
17130 static int
17131 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17132 {
17133   vl_api_one_get_map_request_itr_rlocs_t *mp;
17134   int ret;
17135
17136   if (!vam->json_output)
17137     {
17138       print (vam->ofp, "%=20s", "itr-rlocs:");
17139     }
17140
17141   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17142   /* send it... */
17143   S (mp);
17144   /* Wait for a reply... */
17145   W (ret);
17146   return ret;
17147 }
17148
17149 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17150
17151 static int
17152 api_af_packet_create (vat_main_t * vam)
17153 {
17154   unformat_input_t *i = vam->input;
17155   vl_api_af_packet_create_t *mp;
17156   u8 *host_if_name = 0;
17157   u8 hw_addr[6];
17158   u8 random_hw_addr = 1;
17159   int ret;
17160
17161   clib_memset (hw_addr, 0, sizeof (hw_addr));
17162
17163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17164     {
17165       if (unformat (i, "name %s", &host_if_name))
17166         vec_add1 (host_if_name, 0);
17167       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17168         random_hw_addr = 0;
17169       else
17170         break;
17171     }
17172
17173   if (!vec_len (host_if_name))
17174     {
17175       errmsg ("host-interface name must be specified");
17176       return -99;
17177     }
17178
17179   if (vec_len (host_if_name) > 64)
17180     {
17181       errmsg ("host-interface name too long");
17182       return -99;
17183     }
17184
17185   M (AF_PACKET_CREATE, mp);
17186
17187   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17188   clib_memcpy (mp->hw_addr, hw_addr, 6);
17189   mp->use_random_hw_addr = random_hw_addr;
17190   vec_free (host_if_name);
17191
17192   S (mp);
17193
17194   /* *INDENT-OFF* */
17195   W2 (ret,
17196       ({
17197         if (ret == 0)
17198           fprintf (vam->ofp ? vam->ofp : stderr,
17199                    " new sw_if_index = %d\n", vam->sw_if_index);
17200       }));
17201   /* *INDENT-ON* */
17202   return ret;
17203 }
17204
17205 static int
17206 api_af_packet_delete (vat_main_t * vam)
17207 {
17208   unformat_input_t *i = vam->input;
17209   vl_api_af_packet_delete_t *mp;
17210   u8 *host_if_name = 0;
17211   int ret;
17212
17213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17214     {
17215       if (unformat (i, "name %s", &host_if_name))
17216         vec_add1 (host_if_name, 0);
17217       else
17218         break;
17219     }
17220
17221   if (!vec_len (host_if_name))
17222     {
17223       errmsg ("host-interface name must be specified");
17224       return -99;
17225     }
17226
17227   if (vec_len (host_if_name) > 64)
17228     {
17229       errmsg ("host-interface name too long");
17230       return -99;
17231     }
17232
17233   M (AF_PACKET_DELETE, mp);
17234
17235   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17236   vec_free (host_if_name);
17237
17238   S (mp);
17239   W (ret);
17240   return ret;
17241 }
17242
17243 static void vl_api_af_packet_details_t_handler
17244   (vl_api_af_packet_details_t * mp)
17245 {
17246   vat_main_t *vam = &vat_main;
17247
17248   print (vam->ofp, "%-16s %d",
17249          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17250 }
17251
17252 static void vl_api_af_packet_details_t_handler_json
17253   (vl_api_af_packet_details_t * mp)
17254 {
17255   vat_main_t *vam = &vat_main;
17256   vat_json_node_t *node = NULL;
17257
17258   if (VAT_JSON_ARRAY != vam->json_tree.type)
17259     {
17260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17261       vat_json_init_array (&vam->json_tree);
17262     }
17263   node = vat_json_array_add (&vam->json_tree);
17264
17265   vat_json_init_object (node);
17266   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17267   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17268 }
17269
17270 static int
17271 api_af_packet_dump (vat_main_t * vam)
17272 {
17273   vl_api_af_packet_dump_t *mp;
17274   vl_api_control_ping_t *mp_ping;
17275   int ret;
17276
17277   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17278   /* Get list of tap interfaces */
17279   M (AF_PACKET_DUMP, mp);
17280   S (mp);
17281
17282   /* Use a control ping for synchronization */
17283   MPING (CONTROL_PING, mp_ping);
17284   S (mp_ping);
17285
17286   W (ret);
17287   return ret;
17288 }
17289
17290 static int
17291 api_policer_add_del (vat_main_t * vam)
17292 {
17293   unformat_input_t *i = vam->input;
17294   vl_api_policer_add_del_t *mp;
17295   u8 is_add = 1;
17296   u8 *name = 0;
17297   u32 cir = 0;
17298   u32 eir = 0;
17299   u64 cb = 0;
17300   u64 eb = 0;
17301   u8 rate_type = 0;
17302   u8 round_type = 0;
17303   u8 type = 0;
17304   u8 color_aware = 0;
17305   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17306   int ret;
17307
17308   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17309   conform_action.dscp = 0;
17310   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17311   exceed_action.dscp = 0;
17312   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17313   violate_action.dscp = 0;
17314
17315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17316     {
17317       if (unformat (i, "del"))
17318         is_add = 0;
17319       else if (unformat (i, "name %s", &name))
17320         vec_add1 (name, 0);
17321       else if (unformat (i, "cir %u", &cir))
17322         ;
17323       else if (unformat (i, "eir %u", &eir))
17324         ;
17325       else if (unformat (i, "cb %u", &cb))
17326         ;
17327       else if (unformat (i, "eb %u", &eb))
17328         ;
17329       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17330                          &rate_type))
17331         ;
17332       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17333                          &round_type))
17334         ;
17335       else if (unformat (i, "type %U", unformat_policer_type, &type))
17336         ;
17337       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17338                          &conform_action))
17339         ;
17340       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17341                          &exceed_action))
17342         ;
17343       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17344                          &violate_action))
17345         ;
17346       else if (unformat (i, "color-aware"))
17347         color_aware = 1;
17348       else
17349         break;
17350     }
17351
17352   if (!vec_len (name))
17353     {
17354       errmsg ("policer name must be specified");
17355       return -99;
17356     }
17357
17358   if (vec_len (name) > 64)
17359     {
17360       errmsg ("policer name too long");
17361       return -99;
17362     }
17363
17364   M (POLICER_ADD_DEL, mp);
17365
17366   clib_memcpy (mp->name, name, vec_len (name));
17367   vec_free (name);
17368   mp->is_add = is_add;
17369   mp->cir = ntohl (cir);
17370   mp->eir = ntohl (eir);
17371   mp->cb = clib_net_to_host_u64 (cb);
17372   mp->eb = clib_net_to_host_u64 (eb);
17373   mp->rate_type = rate_type;
17374   mp->round_type = round_type;
17375   mp->type = type;
17376   mp->conform_action_type = conform_action.action_type;
17377   mp->conform_dscp = conform_action.dscp;
17378   mp->exceed_action_type = exceed_action.action_type;
17379   mp->exceed_dscp = exceed_action.dscp;
17380   mp->violate_action_type = violate_action.action_type;
17381   mp->violate_dscp = violate_action.dscp;
17382   mp->color_aware = color_aware;
17383
17384   S (mp);
17385   W (ret);
17386   return ret;
17387 }
17388
17389 static int
17390 api_policer_dump (vat_main_t * vam)
17391 {
17392   unformat_input_t *i = vam->input;
17393   vl_api_policer_dump_t *mp;
17394   vl_api_control_ping_t *mp_ping;
17395   u8 *match_name = 0;
17396   u8 match_name_valid = 0;
17397   int ret;
17398
17399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17400     {
17401       if (unformat (i, "name %s", &match_name))
17402         {
17403           vec_add1 (match_name, 0);
17404           match_name_valid = 1;
17405         }
17406       else
17407         break;
17408     }
17409
17410   M (POLICER_DUMP, mp);
17411   mp->match_name_valid = match_name_valid;
17412   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17413   vec_free (match_name);
17414   /* send it... */
17415   S (mp);
17416
17417   /* Use a control ping for synchronization */
17418   MPING (CONTROL_PING, mp_ping);
17419   S (mp_ping);
17420
17421   /* Wait for a reply... */
17422   W (ret);
17423   return ret;
17424 }
17425
17426 static int
17427 api_policer_classify_set_interface (vat_main_t * vam)
17428 {
17429   unformat_input_t *i = vam->input;
17430   vl_api_policer_classify_set_interface_t *mp;
17431   u32 sw_if_index;
17432   int sw_if_index_set;
17433   u32 ip4_table_index = ~0;
17434   u32 ip6_table_index = ~0;
17435   u32 l2_table_index = ~0;
17436   u8 is_add = 1;
17437   int ret;
17438
17439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17440     {
17441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17442         sw_if_index_set = 1;
17443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17444         sw_if_index_set = 1;
17445       else if (unformat (i, "del"))
17446         is_add = 0;
17447       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17448         ;
17449       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17450         ;
17451       else if (unformat (i, "l2-table %d", &l2_table_index))
17452         ;
17453       else
17454         {
17455           clib_warning ("parse error '%U'", format_unformat_error, i);
17456           return -99;
17457         }
17458     }
17459
17460   if (sw_if_index_set == 0)
17461     {
17462       errmsg ("missing interface name or sw_if_index");
17463       return -99;
17464     }
17465
17466   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17467
17468   mp->sw_if_index = ntohl (sw_if_index);
17469   mp->ip4_table_index = ntohl (ip4_table_index);
17470   mp->ip6_table_index = ntohl (ip6_table_index);
17471   mp->l2_table_index = ntohl (l2_table_index);
17472   mp->is_add = is_add;
17473
17474   S (mp);
17475   W (ret);
17476   return ret;
17477 }
17478
17479 static int
17480 api_policer_classify_dump (vat_main_t * vam)
17481 {
17482   unformat_input_t *i = vam->input;
17483   vl_api_policer_classify_dump_t *mp;
17484   vl_api_control_ping_t *mp_ping;
17485   u8 type = POLICER_CLASSIFY_N_TABLES;
17486   int ret;
17487
17488   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17489     ;
17490   else
17491     {
17492       errmsg ("classify table type must be specified");
17493       return -99;
17494     }
17495
17496   if (!vam->json_output)
17497     {
17498       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17499     }
17500
17501   M (POLICER_CLASSIFY_DUMP, mp);
17502   mp->type = type;
17503   /* send it... */
17504   S (mp);
17505
17506   /* Use a control ping for synchronization */
17507   MPING (CONTROL_PING, mp_ping);
17508   S (mp_ping);
17509
17510   /* Wait for a reply... */
17511   W (ret);
17512   return ret;
17513 }
17514
17515 static u8 *
17516 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17517 {
17518   vl_api_fib_path_nh_proto_t proto =
17519     va_arg (*args, vl_api_fib_path_nh_proto_t);
17520
17521   switch (proto)
17522     {
17523     case FIB_API_PATH_NH_PROTO_IP4:
17524       s = format (s, "ip4");
17525       break;
17526     case FIB_API_PATH_NH_PROTO_IP6:
17527       s = format (s, "ip6");
17528       break;
17529     case FIB_API_PATH_NH_PROTO_MPLS:
17530       s = format (s, "mpls");
17531       break;
17532     case FIB_API_PATH_NH_PROTO_BIER:
17533       s = format (s, "bier");
17534       break;
17535     case FIB_API_PATH_NH_PROTO_ETHERNET:
17536       s = format (s, "ethernet");
17537       break;
17538     }
17539
17540   return (s);
17541 }
17542
17543 static u8 *
17544 format_vl_api_ip_address_union (u8 * s, va_list * args)
17545 {
17546   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17547   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17548
17549   switch (af)
17550     {
17551     case ADDRESS_IP4:
17552       s = format (s, "%U", format_ip4_address, u->ip4);
17553       break;
17554     case ADDRESS_IP6:
17555       s = format (s, "%U", format_ip6_address, u->ip6);
17556       break;
17557     }
17558   return (s);
17559 }
17560
17561 static u8 *
17562 format_vl_api_fib_path_type (u8 * s, va_list * args)
17563 {
17564   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17565
17566   switch (t)
17567     {
17568     case FIB_API_PATH_TYPE_NORMAL:
17569       s = format (s, "normal");
17570       break;
17571     case FIB_API_PATH_TYPE_LOCAL:
17572       s = format (s, "local");
17573       break;
17574     case FIB_API_PATH_TYPE_DROP:
17575       s = format (s, "drop");
17576       break;
17577     case FIB_API_PATH_TYPE_UDP_ENCAP:
17578       s = format (s, "udp-encap");
17579       break;
17580     case FIB_API_PATH_TYPE_BIER_IMP:
17581       s = format (s, "bier-imp");
17582       break;
17583     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17584       s = format (s, "unreach");
17585       break;
17586     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17587       s = format (s, "prohibit");
17588       break;
17589     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17590       s = format (s, "src-lookup");
17591       break;
17592     case FIB_API_PATH_TYPE_DVR:
17593       s = format (s, "dvr");
17594       break;
17595     case FIB_API_PATH_TYPE_INTERFACE_RX:
17596       s = format (s, "interface-rx");
17597       break;
17598     case FIB_API_PATH_TYPE_CLASSIFY:
17599       s = format (s, "classify");
17600       break;
17601     }
17602
17603   return (s);
17604 }
17605
17606 static void
17607 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17608 {
17609   print (vam->ofp,
17610          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17611          ntohl (fp->weight), ntohl (fp->sw_if_index),
17612          format_vl_api_fib_path_type, fp->type,
17613          format_fib_api_path_nh_proto, fp->proto,
17614          format_vl_api_ip_address_union, &fp->nh.address);
17615 }
17616
17617 static void
17618 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17619                                  vl_api_fib_path_t * fp)
17620 {
17621   struct in_addr ip4;
17622   struct in6_addr ip6;
17623
17624   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17625   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17626   vat_json_object_add_uint (node, "type", fp->type);
17627   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17628   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17629     {
17630       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17631       vat_json_object_add_ip4 (node, "next_hop", ip4);
17632     }
17633   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17634     {
17635       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17636       vat_json_object_add_ip6 (node, "next_hop", ip6);
17637     }
17638 }
17639
17640 static void
17641 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17642 {
17643   vat_main_t *vam = &vat_main;
17644   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17645   vl_api_fib_path_t *fp;
17646   i32 i;
17647
17648   print (vam->ofp, "sw_if_index %d via:",
17649          ntohl (mp->mt_tunnel.mt_sw_if_index));
17650   fp = mp->mt_tunnel.mt_paths;
17651   for (i = 0; i < count; i++)
17652     {
17653       vl_api_fib_path_print (vam, fp);
17654       fp++;
17655     }
17656
17657   print (vam->ofp, "");
17658 }
17659
17660 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17661 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17662
17663 static void
17664 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17665 {
17666   vat_main_t *vam = &vat_main;
17667   vat_json_node_t *node = NULL;
17668   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17669   vl_api_fib_path_t *fp;
17670   i32 i;
17671
17672   if (VAT_JSON_ARRAY != vam->json_tree.type)
17673     {
17674       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17675       vat_json_init_array (&vam->json_tree);
17676     }
17677   node = vat_json_array_add (&vam->json_tree);
17678
17679   vat_json_init_object (node);
17680   vat_json_object_add_uint (node, "sw_if_index",
17681                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17682
17683   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17684
17685   fp = mp->mt_tunnel.mt_paths;
17686   for (i = 0; i < count; i++)
17687     {
17688       vl_api_mpls_fib_path_json_print (node, fp);
17689       fp++;
17690     }
17691 }
17692
17693 static int
17694 api_mpls_tunnel_dump (vat_main_t * vam)
17695 {
17696   vl_api_mpls_tunnel_dump_t *mp;
17697   vl_api_control_ping_t *mp_ping;
17698   int ret;
17699
17700   M (MPLS_TUNNEL_DUMP, mp);
17701
17702   S (mp);
17703
17704   /* Use a control ping for synchronization */
17705   MPING (CONTROL_PING, mp_ping);
17706   S (mp_ping);
17707
17708   W (ret);
17709   return ret;
17710 }
17711
17712 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17713 #define vl_api_mpls_table_details_t_print vl_noop_handler
17714
17715
17716 static void
17717 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17718 {
17719   vat_main_t *vam = &vat_main;
17720
17721   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17722 }
17723
17724 static void vl_api_mpls_table_details_t_handler_json
17725   (vl_api_mpls_table_details_t * mp)
17726 {
17727   vat_main_t *vam = &vat_main;
17728   vat_json_node_t *node = NULL;
17729
17730   if (VAT_JSON_ARRAY != vam->json_tree.type)
17731     {
17732       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17733       vat_json_init_array (&vam->json_tree);
17734     }
17735   node = vat_json_array_add (&vam->json_tree);
17736
17737   vat_json_init_object (node);
17738   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17739 }
17740
17741 static int
17742 api_mpls_table_dump (vat_main_t * vam)
17743 {
17744   vl_api_mpls_table_dump_t *mp;
17745   vl_api_control_ping_t *mp_ping;
17746   int ret;
17747
17748   M (MPLS_TABLE_DUMP, mp);
17749   S (mp);
17750
17751   /* Use a control ping for synchronization */
17752   MPING (CONTROL_PING, mp_ping);
17753   S (mp_ping);
17754
17755   W (ret);
17756   return ret;
17757 }
17758
17759 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17760 #define vl_api_mpls_route_details_t_print vl_noop_handler
17761
17762 static void
17763 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17764 {
17765   vat_main_t *vam = &vat_main;
17766   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17767   vl_api_fib_path_t *fp;
17768   int i;
17769
17770   print (vam->ofp,
17771          "table-id %d, label %u, ess_bit %u",
17772          ntohl (mp->mr_route.mr_table_id),
17773          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17774   fp = mp->mr_route.mr_paths;
17775   for (i = 0; i < count; i++)
17776     {
17777       vl_api_fib_path_print (vam, fp);
17778       fp++;
17779     }
17780 }
17781
17782 static void vl_api_mpls_route_details_t_handler_json
17783   (vl_api_mpls_route_details_t * mp)
17784 {
17785   vat_main_t *vam = &vat_main;
17786   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17787   vat_json_node_t *node = NULL;
17788   vl_api_fib_path_t *fp;
17789   int i;
17790
17791   if (VAT_JSON_ARRAY != vam->json_tree.type)
17792     {
17793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17794       vat_json_init_array (&vam->json_tree);
17795     }
17796   node = vat_json_array_add (&vam->json_tree);
17797
17798   vat_json_init_object (node);
17799   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17800   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17801   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17802   vat_json_object_add_uint (node, "path_count", count);
17803   fp = mp->mr_route.mr_paths;
17804   for (i = 0; i < count; i++)
17805     {
17806       vl_api_mpls_fib_path_json_print (node, fp);
17807       fp++;
17808     }
17809 }
17810
17811 static int
17812 api_mpls_route_dump (vat_main_t * vam)
17813 {
17814   unformat_input_t *input = vam->input;
17815   vl_api_mpls_route_dump_t *mp;
17816   vl_api_control_ping_t *mp_ping;
17817   u32 table_id;
17818   int ret;
17819
17820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17821     {
17822       if (unformat (input, "table_id %d", &table_id))
17823         ;
17824       else
17825         break;
17826     }
17827   if (table_id == ~0)
17828     {
17829       errmsg ("missing table id");
17830       return -99;
17831     }
17832
17833   M (MPLS_ROUTE_DUMP, mp);
17834
17835   mp->table.mt_table_id = ntohl (table_id);
17836   S (mp);
17837
17838   /* Use a control ping for synchronization */
17839   MPING (CONTROL_PING, mp_ping);
17840   S (mp_ping);
17841
17842   W (ret);
17843   return ret;
17844 }
17845
17846 #define vl_api_ip_table_details_t_endian vl_noop_handler
17847 #define vl_api_ip_table_details_t_print vl_noop_handler
17848
17849 static void
17850 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17851 {
17852   vat_main_t *vam = &vat_main;
17853
17854   print (vam->ofp,
17855          "%s; table-id %d, prefix %U/%d",
17856          mp->table.name, ntohl (mp->table.table_id));
17857 }
17858
17859
17860 static void vl_api_ip_table_details_t_handler_json
17861   (vl_api_ip_table_details_t * mp)
17862 {
17863   vat_main_t *vam = &vat_main;
17864   vat_json_node_t *node = NULL;
17865
17866   if (VAT_JSON_ARRAY != vam->json_tree.type)
17867     {
17868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17869       vat_json_init_array (&vam->json_tree);
17870     }
17871   node = vat_json_array_add (&vam->json_tree);
17872
17873   vat_json_init_object (node);
17874   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17875 }
17876
17877 static int
17878 api_ip_table_dump (vat_main_t * vam)
17879 {
17880   vl_api_ip_table_dump_t *mp;
17881   vl_api_control_ping_t *mp_ping;
17882   int ret;
17883
17884   M (IP_TABLE_DUMP, mp);
17885   S (mp);
17886
17887   /* Use a control ping for synchronization */
17888   MPING (CONTROL_PING, mp_ping);
17889   S (mp_ping);
17890
17891   W (ret);
17892   return ret;
17893 }
17894
17895 static int
17896 api_ip_mtable_dump (vat_main_t * vam)
17897 {
17898   vl_api_ip_mtable_dump_t *mp;
17899   vl_api_control_ping_t *mp_ping;
17900   int ret;
17901
17902   M (IP_MTABLE_DUMP, mp);
17903   S (mp);
17904
17905   /* Use a control ping for synchronization */
17906   MPING (CONTROL_PING, mp_ping);
17907   S (mp_ping);
17908
17909   W (ret);
17910   return ret;
17911 }
17912
17913 static int
17914 api_ip_mroute_dump (vat_main_t * vam)
17915 {
17916   unformat_input_t *input = vam->input;
17917   vl_api_control_ping_t *mp_ping;
17918   vl_api_ip_mroute_dump_t *mp;
17919   int ret, is_ip6;
17920   u32 table_id;
17921
17922   is_ip6 = 0;
17923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17924     {
17925       if (unformat (input, "table_id %d", &table_id))
17926         ;
17927       else if (unformat (input, "ip6"))
17928         is_ip6 = 1;
17929       else if (unformat (input, "ip4"))
17930         is_ip6 = 0;
17931       else
17932         break;
17933     }
17934   if (table_id == ~0)
17935     {
17936       errmsg ("missing table id");
17937       return -99;
17938     }
17939
17940   M (IP_MROUTE_DUMP, mp);
17941   mp->table.table_id = table_id;
17942   mp->table.is_ip6 = is_ip6;
17943   S (mp);
17944
17945   /* Use a control ping for synchronization */
17946   MPING (CONTROL_PING, mp_ping);
17947   S (mp_ping);
17948
17949   W (ret);
17950   return ret;
17951 }
17952
17953 #define vl_api_ip_route_details_t_endian vl_noop_handler
17954 #define vl_api_ip_route_details_t_print vl_noop_handler
17955
17956 static void
17957 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17958 {
17959   vat_main_t *vam = &vat_main;
17960   u8 count = mp->route.n_paths;
17961   vl_api_fib_path_t *fp;
17962   int i;
17963
17964   print (vam->ofp,
17965          "table-id %d, prefix %U/%d",
17966          ntohl (mp->route.table_id),
17967          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17968   for (i = 0; i < count; i++)
17969     {
17970       fp = &mp->route.paths[i];
17971
17972       vl_api_fib_path_print (vam, fp);
17973       fp++;
17974     }
17975 }
17976
17977 static void vl_api_ip_route_details_t_handler_json
17978   (vl_api_ip_route_details_t * mp)
17979 {
17980   vat_main_t *vam = &vat_main;
17981   u8 count = mp->route.n_paths;
17982   vat_json_node_t *node = NULL;
17983   struct in_addr ip4;
17984   struct in6_addr ip6;
17985   vl_api_fib_path_t *fp;
17986   int i;
17987
17988   if (VAT_JSON_ARRAY != vam->json_tree.type)
17989     {
17990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17991       vat_json_init_array (&vam->json_tree);
17992     }
17993   node = vat_json_array_add (&vam->json_tree);
17994
17995   vat_json_init_object (node);
17996   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17997   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17998     {
17999       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18000       vat_json_object_add_ip6 (node, "prefix", ip6);
18001     }
18002   else
18003     {
18004       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18005       vat_json_object_add_ip4 (node, "prefix", ip4);
18006     }
18007   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18008   vat_json_object_add_uint (node, "path_count", count);
18009   for (i = 0; i < count; i++)
18010     {
18011       fp = &mp->route.paths[i];
18012       vl_api_mpls_fib_path_json_print (node, fp);
18013     }
18014 }
18015
18016 static int
18017 api_ip_route_dump (vat_main_t * vam)
18018 {
18019   unformat_input_t *input = vam->input;
18020   vl_api_ip_route_dump_t *mp;
18021   vl_api_control_ping_t *mp_ping;
18022   u32 table_id;
18023   u8 is_ip6;
18024   int ret;
18025
18026   is_ip6 = 0;
18027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18028     {
18029       if (unformat (input, "table_id %d", &table_id))
18030         ;
18031       else if (unformat (input, "ip6"))
18032         is_ip6 = 1;
18033       else if (unformat (input, "ip4"))
18034         is_ip6 = 0;
18035       else
18036         break;
18037     }
18038   if (table_id == ~0)
18039     {
18040       errmsg ("missing table id");
18041       return -99;
18042     }
18043
18044   M (IP_ROUTE_DUMP, mp);
18045
18046   mp->table.table_id = table_id;
18047   mp->table.is_ip6 = is_ip6;
18048
18049   S (mp);
18050
18051   /* Use a control ping for synchronization */
18052   MPING (CONTROL_PING, mp_ping);
18053   S (mp_ping);
18054
18055   W (ret);
18056   return ret;
18057 }
18058
18059 int
18060 api_classify_table_ids (vat_main_t * vam)
18061 {
18062   vl_api_classify_table_ids_t *mp;
18063   int ret;
18064
18065   /* Construct the API message */
18066   M (CLASSIFY_TABLE_IDS, mp);
18067   mp->context = 0;
18068
18069   S (mp);
18070   W (ret);
18071   return ret;
18072 }
18073
18074 int
18075 api_classify_table_by_interface (vat_main_t * vam)
18076 {
18077   unformat_input_t *input = vam->input;
18078   vl_api_classify_table_by_interface_t *mp;
18079
18080   u32 sw_if_index = ~0;
18081   int ret;
18082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18083     {
18084       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18085         ;
18086       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18087         ;
18088       else
18089         break;
18090     }
18091   if (sw_if_index == ~0)
18092     {
18093       errmsg ("missing interface name or sw_if_index");
18094       return -99;
18095     }
18096
18097   /* Construct the API message */
18098   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18099   mp->context = 0;
18100   mp->sw_if_index = ntohl (sw_if_index);
18101
18102   S (mp);
18103   W (ret);
18104   return ret;
18105 }
18106
18107 int
18108 api_classify_table_info (vat_main_t * vam)
18109 {
18110   unformat_input_t *input = vam->input;
18111   vl_api_classify_table_info_t *mp;
18112
18113   u32 table_id = ~0;
18114   int ret;
18115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18116     {
18117       if (unformat (input, "table_id %d", &table_id))
18118         ;
18119       else
18120         break;
18121     }
18122   if (table_id == ~0)
18123     {
18124       errmsg ("missing table id");
18125       return -99;
18126     }
18127
18128   /* Construct the API message */
18129   M (CLASSIFY_TABLE_INFO, mp);
18130   mp->context = 0;
18131   mp->table_id = ntohl (table_id);
18132
18133   S (mp);
18134   W (ret);
18135   return ret;
18136 }
18137
18138 int
18139 api_classify_session_dump (vat_main_t * vam)
18140 {
18141   unformat_input_t *input = vam->input;
18142   vl_api_classify_session_dump_t *mp;
18143   vl_api_control_ping_t *mp_ping;
18144
18145   u32 table_id = ~0;
18146   int ret;
18147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18148     {
18149       if (unformat (input, "table_id %d", &table_id))
18150         ;
18151       else
18152         break;
18153     }
18154   if (table_id == ~0)
18155     {
18156       errmsg ("missing table id");
18157       return -99;
18158     }
18159
18160   /* Construct the API message */
18161   M (CLASSIFY_SESSION_DUMP, mp);
18162   mp->context = 0;
18163   mp->table_id = ntohl (table_id);
18164   S (mp);
18165
18166   /* Use a control ping for synchronization */
18167   MPING (CONTROL_PING, mp_ping);
18168   S (mp_ping);
18169
18170   W (ret);
18171   return ret;
18172 }
18173
18174 static void
18175 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18176 {
18177   vat_main_t *vam = &vat_main;
18178
18179   print (vam->ofp, "collector_address %U, collector_port %d, "
18180          "src_address %U, vrf_id %d, path_mtu %u, "
18181          "template_interval %u, udp_checksum %d",
18182          format_ip4_address, mp->collector_address,
18183          ntohs (mp->collector_port),
18184          format_ip4_address, mp->src_address,
18185          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18186          ntohl (mp->template_interval), mp->udp_checksum);
18187
18188   vam->retval = 0;
18189   vam->result_ready = 1;
18190 }
18191
18192 static void
18193   vl_api_ipfix_exporter_details_t_handler_json
18194   (vl_api_ipfix_exporter_details_t * mp)
18195 {
18196   vat_main_t *vam = &vat_main;
18197   vat_json_node_t node;
18198   struct in_addr collector_address;
18199   struct in_addr src_address;
18200
18201   vat_json_init_object (&node);
18202   clib_memcpy (&collector_address, &mp->collector_address,
18203                sizeof (collector_address));
18204   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18205   vat_json_object_add_uint (&node, "collector_port",
18206                             ntohs (mp->collector_port));
18207   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18208   vat_json_object_add_ip4 (&node, "src_address", src_address);
18209   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18210   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18211   vat_json_object_add_uint (&node, "template_interval",
18212                             ntohl (mp->template_interval));
18213   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18214
18215   vat_json_print (vam->ofp, &node);
18216   vat_json_free (&node);
18217   vam->retval = 0;
18218   vam->result_ready = 1;
18219 }
18220
18221 int
18222 api_ipfix_exporter_dump (vat_main_t * vam)
18223 {
18224   vl_api_ipfix_exporter_dump_t *mp;
18225   int ret;
18226
18227   /* Construct the API message */
18228   M (IPFIX_EXPORTER_DUMP, mp);
18229   mp->context = 0;
18230
18231   S (mp);
18232   W (ret);
18233   return ret;
18234 }
18235
18236 static int
18237 api_ipfix_classify_stream_dump (vat_main_t * vam)
18238 {
18239   vl_api_ipfix_classify_stream_dump_t *mp;
18240   int ret;
18241
18242   /* Construct the API message */
18243   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18244   mp->context = 0;
18245
18246   S (mp);
18247   W (ret);
18248   return ret;
18249   /* NOTREACHED */
18250   return 0;
18251 }
18252
18253 static void
18254   vl_api_ipfix_classify_stream_details_t_handler
18255   (vl_api_ipfix_classify_stream_details_t * mp)
18256 {
18257   vat_main_t *vam = &vat_main;
18258   print (vam->ofp, "domain_id %d, src_port %d",
18259          ntohl (mp->domain_id), ntohs (mp->src_port));
18260   vam->retval = 0;
18261   vam->result_ready = 1;
18262 }
18263
18264 static void
18265   vl_api_ipfix_classify_stream_details_t_handler_json
18266   (vl_api_ipfix_classify_stream_details_t * mp)
18267 {
18268   vat_main_t *vam = &vat_main;
18269   vat_json_node_t node;
18270
18271   vat_json_init_object (&node);
18272   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18273   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18274
18275   vat_json_print (vam->ofp, &node);
18276   vat_json_free (&node);
18277   vam->retval = 0;
18278   vam->result_ready = 1;
18279 }
18280
18281 static int
18282 api_ipfix_classify_table_dump (vat_main_t * vam)
18283 {
18284   vl_api_ipfix_classify_table_dump_t *mp;
18285   vl_api_control_ping_t *mp_ping;
18286   int ret;
18287
18288   if (!vam->json_output)
18289     {
18290       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18291              "transport_protocol");
18292     }
18293
18294   /* Construct the API message */
18295   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18296
18297   /* send it... */
18298   S (mp);
18299
18300   /* Use a control ping for synchronization */
18301   MPING (CONTROL_PING, mp_ping);
18302   S (mp_ping);
18303
18304   W (ret);
18305   return ret;
18306 }
18307
18308 static void
18309   vl_api_ipfix_classify_table_details_t_handler
18310   (vl_api_ipfix_classify_table_details_t * mp)
18311 {
18312   vat_main_t *vam = &vat_main;
18313   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18314          mp->transport_protocol);
18315 }
18316
18317 static void
18318   vl_api_ipfix_classify_table_details_t_handler_json
18319   (vl_api_ipfix_classify_table_details_t * mp)
18320 {
18321   vat_json_node_t *node = NULL;
18322   vat_main_t *vam = &vat_main;
18323
18324   if (VAT_JSON_ARRAY != vam->json_tree.type)
18325     {
18326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18327       vat_json_init_array (&vam->json_tree);
18328     }
18329
18330   node = vat_json_array_add (&vam->json_tree);
18331   vat_json_init_object (node);
18332
18333   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18334   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18335   vat_json_object_add_uint (node, "transport_protocol",
18336                             mp->transport_protocol);
18337 }
18338
18339 static int
18340 api_sw_interface_span_enable_disable (vat_main_t * vam)
18341 {
18342   unformat_input_t *i = vam->input;
18343   vl_api_sw_interface_span_enable_disable_t *mp;
18344   u32 src_sw_if_index = ~0;
18345   u32 dst_sw_if_index = ~0;
18346   u8 state = 3;
18347   int ret;
18348   u8 is_l2 = 0;
18349
18350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18351     {
18352       if (unformat
18353           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18354         ;
18355       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18356         ;
18357       else
18358         if (unformat
18359             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18360         ;
18361       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18362         ;
18363       else if (unformat (i, "disable"))
18364         state = 0;
18365       else if (unformat (i, "rx"))
18366         state = 1;
18367       else if (unformat (i, "tx"))
18368         state = 2;
18369       else if (unformat (i, "both"))
18370         state = 3;
18371       else if (unformat (i, "l2"))
18372         is_l2 = 1;
18373       else
18374         break;
18375     }
18376
18377   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18378
18379   mp->sw_if_index_from = htonl (src_sw_if_index);
18380   mp->sw_if_index_to = htonl (dst_sw_if_index);
18381   mp->state = state;
18382   mp->is_l2 = is_l2;
18383
18384   S (mp);
18385   W (ret);
18386   return ret;
18387 }
18388
18389 static void
18390 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18391                                             * mp)
18392 {
18393   vat_main_t *vam = &vat_main;
18394   u8 *sw_if_from_name = 0;
18395   u8 *sw_if_to_name = 0;
18396   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18397   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18398   char *states[] = { "none", "rx", "tx", "both" };
18399   hash_pair_t *p;
18400
18401   /* *INDENT-OFF* */
18402   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18403   ({
18404     if ((u32) p->value[0] == sw_if_index_from)
18405       {
18406         sw_if_from_name = (u8 *)(p->key);
18407         if (sw_if_to_name)
18408           break;
18409       }
18410     if ((u32) p->value[0] == sw_if_index_to)
18411       {
18412         sw_if_to_name = (u8 *)(p->key);
18413         if (sw_if_from_name)
18414           break;
18415       }
18416   }));
18417   /* *INDENT-ON* */
18418   print (vam->ofp, "%20s => %20s (%s) %s",
18419          sw_if_from_name, sw_if_to_name, states[mp->state],
18420          mp->is_l2 ? "l2" : "device");
18421 }
18422
18423 static void
18424   vl_api_sw_interface_span_details_t_handler_json
18425   (vl_api_sw_interface_span_details_t * mp)
18426 {
18427   vat_main_t *vam = &vat_main;
18428   vat_json_node_t *node = NULL;
18429   u8 *sw_if_from_name = 0;
18430   u8 *sw_if_to_name = 0;
18431   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18432   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18433   hash_pair_t *p;
18434
18435   /* *INDENT-OFF* */
18436   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18437   ({
18438     if ((u32) p->value[0] == sw_if_index_from)
18439       {
18440         sw_if_from_name = (u8 *)(p->key);
18441         if (sw_if_to_name)
18442           break;
18443       }
18444     if ((u32) p->value[0] == sw_if_index_to)
18445       {
18446         sw_if_to_name = (u8 *)(p->key);
18447         if (sw_if_from_name)
18448           break;
18449       }
18450   }));
18451   /* *INDENT-ON* */
18452
18453   if (VAT_JSON_ARRAY != vam->json_tree.type)
18454     {
18455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18456       vat_json_init_array (&vam->json_tree);
18457     }
18458   node = vat_json_array_add (&vam->json_tree);
18459
18460   vat_json_init_object (node);
18461   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18462   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18463   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18464   if (0 != sw_if_to_name)
18465     {
18466       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18467     }
18468   vat_json_object_add_uint (node, "state", mp->state);
18469   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18470 }
18471
18472 static int
18473 api_sw_interface_span_dump (vat_main_t * vam)
18474 {
18475   unformat_input_t *input = vam->input;
18476   vl_api_sw_interface_span_dump_t *mp;
18477   vl_api_control_ping_t *mp_ping;
18478   u8 is_l2 = 0;
18479   int ret;
18480
18481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18482     {
18483       if (unformat (input, "l2"))
18484         is_l2 = 1;
18485       else
18486         break;
18487     }
18488
18489   M (SW_INTERFACE_SPAN_DUMP, mp);
18490   mp->is_l2 = is_l2;
18491   S (mp);
18492
18493   /* Use a control ping for synchronization */
18494   MPING (CONTROL_PING, mp_ping);
18495   S (mp_ping);
18496
18497   W (ret);
18498   return ret;
18499 }
18500
18501 int
18502 api_pg_create_interface (vat_main_t * vam)
18503 {
18504   unformat_input_t *input = vam->input;
18505   vl_api_pg_create_interface_t *mp;
18506
18507   u32 if_id = ~0, gso_size = 0;
18508   u8 gso_enabled = 0;
18509   int ret;
18510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18511     {
18512       if (unformat (input, "if_id %d", &if_id))
18513         ;
18514       else if (unformat (input, "gso-enabled"))
18515         {
18516           gso_enabled = 1;
18517           if (unformat (input, "gso-size %u", &gso_size))
18518             ;
18519           else
18520             {
18521               errmsg ("missing gso-size");
18522               return -99;
18523             }
18524         }
18525       else
18526         break;
18527     }
18528   if (if_id == ~0)
18529     {
18530       errmsg ("missing pg interface index");
18531       return -99;
18532     }
18533
18534   /* Construct the API message */
18535   M (PG_CREATE_INTERFACE, mp);
18536   mp->context = 0;
18537   mp->interface_id = ntohl (if_id);
18538   mp->gso_enabled = gso_enabled;
18539
18540   S (mp);
18541   W (ret);
18542   return ret;
18543 }
18544
18545 int
18546 api_pg_capture (vat_main_t * vam)
18547 {
18548   unformat_input_t *input = vam->input;
18549   vl_api_pg_capture_t *mp;
18550
18551   u32 if_id = ~0;
18552   u8 enable = 1;
18553   u32 count = 1;
18554   u8 pcap_file_set = 0;
18555   u8 *pcap_file = 0;
18556   int ret;
18557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18558     {
18559       if (unformat (input, "if_id %d", &if_id))
18560         ;
18561       else if (unformat (input, "pcap %s", &pcap_file))
18562         pcap_file_set = 1;
18563       else if (unformat (input, "count %d", &count))
18564         ;
18565       else if (unformat (input, "disable"))
18566         enable = 0;
18567       else
18568         break;
18569     }
18570   if (if_id == ~0)
18571     {
18572       errmsg ("missing pg interface index");
18573       return -99;
18574     }
18575   if (pcap_file_set > 0)
18576     {
18577       if (vec_len (pcap_file) > 255)
18578         {
18579           errmsg ("pcap file name is too long");
18580           return -99;
18581         }
18582     }
18583
18584   u32 name_len = vec_len (pcap_file);
18585   /* Construct the API message */
18586   M (PG_CAPTURE, mp);
18587   mp->context = 0;
18588   mp->interface_id = ntohl (if_id);
18589   mp->is_enabled = enable;
18590   mp->count = ntohl (count);
18591   mp->pcap_name_length = ntohl (name_len);
18592   if (pcap_file_set != 0)
18593     {
18594       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18595     }
18596   vec_free (pcap_file);
18597
18598   S (mp);
18599   W (ret);
18600   return ret;
18601 }
18602
18603 int
18604 api_pg_enable_disable (vat_main_t * vam)
18605 {
18606   unformat_input_t *input = vam->input;
18607   vl_api_pg_enable_disable_t *mp;
18608
18609   u8 enable = 1;
18610   u8 stream_name_set = 0;
18611   u8 *stream_name = 0;
18612   int ret;
18613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18614     {
18615       if (unformat (input, "stream %s", &stream_name))
18616         stream_name_set = 1;
18617       else if (unformat (input, "disable"))
18618         enable = 0;
18619       else
18620         break;
18621     }
18622
18623   if (stream_name_set > 0)
18624     {
18625       if (vec_len (stream_name) > 255)
18626         {
18627           errmsg ("stream name too long");
18628           return -99;
18629         }
18630     }
18631
18632   u32 name_len = vec_len (stream_name);
18633   /* Construct the API message */
18634   M (PG_ENABLE_DISABLE, mp);
18635   mp->context = 0;
18636   mp->is_enabled = enable;
18637   if (stream_name_set != 0)
18638     {
18639       mp->stream_name_length = ntohl (name_len);
18640       clib_memcpy (mp->stream_name, stream_name, name_len);
18641     }
18642   vec_free (stream_name);
18643
18644   S (mp);
18645   W (ret);
18646   return ret;
18647 }
18648
18649 int
18650 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18651 {
18652   unformat_input_t *input = vam->input;
18653   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18654
18655   u16 *low_ports = 0;
18656   u16 *high_ports = 0;
18657   u16 this_low;
18658   u16 this_hi;
18659   vl_api_prefix_t prefix;
18660   u32 tmp, tmp2;
18661   u8 prefix_set = 0;
18662   u32 vrf_id = ~0;
18663   u8 is_add = 1;
18664   int ret;
18665
18666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18667     {
18668       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18669         prefix_set = 1;
18670       else if (unformat (input, "vrf %d", &vrf_id))
18671         ;
18672       else if (unformat (input, "del"))
18673         is_add = 0;
18674       else if (unformat (input, "port %d", &tmp))
18675         {
18676           if (tmp == 0 || tmp > 65535)
18677             {
18678               errmsg ("port %d out of range", tmp);
18679               return -99;
18680             }
18681           this_low = tmp;
18682           this_hi = this_low + 1;
18683           vec_add1 (low_ports, this_low);
18684           vec_add1 (high_ports, this_hi);
18685         }
18686       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18687         {
18688           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18689             {
18690               errmsg ("incorrect range parameters");
18691               return -99;
18692             }
18693           this_low = tmp;
18694           /* Note: in debug CLI +1 is added to high before
18695              passing to real fn that does "the work"
18696              (ip_source_and_port_range_check_add_del).
18697              This fn is a wrapper around the binary API fn a
18698              control plane will call, which expects this increment
18699              to have occurred. Hence letting the binary API control
18700              plane fn do the increment for consistency between VAT
18701              and other control planes.
18702            */
18703           this_hi = tmp2;
18704           vec_add1 (low_ports, this_low);
18705           vec_add1 (high_ports, this_hi);
18706         }
18707       else
18708         break;
18709     }
18710
18711   if (prefix_set == 0)
18712     {
18713       errmsg ("<address>/<mask> not specified");
18714       return -99;
18715     }
18716
18717   if (vrf_id == ~0)
18718     {
18719       errmsg ("VRF ID required, not specified");
18720       return -99;
18721     }
18722
18723   if (vrf_id == 0)
18724     {
18725       errmsg
18726         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18727       return -99;
18728     }
18729
18730   if (vec_len (low_ports) == 0)
18731     {
18732       errmsg ("At least one port or port range required");
18733       return -99;
18734     }
18735
18736   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18737
18738   mp->is_add = is_add;
18739
18740   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18741
18742   mp->number_of_ranges = vec_len (low_ports);
18743
18744   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18745   vec_free (low_ports);
18746
18747   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18748   vec_free (high_ports);
18749
18750   mp->vrf_id = ntohl (vrf_id);
18751
18752   S (mp);
18753   W (ret);
18754   return ret;
18755 }
18756
18757 int
18758 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18759 {
18760   unformat_input_t *input = vam->input;
18761   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18762   u32 sw_if_index = ~0;
18763   int vrf_set = 0;
18764   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18765   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18766   u8 is_add = 1;
18767   int ret;
18768
18769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18770     {
18771       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18772         ;
18773       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18774         ;
18775       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18776         vrf_set = 1;
18777       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18778         vrf_set = 1;
18779       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18780         vrf_set = 1;
18781       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18782         vrf_set = 1;
18783       else if (unformat (input, "del"))
18784         is_add = 0;
18785       else
18786         break;
18787     }
18788
18789   if (sw_if_index == ~0)
18790     {
18791       errmsg ("Interface required but not specified");
18792       return -99;
18793     }
18794
18795   if (vrf_set == 0)
18796     {
18797       errmsg ("VRF ID required but not specified");
18798       return -99;
18799     }
18800
18801   if (tcp_out_vrf_id == 0
18802       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18803     {
18804       errmsg
18805         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18806       return -99;
18807     }
18808
18809   /* Construct the API message */
18810   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18811
18812   mp->sw_if_index = ntohl (sw_if_index);
18813   mp->is_add = is_add;
18814   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18815   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18816   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18817   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18818
18819   /* send it... */
18820   S (mp);
18821
18822   /* Wait for a reply... */
18823   W (ret);
18824   return ret;
18825 }
18826
18827 static int
18828 api_set_punt (vat_main_t * vam)
18829 {
18830   unformat_input_t *i = vam->input;
18831   vl_api_address_family_t af;
18832   vl_api_set_punt_t *mp;
18833   u32 protocol = ~0;
18834   u32 port = ~0;
18835   int is_add = 1;
18836   int ret;
18837
18838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18839     {
18840       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18841         ;
18842       else if (unformat (i, "protocol %d", &protocol))
18843         ;
18844       else if (unformat (i, "port %d", &port))
18845         ;
18846       else if (unformat (i, "del"))
18847         is_add = 0;
18848       else
18849         {
18850           clib_warning ("parse error '%U'", format_unformat_error, i);
18851           return -99;
18852         }
18853     }
18854
18855   M (SET_PUNT, mp);
18856
18857   mp->is_add = (u8) is_add;
18858   mp->punt.type = PUNT_API_TYPE_L4;
18859   mp->punt.punt.l4.af = af;
18860   mp->punt.punt.l4.protocol = (u8) protocol;
18861   mp->punt.punt.l4.port = htons ((u16) port);
18862
18863   S (mp);
18864   W (ret);
18865   return ret;
18866 }
18867
18868 static int
18869 api_delete_subif (vat_main_t * vam)
18870 {
18871   unformat_input_t *i = vam->input;
18872   vl_api_delete_subif_t *mp;
18873   u32 sw_if_index = ~0;
18874   int ret;
18875
18876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18877     {
18878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18879         ;
18880       if (unformat (i, "sw_if_index %d", &sw_if_index))
18881         ;
18882       else
18883         break;
18884     }
18885
18886   if (sw_if_index == ~0)
18887     {
18888       errmsg ("missing sw_if_index");
18889       return -99;
18890     }
18891
18892   /* Construct the API message */
18893   M (DELETE_SUBIF, mp);
18894   mp->sw_if_index = ntohl (sw_if_index);
18895
18896   S (mp);
18897   W (ret);
18898   return ret;
18899 }
18900
18901 #define foreach_pbb_vtr_op      \
18902 _("disable",  L2_VTR_DISABLED)  \
18903 _("pop",  L2_VTR_POP_2)         \
18904 _("push",  L2_VTR_PUSH_2)
18905
18906 static int
18907 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18908 {
18909   unformat_input_t *i = vam->input;
18910   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18911   u32 sw_if_index = ~0, vtr_op = ~0;
18912   u16 outer_tag = ~0;
18913   u8 dmac[6], smac[6];
18914   u8 dmac_set = 0, smac_set = 0;
18915   u16 vlanid = 0;
18916   u32 sid = ~0;
18917   u32 tmp;
18918   int ret;
18919
18920   /* Shut up coverity */
18921   clib_memset (dmac, 0, sizeof (dmac));
18922   clib_memset (smac, 0, sizeof (smac));
18923
18924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18925     {
18926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18927         ;
18928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18929         ;
18930       else if (unformat (i, "vtr_op %d", &vtr_op))
18931         ;
18932 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18933       foreach_pbb_vtr_op
18934 #undef _
18935         else if (unformat (i, "translate_pbb_stag"))
18936         {
18937           if (unformat (i, "%d", &tmp))
18938             {
18939               vtr_op = L2_VTR_TRANSLATE_2_1;
18940               outer_tag = tmp;
18941             }
18942           else
18943             {
18944               errmsg
18945                 ("translate_pbb_stag operation requires outer tag definition");
18946               return -99;
18947             }
18948         }
18949       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18950         dmac_set++;
18951       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18952         smac_set++;
18953       else if (unformat (i, "sid %d", &sid))
18954         ;
18955       else if (unformat (i, "vlanid %d", &tmp))
18956         vlanid = tmp;
18957       else
18958         {
18959           clib_warning ("parse error '%U'", format_unformat_error, i);
18960           return -99;
18961         }
18962     }
18963
18964   if ((sw_if_index == ~0) || (vtr_op == ~0))
18965     {
18966       errmsg ("missing sw_if_index or vtr operation");
18967       return -99;
18968     }
18969   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18970       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18971     {
18972       errmsg
18973         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18974       return -99;
18975     }
18976
18977   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18978   mp->sw_if_index = ntohl (sw_if_index);
18979   mp->vtr_op = ntohl (vtr_op);
18980   mp->outer_tag = ntohs (outer_tag);
18981   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18982   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18983   mp->b_vlanid = ntohs (vlanid);
18984   mp->i_sid = ntohl (sid);
18985
18986   S (mp);
18987   W (ret);
18988   return ret;
18989 }
18990
18991 static int
18992 api_flow_classify_set_interface (vat_main_t * vam)
18993 {
18994   unformat_input_t *i = vam->input;
18995   vl_api_flow_classify_set_interface_t *mp;
18996   u32 sw_if_index;
18997   int sw_if_index_set;
18998   u32 ip4_table_index = ~0;
18999   u32 ip6_table_index = ~0;
19000   u8 is_add = 1;
19001   int ret;
19002
19003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19004     {
19005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19006         sw_if_index_set = 1;
19007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19008         sw_if_index_set = 1;
19009       else if (unformat (i, "del"))
19010         is_add = 0;
19011       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19012         ;
19013       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19014         ;
19015       else
19016         {
19017           clib_warning ("parse error '%U'", format_unformat_error, i);
19018           return -99;
19019         }
19020     }
19021
19022   if (sw_if_index_set == 0)
19023     {
19024       errmsg ("missing interface name or sw_if_index");
19025       return -99;
19026     }
19027
19028   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19029
19030   mp->sw_if_index = ntohl (sw_if_index);
19031   mp->ip4_table_index = ntohl (ip4_table_index);
19032   mp->ip6_table_index = ntohl (ip6_table_index);
19033   mp->is_add = is_add;
19034
19035   S (mp);
19036   W (ret);
19037   return ret;
19038 }
19039
19040 static int
19041 api_flow_classify_dump (vat_main_t * vam)
19042 {
19043   unformat_input_t *i = vam->input;
19044   vl_api_flow_classify_dump_t *mp;
19045   vl_api_control_ping_t *mp_ping;
19046   u8 type = FLOW_CLASSIFY_N_TABLES;
19047   int ret;
19048
19049   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19050     ;
19051   else
19052     {
19053       errmsg ("classify table type must be specified");
19054       return -99;
19055     }
19056
19057   if (!vam->json_output)
19058     {
19059       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19060     }
19061
19062   M (FLOW_CLASSIFY_DUMP, mp);
19063   mp->type = type;
19064   /* send it... */
19065   S (mp);
19066
19067   /* Use a control ping for synchronization */
19068   MPING (CONTROL_PING, mp_ping);
19069   S (mp_ping);
19070
19071   /* Wait for a reply... */
19072   W (ret);
19073   return ret;
19074 }
19075
19076 static int
19077 api_feature_enable_disable (vat_main_t * vam)
19078 {
19079   unformat_input_t *i = vam->input;
19080   vl_api_feature_enable_disable_t *mp;
19081   u8 *arc_name = 0;
19082   u8 *feature_name = 0;
19083   u32 sw_if_index = ~0;
19084   u8 enable = 1;
19085   int ret;
19086
19087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19088     {
19089       if (unformat (i, "arc_name %s", &arc_name))
19090         ;
19091       else if (unformat (i, "feature_name %s", &feature_name))
19092         ;
19093       else
19094         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19095         ;
19096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19097         ;
19098       else if (unformat (i, "disable"))
19099         enable = 0;
19100       else
19101         break;
19102     }
19103
19104   if (arc_name == 0)
19105     {
19106       errmsg ("missing arc name");
19107       return -99;
19108     }
19109   if (vec_len (arc_name) > 63)
19110     {
19111       errmsg ("arc name too long");
19112     }
19113
19114   if (feature_name == 0)
19115     {
19116       errmsg ("missing feature name");
19117       return -99;
19118     }
19119   if (vec_len (feature_name) > 63)
19120     {
19121       errmsg ("feature name too long");
19122     }
19123
19124   if (sw_if_index == ~0)
19125     {
19126       errmsg ("missing interface name or sw_if_index");
19127       return -99;
19128     }
19129
19130   /* Construct the API message */
19131   M (FEATURE_ENABLE_DISABLE, mp);
19132   mp->sw_if_index = ntohl (sw_if_index);
19133   mp->enable = enable;
19134   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19135   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19136   vec_free (arc_name);
19137   vec_free (feature_name);
19138
19139   S (mp);
19140   W (ret);
19141   return ret;
19142 }
19143
19144 static int
19145 api_feature_gso_enable_disable (vat_main_t * vam)
19146 {
19147   unformat_input_t *i = vam->input;
19148   vl_api_feature_gso_enable_disable_t *mp;
19149   u32 sw_if_index = ~0;
19150   u8 enable = 1;
19151   int ret;
19152
19153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19154     {
19155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19156         ;
19157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19158         ;
19159       else if (unformat (i, "enable"))
19160         enable = 1;
19161       else if (unformat (i, "disable"))
19162         enable = 0;
19163       else
19164         break;
19165     }
19166
19167   if (sw_if_index == ~0)
19168     {
19169       errmsg ("missing interface name or sw_if_index");
19170       return -99;
19171     }
19172
19173   /* Construct the API message */
19174   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19175   mp->sw_if_index = ntohl (sw_if_index);
19176   mp->enable_disable = enable;
19177
19178   S (mp);
19179   W (ret);
19180   return ret;
19181 }
19182
19183 static int
19184 api_sw_interface_tag_add_del (vat_main_t * vam)
19185 {
19186   unformat_input_t *i = vam->input;
19187   vl_api_sw_interface_tag_add_del_t *mp;
19188   u32 sw_if_index = ~0;
19189   u8 *tag = 0;
19190   u8 enable = 1;
19191   int ret;
19192
19193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19194     {
19195       if (unformat (i, "tag %s", &tag))
19196         ;
19197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19198         ;
19199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19200         ;
19201       else if (unformat (i, "del"))
19202         enable = 0;
19203       else
19204         break;
19205     }
19206
19207   if (sw_if_index == ~0)
19208     {
19209       errmsg ("missing interface name or sw_if_index");
19210       return -99;
19211     }
19212
19213   if (enable && (tag == 0))
19214     {
19215       errmsg ("no tag specified");
19216       return -99;
19217     }
19218
19219   /* Construct the API message */
19220   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19221   mp->sw_if_index = ntohl (sw_if_index);
19222   mp->is_add = enable;
19223   if (enable)
19224     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19225   vec_free (tag);
19226
19227   S (mp);
19228   W (ret);
19229   return ret;
19230 }
19231
19232 static int
19233 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19234 {
19235   unformat_input_t *i = vam->input;
19236   vl_api_mac_address_t mac = { 0 };
19237   vl_api_sw_interface_add_del_mac_address_t *mp;
19238   u32 sw_if_index = ~0;
19239   u8 is_add = 1;
19240   u8 mac_set = 0;
19241   int ret;
19242
19243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19244     {
19245       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19246         ;
19247       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19248         ;
19249       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19250         mac_set++;
19251       else if (unformat (i, "del"))
19252         is_add = 0;
19253       else
19254         break;
19255     }
19256
19257   if (sw_if_index == ~0)
19258     {
19259       errmsg ("missing interface name or sw_if_index");
19260       return -99;
19261     }
19262
19263   if (!mac_set)
19264     {
19265       errmsg ("missing MAC address");
19266       return -99;
19267     }
19268
19269   /* Construct the API message */
19270   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19271   mp->sw_if_index = ntohl (sw_if_index);
19272   mp->is_add = is_add;
19273   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19274
19275   S (mp);
19276   W (ret);
19277   return ret;
19278 }
19279
19280 static void vl_api_l2_xconnect_details_t_handler
19281   (vl_api_l2_xconnect_details_t * mp)
19282 {
19283   vat_main_t *vam = &vat_main;
19284
19285   print (vam->ofp, "%15d%15d",
19286          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19287 }
19288
19289 static void vl_api_l2_xconnect_details_t_handler_json
19290   (vl_api_l2_xconnect_details_t * mp)
19291 {
19292   vat_main_t *vam = &vat_main;
19293   vat_json_node_t *node = NULL;
19294
19295   if (VAT_JSON_ARRAY != vam->json_tree.type)
19296     {
19297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19298       vat_json_init_array (&vam->json_tree);
19299     }
19300   node = vat_json_array_add (&vam->json_tree);
19301
19302   vat_json_init_object (node);
19303   vat_json_object_add_uint (node, "rx_sw_if_index",
19304                             ntohl (mp->rx_sw_if_index));
19305   vat_json_object_add_uint (node, "tx_sw_if_index",
19306                             ntohl (mp->tx_sw_if_index));
19307 }
19308
19309 static int
19310 api_l2_xconnect_dump (vat_main_t * vam)
19311 {
19312   vl_api_l2_xconnect_dump_t *mp;
19313   vl_api_control_ping_t *mp_ping;
19314   int ret;
19315
19316   if (!vam->json_output)
19317     {
19318       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19319     }
19320
19321   M (L2_XCONNECT_DUMP, mp);
19322
19323   S (mp);
19324
19325   /* Use a control ping for synchronization */
19326   MPING (CONTROL_PING, mp_ping);
19327   S (mp_ping);
19328
19329   W (ret);
19330   return ret;
19331 }
19332
19333 static int
19334 api_hw_interface_set_mtu (vat_main_t * vam)
19335 {
19336   unformat_input_t *i = vam->input;
19337   vl_api_hw_interface_set_mtu_t *mp;
19338   u32 sw_if_index = ~0;
19339   u32 mtu = 0;
19340   int ret;
19341
19342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19343     {
19344       if (unformat (i, "mtu %d", &mtu))
19345         ;
19346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19347         ;
19348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19349         ;
19350       else
19351         break;
19352     }
19353
19354   if (sw_if_index == ~0)
19355     {
19356       errmsg ("missing interface name or sw_if_index");
19357       return -99;
19358     }
19359
19360   if (mtu == 0)
19361     {
19362       errmsg ("no mtu specified");
19363       return -99;
19364     }
19365
19366   /* Construct the API message */
19367   M (HW_INTERFACE_SET_MTU, mp);
19368   mp->sw_if_index = ntohl (sw_if_index);
19369   mp->mtu = ntohs ((u16) mtu);
19370
19371   S (mp);
19372   W (ret);
19373   return ret;
19374 }
19375
19376 static int
19377 api_p2p_ethernet_add (vat_main_t * vam)
19378 {
19379   unformat_input_t *i = vam->input;
19380   vl_api_p2p_ethernet_add_t *mp;
19381   u32 parent_if_index = ~0;
19382   u32 sub_id = ~0;
19383   u8 remote_mac[6];
19384   u8 mac_set = 0;
19385   int ret;
19386
19387   clib_memset (remote_mac, 0, sizeof (remote_mac));
19388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19391         ;
19392       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19393         ;
19394       else
19395         if (unformat
19396             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19397         mac_set++;
19398       else if (unformat (i, "sub_id %d", &sub_id))
19399         ;
19400       else
19401         {
19402           clib_warning ("parse error '%U'", format_unformat_error, i);
19403           return -99;
19404         }
19405     }
19406
19407   if (parent_if_index == ~0)
19408     {
19409       errmsg ("missing interface name or sw_if_index");
19410       return -99;
19411     }
19412   if (mac_set == 0)
19413     {
19414       errmsg ("missing remote mac address");
19415       return -99;
19416     }
19417   if (sub_id == ~0)
19418     {
19419       errmsg ("missing sub-interface id");
19420       return -99;
19421     }
19422
19423   M (P2P_ETHERNET_ADD, mp);
19424   mp->parent_if_index = ntohl (parent_if_index);
19425   mp->subif_id = ntohl (sub_id);
19426   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19427
19428   S (mp);
19429   W (ret);
19430   return ret;
19431 }
19432
19433 static int
19434 api_p2p_ethernet_del (vat_main_t * vam)
19435 {
19436   unformat_input_t *i = vam->input;
19437   vl_api_p2p_ethernet_del_t *mp;
19438   u32 parent_if_index = ~0;
19439   u8 remote_mac[6];
19440   u8 mac_set = 0;
19441   int ret;
19442
19443   clib_memset (remote_mac, 0, sizeof (remote_mac));
19444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19445     {
19446       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19447         ;
19448       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19449         ;
19450       else
19451         if (unformat
19452             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19453         mac_set++;
19454       else
19455         {
19456           clib_warning ("parse error '%U'", format_unformat_error, i);
19457           return -99;
19458         }
19459     }
19460
19461   if (parent_if_index == ~0)
19462     {
19463       errmsg ("missing interface name or sw_if_index");
19464       return -99;
19465     }
19466   if (mac_set == 0)
19467     {
19468       errmsg ("missing remote mac address");
19469       return -99;
19470     }
19471
19472   M (P2P_ETHERNET_DEL, mp);
19473   mp->parent_if_index = ntohl (parent_if_index);
19474   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19475
19476   S (mp);
19477   W (ret);
19478   return ret;
19479 }
19480
19481 static int
19482 api_lldp_config (vat_main_t * vam)
19483 {
19484   unformat_input_t *i = vam->input;
19485   vl_api_lldp_config_t *mp;
19486   int tx_hold = 0;
19487   int tx_interval = 0;
19488   u8 *sys_name = NULL;
19489   int ret;
19490
19491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19492     {
19493       if (unformat (i, "system-name %s", &sys_name))
19494         ;
19495       else if (unformat (i, "tx-hold %d", &tx_hold))
19496         ;
19497       else if (unformat (i, "tx-interval %d", &tx_interval))
19498         ;
19499       else
19500         {
19501           clib_warning ("parse error '%U'", format_unformat_error, i);
19502           return -99;
19503         }
19504     }
19505
19506   vec_add1 (sys_name, 0);
19507
19508   M (LLDP_CONFIG, mp);
19509   mp->tx_hold = htonl (tx_hold);
19510   mp->tx_interval = htonl (tx_interval);
19511   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19512   vec_free (sys_name);
19513
19514   S (mp);
19515   W (ret);
19516   return ret;
19517 }
19518
19519 static int
19520 api_sw_interface_set_lldp (vat_main_t * vam)
19521 {
19522   unformat_input_t *i = vam->input;
19523   vl_api_sw_interface_set_lldp_t *mp;
19524   u32 sw_if_index = ~0;
19525   u32 enable = 1;
19526   u8 *port_desc = NULL, *mgmt_oid = NULL;
19527   ip4_address_t ip4_addr;
19528   ip6_address_t ip6_addr;
19529   int ret;
19530
19531   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19532   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19533
19534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19535     {
19536       if (unformat (i, "disable"))
19537         enable = 0;
19538       else
19539         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19540         ;
19541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19542         ;
19543       else if (unformat (i, "port-desc %s", &port_desc))
19544         ;
19545       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19546         ;
19547       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19548         ;
19549       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19550         ;
19551       else
19552         break;
19553     }
19554
19555   if (sw_if_index == ~0)
19556     {
19557       errmsg ("missing interface name or sw_if_index");
19558       return -99;
19559     }
19560
19561   /* Construct the API message */
19562   vec_add1 (port_desc, 0);
19563   vec_add1 (mgmt_oid, 0);
19564   M (SW_INTERFACE_SET_LLDP, mp);
19565   mp->sw_if_index = ntohl (sw_if_index);
19566   mp->enable = enable;
19567   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19568   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19569   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19570   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19571   vec_free (port_desc);
19572   vec_free (mgmt_oid);
19573
19574   S (mp);
19575   W (ret);
19576   return ret;
19577 }
19578
19579 static int
19580 api_tcp_configure_src_addresses (vat_main_t * vam)
19581 {
19582   vl_api_tcp_configure_src_addresses_t *mp;
19583   unformat_input_t *i = vam->input;
19584   vl_api_address_t first, last;
19585   u8 range_set = 0;
19586   u32 vrf_id = 0;
19587   int ret;
19588
19589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19590     {
19591       if (unformat (i, "%U - %U",
19592                     unformat_vl_api_address, &first,
19593                     unformat_vl_api_address, &last))
19594         {
19595           if (range_set)
19596             {
19597               errmsg ("one range per message (range already set)");
19598               return -99;
19599             }
19600           range_set = 1;
19601         }
19602       else if (unformat (i, "vrf %d", &vrf_id))
19603         ;
19604       else
19605         break;
19606     }
19607
19608   if (range_set == 0)
19609     {
19610       errmsg ("address range not set");
19611       return -99;
19612     }
19613
19614   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19615
19616   mp->vrf_id = ntohl (vrf_id);
19617   clib_memcpy (&mp->first_address, &first, sizeof (first));
19618   clib_memcpy (&mp->last_address, &last, sizeof (last));
19619
19620   S (mp);
19621   W (ret);
19622   return ret;
19623 }
19624
19625 static void vl_api_app_namespace_add_del_reply_t_handler
19626   (vl_api_app_namespace_add_del_reply_t * mp)
19627 {
19628   vat_main_t *vam = &vat_main;
19629   i32 retval = ntohl (mp->retval);
19630   if (vam->async_mode)
19631     {
19632       vam->async_errors += (retval < 0);
19633     }
19634   else
19635     {
19636       vam->retval = retval;
19637       if (retval == 0)
19638         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19639       vam->result_ready = 1;
19640     }
19641 }
19642
19643 static void vl_api_app_namespace_add_del_reply_t_handler_json
19644   (vl_api_app_namespace_add_del_reply_t * mp)
19645 {
19646   vat_main_t *vam = &vat_main;
19647   vat_json_node_t node;
19648
19649   vat_json_init_object (&node);
19650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19651   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19652
19653   vat_json_print (vam->ofp, &node);
19654   vat_json_free (&node);
19655
19656   vam->retval = ntohl (mp->retval);
19657   vam->result_ready = 1;
19658 }
19659
19660 static int
19661 api_app_namespace_add_del (vat_main_t * vam)
19662 {
19663   vl_api_app_namespace_add_del_t *mp;
19664   unformat_input_t *i = vam->input;
19665   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19666   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19667   u64 secret;
19668   int ret;
19669
19670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19671     {
19672       if (unformat (i, "id %_%v%_", &ns_id))
19673         ;
19674       else if (unformat (i, "secret %lu", &secret))
19675         secret_set = 1;
19676       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19677         sw_if_index_set = 1;
19678       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19679         ;
19680       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19681         ;
19682       else
19683         break;
19684     }
19685   if (!ns_id || !secret_set || !sw_if_index_set)
19686     {
19687       errmsg ("namespace id, secret and sw_if_index must be set");
19688       return -99;
19689     }
19690   if (vec_len (ns_id) > 64)
19691     {
19692       errmsg ("namespace id too long");
19693       return -99;
19694     }
19695   M (APP_NAMESPACE_ADD_DEL, mp);
19696
19697   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19698   mp->namespace_id_len = vec_len (ns_id);
19699   mp->secret = clib_host_to_net_u64 (secret);
19700   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19701   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19702   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19703   vec_free (ns_id);
19704   S (mp);
19705   W (ret);
19706   return ret;
19707 }
19708
19709 static int
19710 api_sock_init_shm (vat_main_t * vam)
19711 {
19712 #if VPP_API_TEST_BUILTIN == 0
19713   unformat_input_t *i = vam->input;
19714   vl_api_shm_elem_config_t *config = 0;
19715   u64 size = 64 << 20;
19716   int rv;
19717
19718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19719     {
19720       if (unformat (i, "size %U", unformat_memory_size, &size))
19721         ;
19722       else
19723         break;
19724     }
19725
19726   /*
19727    * Canned custom ring allocator config.
19728    * Should probably parse all of this
19729    */
19730   vec_validate (config, 6);
19731   config[0].type = VL_API_VLIB_RING;
19732   config[0].size = 256;
19733   config[0].count = 32;
19734
19735   config[1].type = VL_API_VLIB_RING;
19736   config[1].size = 1024;
19737   config[1].count = 16;
19738
19739   config[2].type = VL_API_VLIB_RING;
19740   config[2].size = 4096;
19741   config[2].count = 2;
19742
19743   config[3].type = VL_API_CLIENT_RING;
19744   config[3].size = 256;
19745   config[3].count = 32;
19746
19747   config[4].type = VL_API_CLIENT_RING;
19748   config[4].size = 1024;
19749   config[4].count = 16;
19750
19751   config[5].type = VL_API_CLIENT_RING;
19752   config[5].size = 4096;
19753   config[5].count = 2;
19754
19755   config[6].type = VL_API_QUEUE;
19756   config[6].count = 128;
19757   config[6].size = sizeof (uword);
19758
19759   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19760   if (!rv)
19761     vam->client_index_invalid = 1;
19762   return rv;
19763 #else
19764   return -99;
19765 #endif
19766 }
19767
19768 static void
19769 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19770 {
19771   vat_main_t *vam = &vat_main;
19772
19773   if (mp->is_ip4)
19774     {
19775       print (vam->ofp,
19776              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19777              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19778              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19779              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19780              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19781              clib_net_to_host_u32 (mp->action_index), mp->tag);
19782     }
19783   else
19784     {
19785       print (vam->ofp,
19786              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19787              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19788              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19789              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19790              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19791              clib_net_to_host_u32 (mp->action_index), mp->tag);
19792     }
19793 }
19794
19795 static void
19796 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19797                                              mp)
19798 {
19799   vat_main_t *vam = &vat_main;
19800   vat_json_node_t *node = NULL;
19801   struct in6_addr ip6;
19802   struct in_addr ip4;
19803
19804   if (VAT_JSON_ARRAY != vam->json_tree.type)
19805     {
19806       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19807       vat_json_init_array (&vam->json_tree);
19808     }
19809   node = vat_json_array_add (&vam->json_tree);
19810   vat_json_init_object (node);
19811
19812   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19813   vat_json_object_add_uint (node, "appns_index",
19814                             clib_net_to_host_u32 (mp->appns_index));
19815   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19816   vat_json_object_add_uint (node, "scope", mp->scope);
19817   vat_json_object_add_uint (node, "action_index",
19818                             clib_net_to_host_u32 (mp->action_index));
19819   vat_json_object_add_uint (node, "lcl_port",
19820                             clib_net_to_host_u16 (mp->lcl_port));
19821   vat_json_object_add_uint (node, "rmt_port",
19822                             clib_net_to_host_u16 (mp->rmt_port));
19823   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19824   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19825   vat_json_object_add_string_copy (node, "tag", mp->tag);
19826   if (mp->is_ip4)
19827     {
19828       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19829       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19830       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19831       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19832     }
19833   else
19834     {
19835       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19836       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19837       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19838       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19839     }
19840 }
19841
19842 static int
19843 api_session_rule_add_del (vat_main_t * vam)
19844 {
19845   vl_api_session_rule_add_del_t *mp;
19846   unformat_input_t *i = vam->input;
19847   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19848   u32 appns_index = 0, scope = 0;
19849   ip4_address_t lcl_ip4, rmt_ip4;
19850   ip6_address_t lcl_ip6, rmt_ip6;
19851   u8 is_ip4 = 1, conn_set = 0;
19852   u8 is_add = 1, *tag = 0;
19853   int ret;
19854
19855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19856     {
19857       if (unformat (i, "del"))
19858         is_add = 0;
19859       else if (unformat (i, "add"))
19860         ;
19861       else if (unformat (i, "proto tcp"))
19862         proto = 0;
19863       else if (unformat (i, "proto udp"))
19864         proto = 1;
19865       else if (unformat (i, "appns %d", &appns_index))
19866         ;
19867       else if (unformat (i, "scope %d", &scope))
19868         ;
19869       else if (unformat (i, "tag %_%v%_", &tag))
19870         ;
19871       else
19872         if (unformat
19873             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19874              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19875              &rmt_port))
19876         {
19877           is_ip4 = 1;
19878           conn_set = 1;
19879         }
19880       else
19881         if (unformat
19882             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19883              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19884              &rmt_port))
19885         {
19886           is_ip4 = 0;
19887           conn_set = 1;
19888         }
19889       else if (unformat (i, "action %d", &action))
19890         ;
19891       else
19892         break;
19893     }
19894   if (proto == ~0 || !conn_set || action == ~0)
19895     {
19896       errmsg ("transport proto, connection and action must be set");
19897       return -99;
19898     }
19899
19900   if (scope > 3)
19901     {
19902       errmsg ("scope should be 0-3");
19903       return -99;
19904     }
19905
19906   M (SESSION_RULE_ADD_DEL, mp);
19907
19908   mp->is_ip4 = is_ip4;
19909   mp->transport_proto = proto;
19910   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19911   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19912   mp->lcl_plen = lcl_plen;
19913   mp->rmt_plen = rmt_plen;
19914   mp->action_index = clib_host_to_net_u32 (action);
19915   mp->appns_index = clib_host_to_net_u32 (appns_index);
19916   mp->scope = scope;
19917   mp->is_add = is_add;
19918   if (is_ip4)
19919     {
19920       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
19921       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
19922     }
19923   else
19924     {
19925       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
19926       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
19927     }
19928   if (tag)
19929     {
19930       clib_memcpy (mp->tag, tag, vec_len (tag));
19931       vec_free (tag);
19932     }
19933
19934   S (mp);
19935   W (ret);
19936   return ret;
19937 }
19938
19939 static int
19940 api_session_rules_dump (vat_main_t * vam)
19941 {
19942   vl_api_session_rules_dump_t *mp;
19943   vl_api_control_ping_t *mp_ping;
19944   int ret;
19945
19946   if (!vam->json_output)
19947     {
19948       print (vam->ofp, "%=20s", "Session Rules");
19949     }
19950
19951   M (SESSION_RULES_DUMP, mp);
19952   /* send it... */
19953   S (mp);
19954
19955   /* Use a control ping for synchronization */
19956   MPING (CONTROL_PING, mp_ping);
19957   S (mp_ping);
19958
19959   /* Wait for a reply... */
19960   W (ret);
19961   return ret;
19962 }
19963
19964 static int
19965 api_ip_container_proxy_add_del (vat_main_t * vam)
19966 {
19967   vl_api_ip_container_proxy_add_del_t *mp;
19968   unformat_input_t *i = vam->input;
19969   u32 sw_if_index = ~0;
19970   vl_api_prefix_t pfx = { };
19971   u8 is_add = 1;
19972   int ret;
19973
19974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19975     {
19976       if (unformat (i, "del"))
19977         is_add = 0;
19978       else if (unformat (i, "add"))
19979         ;
19980       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19981         ;
19982       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19983         ;
19984       else
19985         break;
19986     }
19987   if (sw_if_index == ~0 || pfx.len == 0)
19988     {
19989       errmsg ("address and sw_if_index must be set");
19990       return -99;
19991     }
19992
19993   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19994
19995   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19996   mp->is_add = is_add;
19997   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19998
19999   S (mp);
20000   W (ret);
20001   return ret;
20002 }
20003
20004 static int
20005 api_qos_record_enable_disable (vat_main_t * vam)
20006 {
20007   unformat_input_t *i = vam->input;
20008   vl_api_qos_record_enable_disable_t *mp;
20009   u32 sw_if_index, qs = 0xff;
20010   u8 sw_if_index_set = 0;
20011   u8 enable = 1;
20012   int ret;
20013
20014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20015     {
20016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20017         sw_if_index_set = 1;
20018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20019         sw_if_index_set = 1;
20020       else if (unformat (i, "%U", unformat_qos_source, &qs))
20021         ;
20022       else if (unformat (i, "disable"))
20023         enable = 0;
20024       else
20025         {
20026           clib_warning ("parse error '%U'", format_unformat_error, i);
20027           return -99;
20028         }
20029     }
20030
20031   if (sw_if_index_set == 0)
20032     {
20033       errmsg ("missing interface name or sw_if_index");
20034       return -99;
20035     }
20036   if (qs == 0xff)
20037     {
20038       errmsg ("input location must be specified");
20039       return -99;
20040     }
20041
20042   M (QOS_RECORD_ENABLE_DISABLE, mp);
20043
20044   mp->record.sw_if_index = ntohl (sw_if_index);
20045   mp->record.input_source = qs;
20046   mp->enable = enable;
20047
20048   S (mp);
20049   W (ret);
20050   return ret;
20051 }
20052
20053
20054 static int
20055 q_or_quit (vat_main_t * vam)
20056 {
20057 #if VPP_API_TEST_BUILTIN == 0
20058   longjmp (vam->jump_buf, 1);
20059 #endif
20060   return 0;                     /* not so much */
20061 }
20062
20063 static int
20064 q (vat_main_t * vam)
20065 {
20066   return q_or_quit (vam);
20067 }
20068
20069 static int
20070 quit (vat_main_t * vam)
20071 {
20072   return q_or_quit (vam);
20073 }
20074
20075 static int
20076 comment (vat_main_t * vam)
20077 {
20078   return 0;
20079 }
20080
20081 static int
20082 elog_save (vat_main_t * vam)
20083 {
20084 #if VPP_API_TEST_BUILTIN == 0
20085   elog_main_t *em = &vam->elog_main;
20086   unformat_input_t *i = vam->input;
20087   char *file, *chroot_file;
20088   clib_error_t *error;
20089
20090   if (!unformat (i, "%s", &file))
20091     {
20092       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20093       return 0;
20094     }
20095
20096   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20097   if (strstr (file, "..") || index (file, '/'))
20098     {
20099       errmsg ("illegal characters in filename '%s'", file);
20100       return 0;
20101     }
20102
20103   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20104
20105   vec_free (file);
20106
20107   errmsg ("Saving %wd of %wd events to %s",
20108           elog_n_events_in_buffer (em),
20109           elog_buffer_capacity (em), chroot_file);
20110
20111   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20112   vec_free (chroot_file);
20113
20114   if (error)
20115     clib_error_report (error);
20116 #else
20117   errmsg ("Use the vpp event loger...");
20118 #endif
20119
20120   return 0;
20121 }
20122
20123 static int
20124 elog_setup (vat_main_t * vam)
20125 {
20126 #if VPP_API_TEST_BUILTIN == 0
20127   elog_main_t *em = &vam->elog_main;
20128   unformat_input_t *i = vam->input;
20129   u32 nevents = 128 << 10;
20130
20131   (void) unformat (i, "nevents %d", &nevents);
20132
20133   elog_init (em, nevents);
20134   vl_api_set_elog_main (em);
20135   vl_api_set_elog_trace_api_messages (1);
20136   errmsg ("Event logger initialized with %u events", nevents);
20137 #else
20138   errmsg ("Use the vpp event loger...");
20139 #endif
20140   return 0;
20141 }
20142
20143 static int
20144 elog_enable (vat_main_t * vam)
20145 {
20146 #if VPP_API_TEST_BUILTIN == 0
20147   elog_main_t *em = &vam->elog_main;
20148
20149   elog_enable_disable (em, 1 /* enable */ );
20150   vl_api_set_elog_trace_api_messages (1);
20151   errmsg ("Event logger enabled...");
20152 #else
20153   errmsg ("Use the vpp event loger...");
20154 #endif
20155   return 0;
20156 }
20157
20158 static int
20159 elog_disable (vat_main_t * vam)
20160 {
20161 #if VPP_API_TEST_BUILTIN == 0
20162   elog_main_t *em = &vam->elog_main;
20163
20164   elog_enable_disable (em, 0 /* enable */ );
20165   vl_api_set_elog_trace_api_messages (1);
20166   errmsg ("Event logger disabled...");
20167 #else
20168   errmsg ("Use the vpp event loger...");
20169 #endif
20170   return 0;
20171 }
20172
20173 static int
20174 statseg (vat_main_t * vam)
20175 {
20176   ssvm_private_t *ssvmp = &vam->stat_segment;
20177   ssvm_shared_header_t *shared_header = ssvmp->sh;
20178   vlib_counter_t **counters;
20179   u64 thread0_index1_packets;
20180   u64 thread0_index1_bytes;
20181   f64 vector_rate, input_rate;
20182   uword *p;
20183
20184   uword *counter_vector_by_name;
20185   if (vam->stat_segment_lockp == 0)
20186     {
20187       errmsg ("Stat segment not mapped...");
20188       return -99;
20189     }
20190
20191   /* look up "/if/rx for sw_if_index 1 as a test */
20192
20193   clib_spinlock_lock (vam->stat_segment_lockp);
20194
20195   counter_vector_by_name = (uword *) shared_header->opaque[1];
20196
20197   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20198   if (p == 0)
20199     {
20200       clib_spinlock_unlock (vam->stat_segment_lockp);
20201       errmsg ("/if/tx not found?");
20202       return -99;
20203     }
20204
20205   /* Fish per-thread vector of combined counters from shared memory */
20206   counters = (vlib_counter_t **) p[0];
20207
20208   if (vec_len (counters[0]) < 2)
20209     {
20210       clib_spinlock_unlock (vam->stat_segment_lockp);
20211       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20212       return -99;
20213     }
20214
20215   /* Read thread 0 sw_if_index 1 counter */
20216   thread0_index1_packets = counters[0][1].packets;
20217   thread0_index1_bytes = counters[0][1].bytes;
20218
20219   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20220   if (p == 0)
20221     {
20222       clib_spinlock_unlock (vam->stat_segment_lockp);
20223       errmsg ("vector_rate not found?");
20224       return -99;
20225     }
20226
20227   vector_rate = *(f64 *) (p[0]);
20228   p = hash_get_mem (counter_vector_by_name, "input_rate");
20229   if (p == 0)
20230     {
20231       clib_spinlock_unlock (vam->stat_segment_lockp);
20232       errmsg ("input_rate not found?");
20233       return -99;
20234     }
20235   input_rate = *(f64 *) (p[0]);
20236
20237   clib_spinlock_unlock (vam->stat_segment_lockp);
20238
20239   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20240          vector_rate, input_rate);
20241   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20242          thread0_index1_packets, thread0_index1_bytes);
20243
20244   return 0;
20245 }
20246
20247 static int
20248 cmd_cmp (void *a1, void *a2)
20249 {
20250   u8 **c1 = a1;
20251   u8 **c2 = a2;
20252
20253   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20254 }
20255
20256 static int
20257 help (vat_main_t * vam)
20258 {
20259   u8 **cmds = 0;
20260   u8 *name = 0;
20261   hash_pair_t *p;
20262   unformat_input_t *i = vam->input;
20263   int j;
20264
20265   if (unformat (i, "%s", &name))
20266     {
20267       uword *hs;
20268
20269       vec_add1 (name, 0);
20270
20271       hs = hash_get_mem (vam->help_by_name, name);
20272       if (hs)
20273         print (vam->ofp, "usage: %s %s", name, hs[0]);
20274       else
20275         print (vam->ofp, "No such msg / command '%s'", name);
20276       vec_free (name);
20277       return 0;
20278     }
20279
20280   print (vam->ofp, "Help is available for the following:");
20281
20282     /* *INDENT-OFF* */
20283     hash_foreach_pair (p, vam->function_by_name,
20284     ({
20285       vec_add1 (cmds, (u8 *)(p->key));
20286     }));
20287     /* *INDENT-ON* */
20288
20289   vec_sort_with_function (cmds, cmd_cmp);
20290
20291   for (j = 0; j < vec_len (cmds); j++)
20292     print (vam->ofp, "%s", cmds[j]);
20293
20294   vec_free (cmds);
20295   return 0;
20296 }
20297
20298 static int
20299 set (vat_main_t * vam)
20300 {
20301   u8 *name = 0, *value = 0;
20302   unformat_input_t *i = vam->input;
20303
20304   if (unformat (i, "%s", &name))
20305     {
20306       /* The input buffer is a vector, not a string. */
20307       value = vec_dup (i->buffer);
20308       vec_delete (value, i->index, 0);
20309       /* Almost certainly has a trailing newline */
20310       if (value[vec_len (value) - 1] == '\n')
20311         value[vec_len (value) - 1] = 0;
20312       /* Make sure it's a proper string, one way or the other */
20313       vec_add1 (value, 0);
20314       (void) clib_macro_set_value (&vam->macro_main,
20315                                    (char *) name, (char *) value);
20316     }
20317   else
20318     errmsg ("usage: set <name> <value>");
20319
20320   vec_free (name);
20321   vec_free (value);
20322   return 0;
20323 }
20324
20325 static int
20326 unset (vat_main_t * vam)
20327 {
20328   u8 *name = 0;
20329
20330   if (unformat (vam->input, "%s", &name))
20331     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20332       errmsg ("unset: %s wasn't set", name);
20333   vec_free (name);
20334   return 0;
20335 }
20336
20337 typedef struct
20338 {
20339   u8 *name;
20340   u8 *value;
20341 } macro_sort_t;
20342
20343
20344 static int
20345 macro_sort_cmp (void *a1, void *a2)
20346 {
20347   macro_sort_t *s1 = a1;
20348   macro_sort_t *s2 = a2;
20349
20350   return strcmp ((char *) (s1->name), (char *) (s2->name));
20351 }
20352
20353 static int
20354 dump_macro_table (vat_main_t * vam)
20355 {
20356   macro_sort_t *sort_me = 0, *sm;
20357   int i;
20358   hash_pair_t *p;
20359
20360     /* *INDENT-OFF* */
20361     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20362     ({
20363       vec_add2 (sort_me, sm, 1);
20364       sm->name = (u8 *)(p->key);
20365       sm->value = (u8 *) (p->value[0]);
20366     }));
20367     /* *INDENT-ON* */
20368
20369   vec_sort_with_function (sort_me, macro_sort_cmp);
20370
20371   if (vec_len (sort_me))
20372     print (vam->ofp, "%-15s%s", "Name", "Value");
20373   else
20374     print (vam->ofp, "The macro table is empty...");
20375
20376   for (i = 0; i < vec_len (sort_me); i++)
20377     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20378   return 0;
20379 }
20380
20381 static int
20382 dump_node_table (vat_main_t * vam)
20383 {
20384   int i, j;
20385   vlib_node_t *node, *next_node;
20386
20387   if (vec_len (vam->graph_nodes) == 0)
20388     {
20389       print (vam->ofp, "Node table empty, issue get_node_graph...");
20390       return 0;
20391     }
20392
20393   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20394     {
20395       node = vam->graph_nodes[0][i];
20396       print (vam->ofp, "[%d] %s", i, node->name);
20397       for (j = 0; j < vec_len (node->next_nodes); j++)
20398         {
20399           if (node->next_nodes[j] != ~0)
20400             {
20401               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20402               print (vam->ofp, "  [%d] %s", j, next_node->name);
20403             }
20404         }
20405     }
20406   return 0;
20407 }
20408
20409 static int
20410 value_sort_cmp (void *a1, void *a2)
20411 {
20412   name_sort_t *n1 = a1;
20413   name_sort_t *n2 = a2;
20414
20415   if (n1->value < n2->value)
20416     return -1;
20417   if (n1->value > n2->value)
20418     return 1;
20419   return 0;
20420 }
20421
20422
20423 static int
20424 dump_msg_api_table (vat_main_t * vam)
20425 {
20426   api_main_t *am = vlibapi_get_main ();
20427   name_sort_t *nses = 0, *ns;
20428   hash_pair_t *hp;
20429   int i;
20430
20431   /* *INDENT-OFF* */
20432   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20433   ({
20434     vec_add2 (nses, ns, 1);
20435     ns->name = (u8 *)(hp->key);
20436     ns->value = (u32) hp->value[0];
20437   }));
20438   /* *INDENT-ON* */
20439
20440   vec_sort_with_function (nses, value_sort_cmp);
20441
20442   for (i = 0; i < vec_len (nses); i++)
20443     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20444   vec_free (nses);
20445   return 0;
20446 }
20447
20448 static int
20449 get_msg_id (vat_main_t * vam)
20450 {
20451   u8 *name_and_crc;
20452   u32 message_index;
20453
20454   if (unformat (vam->input, "%s", &name_and_crc))
20455     {
20456       message_index = vl_msg_api_get_msg_index (name_and_crc);
20457       if (message_index == ~0)
20458         {
20459           print (vam->ofp, " '%s' not found", name_and_crc);
20460           return 0;
20461         }
20462       print (vam->ofp, " '%s' has message index %d",
20463              name_and_crc, message_index);
20464       return 0;
20465     }
20466   errmsg ("name_and_crc required...");
20467   return 0;
20468 }
20469
20470 static int
20471 search_node_table (vat_main_t * vam)
20472 {
20473   unformat_input_t *line_input = vam->input;
20474   u8 *node_to_find;
20475   int j;
20476   vlib_node_t *node, *next_node;
20477   uword *p;
20478
20479   if (vam->graph_node_index_by_name == 0)
20480     {
20481       print (vam->ofp, "Node table empty, issue get_node_graph...");
20482       return 0;
20483     }
20484
20485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20486     {
20487       if (unformat (line_input, "%s", &node_to_find))
20488         {
20489           vec_add1 (node_to_find, 0);
20490           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20491           if (p == 0)
20492             {
20493               print (vam->ofp, "%s not found...", node_to_find);
20494               goto out;
20495             }
20496           node = vam->graph_nodes[0][p[0]];
20497           print (vam->ofp, "[%d] %s", p[0], node->name);
20498           for (j = 0; j < vec_len (node->next_nodes); j++)
20499             {
20500               if (node->next_nodes[j] != ~0)
20501                 {
20502                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20503                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20504                 }
20505             }
20506         }
20507
20508       else
20509         {
20510           clib_warning ("parse error '%U'", format_unformat_error,
20511                         line_input);
20512           return -99;
20513         }
20514
20515     out:
20516       vec_free (node_to_find);
20517
20518     }
20519
20520   return 0;
20521 }
20522
20523
20524 static int
20525 script (vat_main_t * vam)
20526 {
20527 #if (VPP_API_TEST_BUILTIN==0)
20528   u8 *s = 0;
20529   char *save_current_file;
20530   unformat_input_t save_input;
20531   jmp_buf save_jump_buf;
20532   u32 save_line_number;
20533
20534   FILE *new_fp, *save_ifp;
20535
20536   if (unformat (vam->input, "%s", &s))
20537     {
20538       new_fp = fopen ((char *) s, "r");
20539       if (new_fp == 0)
20540         {
20541           errmsg ("Couldn't open script file %s", s);
20542           vec_free (s);
20543           return -99;
20544         }
20545     }
20546   else
20547     {
20548       errmsg ("Missing script name");
20549       return -99;
20550     }
20551
20552   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20553   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20554   save_ifp = vam->ifp;
20555   save_line_number = vam->input_line_number;
20556   save_current_file = (char *) vam->current_file;
20557
20558   vam->input_line_number = 0;
20559   vam->ifp = new_fp;
20560   vam->current_file = s;
20561   do_one_file (vam);
20562
20563   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20564   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20565   vam->ifp = save_ifp;
20566   vam->input_line_number = save_line_number;
20567   vam->current_file = (u8 *) save_current_file;
20568   vec_free (s);
20569
20570   return 0;
20571 #else
20572   clib_warning ("use the exec command...");
20573   return -99;
20574 #endif
20575 }
20576
20577 static int
20578 echo (vat_main_t * vam)
20579 {
20580   print (vam->ofp, "%v", vam->input->buffer);
20581   return 0;
20582 }
20583
20584 /* List of API message constructors, CLI names map to api_xxx */
20585 #define foreach_vpe_api_msg                                             \
20586 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20587 _(sw_interface_dump,"")                                                 \
20588 _(sw_interface_set_flags,                                               \
20589   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20590 _(sw_interface_add_del_address,                                         \
20591   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20592 _(sw_interface_set_rx_mode,                                             \
20593   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20594 _(sw_interface_set_rx_placement,                                        \
20595   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20596 _(sw_interface_rx_placement_dump,                                       \
20597   "[<intfc> | sw_if_index <id>]")                                         \
20598 _(sw_interface_set_table,                                               \
20599   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20600 _(sw_interface_set_mpls_enable,                                         \
20601   "<intfc> | sw_if_index [disable | dis]")                              \
20602 _(sw_interface_set_vpath,                                               \
20603   "<intfc> | sw_if_index <id> enable | disable")                        \
20604 _(sw_interface_set_vxlan_bypass,                                        \
20605   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20606 _(sw_interface_set_geneve_bypass,                                       \
20607   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20608 _(sw_interface_set_l2_xconnect,                                         \
20609   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20610   "enable | disable")                                                   \
20611 _(sw_interface_set_l2_bridge,                                           \
20612   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20613   "[shg <split-horizon-group>] [bvi]\n"                                 \
20614   "enable | disable")                                                   \
20615 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20616 _(bridge_domain_add_del,                                                \
20617   "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") \
20618 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20619 _(l2fib_add_del,                                                        \
20620   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20621 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20622 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20623 _(l2_flags,                                                             \
20624   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20625 _(bridge_flags,                                                         \
20626   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20627 _(tap_create_v2,                                                        \
20628   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
20629 _(tap_delete_v2,                                                        \
20630   "<vpp-if-name> | sw_if_index <id>")                                   \
20631 _(sw_interface_tap_v2_dump, "")                                         \
20632 _(virtio_pci_create,                                                    \
20633   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20634 _(virtio_pci_delete,                                                    \
20635   "<vpp-if-name> | sw_if_index <id>")                                   \
20636 _(sw_interface_virtio_pci_dump, "")                                     \
20637 _(bond_create,                                                          \
20638   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20639   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20640   "[id <if-id>]")                                                       \
20641 _(bond_delete,                                                          \
20642   "<vpp-if-name> | sw_if_index <id>")                                   \
20643 _(bond_enslave,                                                         \
20644   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20645 _(bond_detach_slave,                                                    \
20646   "sw_if_index <n>")                                                    \
20647  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20648 _(sw_interface_bond_dump, "")                                           \
20649 _(sw_interface_slave_dump,                                              \
20650   "<vpp-if-name> | sw_if_index <id>")                                   \
20651 _(ip_table_add_del,                                                     \
20652   "table <n> [ipv6] [add | del]\n")                                     \
20653 _(ip_route_add_del,                                                     \
20654   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20655   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20656   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20657   "[multipath] [count <n>] [del]")                                      \
20658 _(ip_mroute_add_del,                                                    \
20659   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20660   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20661 _(mpls_table_add_del,                                                   \
20662   "table <n> [add | del]\n")                                            \
20663 _(mpls_route_add_del,                                                   \
20664   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20665   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20666   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20667   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20668   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20669   "[count <n>] [del]")                                                  \
20670 _(mpls_ip_bind_unbind,                                                  \
20671   "<label> <addr/len>")                                                 \
20672 _(mpls_tunnel_add_del,                                                  \
20673   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20674   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20675   "[l2-only]  [out-label <n>]")                                         \
20676 _(sr_mpls_policy_add,                                                   \
20677   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20678 _(sr_mpls_policy_del,                                                   \
20679   "bsid <id>")                                                          \
20680 _(bier_table_add_del,                                                   \
20681   "<label> <sub-domain> <set> <bsl> [del]")                             \
20682 _(bier_route_add_del,                                                   \
20683   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20684   "[<intfc> | sw_if_index <id>]"                                        \
20685   "[weight <n>] [del] [multipath]")                                     \
20686 _(sw_interface_set_unnumbered,                                          \
20687   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20688 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20689 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20690   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20691   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20692   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20693 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20694 _(ip_table_flush, "table <n> [ipv6]")                                   \
20695 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20696 _(set_ip_flow_hash,                                                     \
20697   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20698 _(sw_interface_ip6_enable_disable,                                      \
20699   "<intfc> | sw_if_index <id> enable | disable")                        \
20700 _(l2_patch_add_del,                                                     \
20701   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20702   "enable | disable")                                                   \
20703 _(sr_localsid_add_del,                                                  \
20704   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20705   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20706 _(classify_add_del_table,                                               \
20707   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20708   " [del] [del-chain] mask <mask-value>\n"                              \
20709   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20710   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20711 _(classify_add_del_session,                                             \
20712   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20713   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20714   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20715   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20716 _(classify_set_interface_ip_table,                                      \
20717   "<intfc> | sw_if_index <nn> table <nn>")                              \
20718 _(classify_set_interface_l2_tables,                                     \
20719   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20720   "  [other-table <nn>]")                                               \
20721 _(get_node_index, "node <node-name")                                    \
20722 _(add_node_next, "node <node-name> next <next-node-name>")              \
20723 _(l2tpv3_create_tunnel,                                                 \
20724   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20725   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20726   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20727 _(l2tpv3_set_tunnel_cookies,                                            \
20728   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20729   "[new_remote_cookie <nn>]\n")                                         \
20730 _(l2tpv3_interface_enable_disable,                                      \
20731   "<intfc> | sw_if_index <nn> enable | disable")                        \
20732 _(l2tpv3_set_lookup_key,                                                \
20733   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20734 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20735 _(vxlan_offload_rx,                                                     \
20736   "hw { <interface name> | hw_if_index <nn>} "                          \
20737   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20738 _(vxlan_add_del_tunnel,                                                 \
20739   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20740   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20741   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20742 _(geneve_add_del_tunnel,                                                \
20743   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20744   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20745   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20746 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20747 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20748 _(gre_tunnel_add_del,                                                   \
20749   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20750   "[teb | erspan <session-id>] [del]")                                  \
20751 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20752 _(l2_fib_clear_table, "")                                               \
20753 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20754 _(l2_interface_vlan_tag_rewrite,                                        \
20755   "<intfc> | sw_if_index <nn> \n"                                       \
20756   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20757   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20758 _(create_vhost_user_if,                                                 \
20759         "socket <filename> [server] [renumber <dev_instance>] "         \
20760         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20761         "[mac <mac_address>]")                                          \
20762 _(modify_vhost_user_if,                                                 \
20763         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20764         "[server] [renumber <dev_instance>] [gso]")                     \
20765 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20766 _(sw_interface_vhost_user_dump, "")                                     \
20767 _(show_version, "")                                                     \
20768 _(show_threads, "")                                                     \
20769 _(vxlan_gpe_add_del_tunnel,                                             \
20770   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20771   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20772   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20773   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20774 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20775 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20776 _(interface_name_renumber,                                              \
20777   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20778 _(input_acl_set_interface,                                              \
20779   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20780   "  [l2-table <nn>] [del]")                                            \
20781 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20782 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20783 _(ip_dump, "ipv4 | ipv6")                                               \
20784 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20785 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20786   "  spid_id <n> ")                                                     \
20787 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20788   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20789   "  integ_alg <alg> integ_key <hex>")                                  \
20790 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20791   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20792   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20793   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20794 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20795   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20796   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20797   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20798   "  [instance <n>]")     \
20799 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20800 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20801 _(delete_loopback,"sw_if_index <nn>")                                   \
20802 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20803 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20804 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20805 _(want_interface_events,  "enable|disable")                             \
20806 _(get_first_msg_id, "client <name>")                                    \
20807 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20808 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20809   "fib-id <nn> [ip4][ip6][default]")                                    \
20810 _(get_node_graph, " ")                                                  \
20811 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20812 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20813 _(ioam_disable, "")                                                     \
20814 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20815                             " sw_if_index <sw_if_index> p <priority> "  \
20816                             "w <weight>] [del]")                        \
20817 _(one_add_del_locator, "locator-set <locator_name> "                    \
20818                         "iface <intf> | sw_if_index <sw_if_index> "     \
20819                         "p <priority> w <weight> [del]")                \
20820 _(one_add_del_local_eid,"vni <vni> eid "                                \
20821                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20822                          "locator-set <locator_name> [del]"             \
20823                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20824 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20825 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20826 _(one_enable_disable, "enable|disable")                                 \
20827 _(one_map_register_enable_disable, "enable|disable")                    \
20828 _(one_map_register_fallback_threshold, "<value>")                       \
20829 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20830 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20831                                "[seid <seid>] "                         \
20832                                "rloc <locator> p <prio> "               \
20833                                "w <weight> [rloc <loc> ... ] "          \
20834                                "action <action> [del-all]")             \
20835 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20836                           "<local-eid>")                                \
20837 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20838 _(one_use_petr, "ip-address> | disable")                                \
20839 _(one_map_request_mode, "src-dst|dst-only")                             \
20840 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20841 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20842 _(one_locator_set_dump, "[local | remote]")                             \
20843 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20844 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20845                        "[local] | [remote]")                            \
20846 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20847 _(one_ndp_bd_get, "")                                                   \
20848 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20849 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20850 _(one_l2_arp_bd_get, "")                                                \
20851 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20852 _(one_stats_enable_disable, "enable|disable")                           \
20853 _(show_one_stats_enable_disable, "")                                    \
20854 _(one_eid_table_vni_dump, "")                                           \
20855 _(one_eid_table_map_dump, "l2|l3")                                      \
20856 _(one_map_resolver_dump, "")                                            \
20857 _(one_map_server_dump, "")                                              \
20858 _(one_adjacencies_get, "vni <vni>")                                     \
20859 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20860 _(show_one_rloc_probe_state, "")                                        \
20861 _(show_one_map_register_state, "")                                      \
20862 _(show_one_status, "")                                                  \
20863 _(one_stats_dump, "")                                                   \
20864 _(one_stats_flush, "")                                                  \
20865 _(one_get_map_request_itr_rlocs, "")                                    \
20866 _(one_map_register_set_ttl, "<ttl>")                                    \
20867 _(one_set_transport_protocol, "udp|api")                                \
20868 _(one_get_transport_protocol, "")                                       \
20869 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20870 _(one_show_xtr_mode, "")                                                \
20871 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20872 _(one_show_pitr_mode, "")                                               \
20873 _(one_enable_disable_petr_mode, "enable|disable")                       \
20874 _(one_show_petr_mode, "")                                               \
20875 _(show_one_nsh_mapping, "")                                             \
20876 _(show_one_pitr, "")                                                    \
20877 _(show_one_use_petr, "")                                                \
20878 _(show_one_map_request_mode, "")                                        \
20879 _(show_one_map_register_ttl, "")                                        \
20880 _(show_one_map_register_fallback_threshold, "")                         \
20881 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20882                             " sw_if_index <sw_if_index> p <priority> "  \
20883                             "w <weight>] [del]")                        \
20884 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20885                         "iface <intf> | sw_if_index <sw_if_index> "     \
20886                         "p <priority> w <weight> [del]")                \
20887 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20888                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20889                          "locator-set <locator_name> [del]"             \
20890                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20891 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20892 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20893 _(lisp_enable_disable, "enable|disable")                                \
20894 _(lisp_map_register_enable_disable, "enable|disable")                   \
20895 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20896 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20897                                "[seid <seid>] "                         \
20898                                "rloc <locator> p <prio> "               \
20899                                "w <weight> [rloc <loc> ... ] "          \
20900                                "action <action> [del-all]")             \
20901 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20902                           "<local-eid>")                                \
20903 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20904 _(lisp_use_petr, "<ip-address> | disable")                              \
20905 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20906 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20907 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20908 _(lisp_locator_set_dump, "[local | remote]")                            \
20909 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20910 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20911                        "[local] | [remote]")                            \
20912 _(lisp_eid_table_vni_dump, "")                                          \
20913 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20914 _(lisp_map_resolver_dump, "")                                           \
20915 _(lisp_map_server_dump, "")                                             \
20916 _(lisp_adjacencies_get, "vni <vni>")                                    \
20917 _(gpe_fwd_entry_vnis_get, "")                                           \
20918 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20919 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20920                                 "[table <table-id>]")                   \
20921 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20922 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20923 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20924 _(gpe_get_encap_mode, "")                                               \
20925 _(lisp_gpe_add_del_iface, "up|down")                                    \
20926 _(lisp_gpe_enable_disable, "enable|disable")                            \
20927 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20928   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20929 _(show_lisp_rloc_probe_state, "")                                       \
20930 _(show_lisp_map_register_state, "")                                     \
20931 _(show_lisp_status, "")                                                 \
20932 _(lisp_get_map_request_itr_rlocs, "")                                   \
20933 _(show_lisp_pitr, "")                                                   \
20934 _(show_lisp_use_petr, "")                                               \
20935 _(show_lisp_map_request_mode, "")                                       \
20936 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20937 _(af_packet_delete, "name <host interface name>")                       \
20938 _(af_packet_dump, "")                                                   \
20939 _(policer_add_del, "name <policer name> <params> [del]")                \
20940 _(policer_dump, "[name <policer name>]")                                \
20941 _(policer_classify_set_interface,                                       \
20942   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20943   "  [l2-table <nn>] [del]")                                            \
20944 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20945 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20946 _(mpls_table_dump, "")                                                  \
20947 _(mpls_route_dump, "table-id <ID>")                                     \
20948 _(classify_table_ids, "")                                               \
20949 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20950 _(classify_table_info, "table_id <nn>")                                 \
20951 _(classify_session_dump, "table_id <nn>")                               \
20952 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20953     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20954     "[template_interval <nn>] [udp_checksum]")                          \
20955 _(ipfix_exporter_dump, "")                                              \
20956 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20957 _(ipfix_classify_stream_dump, "")                                       \
20958 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20959 _(ipfix_classify_table_dump, "")                                        \
20960 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20961 _(sw_interface_span_dump, "[l2]")                                           \
20962 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20963 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20964 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20965 _(pg_enable_disable, "[stream <id>] disable")                           \
20966 _(ip_source_and_port_range_check_add_del,                               \
20967   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20968 _(ip_source_and_port_range_check_interface_add_del,                     \
20969   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20970   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20971 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20972 _(l2_interface_pbb_tag_rewrite,                                         \
20973   "<intfc> | sw_if_index <nn> \n"                                       \
20974   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20975   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20976 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20977 _(flow_classify_set_interface,                                          \
20978   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20979 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20980 _(ip_table_dump, "")                                                    \
20981 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20982 _(ip_mtable_dump, "")                                                   \
20983 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20984 _(feature_enable_disable, "arc_name <arc_name> "                        \
20985   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20986 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20987   "[enable | disable] ")                                                \
20988 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20989 "[disable]")                                                            \
20990 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20991   "mac <mac-address> [del]")                                            \
20992 _(l2_xconnect_dump, "")                                                 \
20993 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20994 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20995 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20996 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20997 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20998 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20999   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21000 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21001 _(sock_init_shm, "size <nnn>")                                          \
21002 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21003 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21004   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21005 _(session_rules_dump, "")                                               \
21006 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21007 _(output_acl_set_interface,                                             \
21008   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21009   "  [l2-table <nn>] [del]")                                            \
21010 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21011
21012 /* List of command functions, CLI names map directly to functions */
21013 #define foreach_cli_function                                    \
21014 _(comment, "usage: comment <ignore-rest-of-line>")              \
21015 _(dump_interface_table, "usage: dump_interface_table")          \
21016 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21017 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21018 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21019 _(dump_macro_table, "usage: dump_macro_table ")                 \
21020 _(dump_node_table, "usage: dump_node_table")                    \
21021 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21022 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21023 _(elog_disable, "usage: elog_disable")                          \
21024 _(elog_enable, "usage: elog_enable")                            \
21025 _(elog_save, "usage: elog_save <filename>")                     \
21026 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21027 _(echo, "usage: echo <message>")                                \
21028 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21029 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21030 _(help, "usage: help")                                          \
21031 _(q, "usage: quit")                                             \
21032 _(quit, "usage: quit")                                          \
21033 _(search_node_table, "usage: search_node_table <name>...")      \
21034 _(set, "usage: set <variable-name> <value>")                    \
21035 _(script, "usage: script <file-name>")                          \
21036 _(statseg, "usage: statseg")                                    \
21037 _(unset, "usage: unset <variable-name>")
21038
21039 #define _(N,n)                                  \
21040     static void vl_api_##n##_t_handler_uni      \
21041     (vl_api_##n##_t * mp)                       \
21042     {                                           \
21043         vat_main_t * vam = &vat_main;           \
21044         if (vam->json_output) {                 \
21045             vl_api_##n##_t_handler_json(mp);    \
21046         } else {                                \
21047             vl_api_##n##_t_handler(mp);         \
21048         }                                       \
21049     }
21050 foreach_vpe_api_reply_msg;
21051 #if VPP_API_TEST_BUILTIN == 0
21052 foreach_standalone_reply_msg;
21053 #endif
21054 #undef _
21055
21056 void
21057 vat_api_hookup (vat_main_t * vam)
21058 {
21059 #define _(N,n)                                                  \
21060     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21061                            vl_api_##n##_t_handler_uni,          \
21062                            vl_noop_handler,                     \
21063                            vl_api_##n##_t_endian,               \
21064                            vl_api_##n##_t_print,                \
21065                            sizeof(vl_api_##n##_t), 1);
21066   foreach_vpe_api_reply_msg;
21067 #if VPP_API_TEST_BUILTIN == 0
21068   foreach_standalone_reply_msg;
21069 #endif
21070 #undef _
21071
21072 #if (VPP_API_TEST_BUILTIN==0)
21073   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21074
21075   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21076
21077   vam->function_by_name = hash_create_string (0, sizeof (uword));
21078
21079   vam->help_by_name = hash_create_string (0, sizeof (uword));
21080 #endif
21081
21082   /* API messages we can send */
21083 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21084   foreach_vpe_api_msg;
21085 #undef _
21086
21087   /* Help strings */
21088 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21089   foreach_vpe_api_msg;
21090 #undef _
21091
21092   /* CLI functions */
21093 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21094   foreach_cli_function;
21095 #undef _
21096
21097   /* Help strings */
21098 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21099   foreach_cli_function;
21100 #undef _
21101 }
21102
21103 #if VPP_API_TEST_BUILTIN
21104 static clib_error_t *
21105 vat_api_hookup_shim (vlib_main_t * vm)
21106 {
21107   vat_api_hookup (&vat_main);
21108   return 0;
21109 }
21110
21111 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21112 #endif
21113
21114 /*
21115  * fd.io coding-style-patch-verification: ON
21116  *
21117  * Local Variables:
21118  * eval: (c-set-style "gnu")
21119  * End:
21120  */