interface: dump the interface device type
[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/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   api_main_t *am = &api_main;
1104   void *oldheap;
1105   u8 *reply;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_uint (&node, "reply_in_shmem",
1110                             ntohl (mp->reply_in_shmem));
1111   /* Toss the shared-memory original... */
1112   pthread_mutex_lock (&am->vlib_rp->mutex);
1113   oldheap = svm_push_data_heap (am->vlib_rp);
1114
1115   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1116   vec_free (reply);
1117
1118   svm_pop_heap (oldheap);
1119   pthread_mutex_unlock (&am->vlib_rp->mutex);
1120
1121   vat_json_print (vam->ofp, &node);
1122   vat_json_free (&node);
1123
1124   vam->retval = ntohl (mp->retval);
1125   vam->result_ready = 1;
1126 }
1127
1128 static void
1129 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1130 {
1131   vat_main_t *vam = &vat_main;
1132   i32 retval = ntohl (mp->retval);
1133   u32 length = vl_api_string_len (&mp->reply);
1134
1135   vec_reset_length (vam->cmd_reply);
1136
1137   vam->retval = retval;
1138   if (retval == 0)
1139     {
1140       vec_validate (vam->cmd_reply, length);
1141       clib_memcpy ((char *) (vam->cmd_reply),
1142                    vl_api_from_api_string (&mp->reply), length);
1143       vam->cmd_reply[length] = 0;
1144     }
1145   vam->result_ready = 1;
1146 }
1147
1148 static void
1149 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1150 {
1151   vat_main_t *vam = &vat_main;
1152   vat_json_node_t node;
1153
1154   vec_reset_length (vam->cmd_reply);
1155
1156   vat_json_init_object (&node);
1157   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1158   vat_json_object_add_string_copy (&node, "reply",
1159                                    vl_api_from_api_string (&mp->reply));
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   i32 retval = ntohl (mp->retval);
1173   if (vam->async_mode)
1174     {
1175       vam->async_errors += (retval < 0);
1176     }
1177   else
1178     {
1179       vam->retval = retval;
1180       if (retval == 0 &&
1181           ((mp->new_table_index != 0xFFFFFFFF) ||
1182            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1183            (mp->match_n_vectors != 0xFFFFFFFF)))
1184         /*
1185          * Note: this is just barely thread-safe, depends on
1186          * the main thread spinning waiting for an answer...
1187          */
1188         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1189                 ntohl (mp->new_table_index),
1190                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1191       vam->result_ready = 1;
1192     }
1193 }
1194
1195 static void vl_api_classify_add_del_table_reply_t_handler_json
1196   (vl_api_classify_add_del_table_reply_t * mp)
1197 {
1198   vat_main_t *vam = &vat_main;
1199   vat_json_node_t node;
1200
1201   vat_json_init_object (&node);
1202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1203   vat_json_object_add_uint (&node, "new_table_index",
1204                             ntohl (mp->new_table_index));
1205   vat_json_object_add_uint (&node, "skip_n_vectors",
1206                             ntohl (mp->skip_n_vectors));
1207   vat_json_object_add_uint (&node, "match_n_vectors",
1208                             ntohl (mp->match_n_vectors));
1209
1210   vat_json_print (vam->ofp, &node);
1211   vat_json_free (&node);
1212
1213   vam->retval = ntohl (mp->retval);
1214   vam->result_ready = 1;
1215 }
1216
1217 static void vl_api_get_node_index_reply_t_handler
1218   (vl_api_get_node_index_reply_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   i32 retval = ntohl (mp->retval);
1222   if (vam->async_mode)
1223     {
1224       vam->async_errors += (retval < 0);
1225     }
1226   else
1227     {
1228       vam->retval = retval;
1229       if (retval == 0)
1230         errmsg ("node index %d", ntohl (mp->node_index));
1231       vam->result_ready = 1;
1232     }
1233 }
1234
1235 static void vl_api_get_node_index_reply_t_handler_json
1236   (vl_api_get_node_index_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   vat_json_node_t node;
1240
1241   vat_json_init_object (&node);
1242   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1243   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1244
1245   vat_json_print (vam->ofp, &node);
1246   vat_json_free (&node);
1247
1248   vam->retval = ntohl (mp->retval);
1249   vam->result_ready = 1;
1250 }
1251
1252 static void vl_api_get_next_index_reply_t_handler
1253   (vl_api_get_next_index_reply_t * mp)
1254 {
1255   vat_main_t *vam = &vat_main;
1256   i32 retval = ntohl (mp->retval);
1257   if (vam->async_mode)
1258     {
1259       vam->async_errors += (retval < 0);
1260     }
1261   else
1262     {
1263       vam->retval = retval;
1264       if (retval == 0)
1265         errmsg ("next node index %d", ntohl (mp->next_index));
1266       vam->result_ready = 1;
1267     }
1268 }
1269
1270 static void vl_api_get_next_index_reply_t_handler_json
1271   (vl_api_get_next_index_reply_t * mp)
1272 {
1273   vat_main_t *vam = &vat_main;
1274   vat_json_node_t node;
1275
1276   vat_json_init_object (&node);
1277   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1278   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1279
1280   vat_json_print (vam->ofp, &node);
1281   vat_json_free (&node);
1282
1283   vam->retval = ntohl (mp->retval);
1284   vam->result_ready = 1;
1285 }
1286
1287 static void vl_api_add_node_next_reply_t_handler
1288   (vl_api_add_node_next_reply_t * mp)
1289 {
1290   vat_main_t *vam = &vat_main;
1291   i32 retval = ntohl (mp->retval);
1292   if (vam->async_mode)
1293     {
1294       vam->async_errors += (retval < 0);
1295     }
1296   else
1297     {
1298       vam->retval = retval;
1299       if (retval == 0)
1300         errmsg ("next index %d", ntohl (mp->next_index));
1301       vam->result_ready = 1;
1302     }
1303 }
1304
1305 static void vl_api_add_node_next_reply_t_handler_json
1306   (vl_api_add_node_next_reply_t * mp)
1307 {
1308   vat_main_t *vam = &vat_main;
1309   vat_json_node_t node;
1310
1311   vat_json_init_object (&node);
1312   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1313   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void vl_api_show_version_reply_t_handler
1323   (vl_api_show_version_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327
1328   if (retval >= 0)
1329     {
1330       errmsg ("        program: %s", mp->program);
1331       errmsg ("        version: %s", mp->version);
1332       errmsg ("     build date: %s", mp->build_date);
1333       errmsg ("build directory: %s", mp->build_directory);
1334     }
1335   vam->retval = retval;
1336   vam->result_ready = 1;
1337 }
1338
1339 static void vl_api_show_version_reply_t_handler_json
1340   (vl_api_show_version_reply_t * mp)
1341 {
1342   vat_main_t *vam = &vat_main;
1343   vat_json_node_t node;
1344
1345   vat_json_init_object (&node);
1346   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1347   vat_json_object_add_string_copy (&node, "program", mp->program);
1348   vat_json_object_add_string_copy (&node, "version", mp->version);
1349   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1350   vat_json_object_add_string_copy (&node, "build_directory",
1351                                    mp->build_directory);
1352
1353   vat_json_print (vam->ofp, &node);
1354   vat_json_free (&node);
1355
1356   vam->retval = ntohl (mp->retval);
1357   vam->result_ready = 1;
1358 }
1359
1360 static void vl_api_show_threads_reply_t_handler
1361   (vl_api_show_threads_reply_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   i32 retval = ntohl (mp->retval);
1365   int i, count = 0;
1366
1367   if (retval >= 0)
1368     count = ntohl (mp->count);
1369
1370   for (i = 0; i < count; i++)
1371     print (vam->ofp,
1372            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1373            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1374            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1375            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1376            ntohl (mp->thread_data[i].cpu_socket));
1377
1378   vam->retval = retval;
1379   vam->result_ready = 1;
1380 }
1381
1382 static void vl_api_show_threads_reply_t_handler_json
1383   (vl_api_show_threads_reply_t * mp)
1384 {
1385   vat_main_t *vam = &vat_main;
1386   vat_json_node_t node;
1387   vl_api_thread_data_t *td;
1388   i32 retval = ntohl (mp->retval);
1389   int i, count = 0;
1390
1391   if (retval >= 0)
1392     count = ntohl (mp->count);
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", retval);
1396   vat_json_object_add_uint (&node, "count", count);
1397
1398   for (i = 0; i < count; i++)
1399     {
1400       td = &mp->thread_data[i];
1401       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1402       vat_json_object_add_string_copy (&node, "name", td->name);
1403       vat_json_object_add_string_copy (&node, "type", td->type);
1404       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1405       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1406       vat_json_object_add_int (&node, "core", ntohl (td->id));
1407       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1408     }
1409
1410   vat_json_print (vam->ofp, &node);
1411   vat_json_free (&node);
1412
1413   vam->retval = retval;
1414   vam->result_ready = 1;
1415 }
1416
1417 static int
1418 api_show_threads (vat_main_t * vam)
1419 {
1420   vl_api_show_threads_t *mp;
1421   int ret;
1422
1423   print (vam->ofp,
1424          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1425          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1426
1427   M (SHOW_THREADS, mp);
1428
1429   S (mp);
1430   W (ret);
1431   return ret;
1432 }
1433
1434 static void
1435 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1436 {
1437   u32 sw_if_index = ntohl (mp->sw_if_index);
1438   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1439           mp->mac_ip ? "mac/ip binding" : "address resolution",
1440           ntohl (mp->pid), format_ip4_address, mp->ip,
1441           format_vl_api_mac_address, &mp->mac, sw_if_index);
1442 }
1443
1444 static void
1445 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1446 {
1447   /* JSON output not supported */
1448 }
1449
1450 static void
1451 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1452 {
1453   u32 sw_if_index = ntohl (mp->sw_if_index);
1454   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1455           mp->mac_ip ? "mac/ip binding" : "address resolution",
1456           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1457           format_vl_api_mac_address, mp->mac, sw_if_index);
1458 }
1459
1460 static void
1461 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1462 {
1463   /* JSON output not supported */
1464 }
1465
1466 static void
1467 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1468 {
1469   u32 n_macs = ntohl (mp->n_macs);
1470   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1471           ntohl (mp->pid), mp->client_index, n_macs);
1472   int i;
1473   for (i = 0; i < n_macs; i++)
1474     {
1475       vl_api_mac_entry_t *mac = &mp->mac[i];
1476       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1477               i + 1, ntohl (mac->sw_if_index),
1478               format_ethernet_address, mac->mac_addr, mac->action);
1479       if (i == 1000)
1480         break;
1481     }
1482 }
1483
1484 static void
1485 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1486 {
1487   /* JSON output not supported */
1488 }
1489
1490 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1491 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1492
1493 /*
1494  * Special-case: build the bridge domain table, maintain
1495  * the next bd id vbl.
1496  */
1497 static void vl_api_bridge_domain_details_t_handler
1498   (vl_api_bridge_domain_details_t * mp)
1499 {
1500   vat_main_t *vam = &vat_main;
1501   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1502   int i;
1503
1504   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1505          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1506
1507   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1508          ntohl (mp->bd_id), mp->learn, mp->forward,
1509          mp->flood, ntohl (mp->bvi_sw_if_index),
1510          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1511
1512   if (n_sw_ifs)
1513     {
1514       vl_api_bridge_domain_sw_if_t *sw_ifs;
1515       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1516              "Interface Name");
1517
1518       sw_ifs = mp->sw_if_details;
1519       for (i = 0; i < n_sw_ifs; i++)
1520         {
1521           u8 *sw_if_name = 0;
1522           u32 sw_if_index;
1523           hash_pair_t *p;
1524
1525           sw_if_index = ntohl (sw_ifs->sw_if_index);
1526
1527           /* *INDENT-OFF* */
1528           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1529                              ({
1530                                if ((u32) p->value[0] == sw_if_index)
1531                                  {
1532                                    sw_if_name = (u8 *)(p->key);
1533                                    break;
1534                                  }
1535                              }));
1536           /* *INDENT-ON* */
1537           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1538                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1539                  "sw_if_index not found!");
1540
1541           sw_ifs++;
1542         }
1543     }
1544 }
1545
1546 static void vl_api_bridge_domain_details_t_handler_json
1547   (vl_api_bridge_domain_details_t * mp)
1548 {
1549   vat_main_t *vam = &vat_main;
1550   vat_json_node_t *node, *array = NULL;
1551   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1552
1553   if (VAT_JSON_ARRAY != vam->json_tree.type)
1554     {
1555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1556       vat_json_init_array (&vam->json_tree);
1557     }
1558   node = vat_json_array_add (&vam->json_tree);
1559
1560   vat_json_init_object (node);
1561   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1562   vat_json_object_add_uint (node, "flood", mp->flood);
1563   vat_json_object_add_uint (node, "forward", mp->forward);
1564   vat_json_object_add_uint (node, "learn", mp->learn);
1565   vat_json_object_add_uint (node, "bvi_sw_if_index",
1566                             ntohl (mp->bvi_sw_if_index));
1567   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1568   array = vat_json_object_add (node, "sw_if");
1569   vat_json_init_array (array);
1570
1571
1572
1573   if (n_sw_ifs)
1574     {
1575       vl_api_bridge_domain_sw_if_t *sw_ifs;
1576       int i;
1577
1578       sw_ifs = mp->sw_if_details;
1579       for (i = 0; i < n_sw_ifs; i++)
1580         {
1581           node = vat_json_array_add (array);
1582           vat_json_init_object (node);
1583           vat_json_object_add_uint (node, "sw_if_index",
1584                                     ntohl (sw_ifs->sw_if_index));
1585           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1586           sw_ifs++;
1587         }
1588     }
1589 }
1590
1591 static void vl_api_control_ping_reply_t_handler
1592   (vl_api_control_ping_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605   if (vam->socket_client_main)
1606     vam->socket_client_main->control_pings_outstanding--;
1607 }
1608
1609 static void vl_api_control_ping_reply_t_handler_json
1610   (vl_api_control_ping_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614
1615   if (VAT_JSON_NONE != vam->json_tree.type)
1616     {
1617       vat_json_print (vam->ofp, &vam->json_tree);
1618       vat_json_free (&vam->json_tree);
1619       vam->json_tree.type = VAT_JSON_NONE;
1620     }
1621   else
1622     {
1623       /* just print [] */
1624       vat_json_init_array (&vam->json_tree);
1625       vat_json_print (vam->ofp, &vam->json_tree);
1626       vam->json_tree.type = VAT_JSON_NONE;
1627     }
1628
1629   vam->retval = retval;
1630   vam->result_ready = 1;
1631 }
1632
1633 static void
1634   vl_api_bridge_domain_set_mac_age_reply_t_handler
1635   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1636 {
1637   vat_main_t *vam = &vat_main;
1638   i32 retval = ntohl (mp->retval);
1639   if (vam->async_mode)
1640     {
1641       vam->async_errors += (retval < 0);
1642     }
1643   else
1644     {
1645       vam->retval = retval;
1646       vam->result_ready = 1;
1647     }
1648 }
1649
1650 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1651   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1652 {
1653   vat_main_t *vam = &vat_main;
1654   vat_json_node_t node;
1655
1656   vat_json_init_object (&node);
1657   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1658
1659   vat_json_print (vam->ofp, &node);
1660   vat_json_free (&node);
1661
1662   vam->retval = ntohl (mp->retval);
1663   vam->result_ready = 1;
1664 }
1665
1666 static void
1667 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1668 {
1669   vat_main_t *vam = &vat_main;
1670   i32 retval = ntohl (mp->retval);
1671   if (vam->async_mode)
1672     {
1673       vam->async_errors += (retval < 0);
1674     }
1675   else
1676     {
1677       vam->retval = retval;
1678       vam->result_ready = 1;
1679     }
1680 }
1681
1682 static void vl_api_l2_flags_reply_t_handler_json
1683   (vl_api_l2_flags_reply_t * mp)
1684 {
1685   vat_main_t *vam = &vat_main;
1686   vat_json_node_t node;
1687
1688   vat_json_init_object (&node);
1689   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1690   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1691                             ntohl (mp->resulting_feature_bitmap));
1692
1693   vat_json_print (vam->ofp, &node);
1694   vat_json_free (&node);
1695
1696   vam->retval = ntohl (mp->retval);
1697   vam->result_ready = 1;
1698 }
1699
1700 static void vl_api_bridge_flags_reply_t_handler
1701   (vl_api_bridge_flags_reply_t * mp)
1702 {
1703   vat_main_t *vam = &vat_main;
1704   i32 retval = ntohl (mp->retval);
1705   if (vam->async_mode)
1706     {
1707       vam->async_errors += (retval < 0);
1708     }
1709   else
1710     {
1711       vam->retval = retval;
1712       vam->result_ready = 1;
1713     }
1714 }
1715
1716 static void vl_api_bridge_flags_reply_t_handler_json
1717   (vl_api_bridge_flags_reply_t * mp)
1718 {
1719   vat_main_t *vam = &vat_main;
1720   vat_json_node_t node;
1721
1722   vat_json_init_object (&node);
1723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1724   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1725                             ntohl (mp->resulting_feature_bitmap));
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 static void
1735 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1736 {
1737   vat_main_t *vam = &vat_main;
1738   i32 retval = ntohl (mp->retval);
1739   if (vam->async_mode)
1740     {
1741       vam->async_errors += (retval < 0);
1742     }
1743   else
1744     {
1745       vam->retval = retval;
1746       vam->sw_if_index = ntohl (mp->sw_if_index);
1747       vam->result_ready = 1;
1748     }
1749
1750 }
1751
1752 static void vl_api_tap_create_v2_reply_t_handler_json
1753   (vl_api_tap_create_v2_reply_t * mp)
1754 {
1755   vat_main_t *vam = &vat_main;
1756   vat_json_node_t node;
1757
1758   vat_json_init_object (&node);
1759   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1760   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1761
1762   vat_json_print (vam->ofp, &node);
1763   vat_json_free (&node);
1764
1765   vam->retval = ntohl (mp->retval);
1766   vam->result_ready = 1;
1767
1768 }
1769
1770 static void
1771 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1772 {
1773   vat_main_t *vam = &vat_main;
1774   i32 retval = ntohl (mp->retval);
1775   if (vam->async_mode)
1776     {
1777       vam->async_errors += (retval < 0);
1778     }
1779   else
1780     {
1781       vam->retval = retval;
1782       vam->result_ready = 1;
1783     }
1784 }
1785
1786 static void vl_api_tap_delete_v2_reply_t_handler_json
1787   (vl_api_tap_delete_v2_reply_t * mp)
1788 {
1789   vat_main_t *vam = &vat_main;
1790   vat_json_node_t node;
1791
1792   vat_json_init_object (&node);
1793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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 static void
1803 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1804                                           mp)
1805 {
1806   vat_main_t *vam = &vat_main;
1807   i32 retval = ntohl (mp->retval);
1808   if (vam->async_mode)
1809     {
1810       vam->async_errors += (retval < 0);
1811     }
1812   else
1813     {
1814       vam->retval = retval;
1815       vam->sw_if_index = ntohl (mp->sw_if_index);
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_create_reply_t_handler_json
1821   (vl_api_virtio_pci_create_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1829
1830   vat_json_print (vam->ofp, &node);
1831   vat_json_free (&node);
1832
1833   vam->retval = ntohl (mp->retval);
1834   vam->result_ready = 1;
1835
1836 }
1837
1838 static void
1839 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1840                                           mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   i32 retval = ntohl (mp->retval);
1844   if (vam->async_mode)
1845     {
1846       vam->async_errors += (retval < 0);
1847     }
1848   else
1849     {
1850       vam->retval = retval;
1851       vam->result_ready = 1;
1852     }
1853 }
1854
1855 static void vl_api_virtio_pci_delete_reply_t_handler_json
1856   (vl_api_virtio_pci_delete_reply_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   vat_json_node_t node;
1860
1861   vat_json_init_object (&node);
1862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_create_reply_t_handler (vl_api_bond_create_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->sw_if_index = ntohl (mp->sw_if_index);
1885       vam->result_ready = 1;
1886     }
1887 }
1888
1889 static void vl_api_bond_create_reply_t_handler_json
1890   (vl_api_bond_create_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   vat_json_node_t node;
1894
1895   vat_json_init_object (&node);
1896   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1897   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1898
1899   vat_json_print (vam->ofp, &node);
1900   vat_json_free (&node);
1901
1902   vam->retval = ntohl (mp->retval);
1903   vam->result_ready = 1;
1904 }
1905
1906 static void
1907 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   i32 retval = ntohl (mp->retval);
1911
1912   if (vam->async_mode)
1913     {
1914       vam->async_errors += (retval < 0);
1915     }
1916   else
1917     {
1918       vam->retval = retval;
1919       vam->result_ready = 1;
1920     }
1921 }
1922
1923 static void vl_api_bond_delete_reply_t_handler_json
1924   (vl_api_bond_delete_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   vat_json_node_t node;
1928
1929   vat_json_init_object (&node);
1930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1931
1932   vat_json_print (vam->ofp, &node);
1933   vat_json_free (&node);
1934
1935   vam->retval = ntohl (mp->retval);
1936   vam->result_ready = 1;
1937 }
1938
1939 static void
1940 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   i32 retval = ntohl (mp->retval);
1944
1945   if (vam->async_mode)
1946     {
1947       vam->async_errors += (retval < 0);
1948     }
1949   else
1950     {
1951       vam->retval = retval;
1952       vam->result_ready = 1;
1953     }
1954 }
1955
1956 static void vl_api_bond_enslave_reply_t_handler_json
1957   (vl_api_bond_enslave_reply_t * mp)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   vat_json_node_t node;
1961
1962   vat_json_init_object (&node);
1963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1964
1965   vat_json_print (vam->ofp, &node);
1966   vat_json_free (&node);
1967
1968   vam->retval = ntohl (mp->retval);
1969   vam->result_ready = 1;
1970 }
1971
1972 static void
1973 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1974                                           mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977   i32 retval = ntohl (mp->retval);
1978
1979   if (vam->async_mode)
1980     {
1981       vam->async_errors += (retval < 0);
1982     }
1983   else
1984     {
1985       vam->retval = retval;
1986       vam->result_ready = 1;
1987     }
1988 }
1989
1990 static void vl_api_bond_detach_slave_reply_t_handler_json
1991   (vl_api_bond_detach_slave_reply_t * mp)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   vat_json_node_t node;
1995
1996   vat_json_init_object (&node);
1997   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static int
2007 api_sw_interface_set_bond_weight (vat_main_t * vam)
2008 {
2009   unformat_input_t *i = vam->input;
2010   vl_api_sw_interface_set_bond_weight_t *mp;
2011   u32 sw_if_index = ~0;
2012   u32 weight = 0;
2013   u8 weight_enter = 0;
2014   int ret;
2015
2016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2017     {
2018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2019         ;
2020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2021         ;
2022       else if (unformat (i, "weight %u", &weight))
2023         weight_enter = 1;
2024       else
2025         break;
2026     }
2027
2028   if (sw_if_index == ~0)
2029     {
2030       errmsg ("missing interface name or sw_if_index");
2031       return -99;
2032     }
2033   if (weight_enter == 0)
2034     {
2035       errmsg ("missing valid weight");
2036       return -99;
2037     }
2038
2039   /* Construct the API message */
2040   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2041   mp->sw_if_index = ntohl (sw_if_index);
2042   mp->weight = ntohl (weight);
2043
2044   S (mp);
2045   W (ret);
2046   return ret;
2047 }
2048
2049 static void vl_api_sw_interface_bond_details_t_handler
2050   (vl_api_sw_interface_bond_details_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053
2054   print (vam->ofp,
2055          "%-16s %-12d %-12U %-13U %-14u %-14u",
2056          mp->interface_name, ntohl (mp->sw_if_index),
2057          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2058          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2059 }
2060
2061 static void vl_api_sw_interface_bond_details_t_handler_json
2062   (vl_api_sw_interface_bond_details_t * mp)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   vat_json_node_t *node = NULL;
2066
2067   if (VAT_JSON_ARRAY != vam->json_tree.type)
2068     {
2069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2070       vat_json_init_array (&vam->json_tree);
2071     }
2072   node = vat_json_array_add (&vam->json_tree);
2073
2074   vat_json_init_object (node);
2075   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2076   vat_json_object_add_string_copy (node, "interface_name",
2077                                    mp->interface_name);
2078   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2079   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2080   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2081   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2082 }
2083
2084 static int
2085 api_sw_interface_bond_dump (vat_main_t * vam)
2086 {
2087   vl_api_sw_interface_bond_dump_t *mp;
2088   vl_api_control_ping_t *mp_ping;
2089   int ret;
2090
2091   print (vam->ofp,
2092          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2093          "interface name", "sw_if_index", "mode", "load balance",
2094          "active slaves", "slaves");
2095
2096   /* Get list of bond interfaces */
2097   M (SW_INTERFACE_BOND_DUMP, mp);
2098   S (mp);
2099
2100   /* Use a control ping for synchronization */
2101   MPING (CONTROL_PING, mp_ping);
2102   S (mp_ping);
2103
2104   W (ret);
2105   return ret;
2106 }
2107
2108 static void vl_api_sw_interface_slave_details_t_handler
2109   (vl_api_sw_interface_slave_details_t * mp)
2110 {
2111   vat_main_t *vam = &vat_main;
2112
2113   print (vam->ofp,
2114          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2115          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2116          ntohl (mp->weight), mp->is_local_numa);
2117 }
2118
2119 static void vl_api_sw_interface_slave_details_t_handler_json
2120   (vl_api_sw_interface_slave_details_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t *node = NULL;
2124
2125   if (VAT_JSON_ARRAY != vam->json_tree.type)
2126     {
2127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2128       vat_json_init_array (&vam->json_tree);
2129     }
2130   node = vat_json_array_add (&vam->json_tree);
2131
2132   vat_json_init_object (node);
2133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2134   vat_json_object_add_string_copy (node, "interface_name",
2135                                    mp->interface_name);
2136   vat_json_object_add_uint (node, "passive", mp->is_passive);
2137   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2138   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2139   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2140 }
2141
2142 static int
2143 api_sw_interface_slave_dump (vat_main_t * vam)
2144 {
2145   unformat_input_t *i = vam->input;
2146   vl_api_sw_interface_slave_dump_t *mp;
2147   vl_api_control_ping_t *mp_ping;
2148   u32 sw_if_index = ~0;
2149   u8 sw_if_index_set = 0;
2150   int ret;
2151
2152   /* Parse args required to build the message */
2153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2154     {
2155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2156         sw_if_index_set = 1;
2157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2158         sw_if_index_set = 1;
2159       else
2160         break;
2161     }
2162
2163   if (sw_if_index_set == 0)
2164     {
2165       errmsg ("missing vpp interface name. ");
2166       return -99;
2167     }
2168
2169   print (vam->ofp,
2170          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2171          "slave interface name", "sw_if_index", "passive", "long_timeout",
2172          "weight", "local numa");
2173
2174   /* Get list of bond interfaces */
2175   M (SW_INTERFACE_SLAVE_DUMP, mp);
2176   mp->sw_if_index = ntohl (sw_if_index);
2177   S (mp);
2178
2179   /* Use a control ping for synchronization */
2180   MPING (CONTROL_PING, mp_ping);
2181   S (mp_ping);
2182
2183   W (ret);
2184   return ret;
2185 }
2186
2187 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2188   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   i32 retval = ntohl (mp->retval);
2192   if (vam->async_mode)
2193     {
2194       vam->async_errors += (retval < 0);
2195     }
2196   else
2197     {
2198       vam->retval = retval;
2199       vam->sw_if_index = ntohl (mp->sw_if_index);
2200       vam->result_ready = 1;
2201     }
2202   vam->regenerate_interface_table = 1;
2203 }
2204
2205 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2206   (vl_api_mpls_tunnel_add_del_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, "tunnel_sw_if_index",
2214                             ntohl (mp->sw_if_index));
2215
2216   vat_json_print (vam->ofp, &node);
2217   vat_json_free (&node);
2218
2219   vam->retval = ntohl (mp->retval);
2220   vam->result_ready = 1;
2221 }
2222
2223 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2224   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2225 {
2226   vat_main_t *vam = &vat_main;
2227   i32 retval = ntohl (mp->retval);
2228   if (vam->async_mode)
2229     {
2230       vam->async_errors += (retval < 0);
2231     }
2232   else
2233     {
2234       vam->retval = retval;
2235       vam->sw_if_index = ntohl (mp->sw_if_index);
2236       vam->result_ready = 1;
2237     }
2238 }
2239
2240 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2241   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vat_json_node_t node;
2245
2246   vat_json_init_object (&node);
2247   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2248   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2249
2250   vat_json_print (vam->ofp, &node);
2251   vat_json_free (&node);
2252
2253   vam->retval = ntohl (mp->retval);
2254   vam->result_ready = 1;
2255 }
2256
2257 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2258   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2259 {
2260   vat_main_t *vam = &vat_main;
2261   i32 retval = ntohl (mp->retval);
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271 }
2272
2273 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2274   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   vat_json_node_t node;
2278
2279   vat_json_init_object (&node);
2280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2281   vat_json_object_add_uint (&node, "fwd_entry_index",
2282                             clib_net_to_host_u32 (mp->fwd_entry_index));
2283
2284   vat_json_print (vam->ofp, &node);
2285   vat_json_free (&node);
2286
2287   vam->retval = ntohl (mp->retval);
2288   vam->result_ready = 1;
2289 }
2290
2291 u8 *
2292 format_lisp_transport_protocol (u8 * s, va_list * args)
2293 {
2294   u32 proto = va_arg (*args, u32);
2295
2296   switch (proto)
2297     {
2298     case 1:
2299       return format (s, "udp");
2300     case 2:
2301       return format (s, "api");
2302     default:
2303       return 0;
2304     }
2305   return 0;
2306 }
2307
2308 static void vl_api_one_get_transport_protocol_reply_t_handler
2309   (vl_api_one_get_transport_protocol_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   i32 retval = ntohl (mp->retval);
2313   if (vam->async_mode)
2314     {
2315       vam->async_errors += (retval < 0);
2316     }
2317   else
2318     {
2319       u32 proto = mp->protocol;
2320       print (vam->ofp, "Transport protocol: %U",
2321              format_lisp_transport_protocol, proto);
2322       vam->retval = retval;
2323       vam->result_ready = 1;
2324     }
2325 }
2326
2327 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2328   (vl_api_one_get_transport_protocol_reply_t * mp)
2329 {
2330   vat_main_t *vam = &vat_main;
2331   vat_json_node_t node;
2332   u8 *s;
2333
2334   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2335   vec_add1 (s, 0);
2336
2337   vat_json_init_object (&node);
2338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2339   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2340
2341   vec_free (s);
2342   vat_json_print (vam->ofp, &node);
2343   vat_json_free (&node);
2344
2345   vam->retval = ntohl (mp->retval);
2346   vam->result_ready = 1;
2347 }
2348
2349 static void vl_api_one_add_del_locator_set_reply_t_handler
2350   (vl_api_one_add_del_locator_set_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   i32 retval = ntohl (mp->retval);
2354   if (vam->async_mode)
2355     {
2356       vam->async_errors += (retval < 0);
2357     }
2358   else
2359     {
2360       vam->retval = retval;
2361       vam->result_ready = 1;
2362     }
2363 }
2364
2365 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2366   (vl_api_one_add_del_locator_set_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, "locator_set_index", ntohl (mp->ls_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_add_del_tunnel_reply_t_handler
2383   (vl_api_vxlan_add_del_tunnel_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->sw_if_index = ntohl (mp->sw_if_index);
2395       vam->result_ready = 1;
2396     }
2397   vam->regenerate_interface_table = 1;
2398 }
2399
2400 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2401   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2402 {
2403   vat_main_t *vam = &vat_main;
2404   vat_json_node_t node;
2405
2406   vat_json_init_object (&node);
2407   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2408   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2409
2410   vat_json_print (vam->ofp, &node);
2411   vat_json_free (&node);
2412
2413   vam->retval = ntohl (mp->retval);
2414   vam->result_ready = 1;
2415 }
2416
2417 static void vl_api_vxlan_offload_rx_reply_t_handler
2418   (vl_api_vxlan_offload_rx_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   i32 retval = ntohl (mp->retval);
2422   if (vam->async_mode)
2423     {
2424       vam->async_errors += (retval < 0);
2425     }
2426   else
2427     {
2428       vam->retval = retval;
2429       vam->result_ready = 1;
2430     }
2431 }
2432
2433 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2434   (vl_api_vxlan_offload_rx_reply_t * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437   vat_json_node_t node;
2438
2439   vat_json_init_object (&node);
2440   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2441
2442   vat_json_print (vam->ofp, &node);
2443   vat_json_free (&node);
2444
2445   vam->retval = ntohl (mp->retval);
2446   vam->result_ready = 1;
2447 }
2448
2449 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2450   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   i32 retval = ntohl (mp->retval);
2454   if (vam->async_mode)
2455     {
2456       vam->async_errors += (retval < 0);
2457     }
2458   else
2459     {
2460       vam->retval = retval;
2461       vam->sw_if_index = ntohl (mp->sw_if_index);
2462       vam->result_ready = 1;
2463     }
2464 }
2465
2466 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2467   (vl_api_geneve_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_vxlan_gpe_add_del_tunnel_reply_t_handler
2484   (vl_api_vxlan_gpe_add_del_tunnel_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   vam->regenerate_interface_table = 1;
2499 }
2500
2501 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2502   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2503 {
2504   vat_main_t *vam = &vat_main;
2505   vat_json_node_t node;
2506
2507   vat_json_init_object (&node);
2508   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2509   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2510
2511   vat_json_print (vam->ofp, &node);
2512   vat_json_free (&node);
2513
2514   vam->retval = ntohl (mp->retval);
2515   vam->result_ready = 1;
2516 }
2517
2518 static void vl_api_gre_tunnel_add_del_reply_t_handler
2519   (vl_api_gre_tunnel_add_del_reply_t * mp)
2520 {
2521   vat_main_t *vam = &vat_main;
2522   i32 retval = ntohl (mp->retval);
2523   if (vam->async_mode)
2524     {
2525       vam->async_errors += (retval < 0);
2526     }
2527   else
2528     {
2529       vam->retval = retval;
2530       vam->sw_if_index = ntohl (mp->sw_if_index);
2531       vam->result_ready = 1;
2532     }
2533 }
2534
2535 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2536   (vl_api_gre_tunnel_add_del_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_create_vhost_user_if_reply_t_handler
2553   (vl_api_create_vhost_user_if_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   i32 retval = ntohl (mp->retval);
2557   if (vam->async_mode)
2558     {
2559       vam->async_errors += (retval < 0);
2560     }
2561   else
2562     {
2563       vam->retval = retval;
2564       vam->sw_if_index = ntohl (mp->sw_if_index);
2565       vam->result_ready = 1;
2566     }
2567   vam->regenerate_interface_table = 1;
2568 }
2569
2570 static void vl_api_create_vhost_user_if_reply_t_handler_json
2571   (vl_api_create_vhost_user_if_reply_t * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574   vat_json_node_t node;
2575
2576   vat_json_init_object (&node);
2577   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2578   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2579
2580   vat_json_print (vam->ofp, &node);
2581   vat_json_free (&node);
2582
2583   vam->retval = ntohl (mp->retval);
2584   vam->result_ready = 1;
2585 }
2586
2587 static void vl_api_ip_address_details_t_handler
2588   (vl_api_ip_address_details_t * mp)
2589 {
2590   vat_main_t *vam = &vat_main;
2591   static ip_address_details_t empty_ip_address_details = { {0} };
2592   ip_address_details_t *address = NULL;
2593   ip_details_t *current_ip_details = NULL;
2594   ip_details_t *details = NULL;
2595
2596   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2597
2598   if (!details || vam->current_sw_if_index >= vec_len (details)
2599       || !details[vam->current_sw_if_index].present)
2600     {
2601       errmsg ("ip address details arrived but not stored");
2602       errmsg ("ip_dump should be called first");
2603       return;
2604     }
2605
2606   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2607
2608 #define addresses (current_ip_details->addr)
2609
2610   vec_validate_init_empty (addresses, vec_len (addresses),
2611                            empty_ip_address_details);
2612
2613   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2614
2615   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2616   address->prefix_length = mp->prefix.len;
2617 #undef addresses
2618 }
2619
2620 static void vl_api_ip_address_details_t_handler_json
2621   (vl_api_ip_address_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = NULL;
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   node = vat_json_array_add (&vam->json_tree);
2632
2633   vat_json_init_object (node);
2634   vat_json_object_add_prefix (node, &mp->prefix);
2635 }
2636
2637 static void
2638 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   static ip_details_t empty_ip_details = { 0 };
2642   ip_details_t *ip = NULL;
2643   u32 sw_if_index = ~0;
2644
2645   sw_if_index = ntohl (mp->sw_if_index);
2646
2647   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2648                            sw_if_index, empty_ip_details);
2649
2650   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2651                          sw_if_index);
2652
2653   ip->present = 1;
2654 }
2655
2656 static void
2657 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660
2661   if (VAT_JSON_ARRAY != vam->json_tree.type)
2662     {
2663       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2664       vat_json_init_array (&vam->json_tree);
2665     }
2666   vat_json_array_add_uint (&vam->json_tree,
2667                            clib_net_to_host_u32 (mp->sw_if_index));
2668 }
2669
2670 static void vl_api_get_first_msg_id_reply_t_handler
2671   (vl_api_get_first_msg_id_reply_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   i32 retval = ntohl (mp->retval);
2675
2676   if (vam->async_mode)
2677     {
2678       vam->async_errors += (retval < 0);
2679     }
2680   else
2681     {
2682       vam->retval = retval;
2683       vam->result_ready = 1;
2684     }
2685   if (retval >= 0)
2686     {
2687       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2688     }
2689 }
2690
2691 static void vl_api_get_first_msg_id_reply_t_handler_json
2692   (vl_api_get_first_msg_id_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t node;
2696
2697   vat_json_init_object (&node);
2698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2699   vat_json_object_add_uint (&node, "first_msg_id",
2700                             (uint) ntohs (mp->first_msg_id));
2701
2702   vat_json_print (vam->ofp, &node);
2703   vat_json_free (&node);
2704
2705   vam->retval = ntohl (mp->retval);
2706   vam->result_ready = 1;
2707 }
2708
2709 static void vl_api_get_node_graph_reply_t_handler
2710   (vl_api_get_node_graph_reply_t * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   api_main_t *am = &api_main;
2714   i32 retval = ntohl (mp->retval);
2715   u8 *pvt_copy, *reply;
2716   void *oldheap;
2717   vlib_node_t *node;
2718   int i;
2719
2720   if (vam->async_mode)
2721     {
2722       vam->async_errors += (retval < 0);
2723     }
2724   else
2725     {
2726       vam->retval = retval;
2727       vam->result_ready = 1;
2728     }
2729
2730   /* "Should never happen..." */
2731   if (retval != 0)
2732     return;
2733
2734   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2735   pvt_copy = vec_dup (reply);
2736
2737   /* Toss the shared-memory original... */
2738   pthread_mutex_lock (&am->vlib_rp->mutex);
2739   oldheap = svm_push_data_heap (am->vlib_rp);
2740
2741   vec_free (reply);
2742
2743   svm_pop_heap (oldheap);
2744   pthread_mutex_unlock (&am->vlib_rp->mutex);
2745
2746   if (vam->graph_nodes)
2747     {
2748       hash_free (vam->graph_node_index_by_name);
2749
2750       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2751         {
2752           node = vam->graph_nodes[0][i];
2753           vec_free (node->name);
2754           vec_free (node->next_nodes);
2755           vec_free (node);
2756         }
2757       vec_free (vam->graph_nodes[0]);
2758       vec_free (vam->graph_nodes);
2759     }
2760
2761   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2762   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2763   vec_free (pvt_copy);
2764
2765   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2766     {
2767       node = vam->graph_nodes[0][i];
2768       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2769     }
2770 }
2771
2772 static void vl_api_get_node_graph_reply_t_handler_json
2773   (vl_api_get_node_graph_reply_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   api_main_t *am = &api_main;
2777   void *oldheap;
2778   vat_json_node_t node;
2779   u8 *reply;
2780
2781   /* $$$$ make this real? */
2782   vat_json_init_object (&node);
2783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2784   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2785
2786   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2787
2788   /* Toss the shared-memory original... */
2789   pthread_mutex_lock (&am->vlib_rp->mutex);
2790   oldheap = svm_push_data_heap (am->vlib_rp);
2791
2792   vec_free (reply);
2793
2794   svm_pop_heap (oldheap);
2795   pthread_mutex_unlock (&am->vlib_rp->mutex);
2796
2797   vat_json_print (vam->ofp, &node);
2798   vat_json_free (&node);
2799
2800   vam->retval = ntohl (mp->retval);
2801   vam->result_ready = 1;
2802 }
2803
2804 static void
2805 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   u8 *s = 0;
2809
2810   if (mp->local)
2811     {
2812       s = format (s, "%=16d%=16d%=16d",
2813                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2814     }
2815   else
2816     {
2817       s = format (s, "%=16U%=16d%=16d",
2818                   mp->is_ipv6 ? format_ip6_address :
2819                   format_ip4_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->is_ipv6)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   u32 type = va_arg (*args, u32);
2928   u8 *eid = va_arg (*args, u8 *);
2929   u32 eid_len = va_arg (*args, u32);
2930
2931   switch (type)
2932     {
2933     case 0:
2934       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2935     case 1:
2936       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2937     case 2:
2938       return format (s, "%U", format_ethernet_address, eid);
2939     case 3:
2940       return format (s, "%U", format_nsh_address_vat, eid);
2941     }
2942   return 0;
2943 }
2944
2945 static u8 *
2946 format_lisp_eid_vat (u8 * s, va_list * args)
2947 {
2948   u32 type = va_arg (*args, u32);
2949   u8 *eid = va_arg (*args, u8 *);
2950   u32 eid_len = va_arg (*args, u32);
2951   u8 *seid = va_arg (*args, u8 *);
2952   u32 seid_len = va_arg (*args, u32);
2953   u32 is_src_dst = va_arg (*args, u32);
2954
2955   if (is_src_dst)
2956     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2957
2958   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2959
2960   return s;
2961 }
2962
2963 static void
2964 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   u8 *s = 0, *eid = 0;
2968
2969   if (~0 == mp->locator_set_index)
2970     s = format (0, "action: %d", mp->action);
2971   else
2972     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2973
2974   eid = format (0, "%U", format_lisp_eid_vat,
2975                 mp->eid_type,
2976                 mp->eid,
2977                 mp->eid_prefix_len,
2978                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2979   vec_add1 (eid, 0);
2980
2981   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2982          clib_net_to_host_u32 (mp->vni),
2983          eid,
2984          mp->is_local ? "local" : "remote",
2985          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2986          clib_net_to_host_u16 (mp->key_id), mp->key);
2987
2988   vec_free (s);
2989   vec_free (eid);
2990 }
2991
2992 static void
2993 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2994                                              * mp)
2995 {
2996   vat_main_t *vam = &vat_main;
2997   vat_json_node_t *node = 0;
2998   u8 *eid = 0;
2999
3000   if (VAT_JSON_ARRAY != vam->json_tree.type)
3001     {
3002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3003       vat_json_init_array (&vam->json_tree);
3004     }
3005   node = vat_json_array_add (&vam->json_tree);
3006
3007   vat_json_init_object (node);
3008   if (~0 == mp->locator_set_index)
3009     vat_json_object_add_uint (node, "action", mp->action);
3010   else
3011     vat_json_object_add_uint (node, "locator_set_index",
3012                               clib_net_to_host_u32 (mp->locator_set_index));
3013
3014   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3015   if (mp->eid_type == 3)
3016     {
3017       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3018       vat_json_init_object (nsh_json);
3019       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3020       vat_json_object_add_uint (nsh_json, "spi",
3021                                 clib_net_to_host_u32 (nsh->spi));
3022       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3023     }
3024   else
3025     {
3026       eid = format (0, "%U", format_lisp_eid_vat,
3027                     mp->eid_type,
3028                     mp->eid,
3029                     mp->eid_prefix_len,
3030                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3031       vec_add1 (eid, 0);
3032       vat_json_object_add_string_copy (node, "eid", eid);
3033       vec_free (eid);
3034     }
3035   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3036   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3037   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3038
3039   if (mp->key_id)
3040     {
3041       vat_json_object_add_uint (node, "key_id",
3042                                 clib_net_to_host_u16 (mp->key_id));
3043       vat_json_object_add_string_copy (node, "key", mp->key);
3044     }
3045 }
3046
3047 static void
3048 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   u8 *seid = 0, *deid = 0;
3052   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3053
3054   deid = format (0, "%U", format_lisp_eid_vat,
3055                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3056
3057   seid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3059
3060   vec_add1 (deid, 0);
3061   vec_add1 (seid, 0);
3062
3063   if (mp->is_ip4)
3064     format_ip_address_fcn = format_ip4_address;
3065   else
3066     format_ip_address_fcn = format_ip6_address;
3067
3068
3069   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3070          clib_net_to_host_u32 (mp->vni),
3071          seid, deid,
3072          format_ip_address_fcn, mp->lloc,
3073          format_ip_address_fcn, mp->rloc,
3074          clib_net_to_host_u32 (mp->pkt_count),
3075          clib_net_to_host_u32 (mp->bytes));
3076
3077   vec_free (deid);
3078   vec_free (seid);
3079 }
3080
3081 static void
3082 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3083 {
3084   struct in6_addr ip6;
3085   struct in_addr ip4;
3086   vat_main_t *vam = &vat_main;
3087   vat_json_node_t *node = 0;
3088   u8 *deid = 0, *seid = 0;
3089
3090   if (VAT_JSON_ARRAY != vam->json_tree.type)
3091     {
3092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3093       vat_json_init_array (&vam->json_tree);
3094     }
3095   node = vat_json_array_add (&vam->json_tree);
3096
3097   vat_json_init_object (node);
3098   deid = format (0, "%U", format_lisp_eid_vat,
3099                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3100
3101   seid = format (0, "%U", format_lisp_eid_vat,
3102                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3103
3104   vec_add1 (deid, 0);
3105   vec_add1 (seid, 0);
3106
3107   vat_json_object_add_string_copy (node, "seid", seid);
3108   vat_json_object_add_string_copy (node, "deid", deid);
3109   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3110
3111   if (mp->is_ip4)
3112     {
3113       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3114       vat_json_object_add_ip4 (node, "lloc", ip4);
3115       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3116       vat_json_object_add_ip4 (node, "rloc", ip4);
3117     }
3118   else
3119     {
3120       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3121       vat_json_object_add_ip6 (node, "lloc", ip6);
3122       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3123       vat_json_object_add_ip6 (node, "rloc", ip6);
3124     }
3125   vat_json_object_add_uint (node, "pkt_count",
3126                             clib_net_to_host_u32 (mp->pkt_count));
3127   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3128
3129   vec_free (deid);
3130   vec_free (seid);
3131 }
3132
3133 static void
3134   vl_api_one_eid_table_map_details_t_handler
3135   (vl_api_one_eid_table_map_details_t * mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138
3139   u8 *line = format (0, "%=10d%=10d",
3140                      clib_net_to_host_u32 (mp->vni),
3141                      clib_net_to_host_u32 (mp->dp_table));
3142   print (vam->ofp, "%v", line);
3143   vec_free (line);
3144 }
3145
3146 static void
3147   vl_api_one_eid_table_map_details_t_handler_json
3148   (vl_api_one_eid_table_map_details_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t *node = NULL;
3152
3153   if (VAT_JSON_ARRAY != vam->json_tree.type)
3154     {
3155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3156       vat_json_init_array (&vam->json_tree);
3157     }
3158   node = vat_json_array_add (&vam->json_tree);
3159   vat_json_init_object (node);
3160   vat_json_object_add_uint (node, "dp_table",
3161                             clib_net_to_host_u32 (mp->dp_table));
3162   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3163 }
3164
3165 static void
3166   vl_api_one_eid_table_vni_details_t_handler
3167   (vl_api_one_eid_table_vni_details_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170
3171   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3172   print (vam->ofp, "%v", line);
3173   vec_free (line);
3174 }
3175
3176 static void
3177   vl_api_one_eid_table_vni_details_t_handler_json
3178   (vl_api_one_eid_table_vni_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182
3183   if (VAT_JSON_ARRAY != vam->json_tree.type)
3184     {
3185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3186       vat_json_init_array (&vam->json_tree);
3187     }
3188   node = vat_json_array_add (&vam->json_tree);
3189   vat_json_init_object (node);
3190   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3191 }
3192
3193 static void
3194   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3195   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3196 {
3197   vat_main_t *vam = &vat_main;
3198   int retval = clib_net_to_host_u32 (mp->retval);
3199
3200   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3201   print (vam->ofp, "fallback threshold value: %d", mp->value);
3202
3203   vam->retval = retval;
3204   vam->result_ready = 1;
3205 }
3206
3207 static void
3208   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3209   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t _node, *node = &_node;
3213   int retval = clib_net_to_host_u32 (mp->retval);
3214
3215   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3216   vat_json_init_object (node);
3217   vat_json_object_add_uint (node, "value", mp->value);
3218
3219   vat_json_print (vam->ofp, node);
3220   vat_json_free (node);
3221
3222   vam->retval = retval;
3223   vam->result_ready = 1;
3224 }
3225
3226 static void
3227   vl_api_show_one_map_register_state_reply_t_handler
3228   (vl_api_show_one_map_register_state_reply_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231   int retval = clib_net_to_host_u32 (mp->retval);
3232
3233   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3234
3235   vam->retval = retval;
3236   vam->result_ready = 1;
3237 }
3238
3239 static void
3240   vl_api_show_one_map_register_state_reply_t_handler_json
3241   (vl_api_show_one_map_register_state_reply_t * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t _node, *node = &_node;
3245   int retval = clib_net_to_host_u32 (mp->retval);
3246
3247   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3248
3249   vat_json_init_object (node);
3250   vat_json_object_add_string_copy (node, "state", s);
3251
3252   vat_json_print (vam->ofp, node);
3253   vat_json_free (node);
3254
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257   vec_free (s);
3258 }
3259
3260 static void
3261   vl_api_show_one_rloc_probe_state_reply_t_handler
3262   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3263 {
3264   vat_main_t *vam = &vat_main;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   if (retval)
3268     goto end;
3269
3270   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3271 end:
3272   vam->retval = retval;
3273   vam->result_ready = 1;
3274 }
3275
3276 static void
3277   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3278   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t _node, *node = &_node;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3285   vat_json_init_object (node);
3286   vat_json_object_add_string_copy (node, "state", s);
3287
3288   vat_json_print (vam->ofp, node);
3289   vat_json_free (node);
3290
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293   vec_free (s);
3294 }
3295
3296 static void
3297   vl_api_show_one_stats_enable_disable_reply_t_handler
3298   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3299 {
3300   vat_main_t *vam = &vat_main;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   if (retval)
3304     goto end;
3305
3306   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3307 end:
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3314   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t _node, *node = &_node;
3318   int retval = clib_net_to_host_u32 (mp->retval);
3319
3320   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3321   vat_json_init_object (node);
3322   vat_json_object_add_string_copy (node, "state", s);
3323
3324   vat_json_print (vam->ofp, node);
3325   vat_json_free (node);
3326
3327   vam->retval = retval;
3328   vam->result_ready = 1;
3329   vec_free (s);
3330 }
3331
3332 static void
3333 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3334 {
3335   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3336   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3337   e->vni = clib_net_to_host_u32 (e->vni);
3338 }
3339
3340 static void
3341   gpe_fwd_entries_get_reply_t_net_to_host
3342   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3343 {
3344   u32 i;
3345
3346   mp->count = clib_net_to_host_u32 (mp->count);
3347   for (i = 0; i < mp->count; i++)
3348     {
3349       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3350     }
3351 }
3352
3353 static u8 *
3354 format_gpe_encap_mode (u8 * s, va_list * args)
3355 {
3356   u32 mode = va_arg (*args, u32);
3357
3358   switch (mode)
3359     {
3360     case 0:
3361       return format (s, "lisp");
3362     case 1:
3363       return format (s, "vxlan");
3364     }
3365   return 0;
3366 }
3367
3368 static void
3369   vl_api_gpe_get_encap_mode_reply_t_handler
3370   (vl_api_gpe_get_encap_mode_reply_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373
3374   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3375   vam->retval = ntohl (mp->retval);
3376   vam->result_ready = 1;
3377 }
3378
3379 static void
3380   vl_api_gpe_get_encap_mode_reply_t_handler_json
3381   (vl_api_gpe_get_encap_mode_reply_t * mp)
3382 {
3383   vat_main_t *vam = &vat_main;
3384   vat_json_node_t node;
3385
3386   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3387   vec_add1 (encap_mode, 0);
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3391
3392   vec_free (encap_mode);
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void
3401   vl_api_gpe_fwd_entry_path_details_t_handler
3402   (vl_api_gpe_fwd_entry_path_details_t * mp)
3403 {
3404   vat_main_t *vam = &vat_main;
3405   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3406
3407   if (mp->lcl_loc.is_ip4)
3408     format_ip_address_fcn = format_ip4_address;
3409   else
3410     format_ip_address_fcn = format_ip6_address;
3411
3412   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3413          format_ip_address_fcn, &mp->lcl_loc,
3414          format_ip_address_fcn, &mp->rmt_loc);
3415 }
3416
3417 static void
3418 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3419 {
3420   struct in6_addr ip6;
3421   struct in_addr ip4;
3422
3423   if (loc->is_ip4)
3424     {
3425       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3426       vat_json_object_add_ip4 (n, "address", ip4);
3427     }
3428   else
3429     {
3430       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3431       vat_json_object_add_ip6 (n, "address", ip6);
3432     }
3433   vat_json_object_add_uint (n, "weight", loc->weight);
3434 }
3435
3436 static void
3437   vl_api_gpe_fwd_entry_path_details_t_handler_json
3438   (vl_api_gpe_fwd_entry_path_details_t * mp)
3439 {
3440   vat_main_t *vam = &vat_main;
3441   vat_json_node_t *node = NULL;
3442   vat_json_node_t *loc_node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450   vat_json_init_object (node);
3451
3452   loc_node = vat_json_object_add (node, "local_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3455
3456   loc_node = vat_json_object_add (node, "remote_locator");
3457   vat_json_init_object (loc_node);
3458   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entries_get_reply_t_handler
3463   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u32 i;
3467   int retval = clib_net_to_host_u32 (mp->retval);
3468   vl_api_gpe_fwd_entry_t *e;
3469
3470   if (retval)
3471     goto end;
3472
3473   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3474
3475   for (i = 0; i < mp->count; i++)
3476     {
3477       e = &mp->entries[i];
3478       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3479              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3480              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3481     }
3482
3483 end:
3484   vam->retval = retval;
3485   vam->result_ready = 1;
3486 }
3487
3488 static void
3489   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3490   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3491 {
3492   u8 *s = 0;
3493   vat_main_t *vam = &vat_main;
3494   vat_json_node_t *e = 0, root;
3495   u32 i;
3496   int retval = clib_net_to_host_u32 (mp->retval);
3497   vl_api_gpe_fwd_entry_t *fwd;
3498
3499   if (retval)
3500     goto end;
3501
3502   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3503   vat_json_init_array (&root);
3504
3505   for (i = 0; i < mp->count; i++)
3506     {
3507       e = vat_json_array_add (&root);
3508       fwd = &mp->entries[i];
3509
3510       vat_json_init_object (e);
3511       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3512       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3513       vat_json_object_add_int (e, "vni", fwd->vni);
3514       vat_json_object_add_int (e, "action", fwd->action);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3517                   fwd->leid_prefix_len);
3518       vec_add1 (s, 0);
3519       vat_json_object_add_string_copy (e, "leid", s);
3520       vec_free (s);
3521
3522       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3523                   fwd->reid_prefix_len);
3524       vec_add1 (s, 0);
3525       vat_json_object_add_string_copy (e, "reid", s);
3526       vec_free (s);
3527     }
3528
3529   vat_json_print (vam->ofp, &root);
3530   vat_json_free (&root);
3531
3532 end:
3533   vam->retval = retval;
3534   vam->result_ready = 1;
3535 }
3536
3537 static void
3538   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3539   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3540 {
3541   vat_main_t *vam = &vat_main;
3542   u32 i, n;
3543   int retval = clib_net_to_host_u32 (mp->retval);
3544   vl_api_gpe_native_fwd_rpath_t *r;
3545
3546   if (retval)
3547     goto end;
3548
3549   n = clib_net_to_host_u32 (mp->count);
3550
3551   for (i = 0; i < n; i++)
3552     {
3553       r = &mp->entries[i];
3554       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3555              clib_net_to_host_u32 (r->fib_index),
3556              clib_net_to_host_u32 (r->nh_sw_if_index),
3557              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3558     }
3559
3560 end:
3561   vam->retval = retval;
3562   vam->result_ready = 1;
3563 }
3564
3565 static void
3566   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3567   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570   vat_json_node_t root, *e;
3571   u32 i, n;
3572   int retval = clib_net_to_host_u32 (mp->retval);
3573   vl_api_gpe_native_fwd_rpath_t *r;
3574   u8 *s;
3575
3576   if (retval)
3577     goto end;
3578
3579   n = clib_net_to_host_u32 (mp->count);
3580   vat_json_init_array (&root);
3581
3582   for (i = 0; i < n; i++)
3583     {
3584       e = vat_json_array_add (&root);
3585       vat_json_init_object (e);
3586       r = &mp->entries[i];
3587       s =
3588         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3589                 r->nh_addr);
3590       vec_add1 (s, 0);
3591       vat_json_object_add_string_copy (e, "ip4", s);
3592       vec_free (s);
3593
3594       vat_json_object_add_uint (e, "fib_index",
3595                                 clib_net_to_host_u32 (r->fib_index));
3596       vat_json_object_add_uint (e, "nh_sw_if_index",
3597                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3598     }
3599
3600   vat_json_print (vam->ofp, &root);
3601   vat_json_free (&root);
3602
3603 end:
3604   vam->retval = retval;
3605   vam->result_ready = 1;
3606 }
3607
3608 static void
3609   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3610   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   u32 i, n;
3614   int retval = clib_net_to_host_u32 (mp->retval);
3615
3616   if (retval)
3617     goto end;
3618
3619   n = clib_net_to_host_u32 (mp->count);
3620
3621   for (i = 0; i < n; i++)
3622     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3623
3624 end:
3625   vam->retval = retval;
3626   vam->result_ready = 1;
3627 }
3628
3629 static void
3630   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3631   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3632 {
3633   vat_main_t *vam = &vat_main;
3634   vat_json_node_t root;
3635   u32 i, n;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637
3638   if (retval)
3639     goto end;
3640
3641   n = clib_net_to_host_u32 (mp->count);
3642   vat_json_init_array (&root);
3643
3644   for (i = 0; i < n; i++)
3645     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3646
3647   vat_json_print (vam->ofp, &root);
3648   vat_json_free (&root);
3649
3650 end:
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653 }
3654
3655 static void
3656   vl_api_one_ndp_entries_get_reply_t_handler
3657   (vl_api_one_ndp_entries_get_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   u32 i, n;
3661   int retval = clib_net_to_host_u32 (mp->retval);
3662
3663   if (retval)
3664     goto end;
3665
3666   n = clib_net_to_host_u32 (mp->count);
3667
3668   for (i = 0; i < n; i++)
3669     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3670            format_ethernet_address, mp->entries[i].mac);
3671
3672 end:
3673   vam->retval = retval;
3674   vam->result_ready = 1;
3675 }
3676
3677 static void
3678   vl_api_one_ndp_entries_get_reply_t_handler_json
3679   (vl_api_one_ndp_entries_get_reply_t * mp)
3680 {
3681   u8 *s = 0;
3682   vat_main_t *vam = &vat_main;
3683   vat_json_node_t *e = 0, root;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686   vl_api_one_ndp_entry_t *arp_entry;
3687
3688   if (retval)
3689     goto end;
3690
3691   n = clib_net_to_host_u32 (mp->count);
3692   vat_json_init_array (&root);
3693
3694   for (i = 0; i < n; i++)
3695     {
3696       e = vat_json_array_add (&root);
3697       arp_entry = &mp->entries[i];
3698
3699       vat_json_init_object (e);
3700       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3701       vec_add1 (s, 0);
3702
3703       vat_json_object_add_string_copy (e, "mac", s);
3704       vec_free (s);
3705
3706       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3707       vec_add1 (s, 0);
3708       vat_json_object_add_string_copy (e, "ip6", s);
3709       vec_free (s);
3710     }
3711
3712   vat_json_print (vam->ofp, &root);
3713   vat_json_free (&root);
3714
3715 end:
3716   vam->retval = retval;
3717   vam->result_ready = 1;
3718 }
3719
3720 static void
3721   vl_api_one_l2_arp_entries_get_reply_t_handler
3722   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3723 {
3724   vat_main_t *vam = &vat_main;
3725   u32 i, n;
3726   int retval = clib_net_to_host_u32 (mp->retval);
3727
3728   if (retval)
3729     goto end;
3730
3731   n = clib_net_to_host_u32 (mp->count);
3732
3733   for (i = 0; i < n; i++)
3734     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3735            format_ethernet_address, mp->entries[i].mac);
3736
3737 end:
3738   vam->retval = retval;
3739   vam->result_ready = 1;
3740 }
3741
3742 static void
3743   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3744   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3745 {
3746   u8 *s = 0;
3747   vat_main_t *vam = &vat_main;
3748   vat_json_node_t *e = 0, root;
3749   u32 i, n;
3750   int retval = clib_net_to_host_u32 (mp->retval);
3751   vl_api_one_l2_arp_entry_t *arp_entry;
3752
3753   if (retval)
3754     goto end;
3755
3756   n = clib_net_to_host_u32 (mp->count);
3757   vat_json_init_array (&root);
3758
3759   for (i = 0; i < n; i++)
3760     {
3761       e = vat_json_array_add (&root);
3762       arp_entry = &mp->entries[i];
3763
3764       vat_json_init_object (e);
3765       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3766       vec_add1 (s, 0);
3767
3768       vat_json_object_add_string_copy (e, "mac", s);
3769       vec_free (s);
3770
3771       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3772       vec_add1 (s, 0);
3773       vat_json_object_add_string_copy (e, "ip4", s);
3774       vec_free (s);
3775     }
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791
3792   if (retval)
3793     goto end;
3794
3795   n = clib_net_to_host_u32 (mp->count);
3796
3797   for (i = 0; i < n; i++)
3798     {
3799       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3800     }
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_bd_get_reply_t_handler_json
3809   (vl_api_one_ndp_bd_get_reply_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   vat_json_node_t root;
3813   u32 i, n;
3814   int retval = clib_net_to_host_u32 (mp->retval);
3815
3816   if (retval)
3817     goto end;
3818
3819   n = clib_net_to_host_u32 (mp->count);
3820   vat_json_init_array (&root);
3821
3822   for (i = 0; i < n; i++)
3823     {
3824       vat_json_array_add_uint (&root,
3825                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3826     }
3827
3828   vat_json_print (vam->ofp, &root);
3829   vat_json_free (&root);
3830
3831 end:
3832   vam->retval = retval;
3833   vam->result_ready = 1;
3834 }
3835
3836 static void
3837   vl_api_one_l2_arp_bd_get_reply_t_handler
3838   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3839 {
3840   vat_main_t *vam = &vat_main;
3841   u32 i, n;
3842   int retval = clib_net_to_host_u32 (mp->retval);
3843
3844   if (retval)
3845     goto end;
3846
3847   n = clib_net_to_host_u32 (mp->count);
3848
3849   for (i = 0; i < n; i++)
3850     {
3851       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3852     }
3853
3854 end:
3855   vam->retval = retval;
3856   vam->result_ready = 1;
3857 }
3858
3859 static void
3860   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3861   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3862 {
3863   vat_main_t *vam = &vat_main;
3864   vat_json_node_t root;
3865   u32 i, n;
3866   int retval = clib_net_to_host_u32 (mp->retval);
3867
3868   if (retval)
3869     goto end;
3870
3871   n = clib_net_to_host_u32 (mp->count);
3872   vat_json_init_array (&root);
3873
3874   for (i = 0; i < n; i++)
3875     {
3876       vat_json_array_add_uint (&root,
3877                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880   vat_json_print (vam->ofp, &root);
3881   vat_json_free (&root);
3882
3883 end:
3884   vam->retval = retval;
3885   vam->result_ready = 1;
3886 }
3887
3888 static void
3889   vl_api_one_adjacencies_get_reply_t_handler
3890   (vl_api_one_adjacencies_get_reply_t * mp)
3891 {
3892   vat_main_t *vam = &vat_main;
3893   u32 i, n;
3894   int retval = clib_net_to_host_u32 (mp->retval);
3895   vl_api_one_adjacency_t *a;
3896
3897   if (retval)
3898     goto end;
3899
3900   n = clib_net_to_host_u32 (mp->count);
3901
3902   for (i = 0; i < n; i++)
3903     {
3904       a = &mp->adjacencies[i];
3905       print (vam->ofp, "%U %40U",
3906              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3907              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3908     }
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916   vl_api_one_adjacencies_get_reply_t_handler_json
3917   (vl_api_one_adjacencies_get_reply_t * mp)
3918 {
3919   u8 *s = 0;
3920   vat_main_t *vam = &vat_main;
3921   vat_json_node_t *e = 0, root;
3922   u32 i, n;
3923   int retval = clib_net_to_host_u32 (mp->retval);
3924   vl_api_one_adjacency_t *a;
3925
3926   if (retval)
3927     goto end;
3928
3929   n = clib_net_to_host_u32 (mp->count);
3930   vat_json_init_array (&root);
3931
3932   for (i = 0; i < n; i++)
3933     {
3934       e = vat_json_array_add (&root);
3935       a = &mp->adjacencies[i];
3936
3937       vat_json_init_object (e);
3938       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3939                   a->leid_prefix_len);
3940       vec_add1 (s, 0);
3941       vat_json_object_add_string_copy (e, "leid", s);
3942       vec_free (s);
3943
3944       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3945                   a->reid_prefix_len);
3946       vec_add1 (s, 0);
3947       vat_json_object_add_string_copy (e, "reid", s);
3948       vec_free (s);
3949     }
3950
3951   vat_json_print (vam->ofp, &root);
3952   vat_json_free (&root);
3953
3954 end:
3955   vam->retval = retval;
3956   vam->result_ready = 1;
3957 }
3958
3959 static void
3960 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3961 {
3962   vat_main_t *vam = &vat_main;
3963
3964   print (vam->ofp, "%=20U",
3965          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3966          mp->ip_address);
3967 }
3968
3969 static void
3970   vl_api_one_map_server_details_t_handler_json
3971   (vl_api_one_map_server_details_t * mp)
3972 {
3973   vat_main_t *vam = &vat_main;
3974   vat_json_node_t *node = NULL;
3975   struct in6_addr ip6;
3976   struct in_addr ip4;
3977
3978   if (VAT_JSON_ARRAY != vam->json_tree.type)
3979     {
3980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3981       vat_json_init_array (&vam->json_tree);
3982     }
3983   node = vat_json_array_add (&vam->json_tree);
3984
3985   vat_json_init_object (node);
3986   if (mp->is_ipv6)
3987     {
3988       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3989       vat_json_object_add_ip6 (node, "map-server", ip6);
3990     }
3991   else
3992     {
3993       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3994       vat_json_object_add_ip4 (node, "map-server", ip4);
3995     }
3996 }
3997
3998 static void
3999 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4000                                            * mp)
4001 {
4002   vat_main_t *vam = &vat_main;
4003
4004   print (vam->ofp, "%=20U",
4005          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4006          mp->ip_address);
4007 }
4008
4009 static void
4010   vl_api_one_map_resolver_details_t_handler_json
4011   (vl_api_one_map_resolver_details_t * mp)
4012 {
4013   vat_main_t *vam = &vat_main;
4014   vat_json_node_t *node = NULL;
4015   struct in6_addr ip6;
4016   struct in_addr ip4;
4017
4018   if (VAT_JSON_ARRAY != vam->json_tree.type)
4019     {
4020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4021       vat_json_init_array (&vam->json_tree);
4022     }
4023   node = vat_json_array_add (&vam->json_tree);
4024
4025   vat_json_init_object (node);
4026   if (mp->is_ipv6)
4027     {
4028       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4029       vat_json_object_add_ip6 (node, "map resolver", ip6);
4030     }
4031   else
4032     {
4033       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4034       vat_json_object_add_ip4 (node, "map resolver", ip4);
4035     }
4036 }
4037
4038 static void
4039 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4040 {
4041   vat_main_t *vam = &vat_main;
4042   i32 retval = ntohl (mp->retval);
4043
4044   if (0 <= retval)
4045     {
4046       print (vam->ofp, "feature: %s\ngpe: %s",
4047              mp->feature_status ? "enabled" : "disabled",
4048              mp->gpe_status ? "enabled" : "disabled");
4049     }
4050
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_show_one_status_reply_t_handler_json
4057   (vl_api_show_one_status_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   vat_json_node_t node;
4061   u8 *gpe_status = NULL;
4062   u8 *feature_status = NULL;
4063
4064   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4065   feature_status = format (0, "%s",
4066                            mp->feature_status ? "enabled" : "disabled");
4067   vec_add1 (gpe_status, 0);
4068   vec_add1 (feature_status, 0);
4069
4070   vat_json_init_object (&node);
4071   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4072   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4073
4074   vec_free (gpe_status);
4075   vec_free (feature_status);
4076
4077   vat_json_print (vam->ofp, &node);
4078   vat_json_free (&node);
4079
4080   vam->retval = ntohl (mp->retval);
4081   vam->result_ready = 1;
4082 }
4083
4084 static void
4085   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4086   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4087 {
4088   vat_main_t *vam = &vat_main;
4089   i32 retval = ntohl (mp->retval);
4090
4091   if (retval >= 0)
4092     {
4093       print (vam->ofp, "%=20s", mp->locator_set_name);
4094     }
4095
4096   vam->retval = retval;
4097   vam->result_ready = 1;
4098 }
4099
4100 static void
4101   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4102   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105   vat_json_node_t *node = NULL;
4106
4107   if (VAT_JSON_ARRAY != vam->json_tree.type)
4108     {
4109       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4110       vat_json_init_array (&vam->json_tree);
4111     }
4112   node = vat_json_array_add (&vam->json_tree);
4113
4114   vat_json_init_object (node);
4115   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4116
4117   vat_json_print (vam->ofp, node);
4118   vat_json_free (node);
4119
4120   vam->retval = ntohl (mp->retval);
4121   vam->result_ready = 1;
4122 }
4123
4124 static u8 *
4125 format_lisp_map_request_mode (u8 * s, va_list * args)
4126 {
4127   u32 mode = va_arg (*args, u32);
4128
4129   switch (mode)
4130     {
4131     case 0:
4132       return format (0, "dst-only");
4133     case 1:
4134       return format (0, "src-dst");
4135     }
4136   return 0;
4137 }
4138
4139 static void
4140   vl_api_show_one_map_request_mode_reply_t_handler
4141   (vl_api_show_one_map_request_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       u32 mode = mp->mode;
4149       print (vam->ofp, "map_request_mode: %U",
4150              format_lisp_map_request_mode, mode);
4151     }
4152
4153   vam->retval = retval;
4154   vam->result_ready = 1;
4155 }
4156
4157 static void
4158   vl_api_show_one_map_request_mode_reply_t_handler_json
4159   (vl_api_show_one_map_request_mode_reply_t * mp)
4160 {
4161   vat_main_t *vam = &vat_main;
4162   vat_json_node_t node;
4163   u8 *s = 0;
4164   u32 mode;
4165
4166   mode = mp->mode;
4167   s = format (0, "%U", format_lisp_map_request_mode, mode);
4168   vec_add1 (s, 0);
4169
4170   vat_json_init_object (&node);
4171   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4172   vat_json_print (vam->ofp, &node);
4173   vat_json_free (&node);
4174
4175   vec_free (s);
4176   vam->retval = ntohl (mp->retval);
4177   vam->result_ready = 1;
4178 }
4179
4180 static void
4181   vl_api_one_show_xtr_mode_reply_t_handler
4182   (vl_api_one_show_xtr_mode_reply_t * mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   i32 retval = ntohl (mp->retval);
4186
4187   if (0 <= retval)
4188     {
4189       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4190     }
4191
4192   vam->retval = retval;
4193   vam->result_ready = 1;
4194 }
4195
4196 static void
4197   vl_api_one_show_xtr_mode_reply_t_handler_json
4198   (vl_api_one_show_xtr_mode_reply_t * mp)
4199 {
4200   vat_main_t *vam = &vat_main;
4201   vat_json_node_t node;
4202   u8 *status = 0;
4203
4204   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4205   vec_add1 (status, 0);
4206
4207   vat_json_init_object (&node);
4208   vat_json_object_add_string_copy (&node, "status", status);
4209
4210   vec_free (status);
4211
4212   vat_json_print (vam->ofp, &node);
4213   vat_json_free (&node);
4214
4215   vam->retval = ntohl (mp->retval);
4216   vam->result_ready = 1;
4217 }
4218
4219 static void
4220   vl_api_one_show_pitr_mode_reply_t_handler
4221   (vl_api_one_show_pitr_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   i32 retval = ntohl (mp->retval);
4225
4226   if (0 <= retval)
4227     {
4228       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4229     }
4230
4231   vam->retval = retval;
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_pitr_mode_reply_t_handler_json
4237   (vl_api_one_show_pitr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   vat_json_node_t node;
4241   u8 *status = 0;
4242
4243   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4244   vec_add1 (status, 0);
4245
4246   vat_json_init_object (&node);
4247   vat_json_object_add_string_copy (&node, "status", status);
4248
4249   vec_free (status);
4250
4251   vat_json_print (vam->ofp, &node);
4252   vat_json_free (&node);
4253
4254   vam->retval = ntohl (mp->retval);
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_petr_mode_reply_t_handler
4260   (vl_api_one_show_petr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   i32 retval = ntohl (mp->retval);
4264
4265   if (0 <= retval)
4266     {
4267       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4268     }
4269
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_petr_mode_reply_t_handler_json
4276   (vl_api_one_show_petr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t node;
4280   u8 *status = 0;
4281
4282   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4283   vec_add1 (status, 0);
4284
4285   vat_json_init_object (&node);
4286   vat_json_object_add_string_copy (&node, "status", status);
4287
4288   vec_free (status);
4289
4290   vat_json_print (vam->ofp, &node);
4291   vat_json_free (&node);
4292
4293   vam->retval = ntohl (mp->retval);
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_show_one_use_petr_reply_t_handler
4299   (vl_api_show_one_use_petr_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   i32 retval = ntohl (mp->retval);
4303
4304   if (0 <= retval)
4305     {
4306       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4307       if (mp->status)
4308         {
4309           print (vam->ofp, "Proxy-ETR address; %U",
4310                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4311                  mp->address);
4312         }
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_show_one_use_petr_reply_t_handler_json
4321   (vl_api_show_one_use_petr_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326   struct in_addr ip4;
4327   struct in6_addr ip6;
4328
4329   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4330   vec_add1 (status, 0);
4331
4332   vat_json_init_object (&node);
4333   vat_json_object_add_string_copy (&node, "status", status);
4334   if (mp->status)
4335     {
4336       if (mp->is_ip4)
4337         {
4338           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4339           vat_json_object_add_ip6 (&node, "address", ip6);
4340         }
4341       else
4342         {
4343           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4344           vat_json_object_add_ip4 (&node, "address", ip4);
4345         }
4346     }
4347
4348   vec_free (status);
4349
4350   vat_json_print (vam->ofp, &node);
4351   vat_json_free (&node);
4352
4353   vam->retval = ntohl (mp->retval);
4354   vam->result_ready = 1;
4355 }
4356
4357 static void
4358   vl_api_show_one_nsh_mapping_reply_t_handler
4359   (vl_api_show_one_nsh_mapping_reply_t * mp)
4360 {
4361   vat_main_t *vam = &vat_main;
4362   i32 retval = ntohl (mp->retval);
4363
4364   if (0 <= retval)
4365     {
4366       print (vam->ofp, "%-20s%-16s",
4367              mp->is_set ? "set" : "not-set",
4368              mp->is_set ? (char *) mp->locator_set_name : "");
4369     }
4370
4371   vam->retval = retval;
4372   vam->result_ready = 1;
4373 }
4374
4375 static void
4376   vl_api_show_one_nsh_mapping_reply_t_handler_json
4377   (vl_api_show_one_nsh_mapping_reply_t * mp)
4378 {
4379   vat_main_t *vam = &vat_main;
4380   vat_json_node_t node;
4381   u8 *status = 0;
4382
4383   status = format (0, "%s", mp->is_set ? "yes" : "no");
4384   vec_add1 (status, 0);
4385
4386   vat_json_init_object (&node);
4387   vat_json_object_add_string_copy (&node, "is_set", status);
4388   if (mp->is_set)
4389     {
4390       vat_json_object_add_string_copy (&node, "locator_set",
4391                                        mp->locator_set_name);
4392     }
4393
4394   vec_free (status);
4395
4396   vat_json_print (vam->ofp, &node);
4397   vat_json_free (&node);
4398
4399   vam->retval = ntohl (mp->retval);
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_show_one_map_register_ttl_reply_t_handler
4405   (vl_api_show_one_map_register_ttl_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   i32 retval = ntohl (mp->retval);
4409
4410   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4411
4412   if (0 <= retval)
4413     {
4414       print (vam->ofp, "ttl: %u", mp->ttl);
4415     }
4416
4417   vam->retval = retval;
4418   vam->result_ready = 1;
4419 }
4420
4421 static void
4422   vl_api_show_one_map_register_ttl_reply_t_handler_json
4423   (vl_api_show_one_map_register_ttl_reply_t * mp)
4424 {
4425   vat_main_t *vam = &vat_main;
4426   vat_json_node_t node;
4427
4428   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4429   vat_json_init_object (&node);
4430   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4431
4432   vat_json_print (vam->ofp, &node);
4433   vat_json_free (&node);
4434
4435   vam->retval = ntohl (mp->retval);
4436   vam->result_ready = 1;
4437 }
4438
4439 static void
4440 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4441 {
4442   vat_main_t *vam = &vat_main;
4443   i32 retval = ntohl (mp->retval);
4444
4445   if (0 <= retval)
4446     {
4447       print (vam->ofp, "%-20s%-16s",
4448              mp->status ? "enabled" : "disabled",
4449              mp->status ? (char *) mp->locator_set_name : "");
4450     }
4451
4452   vam->retval = retval;
4453   vam->result_ready = 1;
4454 }
4455
4456 static void
4457 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4458 {
4459   vat_main_t *vam = &vat_main;
4460   vat_json_node_t node;
4461   u8 *status = 0;
4462
4463   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4464   vec_add1 (status, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "status", status);
4468   if (mp->status)
4469     {
4470       vat_json_object_add_string_copy (&node, "locator_set",
4471                                        mp->locator_set_name);
4472     }
4473
4474   vec_free (status);
4475
4476   vat_json_print (vam->ofp, &node);
4477   vat_json_free (&node);
4478
4479   vam->retval = ntohl (mp->retval);
4480   vam->result_ready = 1;
4481 }
4482
4483 static u8 *
4484 format_policer_type (u8 * s, va_list * va)
4485 {
4486   u32 i = va_arg (*va, u32);
4487
4488   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4489     s = format (s, "1r2c");
4490   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4491     s = format (s, "1r3c");
4492   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4493     s = format (s, "2r3c-2698");
4494   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4495     s = format (s, "2r3c-4115");
4496   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4497     s = format (s, "2r3c-mef5cf1");
4498   else
4499     s = format (s, "ILLEGAL");
4500   return s;
4501 }
4502
4503 static u8 *
4504 format_policer_rate_type (u8 * s, va_list * va)
4505 {
4506   u32 i = va_arg (*va, u32);
4507
4508   if (i == SSE2_QOS_RATE_KBPS)
4509     s = format (s, "kbps");
4510   else if (i == SSE2_QOS_RATE_PPS)
4511     s = format (s, "pps");
4512   else
4513     s = format (s, "ILLEGAL");
4514   return s;
4515 }
4516
4517 static u8 *
4518 format_policer_round_type (u8 * s, va_list * va)
4519 {
4520   u32 i = va_arg (*va, u32);
4521
4522   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4523     s = format (s, "closest");
4524   else if (i == SSE2_QOS_ROUND_TO_UP)
4525     s = format (s, "up");
4526   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4527     s = format (s, "down");
4528   else
4529     s = format (s, "ILLEGAL");
4530   return s;
4531 }
4532
4533 static u8 *
4534 format_policer_action_type (u8 * s, va_list * va)
4535 {
4536   u32 i = va_arg (*va, u32);
4537
4538   if (i == SSE2_QOS_ACTION_DROP)
4539     s = format (s, "drop");
4540   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4541     s = format (s, "transmit");
4542   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     s = format (s, "mark-and-transmit");
4544   else
4545     s = format (s, "ILLEGAL");
4546   return s;
4547 }
4548
4549 static u8 *
4550 format_dscp (u8 * s, va_list * va)
4551 {
4552   u32 i = va_arg (*va, u32);
4553   char *t = 0;
4554
4555   switch (i)
4556     {
4557 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4558       foreach_vnet_dscp
4559 #undef _
4560     default:
4561       return format (s, "ILLEGAL");
4562     }
4563   s = format (s, "%s", t);
4564   return s;
4565 }
4566
4567 static void
4568 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4572
4573   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4574     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4575   else
4576     conform_dscp_str = format (0, "");
4577
4578   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4579     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4580   else
4581     exceed_dscp_str = format (0, "");
4582
4583   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4584     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4585   else
4586     violate_dscp_str = format (0, "");
4587
4588   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4589          "rate type %U, round type %U, %s rate, %s color-aware, "
4590          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4591          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4592          "conform action %U%s, exceed action %U%s, violate action %U%s",
4593          mp->name,
4594          format_policer_type, mp->type,
4595          ntohl (mp->cir),
4596          ntohl (mp->eir),
4597          clib_net_to_host_u64 (mp->cb),
4598          clib_net_to_host_u64 (mp->eb),
4599          format_policer_rate_type, mp->rate_type,
4600          format_policer_round_type, mp->round_type,
4601          mp->single_rate ? "single" : "dual",
4602          mp->color_aware ? "is" : "not",
4603          ntohl (mp->cir_tokens_per_period),
4604          ntohl (mp->pir_tokens_per_period),
4605          ntohl (mp->scale),
4606          ntohl (mp->current_limit),
4607          ntohl (mp->current_bucket),
4608          ntohl (mp->extended_limit),
4609          ntohl (mp->extended_bucket),
4610          clib_net_to_host_u64 (mp->last_update_time),
4611          format_policer_action_type, mp->conform_action_type,
4612          conform_dscp_str,
4613          format_policer_action_type, mp->exceed_action_type,
4614          exceed_dscp_str,
4615          format_policer_action_type, mp->violate_action_type,
4616          violate_dscp_str);
4617
4618   vec_free (conform_dscp_str);
4619   vec_free (exceed_dscp_str);
4620   vec_free (violate_dscp_str);
4621 }
4622
4623 static void vl_api_policer_details_t_handler_json
4624   (vl_api_policer_details_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t *node;
4628   u8 *rate_type_str, *round_type_str, *type_str;
4629   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4630
4631   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4632   round_type_str =
4633     format (0, "%U", format_policer_round_type, mp->round_type);
4634   type_str = format (0, "%U", format_policer_type, mp->type);
4635   conform_action_str = format (0, "%U", format_policer_action_type,
4636                                mp->conform_action_type);
4637   exceed_action_str = format (0, "%U", format_policer_action_type,
4638                               mp->exceed_action_type);
4639   violate_action_str = format (0, "%U", format_policer_action_type,
4640                                mp->violate_action_type);
4641
4642   if (VAT_JSON_ARRAY != vam->json_tree.type)
4643     {
4644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4645       vat_json_init_array (&vam->json_tree);
4646     }
4647   node = vat_json_array_add (&vam->json_tree);
4648
4649   vat_json_init_object (node);
4650   vat_json_object_add_string_copy (node, "name", mp->name);
4651   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4652   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4653   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4654   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4655   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4656   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4657   vat_json_object_add_string_copy (node, "type", type_str);
4658   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4659   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4660   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4661   vat_json_object_add_uint (node, "cir_tokens_per_period",
4662                             ntohl (mp->cir_tokens_per_period));
4663   vat_json_object_add_uint (node, "eir_tokens_per_period",
4664                             ntohl (mp->pir_tokens_per_period));
4665   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4666   vat_json_object_add_uint (node, "current_bucket",
4667                             ntohl (mp->current_bucket));
4668   vat_json_object_add_uint (node, "extended_limit",
4669                             ntohl (mp->extended_limit));
4670   vat_json_object_add_uint (node, "extended_bucket",
4671                             ntohl (mp->extended_bucket));
4672   vat_json_object_add_uint (node, "last_update_time",
4673                             ntohl (mp->last_update_time));
4674   vat_json_object_add_string_copy (node, "conform_action",
4675                                    conform_action_str);
4676   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4677     {
4678       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4679       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4680       vec_free (dscp_str);
4681     }
4682   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4683   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4686       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689   vat_json_object_add_string_copy (node, "violate_action",
4690                                    violate_action_str);
4691   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4692     {
4693       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4694       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4695       vec_free (dscp_str);
4696     }
4697
4698   vec_free (rate_type_str);
4699   vec_free (round_type_str);
4700   vec_free (type_str);
4701   vec_free (conform_action_str);
4702   vec_free (exceed_action_str);
4703   vec_free (violate_action_str);
4704 }
4705
4706 static void
4707 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4708                                            mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   int i, count = ntohl (mp->count);
4712
4713   if (count > 0)
4714     print (vam->ofp, "classify table ids (%d) : ", count);
4715   for (i = 0; i < count; i++)
4716     {
4717       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4718       print (vam->ofp, (i < count - 1) ? "," : "");
4719     }
4720   vam->retval = ntohl (mp->retval);
4721   vam->result_ready = 1;
4722 }
4723
4724 static void
4725   vl_api_classify_table_ids_reply_t_handler_json
4726   (vl_api_classify_table_ids_reply_t * mp)
4727 {
4728   vat_main_t *vam = &vat_main;
4729   int i, count = ntohl (mp->count);
4730
4731   if (count > 0)
4732     {
4733       vat_json_node_t node;
4734
4735       vat_json_init_object (&node);
4736       for (i = 0; i < count; i++)
4737         {
4738           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4739         }
4740       vat_json_print (vam->ofp, &node);
4741       vat_json_free (&node);
4742     }
4743   vam->retval = ntohl (mp->retval);
4744   vam->result_ready = 1;
4745 }
4746
4747 static void
4748   vl_api_classify_table_by_interface_reply_t_handler
4749   (vl_api_classify_table_by_interface_reply_t * mp)
4750 {
4751   vat_main_t *vam = &vat_main;
4752   u32 table_id;
4753
4754   table_id = ntohl (mp->l2_table_id);
4755   if (table_id != ~0)
4756     print (vam->ofp, "l2 table id : %d", table_id);
4757   else
4758     print (vam->ofp, "l2 table id : No input ACL tables configured");
4759   table_id = ntohl (mp->ip4_table_id);
4760   if (table_id != ~0)
4761     print (vam->ofp, "ip4 table id : %d", table_id);
4762   else
4763     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4764   table_id = ntohl (mp->ip6_table_id);
4765   if (table_id != ~0)
4766     print (vam->ofp, "ip6 table id : %d", table_id);
4767   else
4768     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4769   vam->retval = ntohl (mp->retval);
4770   vam->result_ready = 1;
4771 }
4772
4773 static void
4774   vl_api_classify_table_by_interface_reply_t_handler_json
4775   (vl_api_classify_table_by_interface_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
4782   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4783   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4784   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4785
4786   vat_json_print (vam->ofp, &node);
4787   vat_json_free (&node);
4788
4789   vam->retval = ntohl (mp->retval);
4790   vam->result_ready = 1;
4791 }
4792
4793 static void vl_api_policer_add_del_reply_t_handler
4794   (vl_api_policer_add_del_reply_t * mp)
4795 {
4796   vat_main_t *vam = &vat_main;
4797   i32 retval = ntohl (mp->retval);
4798   if (vam->async_mode)
4799     {
4800       vam->async_errors += (retval < 0);
4801     }
4802   else
4803     {
4804       vam->retval = retval;
4805       vam->result_ready = 1;
4806       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4807         /*
4808          * Note: this is just barely thread-safe, depends on
4809          * the main thread spinning waiting for an answer...
4810          */
4811         errmsg ("policer index %d", ntohl (mp->policer_index));
4812     }
4813 }
4814
4815 static void vl_api_policer_add_del_reply_t_handler_json
4816   (vl_api_policer_add_del_reply_t * mp)
4817 {
4818   vat_main_t *vam = &vat_main;
4819   vat_json_node_t node;
4820
4821   vat_json_init_object (&node);
4822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4823   vat_json_object_add_uint (&node, "policer_index",
4824                             ntohl (mp->policer_index));
4825
4826   vat_json_print (vam->ofp, &node);
4827   vat_json_free (&node);
4828
4829   vam->retval = ntohl (mp->retval);
4830   vam->result_ready = 1;
4831 }
4832
4833 /* Format hex dump. */
4834 u8 *
4835 format_hex_bytes (u8 * s, va_list * va)
4836 {
4837   u8 *bytes = va_arg (*va, u8 *);
4838   int n_bytes = va_arg (*va, int);
4839   uword i;
4840
4841   /* Print short or long form depending on byte count. */
4842   uword short_form = n_bytes <= 32;
4843   u32 indent = format_get_indent (s);
4844
4845   if (n_bytes == 0)
4846     return s;
4847
4848   for (i = 0; i < n_bytes; i++)
4849     {
4850       if (!short_form && (i % 32) == 0)
4851         s = format (s, "%08x: ", i);
4852       s = format (s, "%02x", bytes[i]);
4853       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4854         s = format (s, "\n%U", format_white_space, indent);
4855     }
4856
4857   return s;
4858 }
4859
4860 static void
4861 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4862                                             * mp)
4863 {
4864   vat_main_t *vam = &vat_main;
4865   i32 retval = ntohl (mp->retval);
4866   if (retval == 0)
4867     {
4868       print (vam->ofp, "classify table info :");
4869       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4870              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4871              ntohl (mp->miss_next_index));
4872       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4873              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4874              ntohl (mp->match_n_vectors));
4875       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4876              ntohl (mp->mask_length));
4877     }
4878   vam->retval = retval;
4879   vam->result_ready = 1;
4880 }
4881
4882 static void
4883   vl_api_classify_table_info_reply_t_handler_json
4884   (vl_api_classify_table_info_reply_t * mp)
4885 {
4886   vat_main_t *vam = &vat_main;
4887   vat_json_node_t node;
4888
4889   i32 retval = ntohl (mp->retval);
4890   if (retval == 0)
4891     {
4892       vat_json_init_object (&node);
4893
4894       vat_json_object_add_int (&node, "sessions",
4895                                ntohl (mp->active_sessions));
4896       vat_json_object_add_int (&node, "nexttbl",
4897                                ntohl (mp->next_table_index));
4898       vat_json_object_add_int (&node, "nextnode",
4899                                ntohl (mp->miss_next_index));
4900       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4901       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4902       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4903       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4904                       ntohl (mp->mask_length), 0);
4905       vat_json_object_add_string_copy (&node, "mask", s);
4906
4907       vat_json_print (vam->ofp, &node);
4908       vat_json_free (&node);
4909     }
4910   vam->retval = ntohl (mp->retval);
4911   vam->result_ready = 1;
4912 }
4913
4914 static void
4915 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4916                                            mp)
4917 {
4918   vat_main_t *vam = &vat_main;
4919
4920   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4921          ntohl (mp->hit_next_index), ntohl (mp->advance),
4922          ntohl (mp->opaque_index));
4923   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4924          ntohl (mp->match_length));
4925 }
4926
4927 static void
4928   vl_api_classify_session_details_t_handler_json
4929   (vl_api_classify_session_details_t * mp)
4930 {
4931   vat_main_t *vam = &vat_main;
4932   vat_json_node_t *node = NULL;
4933
4934   if (VAT_JSON_ARRAY != vam->json_tree.type)
4935     {
4936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4937       vat_json_init_array (&vam->json_tree);
4938     }
4939   node = vat_json_array_add (&vam->json_tree);
4940
4941   vat_json_init_object (node);
4942   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4943   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4944   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4945   u8 *s =
4946     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4947             0);
4948   vat_json_object_add_string_copy (node, "match", s);
4949 }
4950
4951 static void vl_api_pg_create_interface_reply_t_handler
4952   (vl_api_pg_create_interface_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955
4956   vam->retval = ntohl (mp->retval);
4957   vam->result_ready = 1;
4958 }
4959
4960 static void vl_api_pg_create_interface_reply_t_handler_json
4961   (vl_api_pg_create_interface_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964   vat_json_node_t node;
4965
4966   i32 retval = ntohl (mp->retval);
4967   if (retval == 0)
4968     {
4969       vat_json_init_object (&node);
4970
4971       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4972
4973       vat_json_print (vam->ofp, &node);
4974       vat_json_free (&node);
4975     }
4976   vam->retval = ntohl (mp->retval);
4977   vam->result_ready = 1;
4978 }
4979
4980 static void vl_api_policer_classify_details_t_handler
4981   (vl_api_policer_classify_details_t * mp)
4982 {
4983   vat_main_t *vam = &vat_main;
4984
4985   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4986          ntohl (mp->table_index));
4987 }
4988
4989 static void vl_api_policer_classify_details_t_handler_json
4990   (vl_api_policer_classify_details_t * mp)
4991 {
4992   vat_main_t *vam = &vat_main;
4993   vat_json_node_t *node;
4994
4995   if (VAT_JSON_ARRAY != vam->json_tree.type)
4996     {
4997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4998       vat_json_init_array (&vam->json_tree);
4999     }
5000   node = vat_json_array_add (&vam->json_tree);
5001
5002   vat_json_init_object (node);
5003   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5004   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5005 }
5006
5007 static void vl_api_flow_classify_details_t_handler
5008   (vl_api_flow_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5013          ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_flow_classify_details_t_handler_json
5017   (vl_api_flow_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t *node;
5021
5022   if (VAT_JSON_ARRAY != vam->json_tree.type)
5023     {
5024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5025       vat_json_init_array (&vam->json_tree);
5026     }
5027   node = vat_json_array_add (&vam->json_tree);
5028
5029   vat_json_init_object (node);
5030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5031   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5032 }
5033
5034 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5035 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5036 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5037 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5038 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5039 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5040 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5041 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5042 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5043 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5044
5045 /*
5046  * Generate boilerplate reply handlers, which
5047  * dig the return value out of the xxx_reply_t API message,
5048  * stick it into vam->retval, and set vam->result_ready
5049  *
5050  * Could also do this by pointing N message decode slots at
5051  * a single function, but that could break in subtle ways.
5052  */
5053
5054 #define foreach_standard_reply_retval_handler           \
5055 _(sw_interface_set_flags_reply)                         \
5056 _(sw_interface_add_del_address_reply)                   \
5057 _(sw_interface_set_rx_mode_reply)                       \
5058 _(sw_interface_set_rx_placement_reply)                  \
5059 _(sw_interface_set_table_reply)                         \
5060 _(sw_interface_set_mpls_enable_reply)                   \
5061 _(sw_interface_set_vpath_reply)                         \
5062 _(sw_interface_set_vxlan_bypass_reply)                  \
5063 _(sw_interface_set_geneve_bypass_reply)                 \
5064 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5065 _(sw_interface_set_l2_bridge_reply)                     \
5066 _(sw_interface_set_bond_weight_reply)                   \
5067 _(bridge_domain_add_del_reply)                          \
5068 _(sw_interface_set_l2_xconnect_reply)                   \
5069 _(l2fib_add_del_reply)                                  \
5070 _(l2fib_flush_int_reply)                                \
5071 _(l2fib_flush_bd_reply)                                 \
5072 _(ip_route_add_del_reply)                               \
5073 _(ip_table_add_del_reply)                               \
5074 _(ip_mroute_add_del_reply)                              \
5075 _(mpls_route_add_del_reply)                             \
5076 _(mpls_table_add_del_reply)                             \
5077 _(mpls_ip_bind_unbind_reply)                            \
5078 _(bier_route_add_del_reply)                             \
5079 _(bier_table_add_del_reply)                             \
5080 _(proxy_arp_add_del_reply)                              \
5081 _(proxy_arp_intfc_enable_disable_reply)                 \
5082 _(sw_interface_set_unnumbered_reply)                    \
5083 _(ip_neighbor_add_del_reply)                            \
5084 _(reset_fib_reply)                                      \
5085 _(set_ip_flow_hash_reply)                               \
5086 _(sw_interface_ip6_enable_disable_reply)                \
5087 _(ip6nd_proxy_add_del_reply)                            \
5088 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5089 _(sw_interface_ip6nd_ra_config_reply)                   \
5090 _(set_arp_neighbor_limit_reply)                         \
5091 _(l2_patch_add_del_reply)                               \
5092 _(sr_mpls_policy_add_reply)                             \
5093 _(sr_mpls_policy_mod_reply)                             \
5094 _(sr_mpls_policy_del_reply)                             \
5095 _(sr_policy_add_reply)                                  \
5096 _(sr_policy_mod_reply)                                  \
5097 _(sr_policy_del_reply)                                  \
5098 _(sr_localsid_add_del_reply)                            \
5099 _(sr_steering_add_del_reply)                            \
5100 _(classify_add_del_session_reply)                       \
5101 _(classify_set_interface_ip_table_reply)                \
5102 _(classify_set_interface_l2_tables_reply)               \
5103 _(l2tpv3_set_tunnel_cookies_reply)                      \
5104 _(l2tpv3_interface_enable_disable_reply)                \
5105 _(l2tpv3_set_lookup_key_reply)                          \
5106 _(l2_fib_clear_table_reply)                             \
5107 _(l2_interface_efp_filter_reply)                        \
5108 _(l2_interface_vlan_tag_rewrite_reply)                  \
5109 _(modify_vhost_user_if_reply)                           \
5110 _(delete_vhost_user_if_reply)                           \
5111 _(ip_probe_neighbor_reply)                              \
5112 _(ip_scan_neighbor_enable_disable_reply)                \
5113 _(want_ip4_arp_events_reply)                            \
5114 _(want_ip6_nd_events_reply)                             \
5115 _(want_l2_macs_events_reply)                            \
5116 _(input_acl_set_interface_reply)                        \
5117 _(ipsec_spd_add_del_reply)                              \
5118 _(ipsec_interface_add_del_spd_reply)                    \
5119 _(ipsec_spd_entry_add_del_reply)                        \
5120 _(ipsec_sad_entry_add_del_reply)                        \
5121 _(ipsec_tunnel_if_add_del_reply)                        \
5122 _(ipsec_tunnel_if_set_sa_reply)                         \
5123 _(delete_loopback_reply)                                \
5124 _(bd_ip_mac_add_del_reply)                              \
5125 _(bd_ip_mac_flush_reply)                                \
5126 _(want_interface_events_reply)                          \
5127 _(cop_interface_enable_disable_reply)                   \
5128 _(cop_whitelist_enable_disable_reply)                   \
5129 _(sw_interface_clear_stats_reply)                       \
5130 _(ioam_enable_reply)                                    \
5131 _(ioam_disable_reply)                                   \
5132 _(one_add_del_locator_reply)                            \
5133 _(one_add_del_local_eid_reply)                          \
5134 _(one_add_del_remote_mapping_reply)                     \
5135 _(one_add_del_adjacency_reply)                          \
5136 _(one_add_del_map_resolver_reply)                       \
5137 _(one_add_del_map_server_reply)                         \
5138 _(one_enable_disable_reply)                             \
5139 _(one_rloc_probe_enable_disable_reply)                  \
5140 _(one_map_register_enable_disable_reply)                \
5141 _(one_map_register_set_ttl_reply)                       \
5142 _(one_set_transport_protocol_reply)                     \
5143 _(one_map_register_fallback_threshold_reply)            \
5144 _(one_pitr_set_locator_set_reply)                       \
5145 _(one_map_request_mode_reply)                           \
5146 _(one_add_del_map_request_itr_rlocs_reply)              \
5147 _(one_eid_table_add_del_map_reply)                      \
5148 _(one_use_petr_reply)                                   \
5149 _(one_stats_enable_disable_reply)                       \
5150 _(one_add_del_l2_arp_entry_reply)                       \
5151 _(one_add_del_ndp_entry_reply)                          \
5152 _(one_stats_flush_reply)                                \
5153 _(one_enable_disable_xtr_mode_reply)                    \
5154 _(one_enable_disable_pitr_mode_reply)                   \
5155 _(one_enable_disable_petr_mode_reply)                   \
5156 _(gpe_enable_disable_reply)                             \
5157 _(gpe_set_encap_mode_reply)                             \
5158 _(gpe_add_del_iface_reply)                              \
5159 _(gpe_add_del_native_fwd_rpath_reply)                   \
5160 _(af_packet_delete_reply)                               \
5161 _(policer_classify_set_interface_reply)                 \
5162 _(netmap_create_reply)                                  \
5163 _(netmap_delete_reply)                                  \
5164 _(set_ipfix_exporter_reply)                             \
5165 _(set_ipfix_classify_stream_reply)                      \
5166 _(ipfix_classify_table_add_del_reply)                   \
5167 _(flow_classify_set_interface_reply)                    \
5168 _(sw_interface_span_enable_disable_reply)               \
5169 _(pg_capture_reply)                                     \
5170 _(pg_enable_disable_reply)                              \
5171 _(ip_source_and_port_range_check_add_del_reply)         \
5172 _(ip_source_and_port_range_check_interface_add_del_reply)\
5173 _(delete_subif_reply)                                   \
5174 _(l2_interface_pbb_tag_rewrite_reply)                   \
5175 _(set_punt_reply)                                       \
5176 _(feature_enable_disable_reply)                         \
5177 _(sw_interface_tag_add_del_reply)                       \
5178 _(sw_interface_add_del_mac_address_reply)               \
5179 _(hw_interface_set_mtu_reply)                           \
5180 _(p2p_ethernet_add_reply)                               \
5181 _(p2p_ethernet_del_reply)                               \
5182 _(lldp_config_reply)                                    \
5183 _(sw_interface_set_lldp_reply)                          \
5184 _(tcp_configure_src_addresses_reply)                    \
5185 _(session_rule_add_del_reply)                           \
5186 _(ip_container_proxy_add_del_reply)                     \
5187 _(output_acl_set_interface_reply)                       \
5188 _(qos_record_enable_disable_reply)
5189
5190 #define _(n)                                    \
5191     static void vl_api_##n##_t_handler          \
5192     (vl_api_##n##_t * mp)                       \
5193     {                                           \
5194         vat_main_t * vam = &vat_main;           \
5195         i32 retval = ntohl(mp->retval);         \
5196         if (vam->async_mode) {                  \
5197             vam->async_errors += (retval < 0);  \
5198         } else {                                \
5199             vam->retval = retval;               \
5200             vam->result_ready = 1;              \
5201         }                                       \
5202     }
5203 foreach_standard_reply_retval_handler;
5204 #undef _
5205
5206 #define _(n)                                    \
5207     static void vl_api_##n##_t_handler_json     \
5208     (vl_api_##n##_t * mp)                       \
5209     {                                           \
5210         vat_main_t * vam = &vat_main;           \
5211         vat_json_node_t node;                   \
5212         vat_json_init_object(&node);            \
5213         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5214         vat_json_print(vam->ofp, &node);        \
5215         vam->retval = ntohl(mp->retval);        \
5216         vam->result_ready = 1;                  \
5217     }
5218 foreach_standard_reply_retval_handler;
5219 #undef _
5220
5221 /*
5222  * Table of message reply handlers, must include boilerplate handlers
5223  * we just generated
5224  */
5225
5226 #define foreach_vpe_api_reply_msg                                       \
5227 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5228 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5229 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5230 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5231 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5232 _(CLI_REPLY, cli_reply)                                                 \
5233 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5234 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5235   sw_interface_add_del_address_reply)                                   \
5236 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5237 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5238 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5239 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5240 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5241 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5242 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5243 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5244 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5245 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5246   sw_interface_set_l2_xconnect_reply)                                   \
5247 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5248   sw_interface_set_l2_bridge_reply)                                     \
5249 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5250 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5251 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5252 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5253 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5254 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5255 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5256 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5257 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5258 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5259 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5260 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5261 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5262 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5263 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5264 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5265 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5266 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5267 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5268 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5269 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5270 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5271 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5272 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5273 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5274 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5275 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5276 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5277 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5278 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5279 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5280   proxy_arp_intfc_enable_disable_reply)                                 \
5281 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5282 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5283   sw_interface_set_unnumbered_reply)                                    \
5284 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5285 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5286 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5287 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5288 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5289 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5290   sw_interface_ip6_enable_disable_reply)                                \
5291 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5292 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5293 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5294   sw_interface_ip6nd_ra_prefix_reply)                                   \
5295 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5296   sw_interface_ip6nd_ra_config_reply)                                   \
5297 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5298 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5299 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5300 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5301 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5302 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5303 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5304 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5305 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5306 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5307 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5308 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5309 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5310 classify_set_interface_ip_table_reply)                                  \
5311 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5312   classify_set_interface_l2_tables_reply)                               \
5313 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5314 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5315 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5316 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5317 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5318   l2tpv3_interface_enable_disable_reply)                                \
5319 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5320 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5321 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5322 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5323 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5324 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5325 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5326 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5327 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5328 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5329 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5330 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5331 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5332 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5333 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5334 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5335 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5336 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5337 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5338 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5339 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5340 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5341 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5342 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5343 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5344 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5345 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5346 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5347 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5348 _(L2_MACS_EVENT, l2_macs_event)                                         \
5349 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5350 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5351 _(IP_DETAILS, ip_details)                                               \
5352 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5353 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5354 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5355 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5356 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5357 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5358 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5359 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5360 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5361 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5362 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5363 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5364 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5365 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5366 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5367 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5368 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5369 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5370 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5371 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5372 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5373 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5374 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5375 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5376 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5377 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5378 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5379 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5380   one_map_register_enable_disable_reply)                                \
5381 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5382 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5383 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5384 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5385   one_map_register_fallback_threshold_reply)                            \
5386 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5387   one_rloc_probe_enable_disable_reply)                                  \
5388 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5389 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5390 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5391 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5392 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5393 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5394 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5395 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5396 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5397 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5398 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5399 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5400 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5401 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5402 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5403 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5404   show_one_stats_enable_disable_reply)                                  \
5405 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5406 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5407 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5408 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5409 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5410 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5411 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5412 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5413   one_enable_disable_pitr_mode_reply)                                   \
5414 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5415   one_enable_disable_petr_mode_reply)                                   \
5416 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5417 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5418 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5419 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5420 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5421 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5422 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5423 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5424 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5425 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5426 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5427 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5428   gpe_add_del_native_fwd_rpath_reply)                                   \
5429 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5430   gpe_fwd_entry_path_details)                                           \
5431 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5432 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5433   one_add_del_map_request_itr_rlocs_reply)                              \
5434 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5435   one_get_map_request_itr_rlocs_reply)                                  \
5436 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5437 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5438 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5439 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5440 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5442   show_one_map_register_state_reply)                                    \
5443 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5444 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5445   show_one_map_register_fallback_threshold_reply)                       \
5446 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5447 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5448 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5449 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5450 _(POLICER_DETAILS, policer_details)                                     \
5451 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5452 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5453 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5454 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5455 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5456 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5457 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5458 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5459 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5460 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5461 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5462 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5463 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5464 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5465 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5466 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5467 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5468 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5469 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5470 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5471 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5472 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5473 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5474 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5475 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5476 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5477  ip_source_and_port_range_check_add_del_reply)                          \
5478 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5479  ip_source_and_port_range_check_interface_add_del_reply)                \
5480 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5481 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5482 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5483 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5484 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5485 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5486 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5487 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5488 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5489 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5490 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5491 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5492 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5493 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5494 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5495 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5496 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5497 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5498 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5499 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5500 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5501 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5502 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5503
5504 #define foreach_standalone_reply_msg                                    \
5505 _(SW_INTERFACE_EVENT, sw_interface_event)
5506
5507 typedef struct
5508 {
5509   u8 *name;
5510   u32 value;
5511 } name_sort_t;
5512
5513 #define STR_VTR_OP_CASE(op)     \
5514     case L2_VTR_ ## op:         \
5515         return "" # op;
5516
5517 static const char *
5518 str_vtr_op (u32 vtr_op)
5519 {
5520   switch (vtr_op)
5521     {
5522       STR_VTR_OP_CASE (DISABLED);
5523       STR_VTR_OP_CASE (PUSH_1);
5524       STR_VTR_OP_CASE (PUSH_2);
5525       STR_VTR_OP_CASE (POP_1);
5526       STR_VTR_OP_CASE (POP_2);
5527       STR_VTR_OP_CASE (TRANSLATE_1_1);
5528       STR_VTR_OP_CASE (TRANSLATE_1_2);
5529       STR_VTR_OP_CASE (TRANSLATE_2_1);
5530       STR_VTR_OP_CASE (TRANSLATE_2_2);
5531     }
5532
5533   return "UNKNOWN";
5534 }
5535
5536 static int
5537 dump_sub_interface_table (vat_main_t * vam)
5538 {
5539   const sw_interface_subif_t *sub = NULL;
5540
5541   if (vam->json_output)
5542     {
5543       clib_warning
5544         ("JSON output supported only for VPE API calls and dump_stats_table");
5545       return -99;
5546     }
5547
5548   print (vam->ofp,
5549          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5550          "Interface", "sw_if_index",
5551          "sub id", "dot1ad", "tags", "outer id",
5552          "inner id", "exact", "default", "outer any", "inner any");
5553
5554   vec_foreach (sub, vam->sw_if_subif_table)
5555   {
5556     print (vam->ofp,
5557            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5558            sub->interface_name,
5559            sub->sw_if_index,
5560            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5561            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5562            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5563            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5564     if (sub->vtr_op != L2_VTR_DISABLED)
5565       {
5566         print (vam->ofp,
5567                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5568                "tag1: %d tag2: %d ]",
5569                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5570                sub->vtr_tag1, sub->vtr_tag2);
5571       }
5572   }
5573
5574   return 0;
5575 }
5576
5577 static int
5578 name_sort_cmp (void *a1, void *a2)
5579 {
5580   name_sort_t *n1 = a1;
5581   name_sort_t *n2 = a2;
5582
5583   return strcmp ((char *) n1->name, (char *) n2->name);
5584 }
5585
5586 static int
5587 dump_interface_table (vat_main_t * vam)
5588 {
5589   hash_pair_t *p;
5590   name_sort_t *nses = 0, *ns;
5591
5592   if (vam->json_output)
5593     {
5594       clib_warning
5595         ("JSON output supported only for VPE API calls and dump_stats_table");
5596       return -99;
5597     }
5598
5599   /* *INDENT-OFF* */
5600   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5601   ({
5602     vec_add2 (nses, ns, 1);
5603     ns->name = (u8 *)(p->key);
5604     ns->value = (u32) p->value[0];
5605   }));
5606   /* *INDENT-ON* */
5607
5608   vec_sort_with_function (nses, name_sort_cmp);
5609
5610   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5611   vec_foreach (ns, nses)
5612   {
5613     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5614   }
5615   vec_free (nses);
5616   return 0;
5617 }
5618
5619 static int
5620 dump_ip_table (vat_main_t * vam, int is_ipv6)
5621 {
5622   const ip_details_t *det = NULL;
5623   const ip_address_details_t *address = NULL;
5624   u32 i = ~0;
5625
5626   print (vam->ofp, "%-12s", "sw_if_index");
5627
5628   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5629   {
5630     i++;
5631     if (!det->present)
5632       {
5633         continue;
5634       }
5635     print (vam->ofp, "%-12d", i);
5636     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5637     if (!det->addr)
5638       {
5639         continue;
5640       }
5641     vec_foreach (address, det->addr)
5642     {
5643       print (vam->ofp,
5644              "            %-30U%-13d",
5645              is_ipv6 ? format_ip6_address : format_ip4_address,
5646              address->ip, address->prefix_length);
5647     }
5648   }
5649
5650   return 0;
5651 }
5652
5653 static int
5654 dump_ipv4_table (vat_main_t * vam)
5655 {
5656   if (vam->json_output)
5657     {
5658       clib_warning
5659         ("JSON output supported only for VPE API calls and dump_stats_table");
5660       return -99;
5661     }
5662
5663   return dump_ip_table (vam, 0);
5664 }
5665
5666 static int
5667 dump_ipv6_table (vat_main_t * vam)
5668 {
5669   if (vam->json_output)
5670     {
5671       clib_warning
5672         ("JSON output supported only for VPE API calls and dump_stats_table");
5673       return -99;
5674     }
5675
5676   return dump_ip_table (vam, 1);
5677 }
5678
5679 /*
5680  * Pass CLI buffers directly in the CLI_INBAND API message,
5681  * instead of an additional shared memory area.
5682  */
5683 static int
5684 exec_inband (vat_main_t * vam)
5685 {
5686   vl_api_cli_inband_t *mp;
5687   unformat_input_t *i = vam->input;
5688   int ret;
5689
5690   if (vec_len (i->buffer) == 0)
5691     return -1;
5692
5693   if (vam->exec_mode == 0 && unformat (i, "mode"))
5694     {
5695       vam->exec_mode = 1;
5696       return 0;
5697     }
5698   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5699     {
5700       vam->exec_mode = 0;
5701       return 0;
5702     }
5703
5704   /*
5705    * In order for the CLI command to work, it
5706    * must be a vector ending in \n, not a C-string ending
5707    * in \n\0.
5708    */
5709   u32 len = vec_len (vam->input->buffer);
5710   M2 (CLI_INBAND, mp, len);
5711   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5712
5713   S (mp);
5714   W (ret);
5715   /* json responses may or may not include a useful reply... */
5716   if (vec_len (vam->cmd_reply))
5717     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5718   return ret;
5719 }
5720
5721 int
5722 exec (vat_main_t * vam)
5723 {
5724   return exec_inband (vam);
5725 }
5726
5727 static int
5728 api_create_loopback (vat_main_t * vam)
5729 {
5730   unformat_input_t *i = vam->input;
5731   vl_api_create_loopback_t *mp;
5732   vl_api_create_loopback_instance_t *mp_lbi;
5733   u8 mac_address[6];
5734   u8 mac_set = 0;
5735   u8 is_specified = 0;
5736   u32 user_instance = 0;
5737   int ret;
5738
5739   clib_memset (mac_address, 0, sizeof (mac_address));
5740
5741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5742     {
5743       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5744         mac_set = 1;
5745       if (unformat (i, "instance %d", &user_instance))
5746         is_specified = 1;
5747       else
5748         break;
5749     }
5750
5751   if (is_specified)
5752     {
5753       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5754       mp_lbi->is_specified = is_specified;
5755       if (is_specified)
5756         mp_lbi->user_instance = htonl (user_instance);
5757       if (mac_set)
5758         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5759       S (mp_lbi);
5760     }
5761   else
5762     {
5763       /* Construct the API message */
5764       M (CREATE_LOOPBACK, mp);
5765       if (mac_set)
5766         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5767       S (mp);
5768     }
5769
5770   W (ret);
5771   return ret;
5772 }
5773
5774 static int
5775 api_delete_loopback (vat_main_t * vam)
5776 {
5777   unformat_input_t *i = vam->input;
5778   vl_api_delete_loopback_t *mp;
5779   u32 sw_if_index = ~0;
5780   int ret;
5781
5782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5783     {
5784       if (unformat (i, "sw_if_index %d", &sw_if_index))
5785         ;
5786       else
5787         break;
5788     }
5789
5790   if (sw_if_index == ~0)
5791     {
5792       errmsg ("missing sw_if_index");
5793       return -99;
5794     }
5795
5796   /* Construct the API message */
5797   M (DELETE_LOOPBACK, mp);
5798   mp->sw_if_index = ntohl (sw_if_index);
5799
5800   S (mp);
5801   W (ret);
5802   return ret;
5803 }
5804
5805 static int
5806 api_want_interface_events (vat_main_t * vam)
5807 {
5808   unformat_input_t *i = vam->input;
5809   vl_api_want_interface_events_t *mp;
5810   int enable = -1;
5811   int ret;
5812
5813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5814     {
5815       if (unformat (i, "enable"))
5816         enable = 1;
5817       else if (unformat (i, "disable"))
5818         enable = 0;
5819       else
5820         break;
5821     }
5822
5823   if (enable == -1)
5824     {
5825       errmsg ("missing enable|disable");
5826       return -99;
5827     }
5828
5829   M (WANT_INTERFACE_EVENTS, mp);
5830   mp->enable_disable = enable;
5831
5832   vam->interface_event_display = enable;
5833
5834   S (mp);
5835   W (ret);
5836   return ret;
5837 }
5838
5839
5840 /* Note: non-static, called once to set up the initial intfc table */
5841 int
5842 api_sw_interface_dump (vat_main_t * vam)
5843 {
5844   vl_api_sw_interface_dump_t *mp;
5845   vl_api_control_ping_t *mp_ping;
5846   hash_pair_t *p;
5847   name_sort_t *nses = 0, *ns;
5848   sw_interface_subif_t *sub = NULL;
5849   int ret;
5850
5851   /* Toss the old name table */
5852   /* *INDENT-OFF* */
5853   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5854   ({
5855     vec_add2 (nses, ns, 1);
5856     ns->name = (u8 *)(p->key);
5857     ns->value = (u32) p->value[0];
5858   }));
5859   /* *INDENT-ON* */
5860
5861   hash_free (vam->sw_if_index_by_interface_name);
5862
5863   vec_foreach (ns, nses) vec_free (ns->name);
5864
5865   vec_free (nses);
5866
5867   vec_foreach (sub, vam->sw_if_subif_table)
5868   {
5869     vec_free (sub->interface_name);
5870   }
5871   vec_free (vam->sw_if_subif_table);
5872
5873   /* recreate the interface name hash table */
5874   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5875
5876   /*
5877    * Ask for all interface names. Otherwise, the epic catalog of
5878    * name filters becomes ridiculously long, and vat ends up needing
5879    * to be taught about new interface types.
5880    */
5881   M (SW_INTERFACE_DUMP, mp);
5882   S (mp);
5883
5884   /* Use a control ping for synchronization */
5885   MPING (CONTROL_PING, mp_ping);
5886   S (mp_ping);
5887
5888   W (ret);
5889   return ret;
5890 }
5891
5892 static int
5893 api_sw_interface_set_flags (vat_main_t * vam)
5894 {
5895   unformat_input_t *i = vam->input;
5896   vl_api_sw_interface_set_flags_t *mp;
5897   u32 sw_if_index;
5898   u8 sw_if_index_set = 0;
5899   u8 admin_up = 0;
5900   int ret;
5901
5902   /* Parse args required to build the message */
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "admin-up"))
5906         admin_up = 1;
5907       else if (unformat (i, "admin-down"))
5908         admin_up = 0;
5909       else
5910         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5911         sw_if_index_set = 1;
5912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5913         sw_if_index_set = 1;
5914       else
5915         break;
5916     }
5917
5918   if (sw_if_index_set == 0)
5919     {
5920       errmsg ("missing interface name or sw_if_index");
5921       return -99;
5922     }
5923
5924   /* Construct the API message */
5925   M (SW_INTERFACE_SET_FLAGS, mp);
5926   mp->sw_if_index = ntohl (sw_if_index);
5927   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5928
5929   /* send it... */
5930   S (mp);
5931
5932   /* Wait for a reply, return the good/bad news... */
5933   W (ret);
5934   return ret;
5935 }
5936
5937 static int
5938 api_sw_interface_set_rx_mode (vat_main_t * vam)
5939 {
5940   unformat_input_t *i = vam->input;
5941   vl_api_sw_interface_set_rx_mode_t *mp;
5942   u32 sw_if_index;
5943   u8 sw_if_index_set = 0;
5944   int ret;
5945   u8 queue_id_valid = 0;
5946   u32 queue_id;
5947   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5948
5949   /* Parse args required to build the message */
5950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5951     {
5952       if (unformat (i, "queue %d", &queue_id))
5953         queue_id_valid = 1;
5954       else if (unformat (i, "polling"))
5955         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5956       else if (unformat (i, "interrupt"))
5957         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5958       else if (unformat (i, "adaptive"))
5959         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5960       else
5961         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5962         sw_if_index_set = 1;
5963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5964         sw_if_index_set = 1;
5965       else
5966         break;
5967     }
5968
5969   if (sw_if_index_set == 0)
5970     {
5971       errmsg ("missing interface name or sw_if_index");
5972       return -99;
5973     }
5974   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5975     {
5976       errmsg ("missing rx-mode");
5977       return -99;
5978     }
5979
5980   /* Construct the API message */
5981   M (SW_INTERFACE_SET_RX_MODE, mp);
5982   mp->sw_if_index = ntohl (sw_if_index);
5983   mp->mode = (vl_api_rx_mode_t) mode;
5984   mp->queue_id_valid = queue_id_valid;
5985   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5986
5987   /* send it... */
5988   S (mp);
5989
5990   /* Wait for a reply, return the good/bad news... */
5991   W (ret);
5992   return ret;
5993 }
5994
5995 static int
5996 api_sw_interface_set_rx_placement (vat_main_t * vam)
5997 {
5998   unformat_input_t *i = vam->input;
5999   vl_api_sw_interface_set_rx_placement_t *mp;
6000   u32 sw_if_index;
6001   u8 sw_if_index_set = 0;
6002   int ret;
6003   u8 is_main = 0;
6004   u32 queue_id, thread_index;
6005
6006   /* Parse args required to build the message */
6007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6008     {
6009       if (unformat (i, "queue %d", &queue_id))
6010         ;
6011       else if (unformat (i, "main"))
6012         is_main = 1;
6013       else if (unformat (i, "worker %d", &thread_index))
6014         ;
6015       else
6016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6017         sw_if_index_set = 1;
6018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6019         sw_if_index_set = 1;
6020       else
6021         break;
6022     }
6023
6024   if (sw_if_index_set == 0)
6025     {
6026       errmsg ("missing interface name or sw_if_index");
6027       return -99;
6028     }
6029
6030   if (is_main)
6031     thread_index = 0;
6032   /* Construct the API message */
6033   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6034   mp->sw_if_index = ntohl (sw_if_index);
6035   mp->worker_id = ntohl (thread_index);
6036   mp->queue_id = ntohl (queue_id);
6037   mp->is_main = is_main;
6038
6039   /* send it... */
6040   S (mp);
6041   /* Wait for a reply, return the good/bad news... */
6042   W (ret);
6043   return ret;
6044 }
6045
6046 static void vl_api_sw_interface_rx_placement_details_t_handler
6047   (vl_api_sw_interface_rx_placement_details_t * mp)
6048 {
6049   vat_main_t *vam = &vat_main;
6050   u32 worker_id = ntohl (mp->worker_id);
6051
6052   print (vam->ofp,
6053          "\n%-11d %-11s %-6d %-5d %-9s",
6054          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6055          worker_id, ntohl (mp->queue_id),
6056          (mp->mode ==
6057           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6058 }
6059
6060 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6061   (vl_api_sw_interface_rx_placement_details_t * mp)
6062 {
6063   vat_main_t *vam = &vat_main;
6064   vat_json_node_t *node = NULL;
6065
6066   if (VAT_JSON_ARRAY != vam->json_tree.type)
6067     {
6068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6069       vat_json_init_array (&vam->json_tree);
6070     }
6071   node = vat_json_array_add (&vam->json_tree);
6072
6073   vat_json_init_object (node);
6074   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6075   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6076   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6077   vat_json_object_add_uint (node, "mode", mp->mode);
6078 }
6079
6080 static int
6081 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6082 {
6083   unformat_input_t *i = vam->input;
6084   vl_api_sw_interface_rx_placement_dump_t *mp;
6085   vl_api_control_ping_t *mp_ping;
6086   int ret;
6087   u32 sw_if_index;
6088   u8 sw_if_index_set = 0;
6089
6090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6091     {
6092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093         sw_if_index_set++;
6094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6095         sw_if_index_set++;
6096       else
6097         break;
6098     }
6099
6100   print (vam->ofp,
6101          "\n%-11s %-11s %-6s %-5s %-4s",
6102          "sw_if_index", "main/worker", "thread", "queue", "mode");
6103
6104   /* Dump Interface rx placement */
6105   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6106
6107   if (sw_if_index_set)
6108     mp->sw_if_index = htonl (sw_if_index);
6109   else
6110     mp->sw_if_index = ~0;
6111
6112   S (mp);
6113
6114   /* Use a control ping for synchronization */
6115   MPING (CONTROL_PING, mp_ping);
6116   S (mp_ping);
6117
6118   W (ret);
6119   return ret;
6120 }
6121
6122 static int
6123 api_sw_interface_clear_stats (vat_main_t * vam)
6124 {
6125   unformat_input_t *i = vam->input;
6126   vl_api_sw_interface_clear_stats_t *mp;
6127   u32 sw_if_index;
6128   u8 sw_if_index_set = 0;
6129   int ret;
6130
6131   /* Parse args required to build the message */
6132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6133     {
6134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6137         sw_if_index_set = 1;
6138       else
6139         break;
6140     }
6141
6142   /* Construct the API message */
6143   M (SW_INTERFACE_CLEAR_STATS, mp);
6144
6145   if (sw_if_index_set == 1)
6146     mp->sw_if_index = ntohl (sw_if_index);
6147   else
6148     mp->sw_if_index = ~0;
6149
6150   /* send it... */
6151   S (mp);
6152
6153   /* Wait for a reply, return the good/bad news... */
6154   W (ret);
6155   return ret;
6156 }
6157
6158 static int
6159 api_sw_interface_add_del_address (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_sw_interface_add_del_address_t *mp;
6163   u32 sw_if_index;
6164   u8 sw_if_index_set = 0;
6165   u8 is_add = 1, del_all = 0;
6166   u32 address_length = 0;
6167   u8 v4_address_set = 0;
6168   u8 v6_address_set = 0;
6169   ip4_address_t v4address;
6170   ip6_address_t v6address;
6171   int ret;
6172
6173   /* Parse args required to build the message */
6174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6175     {
6176       if (unformat (i, "del-all"))
6177         del_all = 1;
6178       else if (unformat (i, "del"))
6179         is_add = 0;
6180       else
6181         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6182         sw_if_index_set = 1;
6183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6184         sw_if_index_set = 1;
6185       else if (unformat (i, "%U/%d",
6186                          unformat_ip4_address, &v4address, &address_length))
6187         v4_address_set = 1;
6188       else if (unformat (i, "%U/%d",
6189                          unformat_ip6_address, &v6address, &address_length))
6190         v6_address_set = 1;
6191       else
6192         break;
6193     }
6194
6195   if (sw_if_index_set == 0)
6196     {
6197       errmsg ("missing interface name or sw_if_index");
6198       return -99;
6199     }
6200   if (v4_address_set && v6_address_set)
6201     {
6202       errmsg ("both v4 and v6 addresses set");
6203       return -99;
6204     }
6205   if (!v4_address_set && !v6_address_set && !del_all)
6206     {
6207       errmsg ("no addresses set");
6208       return -99;
6209     }
6210
6211   /* Construct the API message */
6212   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6213
6214   mp->sw_if_index = ntohl (sw_if_index);
6215   mp->is_add = is_add;
6216   mp->del_all = del_all;
6217   if (v6_address_set)
6218     {
6219       mp->prefix.address.af = ADDRESS_IP6;
6220       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6221     }
6222   else
6223     {
6224       mp->prefix.address.af = ADDRESS_IP4;
6225       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6226     }
6227   mp->prefix.len = address_length;
6228
6229   /* send it... */
6230   S (mp);
6231
6232   /* Wait for a reply, return good/bad news  */
6233   W (ret);
6234   return ret;
6235 }
6236
6237 static int
6238 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_sw_interface_set_mpls_enable_t *mp;
6242   u32 sw_if_index;
6243   u8 sw_if_index_set = 0;
6244   u8 enable = 1;
6245   int ret;
6246
6247   /* Parse args required to build the message */
6248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6249     {
6250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6251         sw_if_index_set = 1;
6252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "disable"))
6255         enable = 0;
6256       else if (unformat (i, "dis"))
6257         enable = 0;
6258       else
6259         break;
6260     }
6261
6262   if (sw_if_index_set == 0)
6263     {
6264       errmsg ("missing interface name or sw_if_index");
6265       return -99;
6266     }
6267
6268   /* Construct the API message */
6269   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6270
6271   mp->sw_if_index = ntohl (sw_if_index);
6272   mp->enable = enable;
6273
6274   /* send it... */
6275   S (mp);
6276
6277   /* Wait for a reply... */
6278   W (ret);
6279   return ret;
6280 }
6281
6282 static int
6283 api_sw_interface_set_table (vat_main_t * vam)
6284 {
6285   unformat_input_t *i = vam->input;
6286   vl_api_sw_interface_set_table_t *mp;
6287   u32 sw_if_index, vrf_id = 0;
6288   u8 sw_if_index_set = 0;
6289   u8 is_ipv6 = 0;
6290   int ret;
6291
6292   /* Parse args required to build the message */
6293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6294     {
6295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6296         sw_if_index_set = 1;
6297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "vrf %d", &vrf_id))
6300         ;
6301       else if (unformat (i, "ipv6"))
6302         is_ipv6 = 1;
6303       else
6304         break;
6305     }
6306
6307   if (sw_if_index_set == 0)
6308     {
6309       errmsg ("missing interface name or sw_if_index");
6310       return -99;
6311     }
6312
6313   /* Construct the API message */
6314   M (SW_INTERFACE_SET_TABLE, mp);
6315
6316   mp->sw_if_index = ntohl (sw_if_index);
6317   mp->is_ipv6 = is_ipv6;
6318   mp->vrf_id = ntohl (vrf_id);
6319
6320   /* send it... */
6321   S (mp);
6322
6323   /* Wait for a reply... */
6324   W (ret);
6325   return ret;
6326 }
6327
6328 static void vl_api_sw_interface_get_table_reply_t_handler
6329   (vl_api_sw_interface_get_table_reply_t * mp)
6330 {
6331   vat_main_t *vam = &vat_main;
6332
6333   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6334
6335   vam->retval = ntohl (mp->retval);
6336   vam->result_ready = 1;
6337
6338 }
6339
6340 static void vl_api_sw_interface_get_table_reply_t_handler_json
6341   (vl_api_sw_interface_get_table_reply_t * mp)
6342 {
6343   vat_main_t *vam = &vat_main;
6344   vat_json_node_t node;
6345
6346   vat_json_init_object (&node);
6347   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6348   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6349
6350   vat_json_print (vam->ofp, &node);
6351   vat_json_free (&node);
6352
6353   vam->retval = ntohl (mp->retval);
6354   vam->result_ready = 1;
6355 }
6356
6357 static int
6358 api_sw_interface_get_table (vat_main_t * vam)
6359 {
6360   unformat_input_t *i = vam->input;
6361   vl_api_sw_interface_get_table_t *mp;
6362   u32 sw_if_index;
6363   u8 sw_if_index_set = 0;
6364   u8 is_ipv6 = 0;
6365   int ret;
6366
6367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6368     {
6369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "ipv6"))
6374         is_ipv6 = 1;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index_set == 0)
6380     {
6381       errmsg ("missing interface name or sw_if_index");
6382       return -99;
6383     }
6384
6385   M (SW_INTERFACE_GET_TABLE, mp);
6386   mp->sw_if_index = htonl (sw_if_index);
6387   mp->is_ipv6 = is_ipv6;
6388
6389   S (mp);
6390   W (ret);
6391   return ret;
6392 }
6393
6394 static int
6395 api_sw_interface_set_vpath (vat_main_t * vam)
6396 {
6397   unformat_input_t *i = vam->input;
6398   vl_api_sw_interface_set_vpath_t *mp;
6399   u32 sw_if_index = 0;
6400   u8 sw_if_index_set = 0;
6401   u8 is_enable = 0;
6402   int ret;
6403
6404   /* Parse args required to build the message */
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "enable"))
6412         is_enable = 1;
6413       else if (unformat (i, "disable"))
6414         is_enable = 0;
6415       else
6416         break;
6417     }
6418
6419   if (sw_if_index_set == 0)
6420     {
6421       errmsg ("missing interface name or sw_if_index");
6422       return -99;
6423     }
6424
6425   /* Construct the API message */
6426   M (SW_INTERFACE_SET_VPATH, mp);
6427
6428   mp->sw_if_index = ntohl (sw_if_index);
6429   mp->enable = is_enable;
6430
6431   /* send it... */
6432   S (mp);
6433
6434   /* Wait for a reply... */
6435   W (ret);
6436   return ret;
6437 }
6438
6439 static int
6440 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6441 {
6442   unformat_input_t *i = vam->input;
6443   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6444   u32 sw_if_index = 0;
6445   u8 sw_if_index_set = 0;
6446   u8 is_enable = 1;
6447   u8 is_ipv6 = 0;
6448   int ret;
6449
6450   /* Parse args required to build the message */
6451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6452     {
6453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6454         sw_if_index_set = 1;
6455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "enable"))
6458         is_enable = 1;
6459       else if (unformat (i, "disable"))
6460         is_enable = 0;
6461       else if (unformat (i, "ip4"))
6462         is_ipv6 = 0;
6463       else if (unformat (i, "ip6"))
6464         is_ipv6 = 1;
6465       else
6466         break;
6467     }
6468
6469   if (sw_if_index_set == 0)
6470     {
6471       errmsg ("missing interface name or sw_if_index");
6472       return -99;
6473     }
6474
6475   /* Construct the API message */
6476   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6477
6478   mp->sw_if_index = ntohl (sw_if_index);
6479   mp->enable = is_enable;
6480   mp->is_ipv6 = is_ipv6;
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static int
6491 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6492 {
6493   unformat_input_t *i = vam->input;
6494   vl_api_sw_interface_set_geneve_bypass_t *mp;
6495   u32 sw_if_index = 0;
6496   u8 sw_if_index_set = 0;
6497   u8 is_enable = 1;
6498   u8 is_ipv6 = 0;
6499   int ret;
6500
6501   /* Parse args required to build the message */
6502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6503     {
6504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6505         sw_if_index_set = 1;
6506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6507         sw_if_index_set = 1;
6508       else if (unformat (i, "enable"))
6509         is_enable = 1;
6510       else if (unformat (i, "disable"))
6511         is_enable = 0;
6512       else if (unformat (i, "ip4"))
6513         is_ipv6 = 0;
6514       else if (unformat (i, "ip6"))
6515         is_ipv6 = 1;
6516       else
6517         break;
6518     }
6519
6520   if (sw_if_index_set == 0)
6521     {
6522       errmsg ("missing interface name or sw_if_index");
6523       return -99;
6524     }
6525
6526   /* Construct the API message */
6527   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6528
6529   mp->sw_if_index = ntohl (sw_if_index);
6530   mp->enable = is_enable;
6531   mp->is_ipv6 = is_ipv6;
6532
6533   /* send it... */
6534   S (mp);
6535
6536   /* Wait for a reply... */
6537   W (ret);
6538   return ret;
6539 }
6540
6541 static int
6542 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6543 {
6544   unformat_input_t *i = vam->input;
6545   vl_api_sw_interface_set_l2_xconnect_t *mp;
6546   u32 rx_sw_if_index;
6547   u8 rx_sw_if_index_set = 0;
6548   u32 tx_sw_if_index;
6549   u8 tx_sw_if_index_set = 0;
6550   u8 enable = 1;
6551   int ret;
6552
6553   /* Parse args required to build the message */
6554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6555     {
6556       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6557         rx_sw_if_index_set = 1;
6558       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6559         tx_sw_if_index_set = 1;
6560       else if (unformat (i, "rx"))
6561         {
6562           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6563             {
6564               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6565                             &rx_sw_if_index))
6566                 rx_sw_if_index_set = 1;
6567             }
6568           else
6569             break;
6570         }
6571       else if (unformat (i, "tx"))
6572         {
6573           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574             {
6575               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6576                             &tx_sw_if_index))
6577                 tx_sw_if_index_set = 1;
6578             }
6579           else
6580             break;
6581         }
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or rx_sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (tx_sw_if_index_set == 0))
6597     {
6598       errmsg ("missing tx interface name or tx_sw_if_index");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6606   mp->enable = enable;
6607
6608   S (mp);
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_l2_bridge_t *mp;
6618   vl_api_l2_port_type_t port_type;
6619   u32 rx_sw_if_index;
6620   u8 rx_sw_if_index_set = 0;
6621   u32 bd_id;
6622   u8 bd_id_set = 0;
6623   u32 shg = 0;
6624   u8 enable = 1;
6625   int ret;
6626
6627   port_type = L2_API_PORT_TYPE_NORMAL;
6628
6629   /* Parse args required to build the message */
6630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6631     {
6632       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6633         rx_sw_if_index_set = 1;
6634       else if (unformat (i, "bd_id %d", &bd_id))
6635         bd_id_set = 1;
6636       else
6637         if (unformat
6638             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6639         rx_sw_if_index_set = 1;
6640       else if (unformat (i, "shg %d", &shg))
6641         ;
6642       else if (unformat (i, "bvi"))
6643         port_type = L2_API_PORT_TYPE_BVI;
6644       else if (unformat (i, "uu-fwd"))
6645         port_type = L2_API_PORT_TYPE_UU_FWD;
6646       else if (unformat (i, "enable"))
6647         enable = 1;
6648       else if (unformat (i, "disable"))
6649         enable = 0;
6650       else
6651         break;
6652     }
6653
6654   if (rx_sw_if_index_set == 0)
6655     {
6656       errmsg ("missing rx interface name or sw_if_index");
6657       return -99;
6658     }
6659
6660   if (enable && (bd_id_set == 0))
6661     {
6662       errmsg ("missing bridge domain");
6663       return -99;
6664     }
6665
6666   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6667
6668   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6669   mp->bd_id = ntohl (bd_id);
6670   mp->shg = (u8) shg;
6671   mp->port_type = ntohl (port_type);
6672   mp->enable = enable;
6673
6674   S (mp);
6675   W (ret);
6676   return ret;
6677 }
6678
6679 static int
6680 api_bridge_domain_dump (vat_main_t * vam)
6681 {
6682   unformat_input_t *i = vam->input;
6683   vl_api_bridge_domain_dump_t *mp;
6684   vl_api_control_ping_t *mp_ping;
6685   u32 bd_id = ~0;
6686   int ret;
6687
6688   /* Parse args required to build the message */
6689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6690     {
6691       if (unformat (i, "bd_id %d", &bd_id))
6692         ;
6693       else
6694         break;
6695     }
6696
6697   M (BRIDGE_DOMAIN_DUMP, mp);
6698   mp->bd_id = ntohl (bd_id);
6699   S (mp);
6700
6701   /* Use a control ping for synchronization */
6702   MPING (CONTROL_PING, mp_ping);
6703   S (mp_ping);
6704
6705   W (ret);
6706   return ret;
6707 }
6708
6709 static int
6710 api_bridge_domain_add_del (vat_main_t * vam)
6711 {
6712   unformat_input_t *i = vam->input;
6713   vl_api_bridge_domain_add_del_t *mp;
6714   u32 bd_id = ~0;
6715   u8 is_add = 1;
6716   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6717   u8 *bd_tag = NULL;
6718   u32 mac_age = 0;
6719   int ret;
6720
6721   /* Parse args required to build the message */
6722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6723     {
6724       if (unformat (i, "bd_id %d", &bd_id))
6725         ;
6726       else if (unformat (i, "flood %d", &flood))
6727         ;
6728       else if (unformat (i, "uu-flood %d", &uu_flood))
6729         ;
6730       else if (unformat (i, "forward %d", &forward))
6731         ;
6732       else if (unformat (i, "learn %d", &learn))
6733         ;
6734       else if (unformat (i, "arp-term %d", &arp_term))
6735         ;
6736       else if (unformat (i, "mac-age %d", &mac_age))
6737         ;
6738       else if (unformat (i, "bd-tag %s", &bd_tag))
6739         ;
6740       else if (unformat (i, "del"))
6741         {
6742           is_add = 0;
6743           flood = uu_flood = forward = learn = 0;
6744         }
6745       else
6746         break;
6747     }
6748
6749   if (bd_id == ~0)
6750     {
6751       errmsg ("missing bridge domain");
6752       ret = -99;
6753       goto done;
6754     }
6755
6756   if (mac_age > 255)
6757     {
6758       errmsg ("mac age must be less than 256 ");
6759       ret = -99;
6760       goto done;
6761     }
6762
6763   if ((bd_tag) && (vec_len (bd_tag) > 63))
6764     {
6765       errmsg ("bd-tag cannot be longer than 63");
6766       ret = -99;
6767       goto done;
6768     }
6769
6770   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6771
6772   mp->bd_id = ntohl (bd_id);
6773   mp->flood = flood;
6774   mp->uu_flood = uu_flood;
6775   mp->forward = forward;
6776   mp->learn = learn;
6777   mp->arp_term = arp_term;
6778   mp->is_add = is_add;
6779   mp->mac_age = (u8) mac_age;
6780   if (bd_tag)
6781     {
6782       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6783       mp->bd_tag[vec_len (bd_tag)] = 0;
6784     }
6785   S (mp);
6786   W (ret);
6787
6788 done:
6789   vec_free (bd_tag);
6790   return ret;
6791 }
6792
6793 static int
6794 api_l2fib_flush_bd (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_l2fib_flush_bd_t *mp;
6798   u32 bd_id = ~0;
6799   int ret;
6800
6801   /* Parse args required to build the message */
6802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6803     {
6804       if (unformat (i, "bd_id %d", &bd_id));
6805       else
6806         break;
6807     }
6808
6809   if (bd_id == ~0)
6810     {
6811       errmsg ("missing bridge domain");
6812       return -99;
6813     }
6814
6815   M (L2FIB_FLUSH_BD, mp);
6816
6817   mp->bd_id = htonl (bd_id);
6818
6819   S (mp);
6820   W (ret);
6821   return ret;
6822 }
6823
6824 static int
6825 api_l2fib_flush_int (vat_main_t * vam)
6826 {
6827   unformat_input_t *i = vam->input;
6828   vl_api_l2fib_flush_int_t *mp;
6829   u32 sw_if_index = ~0;
6830   int ret;
6831
6832   /* Parse args required to build the message */
6833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6834     {
6835       if (unformat (i, "sw_if_index %d", &sw_if_index));
6836       else
6837         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6838       else
6839         break;
6840     }
6841
6842   if (sw_if_index == ~0)
6843     {
6844       errmsg ("missing interface name or sw_if_index");
6845       return -99;
6846     }
6847
6848   M (L2FIB_FLUSH_INT, mp);
6849
6850   mp->sw_if_index = ntohl (sw_if_index);
6851
6852   S (mp);
6853   W (ret);
6854   return ret;
6855 }
6856
6857 static int
6858 api_l2fib_add_del (vat_main_t * vam)
6859 {
6860   unformat_input_t *i = vam->input;
6861   vl_api_l2fib_add_del_t *mp;
6862   f64 timeout;
6863   u8 mac[6] = { 0 };
6864   u8 mac_set = 0;
6865   u32 bd_id;
6866   u8 bd_id_set = 0;
6867   u32 sw_if_index = 0;
6868   u8 sw_if_index_set = 0;
6869   u8 is_add = 1;
6870   u8 static_mac = 0;
6871   u8 filter_mac = 0;
6872   u8 bvi_mac = 0;
6873   int count = 1;
6874   f64 before = 0;
6875   int j;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6881         mac_set = 1;
6882       else if (unformat (i, "bd_id %d", &bd_id))
6883         bd_id_set = 1;
6884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6885         sw_if_index_set = 1;
6886       else if (unformat (i, "sw_if"))
6887         {
6888           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6889             {
6890               if (unformat
6891                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6892                 sw_if_index_set = 1;
6893             }
6894           else
6895             break;
6896         }
6897       else if (unformat (i, "static"))
6898         static_mac = 1;
6899       else if (unformat (i, "filter"))
6900         {
6901           filter_mac = 1;
6902           static_mac = 1;
6903         }
6904       else if (unformat (i, "bvi"))
6905         {
6906           bvi_mac = 1;
6907           static_mac = 1;
6908         }
6909       else if (unformat (i, "del"))
6910         is_add = 0;
6911       else if (unformat (i, "count %d", &count))
6912         ;
6913       else
6914         break;
6915     }
6916
6917   if (mac_set == 0)
6918     {
6919       errmsg ("missing mac address");
6920       return -99;
6921     }
6922
6923   if (bd_id_set == 0)
6924     {
6925       errmsg ("missing bridge domain");
6926       return -99;
6927     }
6928
6929   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6930     {
6931       errmsg ("missing interface name or sw_if_index");
6932       return -99;
6933     }
6934
6935   if (count > 1)
6936     {
6937       /* Turn on async mode */
6938       vam->async_mode = 1;
6939       vam->async_errors = 0;
6940       before = vat_time_now (vam);
6941     }
6942
6943   for (j = 0; j < count; j++)
6944     {
6945       M (L2FIB_ADD_DEL, mp);
6946
6947       clib_memcpy (mp->mac, mac, 6);
6948       mp->bd_id = ntohl (bd_id);
6949       mp->is_add = is_add;
6950       mp->sw_if_index = ntohl (sw_if_index);
6951
6952       if (is_add)
6953         {
6954           mp->static_mac = static_mac;
6955           mp->filter_mac = filter_mac;
6956           mp->bvi_mac = bvi_mac;
6957         }
6958       increment_mac_address (mac);
6959       /* send it... */
6960       S (mp);
6961     }
6962
6963   if (count > 1)
6964     {
6965       vl_api_control_ping_t *mp_ping;
6966       f64 after;
6967
6968       /* Shut off async mode */
6969       vam->async_mode = 0;
6970
6971       MPING (CONTROL_PING, mp_ping);
6972       S (mp_ping);
6973
6974       timeout = vat_time_now (vam) + 1.0;
6975       while (vat_time_now (vam) < timeout)
6976         if (vam->result_ready == 1)
6977           goto out;
6978       vam->retval = -99;
6979
6980     out:
6981       if (vam->retval == -99)
6982         errmsg ("timeout");
6983
6984       if (vam->async_errors > 0)
6985         {
6986           errmsg ("%d asynchronous errors", vam->async_errors);
6987           vam->retval = -98;
6988         }
6989       vam->async_errors = 0;
6990       after = vat_time_now (vam);
6991
6992       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6993              count, after - before, count / (after - before));
6994     }
6995   else
6996     {
6997       int ret;
6998
6999       /* Wait for a reply... */
7000       W (ret);
7001       return ret;
7002     }
7003   /* Return the good/bad news */
7004   return (vam->retval);
7005 }
7006
7007 static int
7008 api_bridge_domain_set_mac_age (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_bridge_domain_set_mac_age_t *mp;
7012   u32 bd_id = ~0;
7013   u32 mac_age = 0;
7014   int ret;
7015
7016   /* Parse args required to build the message */
7017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018     {
7019       if (unformat (i, "bd_id %d", &bd_id));
7020       else if (unformat (i, "mac-age %d", &mac_age));
7021       else
7022         break;
7023     }
7024
7025   if (bd_id == ~0)
7026     {
7027       errmsg ("missing bridge domain");
7028       return -99;
7029     }
7030
7031   if (mac_age > 255)
7032     {
7033       errmsg ("mac age must be less than 256 ");
7034       return -99;
7035     }
7036
7037   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7038
7039   mp->bd_id = htonl (bd_id);
7040   mp->mac_age = (u8) mac_age;
7041
7042   S (mp);
7043   W (ret);
7044   return ret;
7045 }
7046
7047 static int
7048 api_l2_flags (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_l2_flags_t *mp;
7052   u32 sw_if_index;
7053   u32 flags = 0;
7054   u8 sw_if_index_set = 0;
7055   u8 is_set = 0;
7056   int ret;
7057
7058   /* Parse args required to build the message */
7059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7060     {
7061       if (unformat (i, "sw_if_index %d", &sw_if_index))
7062         sw_if_index_set = 1;
7063       else if (unformat (i, "sw_if"))
7064         {
7065           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7066             {
7067               if (unformat
7068                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7069                 sw_if_index_set = 1;
7070             }
7071           else
7072             break;
7073         }
7074       else if (unformat (i, "learn"))
7075         flags |= L2_LEARN;
7076       else if (unformat (i, "forward"))
7077         flags |= L2_FWD;
7078       else if (unformat (i, "flood"))
7079         flags |= L2_FLOOD;
7080       else if (unformat (i, "uu-flood"))
7081         flags |= L2_UU_FLOOD;
7082       else if (unformat (i, "arp-term"))
7083         flags |= L2_ARP_TERM;
7084       else if (unformat (i, "off"))
7085         is_set = 0;
7086       else if (unformat (i, "disable"))
7087         is_set = 0;
7088       else
7089         break;
7090     }
7091
7092   if (sw_if_index_set == 0)
7093     {
7094       errmsg ("missing interface name or sw_if_index");
7095       return -99;
7096     }
7097
7098   M (L2_FLAGS, mp);
7099
7100   mp->sw_if_index = ntohl (sw_if_index);
7101   mp->feature_bitmap = ntohl (flags);
7102   mp->is_set = is_set;
7103
7104   S (mp);
7105   W (ret);
7106   return ret;
7107 }
7108
7109 static int
7110 api_bridge_flags (vat_main_t * vam)
7111 {
7112   unformat_input_t *i = vam->input;
7113   vl_api_bridge_flags_t *mp;
7114   u32 bd_id;
7115   u8 bd_id_set = 0;
7116   u8 is_set = 1;
7117   bd_flags_t flags = 0;
7118   int ret;
7119
7120   /* Parse args required to build the message */
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "bd_id %d", &bd_id))
7124         bd_id_set = 1;
7125       else if (unformat (i, "learn"))
7126         flags |= BRIDGE_API_FLAG_LEARN;
7127       else if (unformat (i, "forward"))
7128         flags |= BRIDGE_API_FLAG_FWD;
7129       else if (unformat (i, "flood"))
7130         flags |= BRIDGE_API_FLAG_FLOOD;
7131       else if (unformat (i, "uu-flood"))
7132         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7133       else if (unformat (i, "arp-term"))
7134         flags |= BRIDGE_API_FLAG_ARP_TERM;
7135       else if (unformat (i, "off"))
7136         is_set = 0;
7137       else if (unformat (i, "disable"))
7138         is_set = 0;
7139       else
7140         break;
7141     }
7142
7143   if (bd_id_set == 0)
7144     {
7145       errmsg ("missing bridge domain");
7146       return -99;
7147     }
7148
7149   M (BRIDGE_FLAGS, mp);
7150
7151   mp->bd_id = ntohl (bd_id);
7152   mp->flags = ntohl (flags);
7153   mp->is_set = is_set;
7154
7155   S (mp);
7156   W (ret);
7157   return ret;
7158 }
7159
7160 static int
7161 api_bd_ip_mac_add_del (vat_main_t * vam)
7162 {
7163   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7164   vl_api_mac_address_t mac = { 0 };
7165   unformat_input_t *i = vam->input;
7166   vl_api_bd_ip_mac_add_del_t *mp;
7167   u32 bd_id;
7168   u8 is_add = 1;
7169   u8 bd_id_set = 0;
7170   u8 ip_set = 0;
7171   u8 mac_set = 0;
7172   int ret;
7173
7174
7175   /* Parse args required to build the message */
7176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7177     {
7178       if (unformat (i, "bd_id %d", &bd_id))
7179         {
7180           bd_id_set++;
7181         }
7182       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7183         {
7184           ip_set++;
7185         }
7186       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7187         {
7188           mac_set++;
7189         }
7190       else if (unformat (i, "del"))
7191         is_add = 0;
7192       else
7193         break;
7194     }
7195
7196   if (bd_id_set == 0)
7197     {
7198       errmsg ("missing bridge domain");
7199       return -99;
7200     }
7201   else if (ip_set == 0)
7202     {
7203       errmsg ("missing IP address");
7204       return -99;
7205     }
7206   else if (mac_set == 0)
7207     {
7208       errmsg ("missing MAC address");
7209       return -99;
7210     }
7211
7212   M (BD_IP_MAC_ADD_DEL, mp);
7213
7214   mp->entry.bd_id = ntohl (bd_id);
7215   mp->is_add = is_add;
7216
7217   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7218   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7219
7220   S (mp);
7221   W (ret);
7222   return ret;
7223 }
7224
7225 static int
7226 api_bd_ip_mac_flush (vat_main_t * vam)
7227 {
7228   unformat_input_t *i = vam->input;
7229   vl_api_bd_ip_mac_flush_t *mp;
7230   u32 bd_id;
7231   u8 bd_id_set = 0;
7232   int ret;
7233
7234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7235     {
7236       if (unformat (i, "bd_id %d", &bd_id))
7237         {
7238           bd_id_set++;
7239         }
7240       else
7241         break;
7242     }
7243
7244   if (bd_id_set == 0)
7245     {
7246       errmsg ("missing bridge domain");
7247       return -99;
7248     }
7249
7250   M (BD_IP_MAC_FLUSH, mp);
7251
7252   mp->bd_id = ntohl (bd_id);
7253
7254   S (mp);
7255   W (ret);
7256   return ret;
7257 }
7258
7259 static void vl_api_bd_ip_mac_details_t_handler
7260   (vl_api_bd_ip_mac_details_t * mp)
7261 {
7262   vat_main_t *vam = &vat_main;
7263
7264   print (vam->ofp,
7265          "\n%-5d %U %U",
7266          ntohl (mp->entry.bd_id),
7267          format_vl_api_mac_address, mp->entry.mac,
7268          format_vl_api_address, &mp->entry.ip);
7269 }
7270
7271 static void vl_api_bd_ip_mac_details_t_handler_json
7272   (vl_api_bd_ip_mac_details_t * mp)
7273 {
7274   vat_main_t *vam = &vat_main;
7275   vat_json_node_t *node = NULL;
7276
7277   if (VAT_JSON_ARRAY != vam->json_tree.type)
7278     {
7279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7280       vat_json_init_array (&vam->json_tree);
7281     }
7282   node = vat_json_array_add (&vam->json_tree);
7283
7284   vat_json_init_object (node);
7285   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7286   vat_json_object_add_string_copy (node, "mac_address",
7287                                    format (0, "%U", format_vl_api_mac_address,
7288                                            &mp->entry.mac));
7289   u8 *ip = 0;
7290
7291   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7292   vat_json_object_add_string_copy (node, "ip_address", ip);
7293   vec_free (ip);
7294 }
7295
7296 static int
7297 api_bd_ip_mac_dump (vat_main_t * vam)
7298 {
7299   unformat_input_t *i = vam->input;
7300   vl_api_bd_ip_mac_dump_t *mp;
7301   vl_api_control_ping_t *mp_ping;
7302   int ret;
7303   u32 bd_id;
7304   u8 bd_id_set = 0;
7305
7306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7307     {
7308       if (unformat (i, "bd_id %d", &bd_id))
7309         {
7310           bd_id_set++;
7311         }
7312       else
7313         break;
7314     }
7315
7316   print (vam->ofp,
7317          "\n%-5s %-7s %-20s %-30s",
7318          "bd_id", "is_ipv6", "mac_address", "ip_address");
7319
7320   /* Dump Bridge Domain Ip to Mac entries */
7321   M (BD_IP_MAC_DUMP, mp);
7322
7323   if (bd_id_set)
7324     mp->bd_id = htonl (bd_id);
7325   else
7326     mp->bd_id = ~0;
7327
7328   S (mp);
7329
7330   /* Use a control ping for synchronization */
7331   MPING (CONTROL_PING, mp_ping);
7332   S (mp_ping);
7333
7334   W (ret);
7335   return ret;
7336 }
7337
7338 static int
7339 api_tap_create_v2 (vat_main_t * vam)
7340 {
7341   unformat_input_t *i = vam->input;
7342   vl_api_tap_create_v2_t *mp;
7343 #define TAP_FLAG_GSO (1 << 0)
7344   u8 mac_address[6];
7345   u8 random_mac = 1;
7346   u32 id = ~0;
7347   u8 *host_if_name = 0;
7348   u8 *host_ns = 0;
7349   u8 host_mac_addr[6];
7350   u8 host_mac_addr_set = 0;
7351   u8 *host_bridge = 0;
7352   ip4_address_t host_ip4_addr;
7353   ip4_address_t host_ip4_gw;
7354   u8 host_ip4_gw_set = 0;
7355   u32 host_ip4_prefix_len = 0;
7356   ip6_address_t host_ip6_addr;
7357   ip6_address_t host_ip6_gw;
7358   u8 host_ip6_gw_set = 0;
7359   u32 host_ip6_prefix_len = 0;
7360   u8 host_mtu_set = 0;
7361   u32 host_mtu_size = 0;
7362   u32 tap_flags = 0;
7363   int ret;
7364   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7365
7366   clib_memset (mac_address, 0, sizeof (mac_address));
7367
7368   /* Parse args required to build the message */
7369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7370     {
7371       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7372         {
7373           random_mac = 0;
7374         }
7375       else if (unformat (i, "id %u", &id))
7376         ;
7377       else if (unformat (i, "host-if-name %s", &host_if_name))
7378         ;
7379       else if (unformat (i, "host-ns %s", &host_ns))
7380         ;
7381       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7382                          host_mac_addr))
7383         host_mac_addr_set = 1;
7384       else if (unformat (i, "host-bridge %s", &host_bridge))
7385         ;
7386       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7387                          &host_ip4_addr, &host_ip4_prefix_len))
7388         ;
7389       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7390                          &host_ip6_addr, &host_ip6_prefix_len))
7391         ;
7392       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7393                          &host_ip4_gw))
7394         host_ip4_gw_set = 1;
7395       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7396                          &host_ip6_gw))
7397         host_ip6_gw_set = 1;
7398       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7399         ;
7400       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7401         ;
7402       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7403         host_mtu_set = 1;
7404       else if (unformat (i, "no-gso"))
7405         tap_flags &= ~TAP_FLAG_GSO;
7406       else if (unformat (i, "gso"))
7407         tap_flags |= TAP_FLAG_GSO;
7408       else
7409         break;
7410     }
7411
7412   if (vec_len (host_if_name) > 63)
7413     {
7414       errmsg ("tap name too long. ");
7415       return -99;
7416     }
7417   if (vec_len (host_ns) > 63)
7418     {
7419       errmsg ("host name space too long. ");
7420       return -99;
7421     }
7422   if (vec_len (host_bridge) > 63)
7423     {
7424       errmsg ("host bridge name too long. ");
7425       return -99;
7426     }
7427   if (host_ip4_prefix_len > 32)
7428     {
7429       errmsg ("host ip4 prefix length not valid. ");
7430       return -99;
7431     }
7432   if (host_ip6_prefix_len > 128)
7433     {
7434       errmsg ("host ip6 prefix length not valid. ");
7435       return -99;
7436     }
7437   if (!is_pow2 (rx_ring_sz))
7438     {
7439       errmsg ("rx ring size must be power of 2. ");
7440       return -99;
7441     }
7442   if (rx_ring_sz > 32768)
7443     {
7444       errmsg ("rx ring size must be 32768 or lower. ");
7445       return -99;
7446     }
7447   if (!is_pow2 (tx_ring_sz))
7448     {
7449       errmsg ("tx ring size must be power of 2. ");
7450       return -99;
7451     }
7452   if (tx_ring_sz > 32768)
7453     {
7454       errmsg ("tx ring size must be 32768 or lower. ");
7455       return -99;
7456     }
7457   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7458     {
7459       errmsg ("host MTU size must be in between 64 and 65355. ");
7460       return -99;
7461     }
7462
7463   /* Construct the API message */
7464   M (TAP_CREATE_V2, mp);
7465
7466   mp->use_random_mac = random_mac;
7467
7468   mp->id = ntohl (id);
7469   mp->host_namespace_set = host_ns != 0;
7470   mp->host_bridge_set = host_bridge != 0;
7471   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7472   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7473   mp->rx_ring_sz = ntohs (rx_ring_sz);
7474   mp->tx_ring_sz = ntohs (tx_ring_sz);
7475   mp->host_mtu_set = host_mtu_set;
7476   mp->host_mtu_size = ntohl (host_mtu_size);
7477   mp->tap_flags = ntohl (tap_flags);
7478
7479   if (random_mac == 0)
7480     clib_memcpy (mp->mac_address, mac_address, 6);
7481   if (host_mac_addr_set)
7482     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7483   if (host_if_name)
7484     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7485   if (host_ns)
7486     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7487   if (host_bridge)
7488     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7489   if (host_ip4_prefix_len)
7490     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7491   if (host_ip6_prefix_len)
7492     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7493   if (host_ip4_gw_set)
7494     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7495   if (host_ip6_gw_set)
7496     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7497
7498   vec_free (host_ns);
7499   vec_free (host_if_name);
7500   vec_free (host_bridge);
7501
7502   /* send it... */
7503   S (mp);
7504
7505   /* Wait for a reply... */
7506   W (ret);
7507   return ret;
7508 }
7509
7510 static int
7511 api_tap_delete_v2 (vat_main_t * vam)
7512 {
7513   unformat_input_t *i = vam->input;
7514   vl_api_tap_delete_v2_t *mp;
7515   u32 sw_if_index = ~0;
7516   u8 sw_if_index_set = 0;
7517   int ret;
7518
7519   /* Parse args required to build the message */
7520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7521     {
7522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7523         sw_if_index_set = 1;
7524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7525         sw_if_index_set = 1;
7526       else
7527         break;
7528     }
7529
7530   if (sw_if_index_set == 0)
7531     {
7532       errmsg ("missing vpp interface name. ");
7533       return -99;
7534     }
7535
7536   /* Construct the API message */
7537   M (TAP_DELETE_V2, mp);
7538
7539   mp->sw_if_index = ntohl (sw_if_index);
7540
7541   /* send it... */
7542   S (mp);
7543
7544   /* Wait for a reply... */
7545   W (ret);
7546   return ret;
7547 }
7548
7549 uword
7550 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7551 {
7552   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7553   u32 x[4];
7554
7555   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7556     return 0;
7557
7558   addr->domain = x[0];
7559   addr->bus = x[1];
7560   addr->slot = x[2];
7561   addr->function = x[3];
7562
7563   return 1;
7564 }
7565
7566 static int
7567 api_virtio_pci_create (vat_main_t * vam)
7568 {
7569   unformat_input_t *i = vam->input;
7570   vl_api_virtio_pci_create_t *mp;
7571   u8 mac_address[6];
7572   u8 random_mac = 1;
7573   u8 gso_enabled = 0;
7574   u32 pci_addr = 0;
7575   u64 features = (u64) ~ (0ULL);
7576   int ret;
7577
7578   clib_memset (mac_address, 0, sizeof (mac_address));
7579
7580   /* Parse args required to build the message */
7581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7582     {
7583       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7584         {
7585           random_mac = 0;
7586         }
7587       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7588         ;
7589       else if (unformat (i, "features 0x%llx", &features))
7590         ;
7591       else if (unformat (i, "gso-enabled"))
7592         gso_enabled = 1;
7593       else
7594         break;
7595     }
7596
7597   if (pci_addr == 0)
7598     {
7599       errmsg ("pci address must be non zero. ");
7600       return -99;
7601     }
7602
7603   /* Construct the API message */
7604   M (VIRTIO_PCI_CREATE, mp);
7605
7606   mp->use_random_mac = random_mac;
7607
7608   mp->pci_addr = htonl (pci_addr);
7609   mp->features = clib_host_to_net_u64 (features);
7610   mp->gso_enabled = gso_enabled;
7611
7612   if (random_mac == 0)
7613     clib_memcpy (mp->mac_address, mac_address, 6);
7614
7615   /* send it... */
7616   S (mp);
7617
7618   /* Wait for a reply... */
7619   W (ret);
7620   return ret;
7621 }
7622
7623 static int
7624 api_virtio_pci_delete (vat_main_t * vam)
7625 {
7626   unformat_input_t *i = vam->input;
7627   vl_api_virtio_pci_delete_t *mp;
7628   u32 sw_if_index = ~0;
7629   u8 sw_if_index_set = 0;
7630   int ret;
7631
7632   /* Parse args required to build the message */
7633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7634     {
7635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7636         sw_if_index_set = 1;
7637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7638         sw_if_index_set = 1;
7639       else
7640         break;
7641     }
7642
7643   if (sw_if_index_set == 0)
7644     {
7645       errmsg ("missing vpp interface name. ");
7646       return -99;
7647     }
7648
7649   /* Construct the API message */
7650   M (VIRTIO_PCI_DELETE, mp);
7651
7652   mp->sw_if_index = htonl (sw_if_index);
7653
7654   /* send it... */
7655   S (mp);
7656
7657   /* Wait for a reply... */
7658   W (ret);
7659   return ret;
7660 }
7661
7662 static int
7663 api_bond_create (vat_main_t * vam)
7664 {
7665   unformat_input_t *i = vam->input;
7666   vl_api_bond_create_t *mp;
7667   u8 mac_address[6];
7668   u8 custom_mac = 0;
7669   int ret;
7670   u8 mode;
7671   u8 lb;
7672   u8 mode_is_set = 0;
7673   u32 id = ~0;
7674   u8 numa_only = 0;
7675
7676   clib_memset (mac_address, 0, sizeof (mac_address));
7677   lb = BOND_LB_L2;
7678
7679   /* Parse args required to build the message */
7680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7681     {
7682       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7683         mode_is_set = 1;
7684       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7685                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7686         ;
7687       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7688                          mac_address))
7689         custom_mac = 1;
7690       else if (unformat (i, "numa-only"))
7691         numa_only = 1;
7692       else if (unformat (i, "id %u", &id))
7693         ;
7694       else
7695         break;
7696     }
7697
7698   if (mode_is_set == 0)
7699     {
7700       errmsg ("Missing bond mode. ");
7701       return -99;
7702     }
7703
7704   /* Construct the API message */
7705   M (BOND_CREATE, mp);
7706
7707   mp->use_custom_mac = custom_mac;
7708
7709   mp->mode = htonl (mode);
7710   mp->lb = htonl (lb);
7711   mp->id = htonl (id);
7712   mp->numa_only = numa_only;
7713
7714   if (custom_mac)
7715     clib_memcpy (mp->mac_address, mac_address, 6);
7716
7717   /* send it... */
7718   S (mp);
7719
7720   /* Wait for a reply... */
7721   W (ret);
7722   return ret;
7723 }
7724
7725 static int
7726 api_bond_delete (vat_main_t * vam)
7727 {
7728   unformat_input_t *i = vam->input;
7729   vl_api_bond_delete_t *mp;
7730   u32 sw_if_index = ~0;
7731   u8 sw_if_index_set = 0;
7732   int ret;
7733
7734   /* Parse args required to build the message */
7735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7736     {
7737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7738         sw_if_index_set = 1;
7739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7740         sw_if_index_set = 1;
7741       else
7742         break;
7743     }
7744
7745   if (sw_if_index_set == 0)
7746     {
7747       errmsg ("missing vpp interface name. ");
7748       return -99;
7749     }
7750
7751   /* Construct the API message */
7752   M (BOND_DELETE, mp);
7753
7754   mp->sw_if_index = ntohl (sw_if_index);
7755
7756   /* send it... */
7757   S (mp);
7758
7759   /* Wait for a reply... */
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_bond_enslave (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_bond_enslave_t *mp;
7769   u32 bond_sw_if_index;
7770   int ret;
7771   u8 is_passive;
7772   u8 is_long_timeout;
7773   u32 bond_sw_if_index_is_set = 0;
7774   u32 sw_if_index;
7775   u8 sw_if_index_is_set = 0;
7776
7777   /* Parse args required to build the message */
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "sw_if_index %d", &sw_if_index))
7781         sw_if_index_is_set = 1;
7782       else if (unformat (i, "bond %u", &bond_sw_if_index))
7783         bond_sw_if_index_is_set = 1;
7784       else if (unformat (i, "passive %d", &is_passive))
7785         ;
7786       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7787         ;
7788       else
7789         break;
7790     }
7791
7792   if (bond_sw_if_index_is_set == 0)
7793     {
7794       errmsg ("Missing bond sw_if_index. ");
7795       return -99;
7796     }
7797   if (sw_if_index_is_set == 0)
7798     {
7799       errmsg ("Missing slave sw_if_index. ");
7800       return -99;
7801     }
7802
7803   /* Construct the API message */
7804   M (BOND_ENSLAVE, mp);
7805
7806   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7807   mp->sw_if_index = ntohl (sw_if_index);
7808   mp->is_long_timeout = is_long_timeout;
7809   mp->is_passive = is_passive;
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply... */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_bond_detach_slave (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_bond_detach_slave_t *mp;
7824   u32 sw_if_index = ~0;
7825   u8 sw_if_index_set = 0;
7826   int ret;
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7832         sw_if_index_set = 1;
7833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7834         sw_if_index_set = 1;
7835       else
7836         break;
7837     }
7838
7839   if (sw_if_index_set == 0)
7840     {
7841       errmsg ("missing vpp interface name. ");
7842       return -99;
7843     }
7844
7845   /* Construct the API message */
7846   M (BOND_DETACH_SLAVE, mp);
7847
7848   mp->sw_if_index = ntohl (sw_if_index);
7849
7850   /* send it... */
7851   S (mp);
7852
7853   /* Wait for a reply... */
7854   W (ret);
7855   return ret;
7856 }
7857
7858 static int
7859 api_ip_table_add_del (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_ip_table_add_del_t *mp;
7863   u32 table_id = ~0;
7864   u8 is_ipv6 = 0;
7865   u8 is_add = 1;
7866   int ret = 0;
7867
7868   /* Parse args required to build the message */
7869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7870     {
7871       if (unformat (i, "ipv6"))
7872         is_ipv6 = 1;
7873       else if (unformat (i, "del"))
7874         is_add = 0;
7875       else if (unformat (i, "add"))
7876         is_add = 1;
7877       else if (unformat (i, "table %d", &table_id))
7878         ;
7879       else
7880         {
7881           clib_warning ("parse error '%U'", format_unformat_error, i);
7882           return -99;
7883         }
7884     }
7885
7886   if (~0 == table_id)
7887     {
7888       errmsg ("missing table-ID");
7889       return -99;
7890     }
7891
7892   /* Construct the API message */
7893   M (IP_TABLE_ADD_DEL, mp);
7894
7895   mp->table.table_id = ntohl (table_id);
7896   mp->table.is_ip6 = is_ipv6;
7897   mp->is_add = is_add;
7898
7899   /* send it... */
7900   S (mp);
7901
7902   /* Wait for a reply... */
7903   W (ret);
7904
7905   return ret;
7906 }
7907
7908 uword
7909 unformat_fib_path (unformat_input_t * input, va_list * args)
7910 {
7911   vat_main_t *vam = va_arg (*args, vat_main_t *);
7912   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7913   u32 weight, preference;
7914   mpls_label_t out_label;
7915
7916   clib_memset (path, 0, sizeof (*path));
7917   path->weight = 1;
7918   path->sw_if_index = ~0;
7919   path->rpf_id = ~0;
7920   path->n_labels = 0;
7921
7922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7923     {
7924       if (unformat (input, "%U %U",
7925                     unformat_vl_api_ip4_address,
7926                     &path->nh.address.ip4,
7927                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7928         {
7929           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7930         }
7931       else if (unformat (input, "%U %U",
7932                          unformat_vl_api_ip6_address,
7933                          &path->nh.address.ip6,
7934                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7935         {
7936           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7937         }
7938       else if (unformat (input, "weight %u", &weight))
7939         {
7940           path->weight = weight;
7941         }
7942       else if (unformat (input, "preference %u", &preference))
7943         {
7944           path->preference = preference;
7945         }
7946       else if (unformat (input, "%U next-hop-table %d",
7947                          unformat_vl_api_ip4_address,
7948                          &path->nh.address.ip4, &path->table_id))
7949         {
7950           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7951         }
7952       else if (unformat (input, "%U next-hop-table %d",
7953                          unformat_vl_api_ip6_address,
7954                          &path->nh.address.ip6, &path->table_id))
7955         {
7956           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7957         }
7958       else if (unformat (input, "%U",
7959                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7960         {
7961           /*
7962            * the recursive next-hops are by default in the default table
7963            */
7964           path->table_id = 0;
7965           path->sw_if_index = ~0;
7966           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7967         }
7968       else if (unformat (input, "%U",
7969                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7970         {
7971           /*
7972            * the recursive next-hops are by default in the default table
7973            */
7974           path->table_id = 0;
7975           path->sw_if_index = ~0;
7976           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7977         }
7978       else if (unformat (input, "resolve-via-host"))
7979         {
7980           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7981         }
7982       else if (unformat (input, "resolve-via-attached"))
7983         {
7984           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7985         }
7986       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7987         {
7988           path->type = FIB_API_PATH_TYPE_LOCAL;
7989           path->sw_if_index = ~0;
7990           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7991         }
7992       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7993         {
7994           path->type = FIB_API_PATH_TYPE_LOCAL;
7995           path->sw_if_index = ~0;
7996           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7997         }
7998       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7999         ;
8000       else if (unformat (input, "via-label %d", &path->nh.via_label))
8001         {
8002           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8003           path->sw_if_index = ~0;
8004         }
8005       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8006         {
8007           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8008           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8009         }
8010       else if (unformat (input, "local"))
8011         {
8012           path->type = FIB_API_PATH_TYPE_LOCAL;
8013         }
8014       else if (unformat (input, "out-labels"))
8015         {
8016           while (unformat (input, "%d", &out_label))
8017             {
8018               path->label_stack[path->n_labels].label = out_label;
8019               path->label_stack[path->n_labels].is_uniform = 0;
8020               path->label_stack[path->n_labels].ttl = 64;
8021               path->n_labels++;
8022             }
8023         }
8024       else if (unformat (input, "via"))
8025         {
8026           /* new path, back up and return */
8027           unformat_put_input (input);
8028           unformat_put_input (input);
8029           unformat_put_input (input);
8030           unformat_put_input (input);
8031           break;
8032         }
8033       else
8034         {
8035           return (0);
8036         }
8037     }
8038
8039   path->proto = ntohl (path->proto);
8040   path->type = ntohl (path->type);
8041   path->flags = ntohl (path->flags);
8042   path->table_id = ntohl (path->table_id);
8043   path->sw_if_index = ntohl (path->sw_if_index);
8044
8045   return (1);
8046 }
8047
8048 static int
8049 api_ip_route_add_del (vat_main_t * vam)
8050 {
8051   unformat_input_t *i = vam->input;
8052   vl_api_ip_route_add_del_t *mp;
8053   u32 vrf_id = 0;
8054   u8 is_add = 1;
8055   u8 is_multipath = 0;
8056   u8 prefix_set = 0;
8057   u8 path_count = 0;
8058   vl_api_prefix_t pfx = { };
8059   vl_api_fib_path_t paths[8];
8060   int count = 1;
8061   int j;
8062   f64 before = 0;
8063   u32 random_add_del = 0;
8064   u32 *random_vector = 0;
8065   u32 random_seed = 0xdeaddabe;
8066
8067   /* Parse args required to build the message */
8068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8069     {
8070       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8071         prefix_set = 1;
8072       else if (unformat (i, "del"))
8073         is_add = 0;
8074       else if (unformat (i, "add"))
8075         is_add = 1;
8076       else if (unformat (i, "vrf %d", &vrf_id))
8077         ;
8078       else if (unformat (i, "count %d", &count))
8079         ;
8080       else if (unformat (i, "random"))
8081         random_add_del = 1;
8082       else if (unformat (i, "multipath"))
8083         is_multipath = 1;
8084       else if (unformat (i, "seed %d", &random_seed))
8085         ;
8086       else
8087         if (unformat
8088             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8089         {
8090           path_count++;
8091           if (8 == path_count)
8092             {
8093               errmsg ("max 8 paths");
8094               return -99;
8095             }
8096         }
8097       else
8098         {
8099           clib_warning ("parse error '%U'", format_unformat_error, i);
8100           return -99;
8101         }
8102     }
8103
8104   if (!path_count)
8105     {
8106       errmsg ("specify a path; via ...");
8107       return -99;
8108     }
8109   if (prefix_set == 0)
8110     {
8111       errmsg ("missing prefix");
8112       return -99;
8113     }
8114
8115   /* Generate a pile of unique, random routes */
8116   if (random_add_del)
8117     {
8118       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8119       u32 this_random_address;
8120       uword *random_hash;
8121
8122       random_hash = hash_create (count, sizeof (uword));
8123
8124       hash_set (random_hash, i->as_u32, 1);
8125       for (j = 0; j <= count; j++)
8126         {
8127           do
8128             {
8129               this_random_address = random_u32 (&random_seed);
8130               this_random_address =
8131                 clib_host_to_net_u32 (this_random_address);
8132             }
8133           while (hash_get (random_hash, this_random_address));
8134           vec_add1 (random_vector, this_random_address);
8135           hash_set (random_hash, this_random_address, 1);
8136         }
8137       hash_free (random_hash);
8138       set_ip4_address (&pfx.address, random_vector[0]);
8139     }
8140
8141   if (count > 1)
8142     {
8143       /* Turn on async mode */
8144       vam->async_mode = 1;
8145       vam->async_errors = 0;
8146       before = vat_time_now (vam);
8147     }
8148
8149   for (j = 0; j < count; j++)
8150     {
8151       /* Construct the API message */
8152       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8153
8154       mp->is_add = is_add;
8155       mp->is_multipath = is_multipath;
8156
8157       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8158       mp->route.table_id = ntohl (vrf_id);
8159       mp->route.n_paths = path_count;
8160
8161       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8162
8163       if (random_add_del)
8164         set_ip4_address (&pfx.address, random_vector[j + 1]);
8165       else
8166         increment_address (&pfx.address);
8167       /* send it... */
8168       S (mp);
8169       /* If we receive SIGTERM, stop now... */
8170       if (vam->do_exit)
8171         break;
8172     }
8173
8174   /* When testing multiple add/del ops, use a control-ping to sync */
8175   if (count > 1)
8176     {
8177       vl_api_control_ping_t *mp_ping;
8178       f64 after;
8179       f64 timeout;
8180
8181       /* Shut off async mode */
8182       vam->async_mode = 0;
8183
8184       MPING (CONTROL_PING, mp_ping);
8185       S (mp_ping);
8186
8187       timeout = vat_time_now (vam) + 1.0;
8188       while (vat_time_now (vam) < timeout)
8189         if (vam->result_ready == 1)
8190           goto out;
8191       vam->retval = -99;
8192
8193     out:
8194       if (vam->retval == -99)
8195         errmsg ("timeout");
8196
8197       if (vam->async_errors > 0)
8198         {
8199           errmsg ("%d asynchronous errors", vam->async_errors);
8200           vam->retval = -98;
8201         }
8202       vam->async_errors = 0;
8203       after = vat_time_now (vam);
8204
8205       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8206       if (j > 0)
8207         count = j;
8208
8209       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8210              count, after - before, count / (after - before));
8211     }
8212   else
8213     {
8214       int ret;
8215
8216       /* Wait for a reply... */
8217       W (ret);
8218       return ret;
8219     }
8220
8221   /* Return the good/bad news */
8222   return (vam->retval);
8223 }
8224
8225 static int
8226 api_ip_mroute_add_del (vat_main_t * vam)
8227 {
8228   unformat_input_t *i = vam->input;
8229   u8 path_set = 0, prefix_set = 0, is_add = 1;
8230   vl_api_ip_mroute_add_del_t *mp;
8231   mfib_entry_flags_t eflags = 0;
8232   vl_api_mfib_path_t path;
8233   vl_api_mprefix_t pfx = { };
8234   u32 vrf_id = 0;
8235   int ret;
8236
8237   /* Parse args required to build the message */
8238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8239     {
8240       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8241         {
8242           prefix_set = 1;
8243           pfx.grp_address_length = htons (pfx.grp_address_length);
8244         }
8245       else if (unformat (i, "del"))
8246         is_add = 0;
8247       else if (unformat (i, "add"))
8248         is_add = 1;
8249       else if (unformat (i, "vrf %d", &vrf_id))
8250         ;
8251       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8252         path.itf_flags = htonl (path.itf_flags);
8253       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8254         ;
8255       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8256         path_set = 1;
8257       else
8258         {
8259           clib_warning ("parse error '%U'", format_unformat_error, i);
8260           return -99;
8261         }
8262     }
8263
8264   if (prefix_set == 0)
8265     {
8266       errmsg ("missing addresses\n");
8267       return -99;
8268     }
8269   if (path_set == 0)
8270     {
8271       errmsg ("missing path\n");
8272       return -99;
8273     }
8274
8275   /* Construct the API message */
8276   M (IP_MROUTE_ADD_DEL, mp);
8277
8278   mp->is_add = is_add;
8279   mp->is_multipath = 1;
8280
8281   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8282   mp->route.table_id = htonl (vrf_id);
8283   mp->route.n_paths = 1;
8284   mp->route.entry_flags = htonl (eflags);
8285
8286   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8287
8288   /* send it... */
8289   S (mp);
8290   /* Wait for a reply... */
8291   W (ret);
8292   return ret;
8293 }
8294
8295 static int
8296 api_mpls_table_add_del (vat_main_t * vam)
8297 {
8298   unformat_input_t *i = vam->input;
8299   vl_api_mpls_table_add_del_t *mp;
8300   u32 table_id = ~0;
8301   u8 is_add = 1;
8302   int ret = 0;
8303
8304   /* Parse args required to build the message */
8305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8306     {
8307       if (unformat (i, "table %d", &table_id))
8308         ;
8309       else if (unformat (i, "del"))
8310         is_add = 0;
8311       else if (unformat (i, "add"))
8312         is_add = 1;
8313       else
8314         {
8315           clib_warning ("parse error '%U'", format_unformat_error, i);
8316           return -99;
8317         }
8318     }
8319
8320   if (~0 == table_id)
8321     {
8322       errmsg ("missing table-ID");
8323       return -99;
8324     }
8325
8326   /* Construct the API message */
8327   M (MPLS_TABLE_ADD_DEL, mp);
8328
8329   mp->mt_table.mt_table_id = ntohl (table_id);
8330   mp->mt_is_add = is_add;
8331
8332   /* send it... */
8333   S (mp);
8334
8335   /* Wait for a reply... */
8336   W (ret);
8337
8338   return ret;
8339 }
8340
8341 static int
8342 api_mpls_route_add_del (vat_main_t * vam)
8343 {
8344   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8345   mpls_label_t local_label = MPLS_LABEL_INVALID;
8346   unformat_input_t *i = vam->input;
8347   vl_api_mpls_route_add_del_t *mp;
8348   vl_api_fib_path_t paths[8];
8349   int count = 1, j;
8350   f64 before = 0;
8351
8352   /* Parse args required to build the message */
8353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8354     {
8355       if (unformat (i, "%d", &local_label))
8356         ;
8357       else if (unformat (i, "eos"))
8358         is_eos = 1;
8359       else if (unformat (i, "non-eos"))
8360         is_eos = 0;
8361       else if (unformat (i, "del"))
8362         is_add = 0;
8363       else if (unformat (i, "add"))
8364         is_add = 1;
8365       else if (unformat (i, "multipath"))
8366         is_multipath = 1;
8367       else if (unformat (i, "count %d", &count))
8368         ;
8369       else
8370         if (unformat
8371             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8372         {
8373           path_count++;
8374           if (8 == path_count)
8375             {
8376               errmsg ("max 8 paths");
8377               return -99;
8378             }
8379         }
8380       else
8381         {
8382           clib_warning ("parse error '%U'", format_unformat_error, i);
8383           return -99;
8384         }
8385     }
8386
8387   if (!path_count)
8388     {
8389       errmsg ("specify a path; via ...");
8390       return -99;
8391     }
8392
8393   if (MPLS_LABEL_INVALID == local_label)
8394     {
8395       errmsg ("missing label");
8396       return -99;
8397     }
8398
8399   if (count > 1)
8400     {
8401       /* Turn on async mode */
8402       vam->async_mode = 1;
8403       vam->async_errors = 0;
8404       before = vat_time_now (vam);
8405     }
8406
8407   for (j = 0; j < count; j++)
8408     {
8409       /* Construct the API message */
8410       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8411
8412       mp->mr_is_add = is_add;
8413       mp->mr_is_multipath = is_multipath;
8414
8415       mp->mr_route.mr_label = local_label;
8416       mp->mr_route.mr_eos = is_eos;
8417       mp->mr_route.mr_table_id = 0;
8418       mp->mr_route.mr_n_paths = path_count;
8419
8420       clib_memcpy (&mp->mr_route.mr_paths, paths,
8421                    sizeof (paths[0]) * path_count);
8422
8423       local_label++;
8424
8425       /* send it... */
8426       S (mp);
8427       /* If we receive SIGTERM, stop now... */
8428       if (vam->do_exit)
8429         break;
8430     }
8431
8432   /* When testing multiple add/del ops, use a control-ping to sync */
8433   if (count > 1)
8434     {
8435       vl_api_control_ping_t *mp_ping;
8436       f64 after;
8437       f64 timeout;
8438
8439       /* Shut off async mode */
8440       vam->async_mode = 0;
8441
8442       MPING (CONTROL_PING, mp_ping);
8443       S (mp_ping);
8444
8445       timeout = vat_time_now (vam) + 1.0;
8446       while (vat_time_now (vam) < timeout)
8447         if (vam->result_ready == 1)
8448           goto out;
8449       vam->retval = -99;
8450
8451     out:
8452       if (vam->retval == -99)
8453         errmsg ("timeout");
8454
8455       if (vam->async_errors > 0)
8456         {
8457           errmsg ("%d asynchronous errors", vam->async_errors);
8458           vam->retval = -98;
8459         }
8460       vam->async_errors = 0;
8461       after = vat_time_now (vam);
8462
8463       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8464       if (j > 0)
8465         count = j;
8466
8467       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8468              count, after - before, count / (after - before));
8469     }
8470   else
8471     {
8472       int ret;
8473
8474       /* Wait for a reply... */
8475       W (ret);
8476       return ret;
8477     }
8478
8479   /* Return the good/bad news */
8480   return (vam->retval);
8481   return (0);
8482 }
8483
8484 static int
8485 api_mpls_ip_bind_unbind (vat_main_t * vam)
8486 {
8487   unformat_input_t *i = vam->input;
8488   vl_api_mpls_ip_bind_unbind_t *mp;
8489   u32 ip_table_id = 0;
8490   u8 is_bind = 1;
8491   vl_api_prefix_t pfx;
8492   u8 prefix_set = 0;
8493   mpls_label_t local_label = MPLS_LABEL_INVALID;
8494   int ret;
8495
8496   /* Parse args required to build the message */
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8500         prefix_set = 1;
8501       else if (unformat (i, "%d", &local_label))
8502         ;
8503       else if (unformat (i, "table-id %d", &ip_table_id))
8504         ;
8505       else if (unformat (i, "unbind"))
8506         is_bind = 0;
8507       else if (unformat (i, "bind"))
8508         is_bind = 1;
8509       else
8510         {
8511           clib_warning ("parse error '%U'", format_unformat_error, i);
8512           return -99;
8513         }
8514     }
8515
8516   if (!prefix_set)
8517     {
8518       errmsg ("IP prefix not set");
8519       return -99;
8520     }
8521
8522   if (MPLS_LABEL_INVALID == local_label)
8523     {
8524       errmsg ("missing label");
8525       return -99;
8526     }
8527
8528   /* Construct the API message */
8529   M (MPLS_IP_BIND_UNBIND, mp);
8530
8531   mp->mb_is_bind = is_bind;
8532   mp->mb_ip_table_id = ntohl (ip_table_id);
8533   mp->mb_mpls_table_id = 0;
8534   mp->mb_label = ntohl (local_label);
8535   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8536
8537   /* send it... */
8538   S (mp);
8539
8540   /* Wait for a reply... */
8541   W (ret);
8542   return ret;
8543   return (0);
8544 }
8545
8546 static int
8547 api_sr_mpls_policy_add (vat_main_t * vam)
8548 {
8549   unformat_input_t *i = vam->input;
8550   vl_api_sr_mpls_policy_add_t *mp;
8551   u32 bsid = 0;
8552   u32 weight = 1;
8553   u8 type = 0;
8554   u8 n_segments = 0;
8555   u32 sid;
8556   u32 *segments = NULL;
8557   int ret;
8558
8559   /* Parse args required to build the message */
8560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8561     {
8562       if (unformat (i, "bsid %d", &bsid))
8563         ;
8564       else if (unformat (i, "weight %d", &weight))
8565         ;
8566       else if (unformat (i, "spray"))
8567         type = 1;
8568       else if (unformat (i, "next %d", &sid))
8569         {
8570           n_segments += 1;
8571           vec_add1 (segments, htonl (sid));
8572         }
8573       else
8574         {
8575           clib_warning ("parse error '%U'", format_unformat_error, i);
8576           return -99;
8577         }
8578     }
8579
8580   if (bsid == 0)
8581     {
8582       errmsg ("bsid not set");
8583       return -99;
8584     }
8585
8586   if (n_segments == 0)
8587     {
8588       errmsg ("no sid in segment stack");
8589       return -99;
8590     }
8591
8592   /* Construct the API message */
8593   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8594
8595   mp->bsid = htonl (bsid);
8596   mp->weight = htonl (weight);
8597   mp->type = type;
8598   mp->n_segments = n_segments;
8599   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8600   vec_free (segments);
8601
8602   /* send it... */
8603   S (mp);
8604
8605   /* Wait for a reply... */
8606   W (ret);
8607   return ret;
8608 }
8609
8610 static int
8611 api_sr_mpls_policy_del (vat_main_t * vam)
8612 {
8613   unformat_input_t *i = vam->input;
8614   vl_api_sr_mpls_policy_del_t *mp;
8615   u32 bsid = 0;
8616   int ret;
8617
8618   /* Parse args required to build the message */
8619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8620     {
8621       if (unformat (i, "bsid %d", &bsid))
8622         ;
8623       else
8624         {
8625           clib_warning ("parse error '%U'", format_unformat_error, i);
8626           return -99;
8627         }
8628     }
8629
8630   if (bsid == 0)
8631     {
8632       errmsg ("bsid not set");
8633       return -99;
8634     }
8635
8636   /* Construct the API message */
8637   M (SR_MPLS_POLICY_DEL, mp);
8638
8639   mp->bsid = htonl (bsid);
8640
8641   /* send it... */
8642   S (mp);
8643
8644   /* Wait for a reply... */
8645   W (ret);
8646   return ret;
8647 }
8648
8649 static int
8650 api_bier_table_add_del (vat_main_t * vam)
8651 {
8652   unformat_input_t *i = vam->input;
8653   vl_api_bier_table_add_del_t *mp;
8654   u8 is_add = 1;
8655   u32 set = 0, sub_domain = 0, hdr_len = 3;
8656   mpls_label_t local_label = MPLS_LABEL_INVALID;
8657   int ret;
8658
8659   /* Parse args required to build the message */
8660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8661     {
8662       if (unformat (i, "sub-domain %d", &sub_domain))
8663         ;
8664       else if (unformat (i, "set %d", &set))
8665         ;
8666       else if (unformat (i, "label %d", &local_label))
8667         ;
8668       else if (unformat (i, "hdr-len %d", &hdr_len))
8669         ;
8670       else if (unformat (i, "add"))
8671         is_add = 1;
8672       else if (unformat (i, "del"))
8673         is_add = 0;
8674       else
8675         {
8676           clib_warning ("parse error '%U'", format_unformat_error, i);
8677           return -99;
8678         }
8679     }
8680
8681   if (MPLS_LABEL_INVALID == local_label)
8682     {
8683       errmsg ("missing label\n");
8684       return -99;
8685     }
8686
8687   /* Construct the API message */
8688   M (BIER_TABLE_ADD_DEL, mp);
8689
8690   mp->bt_is_add = is_add;
8691   mp->bt_label = ntohl (local_label);
8692   mp->bt_tbl_id.bt_set = set;
8693   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8694   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8695
8696   /* send it... */
8697   S (mp);
8698
8699   /* Wait for a reply... */
8700   W (ret);
8701
8702   return (ret);
8703 }
8704
8705 static int
8706 api_bier_route_add_del (vat_main_t * vam)
8707 {
8708   unformat_input_t *i = vam->input;
8709   vl_api_bier_route_add_del_t *mp;
8710   u8 is_add = 1;
8711   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8712   ip4_address_t v4_next_hop_address;
8713   ip6_address_t v6_next_hop_address;
8714   u8 next_hop_set = 0;
8715   u8 next_hop_proto_is_ip4 = 1;
8716   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8717   int ret;
8718
8719   /* Parse args required to build the message */
8720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8721     {
8722       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8723         {
8724           next_hop_proto_is_ip4 = 1;
8725           next_hop_set = 1;
8726         }
8727       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8728         {
8729           next_hop_proto_is_ip4 = 0;
8730           next_hop_set = 1;
8731         }
8732       if (unformat (i, "sub-domain %d", &sub_domain))
8733         ;
8734       else if (unformat (i, "set %d", &set))
8735         ;
8736       else if (unformat (i, "hdr-len %d", &hdr_len))
8737         ;
8738       else if (unformat (i, "bp %d", &bp))
8739         ;
8740       else if (unformat (i, "add"))
8741         is_add = 1;
8742       else if (unformat (i, "del"))
8743         is_add = 0;
8744       else if (unformat (i, "out-label %d", &next_hop_out_label))
8745         ;
8746       else
8747         {
8748           clib_warning ("parse error '%U'", format_unformat_error, i);
8749           return -99;
8750         }
8751     }
8752
8753   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8754     {
8755       errmsg ("next hop / label set\n");
8756       return -99;
8757     }
8758   if (0 == bp)
8759     {
8760       errmsg ("bit=position not set\n");
8761       return -99;
8762     }
8763
8764   /* Construct the API message */
8765   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8766
8767   mp->br_is_add = is_add;
8768   mp->br_route.br_tbl_id.bt_set = set;
8769   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8770   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8771   mp->br_route.br_bp = ntohs (bp);
8772   mp->br_route.br_n_paths = 1;
8773   mp->br_route.br_paths[0].n_labels = 1;
8774   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8775   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8776                                     FIB_API_PATH_NH_PROTO_IP4 :
8777                                     FIB_API_PATH_NH_PROTO_IP6);
8778
8779   if (next_hop_proto_is_ip4)
8780     {
8781       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8782                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8783     }
8784   else
8785     {
8786       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8787                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8788     }
8789
8790   /* send it... */
8791   S (mp);
8792
8793   /* Wait for a reply... */
8794   W (ret);
8795
8796   return (ret);
8797 }
8798
8799 static int
8800 api_proxy_arp_add_del (vat_main_t * vam)
8801 {
8802   unformat_input_t *i = vam->input;
8803   vl_api_proxy_arp_add_del_t *mp;
8804   u32 vrf_id = 0;
8805   u8 is_add = 1;
8806   vl_api_ip4_address_t lo, hi;
8807   u8 range_set = 0;
8808   int ret;
8809
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "vrf %d", &vrf_id))
8813         ;
8814       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8815                          unformat_vl_api_ip4_address, &hi))
8816         range_set = 1;
8817       else if (unformat (i, "del"))
8818         is_add = 0;
8819       else
8820         {
8821           clib_warning ("parse error '%U'", format_unformat_error, i);
8822           return -99;
8823         }
8824     }
8825
8826   if (range_set == 0)
8827     {
8828       errmsg ("address range not set");
8829       return -99;
8830     }
8831
8832   M (PROXY_ARP_ADD_DEL, mp);
8833
8834   mp->proxy.table_id = ntohl (vrf_id);
8835   mp->is_add = is_add;
8836   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8837   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8838
8839   S (mp);
8840   W (ret);
8841   return ret;
8842 }
8843
8844 static int
8845 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8846 {
8847   unformat_input_t *i = vam->input;
8848   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8849   u32 sw_if_index;
8850   u8 enable = 1;
8851   u8 sw_if_index_set = 0;
8852   int ret;
8853
8854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8855     {
8856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8857         sw_if_index_set = 1;
8858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8859         sw_if_index_set = 1;
8860       else if (unformat (i, "enable"))
8861         enable = 1;
8862       else if (unformat (i, "disable"))
8863         enable = 0;
8864       else
8865         {
8866           clib_warning ("parse error '%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (sw_if_index_set == 0)
8872     {
8873       errmsg ("missing interface name or sw_if_index");
8874       return -99;
8875     }
8876
8877   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8878
8879   mp->sw_if_index = ntohl (sw_if_index);
8880   mp->enable_disable = enable;
8881
8882   S (mp);
8883   W (ret);
8884   return ret;
8885 }
8886
8887 static int
8888 api_mpls_tunnel_add_del (vat_main_t * vam)
8889 {
8890   unformat_input_t *i = vam->input;
8891   vl_api_mpls_tunnel_add_del_t *mp;
8892
8893   vl_api_fib_path_t paths[8];
8894   u32 sw_if_index = ~0;
8895   u8 path_count = 0;
8896   u8 l2_only = 0;
8897   u8 is_add = 1;
8898   int ret;
8899
8900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8901     {
8902       if (unformat (i, "add"))
8903         is_add = 1;
8904       else
8905         if (unformat
8906             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8907         is_add = 0;
8908       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8909         is_add = 0;
8910       else if (unformat (i, "l2-only"))
8911         l2_only = 1;
8912       else
8913         if (unformat
8914             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8915         {
8916           path_count++;
8917           if (8 == path_count)
8918             {
8919               errmsg ("max 8 paths");
8920               return -99;
8921             }
8922         }
8923       else
8924         {
8925           clib_warning ("parse error '%U'", format_unformat_error, i);
8926           return -99;
8927         }
8928     }
8929
8930   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8931
8932   mp->mt_is_add = is_add;
8933   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8934   mp->mt_tunnel.mt_l2_only = l2_only;
8935   mp->mt_tunnel.mt_is_multicast = 0;
8936   mp->mt_tunnel.mt_n_paths = path_count;
8937
8938   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8939                sizeof (paths[0]) * path_count);
8940
8941   S (mp);
8942   W (ret);
8943   return ret;
8944 }
8945
8946 static int
8947 api_sw_interface_set_unnumbered (vat_main_t * vam)
8948 {
8949   unformat_input_t *i = vam->input;
8950   vl_api_sw_interface_set_unnumbered_t *mp;
8951   u32 sw_if_index;
8952   u32 unnum_sw_index = ~0;
8953   u8 is_add = 1;
8954   u8 sw_if_index_set = 0;
8955   int ret;
8956
8957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8958     {
8959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8960         sw_if_index_set = 1;
8961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8962         sw_if_index_set = 1;
8963       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8964         ;
8965       else if (unformat (i, "del"))
8966         is_add = 0;
8967       else
8968         {
8969           clib_warning ("parse error '%U'", format_unformat_error, i);
8970           return -99;
8971         }
8972     }
8973
8974   if (sw_if_index_set == 0)
8975     {
8976       errmsg ("missing interface name or sw_if_index");
8977       return -99;
8978     }
8979
8980   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8981
8982   mp->sw_if_index = ntohl (sw_if_index);
8983   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8984   mp->is_add = is_add;
8985
8986   S (mp);
8987   W (ret);
8988   return ret;
8989 }
8990
8991 static int
8992 api_ip_neighbor_add_del (vat_main_t * vam)
8993 {
8994   vl_api_mac_address_t mac_address;
8995   unformat_input_t *i = vam->input;
8996   vl_api_ip_neighbor_add_del_t *mp;
8997   vl_api_address_t ip_address;
8998   u32 sw_if_index;
8999   u8 sw_if_index_set = 0;
9000   u8 is_add = 1;
9001   u8 mac_set = 0;
9002   u8 address_set = 0;
9003   int ret;
9004   ip_neighbor_flags_t flags;
9005
9006   flags = IP_NEIGHBOR_FLAG_NONE;
9007   clib_memset (&ip_address, 0, sizeof (ip_address));
9008   clib_memset (&mac_address, 0, sizeof (mac_address));
9009
9010   /* Parse args required to build the message */
9011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9012     {
9013       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9014         {
9015           mac_set = 1;
9016         }
9017       else if (unformat (i, "del"))
9018         is_add = 0;
9019       else
9020         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9021         sw_if_index_set = 1;
9022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9023         sw_if_index_set = 1;
9024       else if (unformat (i, "static"))
9025         flags |= IP_NEIGHBOR_FLAG_STATIC;
9026       else if (unformat (i, "no-fib-entry"))
9027         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9028       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9029         address_set = 1;
9030       else
9031         {
9032           clib_warning ("parse error '%U'", format_unformat_error, i);
9033           return -99;
9034         }
9035     }
9036
9037   if (sw_if_index_set == 0)
9038     {
9039       errmsg ("missing interface name or sw_if_index");
9040       return -99;
9041     }
9042   if (!address_set)
9043     {
9044       errmsg ("no address set");
9045       return -99;
9046     }
9047
9048   /* Construct the API message */
9049   M (IP_NEIGHBOR_ADD_DEL, mp);
9050
9051   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9052   mp->is_add = is_add;
9053   mp->neighbor.flags = htonl (flags);
9054   if (mac_set)
9055     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9056                  sizeof (mac_address));
9057   if (address_set)
9058     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9059
9060   /* send it... */
9061   S (mp);
9062
9063   /* Wait for a reply, return good/bad news  */
9064   W (ret);
9065   return ret;
9066 }
9067
9068 static int
9069 api_create_vlan_subif (vat_main_t * vam)
9070 {
9071   unformat_input_t *i = vam->input;
9072   vl_api_create_vlan_subif_t *mp;
9073   u32 sw_if_index;
9074   u8 sw_if_index_set = 0;
9075   u32 vlan_id;
9076   u8 vlan_id_set = 0;
9077   int ret;
9078
9079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9080     {
9081       if (unformat (i, "sw_if_index %d", &sw_if_index))
9082         sw_if_index_set = 1;
9083       else
9084         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9085         sw_if_index_set = 1;
9086       else if (unformat (i, "vlan %d", &vlan_id))
9087         vlan_id_set = 1;
9088       else
9089         {
9090           clib_warning ("parse error '%U'", format_unformat_error, i);
9091           return -99;
9092         }
9093     }
9094
9095   if (sw_if_index_set == 0)
9096     {
9097       errmsg ("missing interface name or sw_if_index");
9098       return -99;
9099     }
9100
9101   if (vlan_id_set == 0)
9102     {
9103       errmsg ("missing vlan_id");
9104       return -99;
9105     }
9106   M (CREATE_VLAN_SUBIF, mp);
9107
9108   mp->sw_if_index = ntohl (sw_if_index);
9109   mp->vlan_id = ntohl (vlan_id);
9110
9111   S (mp);
9112   W (ret);
9113   return ret;
9114 }
9115
9116 #define foreach_create_subif_bit                \
9117 _(no_tags)                                      \
9118 _(one_tag)                                      \
9119 _(two_tags)                                     \
9120 _(dot1ad)                                       \
9121 _(exact_match)                                  \
9122 _(default_sub)                                  \
9123 _(outer_vlan_id_any)                            \
9124 _(inner_vlan_id_any)
9125
9126 #define foreach_create_subif_flag               \
9127 _(0, "no_tags")                                 \
9128 _(1, "one_tag")                                 \
9129 _(2, "two_tags")                                \
9130 _(3, "dot1ad")                                  \
9131 _(4, "exact_match")                             \
9132 _(5, "default_sub")                             \
9133 _(6, "outer_vlan_id_any")                       \
9134 _(7, "inner_vlan_id_any")
9135
9136 static int
9137 api_create_subif (vat_main_t * vam)
9138 {
9139   unformat_input_t *i = vam->input;
9140   vl_api_create_subif_t *mp;
9141   u32 sw_if_index;
9142   u8 sw_if_index_set = 0;
9143   u32 sub_id;
9144   u8 sub_id_set = 0;
9145   u32 __attribute__ ((unused)) no_tags = 0;
9146   u32 __attribute__ ((unused)) one_tag = 0;
9147   u32 __attribute__ ((unused)) two_tags = 0;
9148   u32 __attribute__ ((unused)) dot1ad = 0;
9149   u32 __attribute__ ((unused)) exact_match = 0;
9150   u32 __attribute__ ((unused)) default_sub = 0;
9151   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9152   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9153   u32 tmp;
9154   u16 outer_vlan_id = 0;
9155   u16 inner_vlan_id = 0;
9156   int ret;
9157
9158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9159     {
9160       if (unformat (i, "sw_if_index %d", &sw_if_index))
9161         sw_if_index_set = 1;
9162       else
9163         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9164         sw_if_index_set = 1;
9165       else if (unformat (i, "sub_id %d", &sub_id))
9166         sub_id_set = 1;
9167       else if (unformat (i, "outer_vlan_id %d", &tmp))
9168         outer_vlan_id = tmp;
9169       else if (unformat (i, "inner_vlan_id %d", &tmp))
9170         inner_vlan_id = tmp;
9171
9172 #define _(a) else if (unformat (i, #a)) a = 1 ;
9173       foreach_create_subif_bit
9174 #undef _
9175         else
9176         {
9177           clib_warning ("parse error '%U'", format_unformat_error, i);
9178           return -99;
9179         }
9180     }
9181
9182   if (sw_if_index_set == 0)
9183     {
9184       errmsg ("missing interface name or sw_if_index");
9185       return -99;
9186     }
9187
9188   if (sub_id_set == 0)
9189     {
9190       errmsg ("missing sub_id");
9191       return -99;
9192     }
9193   M (CREATE_SUBIF, mp);
9194
9195   mp->sw_if_index = ntohl (sw_if_index);
9196   mp->sub_id = ntohl (sub_id);
9197
9198 #define _(a,b) mp->sub_if_flags |= (1 << a);
9199   foreach_create_subif_flag;
9200 #undef _
9201
9202   mp->outer_vlan_id = ntohs (outer_vlan_id);
9203   mp->inner_vlan_id = ntohs (inner_vlan_id);
9204
9205   S (mp);
9206   W (ret);
9207   return ret;
9208 }
9209
9210 static int
9211 api_reset_fib (vat_main_t * vam)
9212 {
9213   unformat_input_t *i = vam->input;
9214   vl_api_reset_fib_t *mp;
9215   u32 vrf_id = 0;
9216   u8 is_ipv6 = 0;
9217   u8 vrf_id_set = 0;
9218
9219   int ret;
9220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9221     {
9222       if (unformat (i, "vrf %d", &vrf_id))
9223         vrf_id_set = 1;
9224       else if (unformat (i, "ipv6"))
9225         is_ipv6 = 1;
9226       else
9227         {
9228           clib_warning ("parse error '%U'", format_unformat_error, i);
9229           return -99;
9230         }
9231     }
9232
9233   if (vrf_id_set == 0)
9234     {
9235       errmsg ("missing vrf id");
9236       return -99;
9237     }
9238
9239   M (RESET_FIB, mp);
9240
9241   mp->vrf_id = ntohl (vrf_id);
9242   mp->is_ipv6 = is_ipv6;
9243
9244   S (mp);
9245   W (ret);
9246   return ret;
9247 }
9248
9249 static int
9250 api_set_ip_flow_hash (vat_main_t * vam)
9251 {
9252   unformat_input_t *i = vam->input;
9253   vl_api_set_ip_flow_hash_t *mp;
9254   u32 vrf_id = 0;
9255   u8 is_ipv6 = 0;
9256   u8 vrf_id_set = 0;
9257   u8 src = 0;
9258   u8 dst = 0;
9259   u8 sport = 0;
9260   u8 dport = 0;
9261   u8 proto = 0;
9262   u8 reverse = 0;
9263   int ret;
9264
9265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9266     {
9267       if (unformat (i, "vrf %d", &vrf_id))
9268         vrf_id_set = 1;
9269       else if (unformat (i, "ipv6"))
9270         is_ipv6 = 1;
9271       else if (unformat (i, "src"))
9272         src = 1;
9273       else if (unformat (i, "dst"))
9274         dst = 1;
9275       else if (unformat (i, "sport"))
9276         sport = 1;
9277       else if (unformat (i, "dport"))
9278         dport = 1;
9279       else if (unformat (i, "proto"))
9280         proto = 1;
9281       else if (unformat (i, "reverse"))
9282         reverse = 1;
9283
9284       else
9285         {
9286           clib_warning ("parse error '%U'", format_unformat_error, i);
9287           return -99;
9288         }
9289     }
9290
9291   if (vrf_id_set == 0)
9292     {
9293       errmsg ("missing vrf id");
9294       return -99;
9295     }
9296
9297   M (SET_IP_FLOW_HASH, mp);
9298   mp->src = src;
9299   mp->dst = dst;
9300   mp->sport = sport;
9301   mp->dport = dport;
9302   mp->proto = proto;
9303   mp->reverse = reverse;
9304   mp->vrf_id = ntohl (vrf_id);
9305   mp->is_ipv6 = is_ipv6;
9306
9307   S (mp);
9308   W (ret);
9309   return ret;
9310 }
9311
9312 static int
9313 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9314 {
9315   unformat_input_t *i = vam->input;
9316   vl_api_sw_interface_ip6_enable_disable_t *mp;
9317   u32 sw_if_index;
9318   u8 sw_if_index_set = 0;
9319   u8 enable = 0;
9320   int ret;
9321
9322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "enable"))
9329         enable = 1;
9330       else if (unformat (i, "disable"))
9331         enable = 0;
9332       else
9333         {
9334           clib_warning ("parse error '%U'", format_unformat_error, i);
9335           return -99;
9336         }
9337     }
9338
9339   if (sw_if_index_set == 0)
9340     {
9341       errmsg ("missing interface name or sw_if_index");
9342       return -99;
9343     }
9344
9345   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9346
9347   mp->sw_if_index = ntohl (sw_if_index);
9348   mp->enable = enable;
9349
9350   S (mp);
9351   W (ret);
9352   return ret;
9353 }
9354
9355 static int
9356 api_ip6nd_proxy_add_del (vat_main_t * vam)
9357 {
9358   unformat_input_t *i = vam->input;
9359   vl_api_ip6nd_proxy_add_del_t *mp;
9360   u32 sw_if_index = ~0;
9361   u8 v6_address_set = 0;
9362   vl_api_ip6_address_t v6address;
9363   u8 is_del = 0;
9364   int ret;
9365
9366   /* Parse args required to build the message */
9367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9368     {
9369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9370         ;
9371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9372         ;
9373       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9374         v6_address_set = 1;
9375       if (unformat (i, "del"))
9376         is_del = 1;
9377       else
9378         {
9379           clib_warning ("parse error '%U'", format_unformat_error, i);
9380           return -99;
9381         }
9382     }
9383
9384   if (sw_if_index == ~0)
9385     {
9386       errmsg ("missing interface name or sw_if_index");
9387       return -99;
9388     }
9389   if (!v6_address_set)
9390     {
9391       errmsg ("no address set");
9392       return -99;
9393     }
9394
9395   /* Construct the API message */
9396   M (IP6ND_PROXY_ADD_DEL, mp);
9397
9398   mp->is_del = is_del;
9399   mp->sw_if_index = ntohl (sw_if_index);
9400   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9401
9402   /* send it... */
9403   S (mp);
9404
9405   /* Wait for a reply, return good/bad news  */
9406   W (ret);
9407   return ret;
9408 }
9409
9410 static int
9411 api_ip6nd_proxy_dump (vat_main_t * vam)
9412 {
9413   vl_api_ip6nd_proxy_dump_t *mp;
9414   vl_api_control_ping_t *mp_ping;
9415   int ret;
9416
9417   M (IP6ND_PROXY_DUMP, mp);
9418
9419   S (mp);
9420
9421   /* Use a control ping for synchronization */
9422   MPING (CONTROL_PING, mp_ping);
9423   S (mp_ping);
9424
9425   W (ret);
9426   return ret;
9427 }
9428
9429 static void vl_api_ip6nd_proxy_details_t_handler
9430   (vl_api_ip6nd_proxy_details_t * mp)
9431 {
9432   vat_main_t *vam = &vat_main;
9433
9434   print (vam->ofp, "host %U sw_if_index %d",
9435          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9436 }
9437
9438 static void vl_api_ip6nd_proxy_details_t_handler_json
9439   (vl_api_ip6nd_proxy_details_t * mp)
9440 {
9441   vat_main_t *vam = &vat_main;
9442   struct in6_addr ip6;
9443   vat_json_node_t *node = NULL;
9444
9445   if (VAT_JSON_ARRAY != vam->json_tree.type)
9446     {
9447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9448       vat_json_init_array (&vam->json_tree);
9449     }
9450   node = vat_json_array_add (&vam->json_tree);
9451
9452   vat_json_init_object (node);
9453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9454
9455   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9456   vat_json_object_add_ip6 (node, "host", ip6);
9457 }
9458
9459 static int
9460 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9461 {
9462   unformat_input_t *i = vam->input;
9463   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9464   u32 sw_if_index;
9465   u8 sw_if_index_set = 0;
9466   u8 v6_address_set = 0;
9467   vl_api_prefix_t pfx;
9468   u8 use_default = 0;
9469   u8 no_advertise = 0;
9470   u8 off_link = 0;
9471   u8 no_autoconfig = 0;
9472   u8 no_onlink = 0;
9473   u8 is_no = 0;
9474   u32 val_lifetime = 0;
9475   u32 pref_lifetime = 0;
9476   int ret;
9477
9478   /* Parse args required to build the message */
9479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9480     {
9481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9482         sw_if_index_set = 1;
9483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9484         sw_if_index_set = 1;
9485       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9486         v6_address_set = 1;
9487       else if (unformat (i, "val_life %d", &val_lifetime))
9488         ;
9489       else if (unformat (i, "pref_life %d", &pref_lifetime))
9490         ;
9491       else if (unformat (i, "def"))
9492         use_default = 1;
9493       else if (unformat (i, "noadv"))
9494         no_advertise = 1;
9495       else if (unformat (i, "offl"))
9496         off_link = 1;
9497       else if (unformat (i, "noauto"))
9498         no_autoconfig = 1;
9499       else if (unformat (i, "nolink"))
9500         no_onlink = 1;
9501       else if (unformat (i, "isno"))
9502         is_no = 1;
9503       else
9504         {
9505           clib_warning ("parse error '%U'", format_unformat_error, i);
9506           return -99;
9507         }
9508     }
9509
9510   if (sw_if_index_set == 0)
9511     {
9512       errmsg ("missing interface name or sw_if_index");
9513       return -99;
9514     }
9515   if (!v6_address_set)
9516     {
9517       errmsg ("no address set");
9518       return -99;
9519     }
9520
9521   /* Construct the API message */
9522   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9523
9524   mp->sw_if_index = ntohl (sw_if_index);
9525   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9526   mp->use_default = use_default;
9527   mp->no_advertise = no_advertise;
9528   mp->off_link = off_link;
9529   mp->no_autoconfig = no_autoconfig;
9530   mp->no_onlink = no_onlink;
9531   mp->is_no = is_no;
9532   mp->val_lifetime = ntohl (val_lifetime);
9533   mp->pref_lifetime = ntohl (pref_lifetime);
9534
9535   /* send it... */
9536   S (mp);
9537
9538   /* Wait for a reply, return good/bad news  */
9539   W (ret);
9540   return ret;
9541 }
9542
9543 static int
9544 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9545 {
9546   unformat_input_t *i = vam->input;
9547   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9548   u32 sw_if_index;
9549   u8 sw_if_index_set = 0;
9550   u8 suppress = 0;
9551   u8 managed = 0;
9552   u8 other = 0;
9553   u8 ll_option = 0;
9554   u8 send_unicast = 0;
9555   u8 cease = 0;
9556   u8 is_no = 0;
9557   u8 default_router = 0;
9558   u32 max_interval = 0;
9559   u32 min_interval = 0;
9560   u32 lifetime = 0;
9561   u32 initial_count = 0;
9562   u32 initial_interval = 0;
9563   int ret;
9564
9565
9566   /* Parse args required to build the message */
9567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9568     {
9569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9570         sw_if_index_set = 1;
9571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9572         sw_if_index_set = 1;
9573       else if (unformat (i, "maxint %d", &max_interval))
9574         ;
9575       else if (unformat (i, "minint %d", &min_interval))
9576         ;
9577       else if (unformat (i, "life %d", &lifetime))
9578         ;
9579       else if (unformat (i, "count %d", &initial_count))
9580         ;
9581       else if (unformat (i, "interval %d", &initial_interval))
9582         ;
9583       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9584         suppress = 1;
9585       else if (unformat (i, "managed"))
9586         managed = 1;
9587       else if (unformat (i, "other"))
9588         other = 1;
9589       else if (unformat (i, "ll"))
9590         ll_option = 1;
9591       else if (unformat (i, "send"))
9592         send_unicast = 1;
9593       else if (unformat (i, "cease"))
9594         cease = 1;
9595       else if (unformat (i, "isno"))
9596         is_no = 1;
9597       else if (unformat (i, "def"))
9598         default_router = 1;
9599       else
9600         {
9601           clib_warning ("parse error '%U'", format_unformat_error, i);
9602           return -99;
9603         }
9604     }
9605
9606   if (sw_if_index_set == 0)
9607     {
9608       errmsg ("missing interface name or sw_if_index");
9609       return -99;
9610     }
9611
9612   /* Construct the API message */
9613   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9614
9615   mp->sw_if_index = ntohl (sw_if_index);
9616   mp->max_interval = ntohl (max_interval);
9617   mp->min_interval = ntohl (min_interval);
9618   mp->lifetime = ntohl (lifetime);
9619   mp->initial_count = ntohl (initial_count);
9620   mp->initial_interval = ntohl (initial_interval);
9621   mp->suppress = suppress;
9622   mp->managed = managed;
9623   mp->other = other;
9624   mp->ll_option = ll_option;
9625   mp->send_unicast = send_unicast;
9626   mp->cease = cease;
9627   mp->is_no = is_no;
9628   mp->default_router = default_router;
9629
9630   /* send it... */
9631   S (mp);
9632
9633   /* Wait for a reply, return good/bad news  */
9634   W (ret);
9635   return ret;
9636 }
9637
9638 static int
9639 api_set_arp_neighbor_limit (vat_main_t * vam)
9640 {
9641   unformat_input_t *i = vam->input;
9642   vl_api_set_arp_neighbor_limit_t *mp;
9643   u32 arp_nbr_limit;
9644   u8 limit_set = 0;
9645   u8 is_ipv6 = 0;
9646   int ret;
9647
9648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9651         limit_set = 1;
9652       else if (unformat (i, "ipv6"))
9653         is_ipv6 = 1;
9654       else
9655         {
9656           clib_warning ("parse error '%U'", format_unformat_error, i);
9657           return -99;
9658         }
9659     }
9660
9661   if (limit_set == 0)
9662     {
9663       errmsg ("missing limit value");
9664       return -99;
9665     }
9666
9667   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9668
9669   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9670   mp->is_ipv6 = is_ipv6;
9671
9672   S (mp);
9673   W (ret);
9674   return ret;
9675 }
9676
9677 static int
9678 api_l2_patch_add_del (vat_main_t * vam)
9679 {
9680   unformat_input_t *i = vam->input;
9681   vl_api_l2_patch_add_del_t *mp;
9682   u32 rx_sw_if_index;
9683   u8 rx_sw_if_index_set = 0;
9684   u32 tx_sw_if_index;
9685   u8 tx_sw_if_index_set = 0;
9686   u8 is_add = 1;
9687   int ret;
9688
9689   /* Parse args required to build the message */
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9693         rx_sw_if_index_set = 1;
9694       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9695         tx_sw_if_index_set = 1;
9696       else if (unformat (i, "rx"))
9697         {
9698           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9699             {
9700               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9701                             &rx_sw_if_index))
9702                 rx_sw_if_index_set = 1;
9703             }
9704           else
9705             break;
9706         }
9707       else if (unformat (i, "tx"))
9708         {
9709           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9710             {
9711               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9712                             &tx_sw_if_index))
9713                 tx_sw_if_index_set = 1;
9714             }
9715           else
9716             break;
9717         }
9718       else if (unformat (i, "del"))
9719         is_add = 0;
9720       else
9721         break;
9722     }
9723
9724   if (rx_sw_if_index_set == 0)
9725     {
9726       errmsg ("missing rx interface name or rx_sw_if_index");
9727       return -99;
9728     }
9729
9730   if (tx_sw_if_index_set == 0)
9731     {
9732       errmsg ("missing tx interface name or tx_sw_if_index");
9733       return -99;
9734     }
9735
9736   M (L2_PATCH_ADD_DEL, mp);
9737
9738   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9739   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9740   mp->is_add = is_add;
9741
9742   S (mp);
9743   W (ret);
9744   return ret;
9745 }
9746
9747 u8 is_del;
9748 u8 localsid_addr[16];
9749 u8 end_psp;
9750 u8 behavior;
9751 u32 sw_if_index;
9752 u32 vlan_index;
9753 u32 fib_table;
9754 u8 nh_addr[16];
9755
9756 static int
9757 api_sr_localsid_add_del (vat_main_t * vam)
9758 {
9759   unformat_input_t *i = vam->input;
9760   vl_api_sr_localsid_add_del_t *mp;
9761
9762   u8 is_del;
9763   ip6_address_t localsid;
9764   u8 end_psp = 0;
9765   u8 behavior = ~0;
9766   u32 sw_if_index;
9767   u32 fib_table = ~(u32) 0;
9768   ip6_address_t nh_addr6;
9769   ip4_address_t nh_addr4;
9770   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9771   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9772
9773   bool nexthop_set = 0;
9774
9775   int ret;
9776
9777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9778     {
9779       if (unformat (i, "del"))
9780         is_del = 1;
9781       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9782       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9783         nexthop_set = 1;
9784       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9785         nexthop_set = 1;
9786       else if (unformat (i, "behavior %u", &behavior));
9787       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9788       else if (unformat (i, "fib-table %u", &fib_table));
9789       else if (unformat (i, "end.psp %u", &behavior));
9790       else
9791         break;
9792     }
9793
9794   M (SR_LOCALSID_ADD_DEL, mp);
9795
9796   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9797   if (nexthop_set)
9798     {
9799       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9800       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9801     }
9802   mp->behavior = behavior;
9803   mp->sw_if_index = ntohl (sw_if_index);
9804   mp->fib_table = ntohl (fib_table);
9805   mp->end_psp = end_psp;
9806   mp->is_del = is_del;
9807
9808   S (mp);
9809   W (ret);
9810   return ret;
9811 }
9812
9813 static int
9814 api_ioam_enable (vat_main_t * vam)
9815 {
9816   unformat_input_t *input = vam->input;
9817   vl_api_ioam_enable_t *mp;
9818   u32 id = 0;
9819   int has_trace_option = 0;
9820   int has_pot_option = 0;
9821   int has_seqno_option = 0;
9822   int has_analyse_option = 0;
9823   int ret;
9824
9825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (input, "trace"))
9828         has_trace_option = 1;
9829       else if (unformat (input, "pot"))
9830         has_pot_option = 1;
9831       else if (unformat (input, "seqno"))
9832         has_seqno_option = 1;
9833       else if (unformat (input, "analyse"))
9834         has_analyse_option = 1;
9835       else
9836         break;
9837     }
9838   M (IOAM_ENABLE, mp);
9839   mp->id = htons (id);
9840   mp->seqno = has_seqno_option;
9841   mp->analyse = has_analyse_option;
9842   mp->pot_enable = has_pot_option;
9843   mp->trace_enable = has_trace_option;
9844
9845   S (mp);
9846   W (ret);
9847   return ret;
9848 }
9849
9850
9851 static int
9852 api_ioam_disable (vat_main_t * vam)
9853 {
9854   vl_api_ioam_disable_t *mp;
9855   int ret;
9856
9857   M (IOAM_DISABLE, mp);
9858   S (mp);
9859   W (ret);
9860   return ret;
9861 }
9862
9863 #define foreach_tcp_proto_field                 \
9864 _(src_port)                                     \
9865 _(dst_port)
9866
9867 #define foreach_udp_proto_field                 \
9868 _(src_port)                                     \
9869 _(dst_port)
9870
9871 #define foreach_ip4_proto_field                 \
9872 _(src_address)                                  \
9873 _(dst_address)                                  \
9874 _(tos)                                          \
9875 _(length)                                       \
9876 _(fragment_id)                                  \
9877 _(ttl)                                          \
9878 _(protocol)                                     \
9879 _(checksum)
9880
9881 typedef struct
9882 {
9883   u16 src_port, dst_port;
9884 } tcpudp_header_t;
9885
9886 #if VPP_API_TEST_BUILTIN == 0
9887 uword
9888 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9889 {
9890   u8 **maskp = va_arg (*args, u8 **);
9891   u8 *mask = 0;
9892   u8 found_something = 0;
9893   tcp_header_t *tcp;
9894
9895 #define _(a) u8 a=0;
9896   foreach_tcp_proto_field;
9897 #undef _
9898
9899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9900     {
9901       if (0);
9902 #define _(a) else if (unformat (input, #a)) a=1;
9903       foreach_tcp_proto_field
9904 #undef _
9905         else
9906         break;
9907     }
9908
9909 #define _(a) found_something += a;
9910   foreach_tcp_proto_field;
9911 #undef _
9912
9913   if (found_something == 0)
9914     return 0;
9915
9916   vec_validate (mask, sizeof (*tcp) - 1);
9917
9918   tcp = (tcp_header_t *) mask;
9919
9920 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9921   foreach_tcp_proto_field;
9922 #undef _
9923
9924   *maskp = mask;
9925   return 1;
9926 }
9927
9928 uword
9929 unformat_udp_mask (unformat_input_t * input, va_list * args)
9930 {
9931   u8 **maskp = va_arg (*args, u8 **);
9932   u8 *mask = 0;
9933   u8 found_something = 0;
9934   udp_header_t *udp;
9935
9936 #define _(a) u8 a=0;
9937   foreach_udp_proto_field;
9938 #undef _
9939
9940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9941     {
9942       if (0);
9943 #define _(a) else if (unformat (input, #a)) a=1;
9944       foreach_udp_proto_field
9945 #undef _
9946         else
9947         break;
9948     }
9949
9950 #define _(a) found_something += a;
9951   foreach_udp_proto_field;
9952 #undef _
9953
9954   if (found_something == 0)
9955     return 0;
9956
9957   vec_validate (mask, sizeof (*udp) - 1);
9958
9959   udp = (udp_header_t *) mask;
9960
9961 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9962   foreach_udp_proto_field;
9963 #undef _
9964
9965   *maskp = mask;
9966   return 1;
9967 }
9968
9969 uword
9970 unformat_l4_mask (unformat_input_t * input, va_list * args)
9971 {
9972   u8 **maskp = va_arg (*args, u8 **);
9973   u16 src_port = 0, dst_port = 0;
9974   tcpudp_header_t *tcpudp;
9975
9976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9977     {
9978       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9979         return 1;
9980       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9981         return 1;
9982       else if (unformat (input, "src_port"))
9983         src_port = 0xFFFF;
9984       else if (unformat (input, "dst_port"))
9985         dst_port = 0xFFFF;
9986       else
9987         return 0;
9988     }
9989
9990   if (!src_port && !dst_port)
9991     return 0;
9992
9993   u8 *mask = 0;
9994   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9995
9996   tcpudp = (tcpudp_header_t *) mask;
9997   tcpudp->src_port = src_port;
9998   tcpudp->dst_port = dst_port;
9999
10000   *maskp = mask;
10001
10002   return 1;
10003 }
10004
10005 uword
10006 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10007 {
10008   u8 **maskp = va_arg (*args, u8 **);
10009   u8 *mask = 0;
10010   u8 found_something = 0;
10011   ip4_header_t *ip;
10012
10013 #define _(a) u8 a=0;
10014   foreach_ip4_proto_field;
10015 #undef _
10016   u8 version = 0;
10017   u8 hdr_length = 0;
10018
10019
10020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10021     {
10022       if (unformat (input, "version"))
10023         version = 1;
10024       else if (unformat (input, "hdr_length"))
10025         hdr_length = 1;
10026       else if (unformat (input, "src"))
10027         src_address = 1;
10028       else if (unformat (input, "dst"))
10029         dst_address = 1;
10030       else if (unformat (input, "proto"))
10031         protocol = 1;
10032
10033 #define _(a) else if (unformat (input, #a)) a=1;
10034       foreach_ip4_proto_field
10035 #undef _
10036         else
10037         break;
10038     }
10039
10040 #define _(a) found_something += a;
10041   foreach_ip4_proto_field;
10042 #undef _
10043
10044   if (found_something == 0)
10045     return 0;
10046
10047   vec_validate (mask, sizeof (*ip) - 1);
10048
10049   ip = (ip4_header_t *) mask;
10050
10051 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10052   foreach_ip4_proto_field;
10053 #undef _
10054
10055   ip->ip_version_and_header_length = 0;
10056
10057   if (version)
10058     ip->ip_version_and_header_length |= 0xF0;
10059
10060   if (hdr_length)
10061     ip->ip_version_and_header_length |= 0x0F;
10062
10063   *maskp = mask;
10064   return 1;
10065 }
10066
10067 #define foreach_ip6_proto_field                 \
10068 _(src_address)                                  \
10069 _(dst_address)                                  \
10070 _(payload_length)                               \
10071 _(hop_limit)                                    \
10072 _(protocol)
10073
10074 uword
10075 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10076 {
10077   u8 **maskp = va_arg (*args, u8 **);
10078   u8 *mask = 0;
10079   u8 found_something = 0;
10080   ip6_header_t *ip;
10081   u32 ip_version_traffic_class_and_flow_label;
10082
10083 #define _(a) u8 a=0;
10084   foreach_ip6_proto_field;
10085 #undef _
10086   u8 version = 0;
10087   u8 traffic_class = 0;
10088   u8 flow_label = 0;
10089
10090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (input, "version"))
10093         version = 1;
10094       else if (unformat (input, "traffic-class"))
10095         traffic_class = 1;
10096       else if (unformat (input, "flow-label"))
10097         flow_label = 1;
10098       else if (unformat (input, "src"))
10099         src_address = 1;
10100       else if (unformat (input, "dst"))
10101         dst_address = 1;
10102       else if (unformat (input, "proto"))
10103         protocol = 1;
10104
10105 #define _(a) else if (unformat (input, #a)) a=1;
10106       foreach_ip6_proto_field
10107 #undef _
10108         else
10109         break;
10110     }
10111
10112 #define _(a) found_something += a;
10113   foreach_ip6_proto_field;
10114 #undef _
10115
10116   if (found_something == 0)
10117     return 0;
10118
10119   vec_validate (mask, sizeof (*ip) - 1);
10120
10121   ip = (ip6_header_t *) mask;
10122
10123 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10124   foreach_ip6_proto_field;
10125 #undef _
10126
10127   ip_version_traffic_class_and_flow_label = 0;
10128
10129   if (version)
10130     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10131
10132   if (traffic_class)
10133     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10134
10135   if (flow_label)
10136     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10137
10138   ip->ip_version_traffic_class_and_flow_label =
10139     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10140
10141   *maskp = mask;
10142   return 1;
10143 }
10144
10145 uword
10146 unformat_l3_mask (unformat_input_t * input, va_list * args)
10147 {
10148   u8 **maskp = va_arg (*args, u8 **);
10149
10150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10151     {
10152       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10153         return 1;
10154       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10155         return 1;
10156       else
10157         break;
10158     }
10159   return 0;
10160 }
10161
10162 uword
10163 unformat_l2_mask (unformat_input_t * input, va_list * args)
10164 {
10165   u8 **maskp = va_arg (*args, u8 **);
10166   u8 *mask = 0;
10167   u8 src = 0;
10168   u8 dst = 0;
10169   u8 proto = 0;
10170   u8 tag1 = 0;
10171   u8 tag2 = 0;
10172   u8 ignore_tag1 = 0;
10173   u8 ignore_tag2 = 0;
10174   u8 cos1 = 0;
10175   u8 cos2 = 0;
10176   u8 dot1q = 0;
10177   u8 dot1ad = 0;
10178   int len = 14;
10179
10180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10181     {
10182       if (unformat (input, "src"))
10183         src = 1;
10184       else if (unformat (input, "dst"))
10185         dst = 1;
10186       else if (unformat (input, "proto"))
10187         proto = 1;
10188       else if (unformat (input, "tag1"))
10189         tag1 = 1;
10190       else if (unformat (input, "tag2"))
10191         tag2 = 1;
10192       else if (unformat (input, "ignore-tag1"))
10193         ignore_tag1 = 1;
10194       else if (unformat (input, "ignore-tag2"))
10195         ignore_tag2 = 1;
10196       else if (unformat (input, "cos1"))
10197         cos1 = 1;
10198       else if (unformat (input, "cos2"))
10199         cos2 = 1;
10200       else if (unformat (input, "dot1q"))
10201         dot1q = 1;
10202       else if (unformat (input, "dot1ad"))
10203         dot1ad = 1;
10204       else
10205         break;
10206     }
10207   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10208        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10209     return 0;
10210
10211   if (tag1 || ignore_tag1 || cos1 || dot1q)
10212     len = 18;
10213   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10214     len = 22;
10215
10216   vec_validate (mask, len - 1);
10217
10218   if (dst)
10219     clib_memset (mask, 0xff, 6);
10220
10221   if (src)
10222     clib_memset (mask + 6, 0xff, 6);
10223
10224   if (tag2 || dot1ad)
10225     {
10226       /* inner vlan tag */
10227       if (tag2)
10228         {
10229           mask[19] = 0xff;
10230           mask[18] = 0x0f;
10231         }
10232       if (cos2)
10233         mask[18] |= 0xe0;
10234       if (proto)
10235         mask[21] = mask[20] = 0xff;
10236       if (tag1)
10237         {
10238           mask[15] = 0xff;
10239           mask[14] = 0x0f;
10240         }
10241       if (cos1)
10242         mask[14] |= 0xe0;
10243       *maskp = mask;
10244       return 1;
10245     }
10246   if (tag1 | dot1q)
10247     {
10248       if (tag1)
10249         {
10250           mask[15] = 0xff;
10251           mask[14] = 0x0f;
10252         }
10253       if (cos1)
10254         mask[14] |= 0xe0;
10255       if (proto)
10256         mask[16] = mask[17] = 0xff;
10257
10258       *maskp = mask;
10259       return 1;
10260     }
10261   if (cos2)
10262     mask[18] |= 0xe0;
10263   if (cos1)
10264     mask[14] |= 0xe0;
10265   if (proto)
10266     mask[12] = mask[13] = 0xff;
10267
10268   *maskp = mask;
10269   return 1;
10270 }
10271
10272 uword
10273 unformat_classify_mask (unformat_input_t * input, va_list * args)
10274 {
10275   u8 **maskp = va_arg (*args, u8 **);
10276   u32 *skipp = va_arg (*args, u32 *);
10277   u32 *matchp = va_arg (*args, u32 *);
10278   u32 match;
10279   u8 *mask = 0;
10280   u8 *l2 = 0;
10281   u8 *l3 = 0;
10282   u8 *l4 = 0;
10283   int i;
10284
10285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10286     {
10287       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10288         ;
10289       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10290         ;
10291       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10292         ;
10293       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10294         ;
10295       else
10296         break;
10297     }
10298
10299   if (l4 && !l3)
10300     {
10301       vec_free (mask);
10302       vec_free (l2);
10303       vec_free (l4);
10304       return 0;
10305     }
10306
10307   if (mask || l2 || l3 || l4)
10308     {
10309       if (l2 || l3 || l4)
10310         {
10311           /* "With a free Ethernet header in every package" */
10312           if (l2 == 0)
10313             vec_validate (l2, 13);
10314           mask = l2;
10315           if (vec_len (l3))
10316             {
10317               vec_append (mask, l3);
10318               vec_free (l3);
10319             }
10320           if (vec_len (l4))
10321             {
10322               vec_append (mask, l4);
10323               vec_free (l4);
10324             }
10325         }
10326
10327       /* Scan forward looking for the first significant mask octet */
10328       for (i = 0; i < vec_len (mask); i++)
10329         if (mask[i])
10330           break;
10331
10332       /* compute (skip, match) params */
10333       *skipp = i / sizeof (u32x4);
10334       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10335
10336       /* Pad mask to an even multiple of the vector size */
10337       while (vec_len (mask) % sizeof (u32x4))
10338         vec_add1 (mask, 0);
10339
10340       match = vec_len (mask) / sizeof (u32x4);
10341
10342       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10343         {
10344           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10345           if (*tmp || *(tmp + 1))
10346             break;
10347           match--;
10348         }
10349       if (match == 0)
10350         clib_warning ("BUG: match 0");
10351
10352       _vec_len (mask) = match * sizeof (u32x4);
10353
10354       *matchp = match;
10355       *maskp = mask;
10356
10357       return 1;
10358     }
10359
10360   return 0;
10361 }
10362 #endif /* VPP_API_TEST_BUILTIN */
10363
10364 #define foreach_l2_next                         \
10365 _(drop, DROP)                                   \
10366 _(ethernet, ETHERNET_INPUT)                     \
10367 _(ip4, IP4_INPUT)                               \
10368 _(ip6, IP6_INPUT)
10369
10370 uword
10371 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10372 {
10373   u32 *miss_next_indexp = va_arg (*args, u32 *);
10374   u32 next_index = 0;
10375   u32 tmp;
10376
10377 #define _(n,N) \
10378   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10379   foreach_l2_next;
10380 #undef _
10381
10382   if (unformat (input, "%d", &tmp))
10383     {
10384       next_index = tmp;
10385       goto out;
10386     }
10387
10388   return 0;
10389
10390 out:
10391   *miss_next_indexp = next_index;
10392   return 1;
10393 }
10394
10395 #define foreach_ip_next                         \
10396 _(drop, DROP)                                   \
10397 _(local, LOCAL)                                 \
10398 _(rewrite, REWRITE)
10399
10400 uword
10401 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10402 {
10403   u32 *miss_next_indexp = va_arg (*args, u32 *);
10404   u32 next_index = 0;
10405   u32 tmp;
10406
10407 #define _(n,N) \
10408   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10409   foreach_ip_next;
10410 #undef _
10411
10412   if (unformat (input, "%d", &tmp))
10413     {
10414       next_index = tmp;
10415       goto out;
10416     }
10417
10418   return 0;
10419
10420 out:
10421   *miss_next_indexp = next_index;
10422   return 1;
10423 }
10424
10425 #define foreach_acl_next                        \
10426 _(deny, DENY)
10427
10428 uword
10429 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10430 {
10431   u32 *miss_next_indexp = va_arg (*args, u32 *);
10432   u32 next_index = 0;
10433   u32 tmp;
10434
10435 #define _(n,N) \
10436   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10437   foreach_acl_next;
10438 #undef _
10439
10440   if (unformat (input, "permit"))
10441     {
10442       next_index = ~0;
10443       goto out;
10444     }
10445   else if (unformat (input, "%d", &tmp))
10446     {
10447       next_index = tmp;
10448       goto out;
10449     }
10450
10451   return 0;
10452
10453 out:
10454   *miss_next_indexp = next_index;
10455   return 1;
10456 }
10457
10458 uword
10459 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10460 {
10461   u32 *r = va_arg (*args, u32 *);
10462
10463   if (unformat (input, "conform-color"))
10464     *r = POLICE_CONFORM;
10465   else if (unformat (input, "exceed-color"))
10466     *r = POLICE_EXCEED;
10467   else
10468     return 0;
10469
10470   return 1;
10471 }
10472
10473 static int
10474 api_classify_add_del_table (vat_main_t * vam)
10475 {
10476   unformat_input_t *i = vam->input;
10477   vl_api_classify_add_del_table_t *mp;
10478
10479   u32 nbuckets = 2;
10480   u32 skip = ~0;
10481   u32 match = ~0;
10482   int is_add = 1;
10483   int del_chain = 0;
10484   u32 table_index = ~0;
10485   u32 next_table_index = ~0;
10486   u32 miss_next_index = ~0;
10487   u32 memory_size = 32 << 20;
10488   u8 *mask = 0;
10489   u32 current_data_flag = 0;
10490   int current_data_offset = 0;
10491   int ret;
10492
10493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (i, "del"))
10496         is_add = 0;
10497       else if (unformat (i, "del-chain"))
10498         {
10499           is_add = 0;
10500           del_chain = 1;
10501         }
10502       else if (unformat (i, "buckets %d", &nbuckets))
10503         ;
10504       else if (unformat (i, "memory_size %d", &memory_size))
10505         ;
10506       else if (unformat (i, "skip %d", &skip))
10507         ;
10508       else if (unformat (i, "match %d", &match))
10509         ;
10510       else if (unformat (i, "table %d", &table_index))
10511         ;
10512       else if (unformat (i, "mask %U", unformat_classify_mask,
10513                          &mask, &skip, &match))
10514         ;
10515       else if (unformat (i, "next-table %d", &next_table_index))
10516         ;
10517       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10518                          &miss_next_index))
10519         ;
10520       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10521                          &miss_next_index))
10522         ;
10523       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10524                          &miss_next_index))
10525         ;
10526       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10527         ;
10528       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10529         ;
10530       else
10531         break;
10532     }
10533
10534   if (is_add && mask == 0)
10535     {
10536       errmsg ("Mask required");
10537       return -99;
10538     }
10539
10540   if (is_add && skip == ~0)
10541     {
10542       errmsg ("skip count required");
10543       return -99;
10544     }
10545
10546   if (is_add && match == ~0)
10547     {
10548       errmsg ("match count required");
10549       return -99;
10550     }
10551
10552   if (!is_add && table_index == ~0)
10553     {
10554       errmsg ("table index required for delete");
10555       return -99;
10556     }
10557
10558   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10559
10560   mp->is_add = is_add;
10561   mp->del_chain = del_chain;
10562   mp->table_index = ntohl (table_index);
10563   mp->nbuckets = ntohl (nbuckets);
10564   mp->memory_size = ntohl (memory_size);
10565   mp->skip_n_vectors = ntohl (skip);
10566   mp->match_n_vectors = ntohl (match);
10567   mp->next_table_index = ntohl (next_table_index);
10568   mp->miss_next_index = ntohl (miss_next_index);
10569   mp->current_data_flag = ntohl (current_data_flag);
10570   mp->current_data_offset = ntohl (current_data_offset);
10571   mp->mask_len = ntohl (vec_len (mask));
10572   clib_memcpy (mp->mask, mask, vec_len (mask));
10573
10574   vec_free (mask);
10575
10576   S (mp);
10577   W (ret);
10578   return ret;
10579 }
10580
10581 #if VPP_API_TEST_BUILTIN == 0
10582 uword
10583 unformat_l4_match (unformat_input_t * input, va_list * args)
10584 {
10585   u8 **matchp = va_arg (*args, u8 **);
10586
10587   u8 *proto_header = 0;
10588   int src_port = 0;
10589   int dst_port = 0;
10590
10591   tcpudp_header_t h;
10592
10593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10594     {
10595       if (unformat (input, "src_port %d", &src_port))
10596         ;
10597       else if (unformat (input, "dst_port %d", &dst_port))
10598         ;
10599       else
10600         return 0;
10601     }
10602
10603   h.src_port = clib_host_to_net_u16 (src_port);
10604   h.dst_port = clib_host_to_net_u16 (dst_port);
10605   vec_validate (proto_header, sizeof (h) - 1);
10606   memcpy (proto_header, &h, sizeof (h));
10607
10608   *matchp = proto_header;
10609
10610   return 1;
10611 }
10612
10613 uword
10614 unformat_ip4_match (unformat_input_t * input, va_list * args)
10615 {
10616   u8 **matchp = va_arg (*args, u8 **);
10617   u8 *match = 0;
10618   ip4_header_t *ip;
10619   int version = 0;
10620   u32 version_val;
10621   int hdr_length = 0;
10622   u32 hdr_length_val;
10623   int src = 0, dst = 0;
10624   ip4_address_t src_val, dst_val;
10625   int proto = 0;
10626   u32 proto_val;
10627   int tos = 0;
10628   u32 tos_val;
10629   int length = 0;
10630   u32 length_val;
10631   int fragment_id = 0;
10632   u32 fragment_id_val;
10633   int ttl = 0;
10634   int ttl_val;
10635   int checksum = 0;
10636   u32 checksum_val;
10637
10638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10639     {
10640       if (unformat (input, "version %d", &version_val))
10641         version = 1;
10642       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10643         hdr_length = 1;
10644       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10645         src = 1;
10646       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10647         dst = 1;
10648       else if (unformat (input, "proto %d", &proto_val))
10649         proto = 1;
10650       else if (unformat (input, "tos %d", &tos_val))
10651         tos = 1;
10652       else if (unformat (input, "length %d", &length_val))
10653         length = 1;
10654       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10655         fragment_id = 1;
10656       else if (unformat (input, "ttl %d", &ttl_val))
10657         ttl = 1;
10658       else if (unformat (input, "checksum %d", &checksum_val))
10659         checksum = 1;
10660       else
10661         break;
10662     }
10663
10664   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10665       + ttl + checksum == 0)
10666     return 0;
10667
10668   /*
10669    * Aligned because we use the real comparison functions
10670    */
10671   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10672
10673   ip = (ip4_header_t *) match;
10674
10675   /* These are realistically matched in practice */
10676   if (src)
10677     ip->src_address.as_u32 = src_val.as_u32;
10678
10679   if (dst)
10680     ip->dst_address.as_u32 = dst_val.as_u32;
10681
10682   if (proto)
10683     ip->protocol = proto_val;
10684
10685
10686   /* These are not, but they're included for completeness */
10687   if (version)
10688     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10689
10690   if (hdr_length)
10691     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10692
10693   if (tos)
10694     ip->tos = tos_val;
10695
10696   if (length)
10697     ip->length = clib_host_to_net_u16 (length_val);
10698
10699   if (ttl)
10700     ip->ttl = ttl_val;
10701
10702   if (checksum)
10703     ip->checksum = clib_host_to_net_u16 (checksum_val);
10704
10705   *matchp = match;
10706   return 1;
10707 }
10708
10709 uword
10710 unformat_ip6_match (unformat_input_t * input, va_list * args)
10711 {
10712   u8 **matchp = va_arg (*args, u8 **);
10713   u8 *match = 0;
10714   ip6_header_t *ip;
10715   int version = 0;
10716   u32 version_val;
10717   u8 traffic_class = 0;
10718   u32 traffic_class_val = 0;
10719   u8 flow_label = 0;
10720   u8 flow_label_val;
10721   int src = 0, dst = 0;
10722   ip6_address_t src_val, dst_val;
10723   int proto = 0;
10724   u32 proto_val;
10725   int payload_length = 0;
10726   u32 payload_length_val;
10727   int hop_limit = 0;
10728   int hop_limit_val;
10729   u32 ip_version_traffic_class_and_flow_label;
10730
10731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10732     {
10733       if (unformat (input, "version %d", &version_val))
10734         version = 1;
10735       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10736         traffic_class = 1;
10737       else if (unformat (input, "flow_label %d", &flow_label_val))
10738         flow_label = 1;
10739       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10740         src = 1;
10741       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10742         dst = 1;
10743       else if (unformat (input, "proto %d", &proto_val))
10744         proto = 1;
10745       else if (unformat (input, "payload_length %d", &payload_length_val))
10746         payload_length = 1;
10747       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10748         hop_limit = 1;
10749       else
10750         break;
10751     }
10752
10753   if (version + traffic_class + flow_label + src + dst + proto +
10754       payload_length + hop_limit == 0)
10755     return 0;
10756
10757   /*
10758    * Aligned because we use the real comparison functions
10759    */
10760   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10761
10762   ip = (ip6_header_t *) match;
10763
10764   if (src)
10765     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10766
10767   if (dst)
10768     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10769
10770   if (proto)
10771     ip->protocol = proto_val;
10772
10773   ip_version_traffic_class_and_flow_label = 0;
10774
10775   if (version)
10776     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10777
10778   if (traffic_class)
10779     ip_version_traffic_class_and_flow_label |=
10780       (traffic_class_val & 0xFF) << 20;
10781
10782   if (flow_label)
10783     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10784
10785   ip->ip_version_traffic_class_and_flow_label =
10786     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10787
10788   if (payload_length)
10789     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10790
10791   if (hop_limit)
10792     ip->hop_limit = hop_limit_val;
10793
10794   *matchp = match;
10795   return 1;
10796 }
10797
10798 uword
10799 unformat_l3_match (unformat_input_t * input, va_list * args)
10800 {
10801   u8 **matchp = va_arg (*args, u8 **);
10802
10803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10804     {
10805       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10806         return 1;
10807       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10808         return 1;
10809       else
10810         break;
10811     }
10812   return 0;
10813 }
10814
10815 uword
10816 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10817 {
10818   u8 *tagp = va_arg (*args, u8 *);
10819   u32 tag;
10820
10821   if (unformat (input, "%d", &tag))
10822     {
10823       tagp[0] = (tag >> 8) & 0x0F;
10824       tagp[1] = tag & 0xFF;
10825       return 1;
10826     }
10827
10828   return 0;
10829 }
10830
10831 uword
10832 unformat_l2_match (unformat_input_t * input, va_list * args)
10833 {
10834   u8 **matchp = va_arg (*args, u8 **);
10835   u8 *match = 0;
10836   u8 src = 0;
10837   u8 src_val[6];
10838   u8 dst = 0;
10839   u8 dst_val[6];
10840   u8 proto = 0;
10841   u16 proto_val;
10842   u8 tag1 = 0;
10843   u8 tag1_val[2];
10844   u8 tag2 = 0;
10845   u8 tag2_val[2];
10846   int len = 14;
10847   u8 ignore_tag1 = 0;
10848   u8 ignore_tag2 = 0;
10849   u8 cos1 = 0;
10850   u8 cos2 = 0;
10851   u32 cos1_val = 0;
10852   u32 cos2_val = 0;
10853
10854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10855     {
10856       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10857         src = 1;
10858       else
10859         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10860         dst = 1;
10861       else if (unformat (input, "proto %U",
10862                          unformat_ethernet_type_host_byte_order, &proto_val))
10863         proto = 1;
10864       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10865         tag1 = 1;
10866       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10867         tag2 = 1;
10868       else if (unformat (input, "ignore-tag1"))
10869         ignore_tag1 = 1;
10870       else if (unformat (input, "ignore-tag2"))
10871         ignore_tag2 = 1;
10872       else if (unformat (input, "cos1 %d", &cos1_val))
10873         cos1 = 1;
10874       else if (unformat (input, "cos2 %d", &cos2_val))
10875         cos2 = 1;
10876       else
10877         break;
10878     }
10879   if ((src + dst + proto + tag1 + tag2 +
10880        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10881     return 0;
10882
10883   if (tag1 || ignore_tag1 || cos1)
10884     len = 18;
10885   if (tag2 || ignore_tag2 || cos2)
10886     len = 22;
10887
10888   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10889
10890   if (dst)
10891     clib_memcpy (match, dst_val, 6);
10892
10893   if (src)
10894     clib_memcpy (match + 6, src_val, 6);
10895
10896   if (tag2)
10897     {
10898       /* inner vlan tag */
10899       match[19] = tag2_val[1];
10900       match[18] = tag2_val[0];
10901       if (cos2)
10902         match[18] |= (cos2_val & 0x7) << 5;
10903       if (proto)
10904         {
10905           match[21] = proto_val & 0xff;
10906           match[20] = proto_val >> 8;
10907         }
10908       if (tag1)
10909         {
10910           match[15] = tag1_val[1];
10911           match[14] = tag1_val[0];
10912         }
10913       if (cos1)
10914         match[14] |= (cos1_val & 0x7) << 5;
10915       *matchp = match;
10916       return 1;
10917     }
10918   if (tag1)
10919     {
10920       match[15] = tag1_val[1];
10921       match[14] = tag1_val[0];
10922       if (proto)
10923         {
10924           match[17] = proto_val & 0xff;
10925           match[16] = proto_val >> 8;
10926         }
10927       if (cos1)
10928         match[14] |= (cos1_val & 0x7) << 5;
10929
10930       *matchp = match;
10931       return 1;
10932     }
10933   if (cos2)
10934     match[18] |= (cos2_val & 0x7) << 5;
10935   if (cos1)
10936     match[14] |= (cos1_val & 0x7) << 5;
10937   if (proto)
10938     {
10939       match[13] = proto_val & 0xff;
10940       match[12] = proto_val >> 8;
10941     }
10942
10943   *matchp = match;
10944   return 1;
10945 }
10946
10947 uword
10948 unformat_qos_source (unformat_input_t * input, va_list * args)
10949 {
10950   int *qs = va_arg (*args, int *);
10951
10952   if (unformat (input, "ip"))
10953     *qs = QOS_SOURCE_IP;
10954   else if (unformat (input, "mpls"))
10955     *qs = QOS_SOURCE_MPLS;
10956   else if (unformat (input, "ext"))
10957     *qs = QOS_SOURCE_EXT;
10958   else if (unformat (input, "vlan"))
10959     *qs = QOS_SOURCE_VLAN;
10960   else
10961     return 0;
10962
10963   return 1;
10964 }
10965 #endif
10966
10967 uword
10968 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10969 {
10970   u8 **matchp = va_arg (*args, u8 **);
10971   u32 skip_n_vectors = va_arg (*args, u32);
10972   u32 match_n_vectors = va_arg (*args, u32);
10973
10974   u8 *match = 0;
10975   u8 *l2 = 0;
10976   u8 *l3 = 0;
10977   u8 *l4 = 0;
10978
10979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10980     {
10981       if (unformat (input, "hex %U", unformat_hex_string, &match))
10982         ;
10983       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10984         ;
10985       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10986         ;
10987       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10988         ;
10989       else
10990         break;
10991     }
10992
10993   if (l4 && !l3)
10994     {
10995       vec_free (match);
10996       vec_free (l2);
10997       vec_free (l4);
10998       return 0;
10999     }
11000
11001   if (match || l2 || l3 || l4)
11002     {
11003       if (l2 || l3 || l4)
11004         {
11005           /* "Win a free Ethernet header in every packet" */
11006           if (l2 == 0)
11007             vec_validate_aligned (l2, 13, sizeof (u32x4));
11008           match = l2;
11009           if (vec_len (l3))
11010             {
11011               vec_append_aligned (match, l3, sizeof (u32x4));
11012               vec_free (l3);
11013             }
11014           if (vec_len (l4))
11015             {
11016               vec_append_aligned (match, l4, sizeof (u32x4));
11017               vec_free (l4);
11018             }
11019         }
11020
11021       /* Make sure the vector is big enough even if key is all 0's */
11022       vec_validate_aligned
11023         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11024          sizeof (u32x4));
11025
11026       /* Set size, include skipped vectors */
11027       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11028
11029       *matchp = match;
11030
11031       return 1;
11032     }
11033
11034   return 0;
11035 }
11036
11037 static int
11038 api_classify_add_del_session (vat_main_t * vam)
11039 {
11040   unformat_input_t *i = vam->input;
11041   vl_api_classify_add_del_session_t *mp;
11042   int is_add = 1;
11043   u32 table_index = ~0;
11044   u32 hit_next_index = ~0;
11045   u32 opaque_index = ~0;
11046   u8 *match = 0;
11047   i32 advance = 0;
11048   u32 skip_n_vectors = 0;
11049   u32 match_n_vectors = 0;
11050   u32 action = 0;
11051   u32 metadata = 0;
11052   int ret;
11053
11054   /*
11055    * Warning: you have to supply skip_n and match_n
11056    * because the API client cant simply look at the classify
11057    * table object.
11058    */
11059
11060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11061     {
11062       if (unformat (i, "del"))
11063         is_add = 0;
11064       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11065                          &hit_next_index))
11066         ;
11067       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11068                          &hit_next_index))
11069         ;
11070       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11071                          &hit_next_index))
11072         ;
11073       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11074         ;
11075       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11076         ;
11077       else if (unformat (i, "opaque-index %d", &opaque_index))
11078         ;
11079       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11080         ;
11081       else if (unformat (i, "match_n %d", &match_n_vectors))
11082         ;
11083       else if (unformat (i, "match %U", api_unformat_classify_match,
11084                          &match, skip_n_vectors, match_n_vectors))
11085         ;
11086       else if (unformat (i, "advance %d", &advance))
11087         ;
11088       else if (unformat (i, "table-index %d", &table_index))
11089         ;
11090       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11091         action = 1;
11092       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11093         action = 2;
11094       else if (unformat (i, "action %d", &action))
11095         ;
11096       else if (unformat (i, "metadata %d", &metadata))
11097         ;
11098       else
11099         break;
11100     }
11101
11102   if (table_index == ~0)
11103     {
11104       errmsg ("Table index required");
11105       return -99;
11106     }
11107
11108   if (is_add && match == 0)
11109     {
11110       errmsg ("Match value required");
11111       return -99;
11112     }
11113
11114   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11115
11116   mp->is_add = is_add;
11117   mp->table_index = ntohl (table_index);
11118   mp->hit_next_index = ntohl (hit_next_index);
11119   mp->opaque_index = ntohl (opaque_index);
11120   mp->advance = ntohl (advance);
11121   mp->action = action;
11122   mp->metadata = ntohl (metadata);
11123   mp->match_len = ntohl (vec_len (match));
11124   clib_memcpy (mp->match, match, vec_len (match));
11125   vec_free (match);
11126
11127   S (mp);
11128   W (ret);
11129   return ret;
11130 }
11131
11132 static int
11133 api_classify_set_interface_ip_table (vat_main_t * vam)
11134 {
11135   unformat_input_t *i = vam->input;
11136   vl_api_classify_set_interface_ip_table_t *mp;
11137   u32 sw_if_index;
11138   int sw_if_index_set;
11139   u32 table_index = ~0;
11140   u8 is_ipv6 = 0;
11141   int ret;
11142
11143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11144     {
11145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11146         sw_if_index_set = 1;
11147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11148         sw_if_index_set = 1;
11149       else if (unformat (i, "table %d", &table_index))
11150         ;
11151       else
11152         {
11153           clib_warning ("parse error '%U'", format_unformat_error, i);
11154           return -99;
11155         }
11156     }
11157
11158   if (sw_if_index_set == 0)
11159     {
11160       errmsg ("missing interface name or sw_if_index");
11161       return -99;
11162     }
11163
11164
11165   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11166
11167   mp->sw_if_index = ntohl (sw_if_index);
11168   mp->table_index = ntohl (table_index);
11169   mp->is_ipv6 = is_ipv6;
11170
11171   S (mp);
11172   W (ret);
11173   return ret;
11174 }
11175
11176 static int
11177 api_classify_set_interface_l2_tables (vat_main_t * vam)
11178 {
11179   unformat_input_t *i = vam->input;
11180   vl_api_classify_set_interface_l2_tables_t *mp;
11181   u32 sw_if_index;
11182   int sw_if_index_set;
11183   u32 ip4_table_index = ~0;
11184   u32 ip6_table_index = ~0;
11185   u32 other_table_index = ~0;
11186   u32 is_input = 1;
11187   int ret;
11188
11189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11190     {
11191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11192         sw_if_index_set = 1;
11193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11196         ;
11197       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11198         ;
11199       else if (unformat (i, "other-table %d", &other_table_index))
11200         ;
11201       else if (unformat (i, "is-input %d", &is_input))
11202         ;
11203       else
11204         {
11205           clib_warning ("parse error '%U'", format_unformat_error, i);
11206           return -99;
11207         }
11208     }
11209
11210   if (sw_if_index_set == 0)
11211     {
11212       errmsg ("missing interface name or sw_if_index");
11213       return -99;
11214     }
11215
11216
11217   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11218
11219   mp->sw_if_index = ntohl (sw_if_index);
11220   mp->ip4_table_index = ntohl (ip4_table_index);
11221   mp->ip6_table_index = ntohl (ip6_table_index);
11222   mp->other_table_index = ntohl (other_table_index);
11223   mp->is_input = (u8) is_input;
11224
11225   S (mp);
11226   W (ret);
11227   return ret;
11228 }
11229
11230 static int
11231 api_set_ipfix_exporter (vat_main_t * vam)
11232 {
11233   unformat_input_t *i = vam->input;
11234   vl_api_set_ipfix_exporter_t *mp;
11235   ip4_address_t collector_address;
11236   u8 collector_address_set = 0;
11237   u32 collector_port = ~0;
11238   ip4_address_t src_address;
11239   u8 src_address_set = 0;
11240   u32 vrf_id = ~0;
11241   u32 path_mtu = ~0;
11242   u32 template_interval = ~0;
11243   u8 udp_checksum = 0;
11244   int ret;
11245
11246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (i, "collector_address %U", unformat_ip4_address,
11249                     &collector_address))
11250         collector_address_set = 1;
11251       else if (unformat (i, "collector_port %d", &collector_port))
11252         ;
11253       else if (unformat (i, "src_address %U", unformat_ip4_address,
11254                          &src_address))
11255         src_address_set = 1;
11256       else if (unformat (i, "vrf_id %d", &vrf_id))
11257         ;
11258       else if (unformat (i, "path_mtu %d", &path_mtu))
11259         ;
11260       else if (unformat (i, "template_interval %d", &template_interval))
11261         ;
11262       else if (unformat (i, "udp_checksum"))
11263         udp_checksum = 1;
11264       else
11265         break;
11266     }
11267
11268   if (collector_address_set == 0)
11269     {
11270       errmsg ("collector_address required");
11271       return -99;
11272     }
11273
11274   if (src_address_set == 0)
11275     {
11276       errmsg ("src_address required");
11277       return -99;
11278     }
11279
11280   M (SET_IPFIX_EXPORTER, mp);
11281
11282   memcpy (mp->collector_address, collector_address.data,
11283           sizeof (collector_address.data));
11284   mp->collector_port = htons ((u16) collector_port);
11285   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11286   mp->vrf_id = htonl (vrf_id);
11287   mp->path_mtu = htonl (path_mtu);
11288   mp->template_interval = htonl (template_interval);
11289   mp->udp_checksum = udp_checksum;
11290
11291   S (mp);
11292   W (ret);
11293   return ret;
11294 }
11295
11296 static int
11297 api_set_ipfix_classify_stream (vat_main_t * vam)
11298 {
11299   unformat_input_t *i = vam->input;
11300   vl_api_set_ipfix_classify_stream_t *mp;
11301   u32 domain_id = 0;
11302   u32 src_port = UDP_DST_PORT_ipfix;
11303   int ret;
11304
11305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (i, "domain %d", &domain_id))
11308         ;
11309       else if (unformat (i, "src_port %d", &src_port))
11310         ;
11311       else
11312         {
11313           errmsg ("unknown input `%U'", format_unformat_error, i);
11314           return -99;
11315         }
11316     }
11317
11318   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11319
11320   mp->domain_id = htonl (domain_id);
11321   mp->src_port = htons ((u16) src_port);
11322
11323   S (mp);
11324   W (ret);
11325   return ret;
11326 }
11327
11328 static int
11329 api_ipfix_classify_table_add_del (vat_main_t * vam)
11330 {
11331   unformat_input_t *i = vam->input;
11332   vl_api_ipfix_classify_table_add_del_t *mp;
11333   int is_add = -1;
11334   u32 classify_table_index = ~0;
11335   u8 ip_version = 0;
11336   u8 transport_protocol = 255;
11337   int ret;
11338
11339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11340     {
11341       if (unformat (i, "add"))
11342         is_add = 1;
11343       else if (unformat (i, "del"))
11344         is_add = 0;
11345       else if (unformat (i, "table %d", &classify_table_index))
11346         ;
11347       else if (unformat (i, "ip4"))
11348         ip_version = 4;
11349       else if (unformat (i, "ip6"))
11350         ip_version = 6;
11351       else if (unformat (i, "tcp"))
11352         transport_protocol = 6;
11353       else if (unformat (i, "udp"))
11354         transport_protocol = 17;
11355       else
11356         {
11357           errmsg ("unknown input `%U'", format_unformat_error, i);
11358           return -99;
11359         }
11360     }
11361
11362   if (is_add == -1)
11363     {
11364       errmsg ("expecting: add|del");
11365       return -99;
11366     }
11367   if (classify_table_index == ~0)
11368     {
11369       errmsg ("classifier table not specified");
11370       return -99;
11371     }
11372   if (ip_version == 0)
11373     {
11374       errmsg ("IP version not specified");
11375       return -99;
11376     }
11377
11378   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11379
11380   mp->is_add = is_add;
11381   mp->table_id = htonl (classify_table_index);
11382   mp->ip_version = ip_version;
11383   mp->transport_protocol = transport_protocol;
11384
11385   S (mp);
11386   W (ret);
11387   return ret;
11388 }
11389
11390 static int
11391 api_get_node_index (vat_main_t * vam)
11392 {
11393   unformat_input_t *i = vam->input;
11394   vl_api_get_node_index_t *mp;
11395   u8 *name = 0;
11396   int ret;
11397
11398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11399     {
11400       if (unformat (i, "node %s", &name))
11401         ;
11402       else
11403         break;
11404     }
11405   if (name == 0)
11406     {
11407       errmsg ("node name required");
11408       return -99;
11409     }
11410   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11411     {
11412       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11413       return -99;
11414     }
11415
11416   M (GET_NODE_INDEX, mp);
11417   clib_memcpy (mp->node_name, name, vec_len (name));
11418   vec_free (name);
11419
11420   S (mp);
11421   W (ret);
11422   return ret;
11423 }
11424
11425 static int
11426 api_get_next_index (vat_main_t * vam)
11427 {
11428   unformat_input_t *i = vam->input;
11429   vl_api_get_next_index_t *mp;
11430   u8 *node_name = 0, *next_node_name = 0;
11431   int ret;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "node-name %s", &node_name))
11436         ;
11437       else if (unformat (i, "next-node-name %s", &next_node_name))
11438         break;
11439     }
11440
11441   if (node_name == 0)
11442     {
11443       errmsg ("node name required");
11444       return -99;
11445     }
11446   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11447     {
11448       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11449       return -99;
11450     }
11451
11452   if (next_node_name == 0)
11453     {
11454       errmsg ("next node name required");
11455       return -99;
11456     }
11457   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11458     {
11459       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11460       return -99;
11461     }
11462
11463   M (GET_NEXT_INDEX, mp);
11464   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11465   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11466   vec_free (node_name);
11467   vec_free (next_node_name);
11468
11469   S (mp);
11470   W (ret);
11471   return ret;
11472 }
11473
11474 static int
11475 api_add_node_next (vat_main_t * vam)
11476 {
11477   unformat_input_t *i = vam->input;
11478   vl_api_add_node_next_t *mp;
11479   u8 *name = 0;
11480   u8 *next = 0;
11481   int ret;
11482
11483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (i, "node %s", &name))
11486         ;
11487       else if (unformat (i, "next %s", &next))
11488         ;
11489       else
11490         break;
11491     }
11492   if (name == 0)
11493     {
11494       errmsg ("node name required");
11495       return -99;
11496     }
11497   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11498     {
11499       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11500       return -99;
11501     }
11502   if (next == 0)
11503     {
11504       errmsg ("next node required");
11505       return -99;
11506     }
11507   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11508     {
11509       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11510       return -99;
11511     }
11512
11513   M (ADD_NODE_NEXT, mp);
11514   clib_memcpy (mp->node_name, name, vec_len (name));
11515   clib_memcpy (mp->next_name, next, vec_len (next));
11516   vec_free (name);
11517   vec_free (next);
11518
11519   S (mp);
11520   W (ret);
11521   return ret;
11522 }
11523
11524 static int
11525 api_l2tpv3_create_tunnel (vat_main_t * vam)
11526 {
11527   unformat_input_t *i = vam->input;
11528   ip6_address_t client_address, our_address;
11529   int client_address_set = 0;
11530   int our_address_set = 0;
11531   u32 local_session_id = 0;
11532   u32 remote_session_id = 0;
11533   u64 local_cookie = 0;
11534   u64 remote_cookie = 0;
11535   u8 l2_sublayer_present = 0;
11536   vl_api_l2tpv3_create_tunnel_t *mp;
11537   int ret;
11538
11539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11540     {
11541       if (unformat (i, "client_address %U", unformat_ip6_address,
11542                     &client_address))
11543         client_address_set = 1;
11544       else if (unformat (i, "our_address %U", unformat_ip6_address,
11545                          &our_address))
11546         our_address_set = 1;
11547       else if (unformat (i, "local_session_id %d", &local_session_id))
11548         ;
11549       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11550         ;
11551       else if (unformat (i, "local_cookie %lld", &local_cookie))
11552         ;
11553       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11554         ;
11555       else if (unformat (i, "l2-sublayer-present"))
11556         l2_sublayer_present = 1;
11557       else
11558         break;
11559     }
11560
11561   if (client_address_set == 0)
11562     {
11563       errmsg ("client_address required");
11564       return -99;
11565     }
11566
11567   if (our_address_set == 0)
11568     {
11569       errmsg ("our_address required");
11570       return -99;
11571     }
11572
11573   M (L2TPV3_CREATE_TUNNEL, mp);
11574
11575   clib_memcpy (mp->client_address, client_address.as_u8,
11576                sizeof (mp->client_address));
11577
11578   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11579
11580   mp->local_session_id = ntohl (local_session_id);
11581   mp->remote_session_id = ntohl (remote_session_id);
11582   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11583   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11584   mp->l2_sublayer_present = l2_sublayer_present;
11585   mp->is_ipv6 = 1;
11586
11587   S (mp);
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static int
11593 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   u32 sw_if_index;
11597   u8 sw_if_index_set = 0;
11598   u64 new_local_cookie = 0;
11599   u64 new_remote_cookie = 0;
11600   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11601   int ret;
11602
11603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11604     {
11605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11606         sw_if_index_set = 1;
11607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11608         sw_if_index_set = 1;
11609       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11610         ;
11611       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11612         ;
11613       else
11614         break;
11615     }
11616
11617   if (sw_if_index_set == 0)
11618     {
11619       errmsg ("missing interface name or sw_if_index");
11620       return -99;
11621     }
11622
11623   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11624
11625   mp->sw_if_index = ntohl (sw_if_index);
11626   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11627   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11628
11629   S (mp);
11630   W (ret);
11631   return ret;
11632 }
11633
11634 static int
11635 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11636 {
11637   unformat_input_t *i = vam->input;
11638   vl_api_l2tpv3_interface_enable_disable_t *mp;
11639   u32 sw_if_index;
11640   u8 sw_if_index_set = 0;
11641   u8 enable_disable = 1;
11642   int ret;
11643
11644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11645     {
11646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11647         sw_if_index_set = 1;
11648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11649         sw_if_index_set = 1;
11650       else if (unformat (i, "enable"))
11651         enable_disable = 1;
11652       else if (unformat (i, "disable"))
11653         enable_disable = 0;
11654       else
11655         break;
11656     }
11657
11658   if (sw_if_index_set == 0)
11659     {
11660       errmsg ("missing interface name or sw_if_index");
11661       return -99;
11662     }
11663
11664   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11665
11666   mp->sw_if_index = ntohl (sw_if_index);
11667   mp->enable_disable = enable_disable;
11668
11669   S (mp);
11670   W (ret);
11671   return ret;
11672 }
11673
11674 static int
11675 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11676 {
11677   unformat_input_t *i = vam->input;
11678   vl_api_l2tpv3_set_lookup_key_t *mp;
11679   u8 key = ~0;
11680   int ret;
11681
11682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11683     {
11684       if (unformat (i, "lookup_v6_src"))
11685         key = L2T_LOOKUP_SRC_ADDRESS;
11686       else if (unformat (i, "lookup_v6_dst"))
11687         key = L2T_LOOKUP_DST_ADDRESS;
11688       else if (unformat (i, "lookup_session_id"))
11689         key = L2T_LOOKUP_SESSION_ID;
11690       else
11691         break;
11692     }
11693
11694   if (key == (u8) ~ 0)
11695     {
11696       errmsg ("l2tp session lookup key unset");
11697       return -99;
11698     }
11699
11700   M (L2TPV3_SET_LOOKUP_KEY, mp);
11701
11702   mp->key = key;
11703
11704   S (mp);
11705   W (ret);
11706   return ret;
11707 }
11708
11709 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11710   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11711 {
11712   vat_main_t *vam = &vat_main;
11713
11714   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11715          format_ip6_address, mp->our_address,
11716          format_ip6_address, mp->client_address,
11717          clib_net_to_host_u32 (mp->sw_if_index));
11718
11719   print (vam->ofp,
11720          "   local cookies %016llx %016llx remote cookie %016llx",
11721          clib_net_to_host_u64 (mp->local_cookie[0]),
11722          clib_net_to_host_u64 (mp->local_cookie[1]),
11723          clib_net_to_host_u64 (mp->remote_cookie));
11724
11725   print (vam->ofp, "   local session-id %d remote session-id %d",
11726          clib_net_to_host_u32 (mp->local_session_id),
11727          clib_net_to_host_u32 (mp->remote_session_id));
11728
11729   print (vam->ofp, "   l2 specific sublayer %s\n",
11730          mp->l2_sublayer_present ? "preset" : "absent");
11731
11732 }
11733
11734 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11735   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11736 {
11737   vat_main_t *vam = &vat_main;
11738   vat_json_node_t *node = NULL;
11739   struct in6_addr addr;
11740
11741   if (VAT_JSON_ARRAY != vam->json_tree.type)
11742     {
11743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11744       vat_json_init_array (&vam->json_tree);
11745     }
11746   node = vat_json_array_add (&vam->json_tree);
11747
11748   vat_json_init_object (node);
11749
11750   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11751   vat_json_object_add_ip6 (node, "our_address", addr);
11752   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11753   vat_json_object_add_ip6 (node, "client_address", addr);
11754
11755   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11756   vat_json_init_array (lc);
11757   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11758   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11759   vat_json_object_add_uint (node, "remote_cookie",
11760                             clib_net_to_host_u64 (mp->remote_cookie));
11761
11762   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11763   vat_json_object_add_uint (node, "local_session_id",
11764                             clib_net_to_host_u32 (mp->local_session_id));
11765   vat_json_object_add_uint (node, "remote_session_id",
11766                             clib_net_to_host_u32 (mp->remote_session_id));
11767   vat_json_object_add_string_copy (node, "l2_sublayer",
11768                                    mp->l2_sublayer_present ? (u8 *) "present"
11769                                    : (u8 *) "absent");
11770 }
11771
11772 static int
11773 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11774 {
11775   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11776   vl_api_control_ping_t *mp_ping;
11777   int ret;
11778
11779   /* Get list of l2tpv3-tunnel interfaces */
11780   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11781   S (mp);
11782
11783   /* Use a control ping for synchronization */
11784   MPING (CONTROL_PING, mp_ping);
11785   S (mp_ping);
11786
11787   W (ret);
11788   return ret;
11789 }
11790
11791
11792 static void vl_api_sw_interface_tap_v2_details_t_handler
11793   (vl_api_sw_interface_tap_v2_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796
11797   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11798                     mp->host_ip4_prefix_len);
11799   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11800                     mp->host_ip6_prefix_len);
11801
11802   print (vam->ofp,
11803          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11804          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11805          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11806          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11807          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11808
11809   vec_free (ip4);
11810   vec_free (ip6);
11811 }
11812
11813 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11814   (vl_api_sw_interface_tap_v2_details_t * mp)
11815 {
11816   vat_main_t *vam = &vat_main;
11817   vat_json_node_t *node = NULL;
11818
11819   if (VAT_JSON_ARRAY != vam->json_tree.type)
11820     {
11821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11822       vat_json_init_array (&vam->json_tree);
11823     }
11824   node = vat_json_array_add (&vam->json_tree);
11825
11826   vat_json_init_object (node);
11827   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11828   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11829   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11830   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11831   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11832   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11833   vat_json_object_add_string_copy (node, "host_mac_addr",
11834                                    format (0, "%U", format_ethernet_address,
11835                                            &mp->host_mac_addr));
11836   vat_json_object_add_string_copy (node, "host_namespace",
11837                                    mp->host_namespace);
11838   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11839   vat_json_object_add_string_copy (node, "host_ip4_addr",
11840                                    format (0, "%U/%d", format_ip4_address,
11841                                            mp->host_ip4_addr,
11842                                            mp->host_ip4_prefix_len));
11843   vat_json_object_add_string_copy (node, "host_ip6_addr",
11844                                    format (0, "%U/%d", format_ip6_address,
11845                                            mp->host_ip6_addr,
11846                                            mp->host_ip6_prefix_len));
11847
11848 }
11849
11850 static int
11851 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11852 {
11853   vl_api_sw_interface_tap_v2_dump_t *mp;
11854   vl_api_control_ping_t *mp_ping;
11855   int ret;
11856
11857   print (vam->ofp,
11858          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11859          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11860          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11861          "host_ip6_addr");
11862
11863   /* Get list of tap interfaces */
11864   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11865   S (mp);
11866
11867   /* Use a control ping for synchronization */
11868   MPING (CONTROL_PING, mp_ping);
11869   S (mp_ping);
11870
11871   W (ret);
11872   return ret;
11873 }
11874
11875 static void vl_api_sw_interface_virtio_pci_details_t_handler
11876   (vl_api_sw_interface_virtio_pci_details_t * mp)
11877 {
11878   vat_main_t *vam = &vat_main;
11879
11880   typedef union
11881   {
11882     struct
11883     {
11884       u16 domain;
11885       u8 bus;
11886       u8 slot:5;
11887       u8 function:3;
11888     };
11889     u32 as_u32;
11890   } pci_addr_t;
11891   pci_addr_t addr;
11892   addr.as_u32 = ntohl (mp->pci_addr);
11893   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11894                          addr.slot, addr.function);
11895
11896   print (vam->ofp,
11897          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11898          pci_addr, ntohl (mp->sw_if_index),
11899          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11900          format_ethernet_address, mp->mac_addr,
11901          clib_net_to_host_u64 (mp->features));
11902   vec_free (pci_addr);
11903 }
11904
11905 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11906   (vl_api_sw_interface_virtio_pci_details_t * mp)
11907 {
11908   vat_main_t *vam = &vat_main;
11909   vat_json_node_t *node = NULL;
11910
11911   if (VAT_JSON_ARRAY != vam->json_tree.type)
11912     {
11913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11914       vat_json_init_array (&vam->json_tree);
11915     }
11916   node = vat_json_array_add (&vam->json_tree);
11917
11918   vat_json_init_object (node);
11919   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11920   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11921   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11922   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11923   vat_json_object_add_uint (node, "features",
11924                             clib_net_to_host_u64 (mp->features));
11925   vat_json_object_add_string_copy (node, "mac_addr",
11926                                    format (0, "%U", format_ethernet_address,
11927                                            &mp->mac_addr));
11928 }
11929
11930 static int
11931 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11932 {
11933   vl_api_sw_interface_virtio_pci_dump_t *mp;
11934   vl_api_control_ping_t *mp_ping;
11935   int ret;
11936
11937   print (vam->ofp,
11938          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11939          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11940          "mac_addr", "features");
11941
11942   /* Get list of tap interfaces */
11943   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11944   S (mp);
11945
11946   /* Use a control ping for synchronization */
11947   MPING (CONTROL_PING, mp_ping);
11948   S (mp_ping);
11949
11950   W (ret);
11951   return ret;
11952 }
11953
11954 static int
11955 api_vxlan_offload_rx (vat_main_t * vam)
11956 {
11957   unformat_input_t *line_input = vam->input;
11958   vl_api_vxlan_offload_rx_t *mp;
11959   u32 hw_if_index = ~0, rx_if_index = ~0;
11960   u8 is_add = 1;
11961   int ret;
11962
11963   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11964     {
11965       if (unformat (line_input, "del"))
11966         is_add = 0;
11967       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11968                          &hw_if_index))
11969         ;
11970       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11971         ;
11972       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11973                          &rx_if_index))
11974         ;
11975       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11976         ;
11977       else
11978         {
11979           errmsg ("parse error '%U'", format_unformat_error, line_input);
11980           return -99;
11981         }
11982     }
11983
11984   if (hw_if_index == ~0)
11985     {
11986       errmsg ("no hw interface");
11987       return -99;
11988     }
11989
11990   if (rx_if_index == ~0)
11991     {
11992       errmsg ("no rx tunnel");
11993       return -99;
11994     }
11995
11996   M (VXLAN_OFFLOAD_RX, mp);
11997
11998   mp->hw_if_index = ntohl (hw_if_index);
11999   mp->sw_if_index = ntohl (rx_if_index);
12000   mp->enable = is_add;
12001
12002   S (mp);
12003   W (ret);
12004   return ret;
12005 }
12006
12007 static uword unformat_vxlan_decap_next
12008   (unformat_input_t * input, va_list * args)
12009 {
12010   u32 *result = va_arg (*args, u32 *);
12011   u32 tmp;
12012
12013   if (unformat (input, "l2"))
12014     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12015   else if (unformat (input, "%d", &tmp))
12016     *result = tmp;
12017   else
12018     return 0;
12019   return 1;
12020 }
12021
12022 static int
12023 api_vxlan_add_del_tunnel (vat_main_t * vam)
12024 {
12025   unformat_input_t *line_input = vam->input;
12026   vl_api_vxlan_add_del_tunnel_t *mp;
12027   ip46_address_t src, dst;
12028   u8 is_add = 1;
12029   u8 ipv4_set = 0, ipv6_set = 0;
12030   u8 src_set = 0;
12031   u8 dst_set = 0;
12032   u8 grp_set = 0;
12033   u32 instance = ~0;
12034   u32 mcast_sw_if_index = ~0;
12035   u32 encap_vrf_id = 0;
12036   u32 decap_next_index = ~0;
12037   u32 vni = 0;
12038   int ret;
12039
12040   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12041   clib_memset (&src, 0, sizeof src);
12042   clib_memset (&dst, 0, sizeof dst);
12043
12044   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12045     {
12046       if (unformat (line_input, "del"))
12047         is_add = 0;
12048       else if (unformat (line_input, "instance %d", &instance))
12049         ;
12050       else
12051         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12052         {
12053           ipv4_set = 1;
12054           src_set = 1;
12055         }
12056       else
12057         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12058         {
12059           ipv4_set = 1;
12060           dst_set = 1;
12061         }
12062       else
12063         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12064         {
12065           ipv6_set = 1;
12066           src_set = 1;
12067         }
12068       else
12069         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12070         {
12071           ipv6_set = 1;
12072           dst_set = 1;
12073         }
12074       else if (unformat (line_input, "group %U %U",
12075                          unformat_ip4_address, &dst.ip4,
12076                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12077         {
12078           grp_set = dst_set = 1;
12079           ipv4_set = 1;
12080         }
12081       else if (unformat (line_input, "group %U",
12082                          unformat_ip4_address, &dst.ip4))
12083         {
12084           grp_set = dst_set = 1;
12085           ipv4_set = 1;
12086         }
12087       else if (unformat (line_input, "group %U %U",
12088                          unformat_ip6_address, &dst.ip6,
12089                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12090         {
12091           grp_set = dst_set = 1;
12092           ipv6_set = 1;
12093         }
12094       else if (unformat (line_input, "group %U",
12095                          unformat_ip6_address, &dst.ip6))
12096         {
12097           grp_set = dst_set = 1;
12098           ipv6_set = 1;
12099         }
12100       else
12101         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12102         ;
12103       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12104         ;
12105       else if (unformat (line_input, "decap-next %U",
12106                          unformat_vxlan_decap_next, &decap_next_index))
12107         ;
12108       else if (unformat (line_input, "vni %d", &vni))
12109         ;
12110       else
12111         {
12112           errmsg ("parse error '%U'", format_unformat_error, line_input);
12113           return -99;
12114         }
12115     }
12116
12117   if (src_set == 0)
12118     {
12119       errmsg ("tunnel src address not specified");
12120       return -99;
12121     }
12122   if (dst_set == 0)
12123     {
12124       errmsg ("tunnel dst address not specified");
12125       return -99;
12126     }
12127
12128   if (grp_set && !ip46_address_is_multicast (&dst))
12129     {
12130       errmsg ("tunnel group address not multicast");
12131       return -99;
12132     }
12133   if (grp_set && mcast_sw_if_index == ~0)
12134     {
12135       errmsg ("tunnel nonexistent multicast device");
12136       return -99;
12137     }
12138   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12139     {
12140       errmsg ("tunnel dst address must be unicast");
12141       return -99;
12142     }
12143
12144
12145   if (ipv4_set && ipv6_set)
12146     {
12147       errmsg ("both IPv4 and IPv6 addresses specified");
12148       return -99;
12149     }
12150
12151   if ((vni == 0) || (vni >> 24))
12152     {
12153       errmsg ("vni not specified or out of range");
12154       return -99;
12155     }
12156
12157   M (VXLAN_ADD_DEL_TUNNEL, mp);
12158
12159   if (ipv6_set)
12160     {
12161       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12162       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12163     }
12164   else
12165     {
12166       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12167       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12168     }
12169
12170   mp->instance = htonl (instance);
12171   mp->encap_vrf_id = ntohl (encap_vrf_id);
12172   mp->decap_next_index = ntohl (decap_next_index);
12173   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12174   mp->vni = ntohl (vni);
12175   mp->is_add = is_add;
12176   mp->is_ipv6 = ipv6_set;
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static void vl_api_vxlan_tunnel_details_t_handler
12184   (vl_api_vxlan_tunnel_details_t * mp)
12185 {
12186   vat_main_t *vam = &vat_main;
12187   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12188   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12189
12190   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12191          ntohl (mp->sw_if_index),
12192          ntohl (mp->instance),
12193          format_ip46_address, &src, IP46_TYPE_ANY,
12194          format_ip46_address, &dst, IP46_TYPE_ANY,
12195          ntohl (mp->encap_vrf_id),
12196          ntohl (mp->decap_next_index), ntohl (mp->vni),
12197          ntohl (mp->mcast_sw_if_index));
12198 }
12199
12200 static void vl_api_vxlan_tunnel_details_t_handler_json
12201   (vl_api_vxlan_tunnel_details_t * mp)
12202 {
12203   vat_main_t *vam = &vat_main;
12204   vat_json_node_t *node = NULL;
12205
12206   if (VAT_JSON_ARRAY != vam->json_tree.type)
12207     {
12208       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12209       vat_json_init_array (&vam->json_tree);
12210     }
12211   node = vat_json_array_add (&vam->json_tree);
12212
12213   vat_json_init_object (node);
12214   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12215
12216   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12217
12218   if (mp->is_ipv6)
12219     {
12220       struct in6_addr ip6;
12221
12222       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12223       vat_json_object_add_ip6 (node, "src_address", ip6);
12224       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12225       vat_json_object_add_ip6 (node, "dst_address", ip6);
12226     }
12227   else
12228     {
12229       struct in_addr ip4;
12230
12231       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12232       vat_json_object_add_ip4 (node, "src_address", ip4);
12233       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12234       vat_json_object_add_ip4 (node, "dst_address", ip4);
12235     }
12236   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12237   vat_json_object_add_uint (node, "decap_next_index",
12238                             ntohl (mp->decap_next_index));
12239   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12240   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12241   vat_json_object_add_uint (node, "mcast_sw_if_index",
12242                             ntohl (mp->mcast_sw_if_index));
12243 }
12244
12245 static int
12246 api_vxlan_tunnel_dump (vat_main_t * vam)
12247 {
12248   unformat_input_t *i = vam->input;
12249   vl_api_vxlan_tunnel_dump_t *mp;
12250   vl_api_control_ping_t *mp_ping;
12251   u32 sw_if_index;
12252   u8 sw_if_index_set = 0;
12253   int ret;
12254
12255   /* Parse args required to build the message */
12256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12257     {
12258       if (unformat (i, "sw_if_index %d", &sw_if_index))
12259         sw_if_index_set = 1;
12260       else
12261         break;
12262     }
12263
12264   if (sw_if_index_set == 0)
12265     {
12266       sw_if_index = ~0;
12267     }
12268
12269   if (!vam->json_output)
12270     {
12271       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12272              "sw_if_index", "instance", "src_address", "dst_address",
12273              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12274     }
12275
12276   /* Get list of vxlan-tunnel interfaces */
12277   M (VXLAN_TUNNEL_DUMP, mp);
12278
12279   mp->sw_if_index = htonl (sw_if_index);
12280
12281   S (mp);
12282
12283   /* Use a control ping for synchronization */
12284   MPING (CONTROL_PING, mp_ping);
12285   S (mp_ping);
12286
12287   W (ret);
12288   return ret;
12289 }
12290
12291 static uword unformat_geneve_decap_next
12292   (unformat_input_t * input, va_list * args)
12293 {
12294   u32 *result = va_arg (*args, u32 *);
12295   u32 tmp;
12296
12297   if (unformat (input, "l2"))
12298     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12299   else if (unformat (input, "%d", &tmp))
12300     *result = tmp;
12301   else
12302     return 0;
12303   return 1;
12304 }
12305
12306 static int
12307 api_geneve_add_del_tunnel (vat_main_t * vam)
12308 {
12309   unformat_input_t *line_input = vam->input;
12310   vl_api_geneve_add_del_tunnel_t *mp;
12311   ip46_address_t src, dst;
12312   u8 is_add = 1;
12313   u8 ipv4_set = 0, ipv6_set = 0;
12314   u8 src_set = 0;
12315   u8 dst_set = 0;
12316   u8 grp_set = 0;
12317   u32 mcast_sw_if_index = ~0;
12318   u32 encap_vrf_id = 0;
12319   u32 decap_next_index = ~0;
12320   u32 vni = 0;
12321   int ret;
12322
12323   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12324   clib_memset (&src, 0, sizeof src);
12325   clib_memset (&dst, 0, sizeof dst);
12326
12327   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12328     {
12329       if (unformat (line_input, "del"))
12330         is_add = 0;
12331       else
12332         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12333         {
12334           ipv4_set = 1;
12335           src_set = 1;
12336         }
12337       else
12338         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12339         {
12340           ipv4_set = 1;
12341           dst_set = 1;
12342         }
12343       else
12344         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12345         {
12346           ipv6_set = 1;
12347           src_set = 1;
12348         }
12349       else
12350         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12351         {
12352           ipv6_set = 1;
12353           dst_set = 1;
12354         }
12355       else if (unformat (line_input, "group %U %U",
12356                          unformat_ip4_address, &dst.ip4,
12357                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12358         {
12359           grp_set = dst_set = 1;
12360           ipv4_set = 1;
12361         }
12362       else if (unformat (line_input, "group %U",
12363                          unformat_ip4_address, &dst.ip4))
12364         {
12365           grp_set = dst_set = 1;
12366           ipv4_set = 1;
12367         }
12368       else if (unformat (line_input, "group %U %U",
12369                          unformat_ip6_address, &dst.ip6,
12370                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12371         {
12372           grp_set = dst_set = 1;
12373           ipv6_set = 1;
12374         }
12375       else if (unformat (line_input, "group %U",
12376                          unformat_ip6_address, &dst.ip6))
12377         {
12378           grp_set = dst_set = 1;
12379           ipv6_set = 1;
12380         }
12381       else
12382         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12383         ;
12384       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12385         ;
12386       else if (unformat (line_input, "decap-next %U",
12387                          unformat_geneve_decap_next, &decap_next_index))
12388         ;
12389       else if (unformat (line_input, "vni %d", &vni))
12390         ;
12391       else
12392         {
12393           errmsg ("parse error '%U'", format_unformat_error, line_input);
12394           return -99;
12395         }
12396     }
12397
12398   if (src_set == 0)
12399     {
12400       errmsg ("tunnel src address not specified");
12401       return -99;
12402     }
12403   if (dst_set == 0)
12404     {
12405       errmsg ("tunnel dst address not specified");
12406       return -99;
12407     }
12408
12409   if (grp_set && !ip46_address_is_multicast (&dst))
12410     {
12411       errmsg ("tunnel group address not multicast");
12412       return -99;
12413     }
12414   if (grp_set && mcast_sw_if_index == ~0)
12415     {
12416       errmsg ("tunnel nonexistent multicast device");
12417       return -99;
12418     }
12419   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12420     {
12421       errmsg ("tunnel dst address must be unicast");
12422       return -99;
12423     }
12424
12425
12426   if (ipv4_set && ipv6_set)
12427     {
12428       errmsg ("both IPv4 and IPv6 addresses specified");
12429       return -99;
12430     }
12431
12432   if ((vni == 0) || (vni >> 24))
12433     {
12434       errmsg ("vni not specified or out of range");
12435       return -99;
12436     }
12437
12438   M (GENEVE_ADD_DEL_TUNNEL, mp);
12439
12440   if (ipv6_set)
12441     {
12442       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12443       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12444     }
12445   else
12446     {
12447       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12448       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12449     }
12450   mp->encap_vrf_id = ntohl (encap_vrf_id);
12451   mp->decap_next_index = ntohl (decap_next_index);
12452   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12453   mp->vni = ntohl (vni);
12454   mp->is_add = is_add;
12455   mp->is_ipv6 = ipv6_set;
12456
12457   S (mp);
12458   W (ret);
12459   return ret;
12460 }
12461
12462 static void vl_api_geneve_tunnel_details_t_handler
12463   (vl_api_geneve_tunnel_details_t * mp)
12464 {
12465   vat_main_t *vam = &vat_main;
12466   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12467   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12468
12469   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12470          ntohl (mp->sw_if_index),
12471          format_ip46_address, &src, IP46_TYPE_ANY,
12472          format_ip46_address, &dst, IP46_TYPE_ANY,
12473          ntohl (mp->encap_vrf_id),
12474          ntohl (mp->decap_next_index), ntohl (mp->vni),
12475          ntohl (mp->mcast_sw_if_index));
12476 }
12477
12478 static void vl_api_geneve_tunnel_details_t_handler_json
12479   (vl_api_geneve_tunnel_details_t * mp)
12480 {
12481   vat_main_t *vam = &vat_main;
12482   vat_json_node_t *node = NULL;
12483
12484   if (VAT_JSON_ARRAY != vam->json_tree.type)
12485     {
12486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12487       vat_json_init_array (&vam->json_tree);
12488     }
12489   node = vat_json_array_add (&vam->json_tree);
12490
12491   vat_json_init_object (node);
12492   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12493   if (mp->is_ipv6)
12494     {
12495       struct in6_addr ip6;
12496
12497       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12498       vat_json_object_add_ip6 (node, "src_address", ip6);
12499       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12500       vat_json_object_add_ip6 (node, "dst_address", ip6);
12501     }
12502   else
12503     {
12504       struct in_addr ip4;
12505
12506       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12507       vat_json_object_add_ip4 (node, "src_address", ip4);
12508       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12509       vat_json_object_add_ip4 (node, "dst_address", ip4);
12510     }
12511   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12512   vat_json_object_add_uint (node, "decap_next_index",
12513                             ntohl (mp->decap_next_index));
12514   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12515   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12516   vat_json_object_add_uint (node, "mcast_sw_if_index",
12517                             ntohl (mp->mcast_sw_if_index));
12518 }
12519
12520 static int
12521 api_geneve_tunnel_dump (vat_main_t * vam)
12522 {
12523   unformat_input_t *i = vam->input;
12524   vl_api_geneve_tunnel_dump_t *mp;
12525   vl_api_control_ping_t *mp_ping;
12526   u32 sw_if_index;
12527   u8 sw_if_index_set = 0;
12528   int ret;
12529
12530   /* Parse args required to build the message */
12531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12532     {
12533       if (unformat (i, "sw_if_index %d", &sw_if_index))
12534         sw_if_index_set = 1;
12535       else
12536         break;
12537     }
12538
12539   if (sw_if_index_set == 0)
12540     {
12541       sw_if_index = ~0;
12542     }
12543
12544   if (!vam->json_output)
12545     {
12546       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12547              "sw_if_index", "local_address", "remote_address",
12548              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12549     }
12550
12551   /* Get list of geneve-tunnel interfaces */
12552   M (GENEVE_TUNNEL_DUMP, mp);
12553
12554   mp->sw_if_index = htonl (sw_if_index);
12555
12556   S (mp);
12557
12558   /* Use a control ping for synchronization */
12559   M (CONTROL_PING, mp_ping);
12560   S (mp_ping);
12561
12562   W (ret);
12563   return ret;
12564 }
12565
12566 static int
12567 api_gre_tunnel_add_del (vat_main_t * vam)
12568 {
12569   unformat_input_t *line_input = vam->input;
12570   vl_api_address_t src = { }, dst =
12571   {
12572   };
12573   vl_api_gre_tunnel_add_del_t *mp;
12574   vl_api_gre_tunnel_type_t t_type;
12575   u8 is_add = 1;
12576   u8 src_set = 0;
12577   u8 dst_set = 0;
12578   u32 outer_fib_id = 0;
12579   u32 session_id = 0;
12580   u32 instance = ~0;
12581   int ret;
12582
12583   t_type = GRE_API_TUNNEL_TYPE_L3;
12584
12585   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12586     {
12587       if (unformat (line_input, "del"))
12588         is_add = 0;
12589       else if (unformat (line_input, "instance %d", &instance))
12590         ;
12591       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12592         {
12593           src_set = 1;
12594         }
12595       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12596         {
12597           dst_set = 1;
12598         }
12599       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12600         ;
12601       else if (unformat (line_input, "teb"))
12602         t_type = GRE_API_TUNNEL_TYPE_TEB;
12603       else if (unformat (line_input, "erspan %d", &session_id))
12604         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12605       else
12606         {
12607           errmsg ("parse error '%U'", format_unformat_error, line_input);
12608           return -99;
12609         }
12610     }
12611
12612   if (src_set == 0)
12613     {
12614       errmsg ("tunnel src address not specified");
12615       return -99;
12616     }
12617   if (dst_set == 0)
12618     {
12619       errmsg ("tunnel dst address not specified");
12620       return -99;
12621     }
12622
12623   M (GRE_TUNNEL_ADD_DEL, mp);
12624
12625   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12626   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12627
12628   mp->tunnel.instance = htonl (instance);
12629   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12630   mp->is_add = is_add;
12631   mp->tunnel.session_id = htons ((u16) session_id);
12632   mp->tunnel.type = htonl (t_type);
12633
12634   S (mp);
12635   W (ret);
12636   return ret;
12637 }
12638
12639 static void vl_api_gre_tunnel_details_t_handler
12640   (vl_api_gre_tunnel_details_t * mp)
12641 {
12642   vat_main_t *vam = &vat_main;
12643
12644   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12645          ntohl (mp->tunnel.sw_if_index),
12646          ntohl (mp->tunnel.instance),
12647          format_vl_api_address, &mp->tunnel.src,
12648          format_vl_api_address, &mp->tunnel.dst,
12649          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12650          ntohl (mp->tunnel.session_id));
12651 }
12652
12653 static void vl_api_gre_tunnel_details_t_handler_json
12654   (vl_api_gre_tunnel_details_t * mp)
12655 {
12656   vat_main_t *vam = &vat_main;
12657   vat_json_node_t *node = NULL;
12658
12659   if (VAT_JSON_ARRAY != vam->json_tree.type)
12660     {
12661       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12662       vat_json_init_array (&vam->json_tree);
12663     }
12664   node = vat_json_array_add (&vam->json_tree);
12665
12666   vat_json_init_object (node);
12667   vat_json_object_add_uint (node, "sw_if_index",
12668                             ntohl (mp->tunnel.sw_if_index));
12669   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12670
12671   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12672   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12673   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12674   vat_json_object_add_uint (node, "outer_fib_id",
12675                             ntohl (mp->tunnel.outer_fib_id));
12676   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12677 }
12678
12679 static int
12680 api_gre_tunnel_dump (vat_main_t * vam)
12681 {
12682   unformat_input_t *i = vam->input;
12683   vl_api_gre_tunnel_dump_t *mp;
12684   vl_api_control_ping_t *mp_ping;
12685   u32 sw_if_index;
12686   u8 sw_if_index_set = 0;
12687   int ret;
12688
12689   /* Parse args required to build the message */
12690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12691     {
12692       if (unformat (i, "sw_if_index %d", &sw_if_index))
12693         sw_if_index_set = 1;
12694       else
12695         break;
12696     }
12697
12698   if (sw_if_index_set == 0)
12699     {
12700       sw_if_index = ~0;
12701     }
12702
12703   if (!vam->json_output)
12704     {
12705       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12706              "sw_if_index", "instance", "src_address", "dst_address",
12707              "tunnel_type", "outer_fib_id", "session_id");
12708     }
12709
12710   /* Get list of gre-tunnel interfaces */
12711   M (GRE_TUNNEL_DUMP, mp);
12712
12713   mp->sw_if_index = htonl (sw_if_index);
12714
12715   S (mp);
12716
12717   /* Use a control ping for synchronization */
12718   MPING (CONTROL_PING, mp_ping);
12719   S (mp_ping);
12720
12721   W (ret);
12722   return ret;
12723 }
12724
12725 static int
12726 api_l2_fib_clear_table (vat_main_t * vam)
12727 {
12728 //  unformat_input_t * i = vam->input;
12729   vl_api_l2_fib_clear_table_t *mp;
12730   int ret;
12731
12732   M (L2_FIB_CLEAR_TABLE, mp);
12733
12734   S (mp);
12735   W (ret);
12736   return ret;
12737 }
12738
12739 static int
12740 api_l2_interface_efp_filter (vat_main_t * vam)
12741 {
12742   unformat_input_t *i = vam->input;
12743   vl_api_l2_interface_efp_filter_t *mp;
12744   u32 sw_if_index;
12745   u8 enable = 1;
12746   u8 sw_if_index_set = 0;
12747   int ret;
12748
12749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12750     {
12751       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12752         sw_if_index_set = 1;
12753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12754         sw_if_index_set = 1;
12755       else if (unformat (i, "enable"))
12756         enable = 1;
12757       else if (unformat (i, "disable"))
12758         enable = 0;
12759       else
12760         {
12761           clib_warning ("parse error '%U'", format_unformat_error, i);
12762           return -99;
12763         }
12764     }
12765
12766   if (sw_if_index_set == 0)
12767     {
12768       errmsg ("missing sw_if_index");
12769       return -99;
12770     }
12771
12772   M (L2_INTERFACE_EFP_FILTER, mp);
12773
12774   mp->sw_if_index = ntohl (sw_if_index);
12775   mp->enable_disable = enable;
12776
12777   S (mp);
12778   W (ret);
12779   return ret;
12780 }
12781
12782 #define foreach_vtr_op                          \
12783 _("disable",  L2_VTR_DISABLED)                  \
12784 _("push-1",  L2_VTR_PUSH_1)                     \
12785 _("push-2",  L2_VTR_PUSH_2)                     \
12786 _("pop-1",  L2_VTR_POP_1)                       \
12787 _("pop-2",  L2_VTR_POP_2)                       \
12788 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12789 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12790 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12791 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12792
12793 static int
12794 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12795 {
12796   unformat_input_t *i = vam->input;
12797   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12798   u32 sw_if_index;
12799   u8 sw_if_index_set = 0;
12800   u8 vtr_op_set = 0;
12801   u32 vtr_op = 0;
12802   u32 push_dot1q = 1;
12803   u32 tag1 = ~0;
12804   u32 tag2 = ~0;
12805   int ret;
12806
12807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12808     {
12809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12810         sw_if_index_set = 1;
12811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12812         sw_if_index_set = 1;
12813       else if (unformat (i, "vtr_op %d", &vtr_op))
12814         vtr_op_set = 1;
12815 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12816       foreach_vtr_op
12817 #undef _
12818         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12819         ;
12820       else if (unformat (i, "tag1 %d", &tag1))
12821         ;
12822       else if (unformat (i, "tag2 %d", &tag2))
12823         ;
12824       else
12825         {
12826           clib_warning ("parse error '%U'", format_unformat_error, i);
12827           return -99;
12828         }
12829     }
12830
12831   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12832     {
12833       errmsg ("missing vtr operation or sw_if_index");
12834       return -99;
12835     }
12836
12837   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12838   mp->sw_if_index = ntohl (sw_if_index);
12839   mp->vtr_op = ntohl (vtr_op);
12840   mp->push_dot1q = ntohl (push_dot1q);
12841   mp->tag1 = ntohl (tag1);
12842   mp->tag2 = ntohl (tag2);
12843
12844   S (mp);
12845   W (ret);
12846   return ret;
12847 }
12848
12849 static int
12850 api_create_vhost_user_if (vat_main_t * vam)
12851 {
12852   unformat_input_t *i = vam->input;
12853   vl_api_create_vhost_user_if_t *mp;
12854   u8 *file_name;
12855   u8 is_server = 0;
12856   u8 file_name_set = 0;
12857   u32 custom_dev_instance = ~0;
12858   u8 hwaddr[6];
12859   u8 use_custom_mac = 0;
12860   u8 disable_mrg_rxbuf = 0;
12861   u8 disable_indirect_desc = 0;
12862   u8 *tag = 0;
12863   u8 enable_gso = 0;
12864   int ret;
12865
12866   /* Shut up coverity */
12867   clib_memset (hwaddr, 0, sizeof (hwaddr));
12868
12869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12870     {
12871       if (unformat (i, "socket %s", &file_name))
12872         {
12873           file_name_set = 1;
12874         }
12875       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12876         ;
12877       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12878         use_custom_mac = 1;
12879       else if (unformat (i, "server"))
12880         is_server = 1;
12881       else if (unformat (i, "disable_mrg_rxbuf"))
12882         disable_mrg_rxbuf = 1;
12883       else if (unformat (i, "disable_indirect_desc"))
12884         disable_indirect_desc = 1;
12885       else if (unformat (i, "gso"))
12886         enable_gso = 1;
12887       else if (unformat (i, "tag %s", &tag))
12888         ;
12889       else
12890         break;
12891     }
12892
12893   if (file_name_set == 0)
12894     {
12895       errmsg ("missing socket file name");
12896       return -99;
12897     }
12898
12899   if (vec_len (file_name) > 255)
12900     {
12901       errmsg ("socket file name too long");
12902       return -99;
12903     }
12904   vec_add1 (file_name, 0);
12905
12906   M (CREATE_VHOST_USER_IF, mp);
12907
12908   mp->is_server = is_server;
12909   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12910   mp->disable_indirect_desc = disable_indirect_desc;
12911   mp->enable_gso = enable_gso;
12912   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12913   vec_free (file_name);
12914   if (custom_dev_instance != ~0)
12915     {
12916       mp->renumber = 1;
12917       mp->custom_dev_instance = ntohl (custom_dev_instance);
12918     }
12919
12920   mp->use_custom_mac = use_custom_mac;
12921   clib_memcpy (mp->mac_address, hwaddr, 6);
12922   if (tag)
12923     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12924   vec_free (tag);
12925
12926   S (mp);
12927   W (ret);
12928   return ret;
12929 }
12930
12931 static int
12932 api_modify_vhost_user_if (vat_main_t * vam)
12933 {
12934   unformat_input_t *i = vam->input;
12935   vl_api_modify_vhost_user_if_t *mp;
12936   u8 *file_name;
12937   u8 is_server = 0;
12938   u8 file_name_set = 0;
12939   u32 custom_dev_instance = ~0;
12940   u8 sw_if_index_set = 0;
12941   u32 sw_if_index = (u32) ~ 0;
12942   u8 enable_gso = 0;
12943   int ret;
12944
12945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12946     {
12947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12948         sw_if_index_set = 1;
12949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12950         sw_if_index_set = 1;
12951       else if (unformat (i, "socket %s", &file_name))
12952         {
12953           file_name_set = 1;
12954         }
12955       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12956         ;
12957       else if (unformat (i, "server"))
12958         is_server = 1;
12959       else if (unformat (i, "gso"))
12960         enable_gso = 1;
12961       else
12962         break;
12963     }
12964
12965   if (sw_if_index_set == 0)
12966     {
12967       errmsg ("missing sw_if_index or interface name");
12968       return -99;
12969     }
12970
12971   if (file_name_set == 0)
12972     {
12973       errmsg ("missing socket file name");
12974       return -99;
12975     }
12976
12977   if (vec_len (file_name) > 255)
12978     {
12979       errmsg ("socket file name too long");
12980       return -99;
12981     }
12982   vec_add1 (file_name, 0);
12983
12984   M (MODIFY_VHOST_USER_IF, mp);
12985
12986   mp->sw_if_index = ntohl (sw_if_index);
12987   mp->is_server = is_server;
12988   mp->enable_gso = enable_gso;
12989   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12990   vec_free (file_name);
12991   if (custom_dev_instance != ~0)
12992     {
12993       mp->renumber = 1;
12994       mp->custom_dev_instance = ntohl (custom_dev_instance);
12995     }
12996
12997   S (mp);
12998   W (ret);
12999   return ret;
13000 }
13001
13002 static int
13003 api_delete_vhost_user_if (vat_main_t * vam)
13004 {
13005   unformat_input_t *i = vam->input;
13006   vl_api_delete_vhost_user_if_t *mp;
13007   u32 sw_if_index = ~0;
13008   u8 sw_if_index_set = 0;
13009   int ret;
13010
13011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13012     {
13013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13014         sw_if_index_set = 1;
13015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13016         sw_if_index_set = 1;
13017       else
13018         break;
13019     }
13020
13021   if (sw_if_index_set == 0)
13022     {
13023       errmsg ("missing sw_if_index or interface name");
13024       return -99;
13025     }
13026
13027
13028   M (DELETE_VHOST_USER_IF, mp);
13029
13030   mp->sw_if_index = ntohl (sw_if_index);
13031
13032   S (mp);
13033   W (ret);
13034   return ret;
13035 }
13036
13037 static void vl_api_sw_interface_vhost_user_details_t_handler
13038   (vl_api_sw_interface_vhost_user_details_t * mp)
13039 {
13040   vat_main_t *vam = &vat_main;
13041
13042   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13043          (char *) mp->interface_name,
13044          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13045          clib_net_to_host_u64 (mp->features), mp->is_server,
13046          ntohl (mp->num_regions), (char *) mp->sock_filename);
13047   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13048 }
13049
13050 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13051   (vl_api_sw_interface_vhost_user_details_t * mp)
13052 {
13053   vat_main_t *vam = &vat_main;
13054   vat_json_node_t *node = NULL;
13055
13056   if (VAT_JSON_ARRAY != vam->json_tree.type)
13057     {
13058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13059       vat_json_init_array (&vam->json_tree);
13060     }
13061   node = vat_json_array_add (&vam->json_tree);
13062
13063   vat_json_init_object (node);
13064   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13065   vat_json_object_add_string_copy (node, "interface_name",
13066                                    mp->interface_name);
13067   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13068                             ntohl (mp->virtio_net_hdr_sz));
13069   vat_json_object_add_uint (node, "features",
13070                             clib_net_to_host_u64 (mp->features));
13071   vat_json_object_add_uint (node, "is_server", mp->is_server);
13072   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13073   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13074   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13075 }
13076
13077 static int
13078 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13079 {
13080   vl_api_sw_interface_vhost_user_dump_t *mp;
13081   vl_api_control_ping_t *mp_ping;
13082   int ret;
13083   print (vam->ofp,
13084          "Interface name            idx hdr_sz features server regions filename");
13085
13086   /* Get list of vhost-user interfaces */
13087   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13088   S (mp);
13089
13090   /* Use a control ping for synchronization */
13091   MPING (CONTROL_PING, mp_ping);
13092   S (mp_ping);
13093
13094   W (ret);
13095   return ret;
13096 }
13097
13098 static int
13099 api_show_version (vat_main_t * vam)
13100 {
13101   vl_api_show_version_t *mp;
13102   int ret;
13103
13104   M (SHOW_VERSION, mp);
13105
13106   S (mp);
13107   W (ret);
13108   return ret;
13109 }
13110
13111
13112 static int
13113 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13114 {
13115   unformat_input_t *line_input = vam->input;
13116   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13117   ip4_address_t local4, remote4;
13118   ip6_address_t local6, remote6;
13119   u8 is_add = 1;
13120   u8 ipv4_set = 0, ipv6_set = 0;
13121   u8 local_set = 0;
13122   u8 remote_set = 0;
13123   u8 grp_set = 0;
13124   u32 mcast_sw_if_index = ~0;
13125   u32 encap_vrf_id = 0;
13126   u32 decap_vrf_id = 0;
13127   u8 protocol = ~0;
13128   u32 vni;
13129   u8 vni_set = 0;
13130   int ret;
13131
13132   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13133   clib_memset (&local4, 0, sizeof local4);
13134   clib_memset (&remote4, 0, sizeof remote4);
13135   clib_memset (&local6, 0, sizeof local6);
13136   clib_memset (&remote6, 0, sizeof remote6);
13137
13138   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13139     {
13140       if (unformat (line_input, "del"))
13141         is_add = 0;
13142       else if (unformat (line_input, "local %U",
13143                          unformat_ip4_address, &local4))
13144         {
13145           local_set = 1;
13146           ipv4_set = 1;
13147         }
13148       else if (unformat (line_input, "remote %U",
13149                          unformat_ip4_address, &remote4))
13150         {
13151           remote_set = 1;
13152           ipv4_set = 1;
13153         }
13154       else if (unformat (line_input, "local %U",
13155                          unformat_ip6_address, &local6))
13156         {
13157           local_set = 1;
13158           ipv6_set = 1;
13159         }
13160       else if (unformat (line_input, "remote %U",
13161                          unformat_ip6_address, &remote6))
13162         {
13163           remote_set = 1;
13164           ipv6_set = 1;
13165         }
13166       else if (unformat (line_input, "group %U %U",
13167                          unformat_ip4_address, &remote4,
13168                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13169         {
13170           grp_set = remote_set = 1;
13171           ipv4_set = 1;
13172         }
13173       else if (unformat (line_input, "group %U",
13174                          unformat_ip4_address, &remote4))
13175         {
13176           grp_set = remote_set = 1;
13177           ipv4_set = 1;
13178         }
13179       else if (unformat (line_input, "group %U %U",
13180                          unformat_ip6_address, &remote6,
13181                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13182         {
13183           grp_set = remote_set = 1;
13184           ipv6_set = 1;
13185         }
13186       else if (unformat (line_input, "group %U",
13187                          unformat_ip6_address, &remote6))
13188         {
13189           grp_set = remote_set = 1;
13190           ipv6_set = 1;
13191         }
13192       else
13193         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13194         ;
13195       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13196         ;
13197       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13198         ;
13199       else if (unformat (line_input, "vni %d", &vni))
13200         vni_set = 1;
13201       else if (unformat (line_input, "next-ip4"))
13202         protocol = 1;
13203       else if (unformat (line_input, "next-ip6"))
13204         protocol = 2;
13205       else if (unformat (line_input, "next-ethernet"))
13206         protocol = 3;
13207       else if (unformat (line_input, "next-nsh"))
13208         protocol = 4;
13209       else
13210         {
13211           errmsg ("parse error '%U'", format_unformat_error, line_input);
13212           return -99;
13213         }
13214     }
13215
13216   if (local_set == 0)
13217     {
13218       errmsg ("tunnel local address not specified");
13219       return -99;
13220     }
13221   if (remote_set == 0)
13222     {
13223       errmsg ("tunnel remote address not specified");
13224       return -99;
13225     }
13226   if (grp_set && mcast_sw_if_index == ~0)
13227     {
13228       errmsg ("tunnel nonexistent multicast device");
13229       return -99;
13230     }
13231   if (ipv4_set && ipv6_set)
13232     {
13233       errmsg ("both IPv4 and IPv6 addresses specified");
13234       return -99;
13235     }
13236
13237   if (vni_set == 0)
13238     {
13239       errmsg ("vni not specified");
13240       return -99;
13241     }
13242
13243   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13244
13245
13246   if (ipv6_set)
13247     {
13248       clib_memcpy (&mp->local, &local6, sizeof (local6));
13249       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13250     }
13251   else
13252     {
13253       clib_memcpy (&mp->local, &local4, sizeof (local4));
13254       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13255     }
13256
13257   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13258   mp->encap_vrf_id = ntohl (encap_vrf_id);
13259   mp->decap_vrf_id = ntohl (decap_vrf_id);
13260   mp->protocol = protocol;
13261   mp->vni = ntohl (vni);
13262   mp->is_add = is_add;
13263   mp->is_ipv6 = ipv6_set;
13264
13265   S (mp);
13266   W (ret);
13267   return ret;
13268 }
13269
13270 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13271   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13272 {
13273   vat_main_t *vam = &vat_main;
13274   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13275   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13276
13277   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13278          ntohl (mp->sw_if_index),
13279          format_ip46_address, &local, IP46_TYPE_ANY,
13280          format_ip46_address, &remote, IP46_TYPE_ANY,
13281          ntohl (mp->vni), mp->protocol,
13282          ntohl (mp->mcast_sw_if_index),
13283          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13284 }
13285
13286
13287 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13288   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13289 {
13290   vat_main_t *vam = &vat_main;
13291   vat_json_node_t *node = NULL;
13292   struct in_addr ip4;
13293   struct in6_addr ip6;
13294
13295   if (VAT_JSON_ARRAY != vam->json_tree.type)
13296     {
13297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13298       vat_json_init_array (&vam->json_tree);
13299     }
13300   node = vat_json_array_add (&vam->json_tree);
13301
13302   vat_json_init_object (node);
13303   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13304   if (mp->is_ipv6)
13305     {
13306       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13307       vat_json_object_add_ip6 (node, "local", ip6);
13308       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13309       vat_json_object_add_ip6 (node, "remote", ip6);
13310     }
13311   else
13312     {
13313       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13314       vat_json_object_add_ip4 (node, "local", ip4);
13315       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13316       vat_json_object_add_ip4 (node, "remote", ip4);
13317     }
13318   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13319   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13320   vat_json_object_add_uint (node, "mcast_sw_if_index",
13321                             ntohl (mp->mcast_sw_if_index));
13322   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13323   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13324   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13325 }
13326
13327 static int
13328 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13329 {
13330   unformat_input_t *i = vam->input;
13331   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13332   vl_api_control_ping_t *mp_ping;
13333   u32 sw_if_index;
13334   u8 sw_if_index_set = 0;
13335   int ret;
13336
13337   /* Parse args required to build the message */
13338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13339     {
13340       if (unformat (i, "sw_if_index %d", &sw_if_index))
13341         sw_if_index_set = 1;
13342       else
13343         break;
13344     }
13345
13346   if (sw_if_index_set == 0)
13347     {
13348       sw_if_index = ~0;
13349     }
13350
13351   if (!vam->json_output)
13352     {
13353       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13354              "sw_if_index", "local", "remote", "vni",
13355              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13356     }
13357
13358   /* Get list of vxlan-tunnel interfaces */
13359   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13360
13361   mp->sw_if_index = htonl (sw_if_index);
13362
13363   S (mp);
13364
13365   /* Use a control ping for synchronization */
13366   MPING (CONTROL_PING, mp_ping);
13367   S (mp_ping);
13368
13369   W (ret);
13370   return ret;
13371 }
13372
13373 static void vl_api_l2_fib_table_details_t_handler
13374   (vl_api_l2_fib_table_details_t * mp)
13375 {
13376   vat_main_t *vam = &vat_main;
13377
13378   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13379          "       %d       %d     %d",
13380          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13381          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13382          mp->bvi_mac);
13383 }
13384
13385 static void vl_api_l2_fib_table_details_t_handler_json
13386   (vl_api_l2_fib_table_details_t * mp)
13387 {
13388   vat_main_t *vam = &vat_main;
13389   vat_json_node_t *node = NULL;
13390
13391   if (VAT_JSON_ARRAY != vam->json_tree.type)
13392     {
13393       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13394       vat_json_init_array (&vam->json_tree);
13395     }
13396   node = vat_json_array_add (&vam->json_tree);
13397
13398   vat_json_init_object (node);
13399   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13400   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13401   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13402   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13403   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13404   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13405 }
13406
13407 static int
13408 api_l2_fib_table_dump (vat_main_t * vam)
13409 {
13410   unformat_input_t *i = vam->input;
13411   vl_api_l2_fib_table_dump_t *mp;
13412   vl_api_control_ping_t *mp_ping;
13413   u32 bd_id;
13414   u8 bd_id_set = 0;
13415   int ret;
13416
13417   /* Parse args required to build the message */
13418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13419     {
13420       if (unformat (i, "bd_id %d", &bd_id))
13421         bd_id_set = 1;
13422       else
13423         break;
13424     }
13425
13426   if (bd_id_set == 0)
13427     {
13428       errmsg ("missing bridge domain");
13429       return -99;
13430     }
13431
13432   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13433
13434   /* Get list of l2 fib entries */
13435   M (L2_FIB_TABLE_DUMP, mp);
13436
13437   mp->bd_id = ntohl (bd_id);
13438   S (mp);
13439
13440   /* Use a control ping for synchronization */
13441   MPING (CONTROL_PING, mp_ping);
13442   S (mp_ping);
13443
13444   W (ret);
13445   return ret;
13446 }
13447
13448
13449 static int
13450 api_interface_name_renumber (vat_main_t * vam)
13451 {
13452   unformat_input_t *line_input = vam->input;
13453   vl_api_interface_name_renumber_t *mp;
13454   u32 sw_if_index = ~0;
13455   u32 new_show_dev_instance = ~0;
13456   int ret;
13457
13458   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13459     {
13460       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13461                     &sw_if_index))
13462         ;
13463       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13464         ;
13465       else if (unformat (line_input, "new_show_dev_instance %d",
13466                          &new_show_dev_instance))
13467         ;
13468       else
13469         break;
13470     }
13471
13472   if (sw_if_index == ~0)
13473     {
13474       errmsg ("missing interface name or sw_if_index");
13475       return -99;
13476     }
13477
13478   if (new_show_dev_instance == ~0)
13479     {
13480       errmsg ("missing new_show_dev_instance");
13481       return -99;
13482     }
13483
13484   M (INTERFACE_NAME_RENUMBER, mp);
13485
13486   mp->sw_if_index = ntohl (sw_if_index);
13487   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13488
13489   S (mp);
13490   W (ret);
13491   return ret;
13492 }
13493
13494 static int
13495 api_ip_probe_neighbor (vat_main_t * vam)
13496 {
13497   unformat_input_t *i = vam->input;
13498   vl_api_ip_probe_neighbor_t *mp;
13499   vl_api_address_t dst_adr = { };
13500   u8 int_set = 0;
13501   u8 adr_set = 0;
13502   u32 sw_if_index;
13503   int ret;
13504
13505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13506     {
13507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13508         int_set = 1;
13509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13510         int_set = 1;
13511       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13512         adr_set = 1;
13513       else
13514         break;
13515     }
13516
13517   if (int_set == 0)
13518     {
13519       errmsg ("missing interface");
13520       return -99;
13521     }
13522
13523   if (adr_set == 0)
13524     {
13525       errmsg ("missing addresses");
13526       return -99;
13527     }
13528
13529   M (IP_PROBE_NEIGHBOR, mp);
13530
13531   mp->sw_if_index = ntohl (sw_if_index);
13532   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13533
13534   S (mp);
13535   W (ret);
13536   return ret;
13537 }
13538
13539 static int
13540 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13541 {
13542   unformat_input_t *i = vam->input;
13543   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13544   u8 mode = IP_SCAN_V46_NEIGHBORS;
13545   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13546   int ret;
13547
13548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13549     {
13550       if (unformat (i, "ip4"))
13551         mode = IP_SCAN_V4_NEIGHBORS;
13552       else if (unformat (i, "ip6"))
13553         mode = IP_SCAN_V6_NEIGHBORS;
13554       if (unformat (i, "both"))
13555         mode = IP_SCAN_V46_NEIGHBORS;
13556       else if (unformat (i, "disable"))
13557         mode = IP_SCAN_DISABLED;
13558       else if (unformat (i, "interval %d", &interval))
13559         ;
13560       else if (unformat (i, "max-time %d", &time))
13561         ;
13562       else if (unformat (i, "max-update %d", &update))
13563         ;
13564       else if (unformat (i, "delay %d", &delay))
13565         ;
13566       else if (unformat (i, "stale %d", &stale))
13567         ;
13568       else
13569         break;
13570     }
13571
13572   if (interval > 255)
13573     {
13574       errmsg ("interval cannot exceed 255 minutes.");
13575       return -99;
13576     }
13577   if (time > 255)
13578     {
13579       errmsg ("max-time cannot exceed 255 usec.");
13580       return -99;
13581     }
13582   if (update > 255)
13583     {
13584       errmsg ("max-update cannot exceed 255.");
13585       return -99;
13586     }
13587   if (delay > 255)
13588     {
13589       errmsg ("delay cannot exceed 255 msec.");
13590       return -99;
13591     }
13592   if (stale > 255)
13593     {
13594       errmsg ("stale cannot exceed 255 minutes.");
13595       return -99;
13596     }
13597
13598   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13599   mp->mode = mode;
13600   mp->scan_interval = interval;
13601   mp->max_proc_time = time;
13602   mp->max_update = update;
13603   mp->scan_int_delay = delay;
13604   mp->stale_threshold = stale;
13605
13606   S (mp);
13607   W (ret);
13608   return ret;
13609 }
13610
13611 static int
13612 api_want_ip4_arp_events (vat_main_t * vam)
13613 {
13614   unformat_input_t *line_input = vam->input;
13615   vl_api_want_ip4_arp_events_t *mp;
13616   ip4_address_t address;
13617   int address_set = 0;
13618   u32 enable_disable = 1;
13619   int ret;
13620
13621   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13622     {
13623       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13624         address_set = 1;
13625       else if (unformat (line_input, "del"))
13626         enable_disable = 0;
13627       else
13628         break;
13629     }
13630
13631   if (address_set == 0)
13632     {
13633       errmsg ("missing addresses");
13634       return -99;
13635     }
13636
13637   M (WANT_IP4_ARP_EVENTS, mp);
13638   mp->enable_disable = enable_disable;
13639   mp->pid = htonl (getpid ());
13640   clib_memcpy (mp->ip, &address, sizeof (address));
13641
13642   S (mp);
13643   W (ret);
13644   return ret;
13645 }
13646
13647 static int
13648 api_want_ip6_nd_events (vat_main_t * vam)
13649 {
13650   unformat_input_t *line_input = vam->input;
13651   vl_api_want_ip6_nd_events_t *mp;
13652   vl_api_ip6_address_t address;
13653   int address_set = 0;
13654   u32 enable_disable = 1;
13655   int ret;
13656
13657   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13658     {
13659       if (unformat
13660           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13661         address_set = 1;
13662       else if (unformat (line_input, "del"))
13663         enable_disable = 0;
13664       else
13665         break;
13666     }
13667
13668   if (address_set == 0)
13669     {
13670       errmsg ("missing addresses");
13671       return -99;
13672     }
13673
13674   M (WANT_IP6_ND_EVENTS, mp);
13675   mp->enable_disable = enable_disable;
13676   mp->pid = htonl (getpid ());
13677   clib_memcpy (&mp->ip, &address, sizeof (address));
13678
13679   S (mp);
13680   W (ret);
13681   return ret;
13682 }
13683
13684 static int
13685 api_want_l2_macs_events (vat_main_t * vam)
13686 {
13687   unformat_input_t *line_input = vam->input;
13688   vl_api_want_l2_macs_events_t *mp;
13689   u8 enable_disable = 1;
13690   u32 scan_delay = 0;
13691   u32 max_macs_in_event = 0;
13692   u32 learn_limit = 0;
13693   int ret;
13694
13695   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13696     {
13697       if (unformat (line_input, "learn-limit %d", &learn_limit))
13698         ;
13699       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13700         ;
13701       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13702         ;
13703       else if (unformat (line_input, "disable"))
13704         enable_disable = 0;
13705       else
13706         break;
13707     }
13708
13709   M (WANT_L2_MACS_EVENTS, mp);
13710   mp->enable_disable = enable_disable;
13711   mp->pid = htonl (getpid ());
13712   mp->learn_limit = htonl (learn_limit);
13713   mp->scan_delay = (u8) scan_delay;
13714   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13715   S (mp);
13716   W (ret);
13717   return ret;
13718 }
13719
13720 static int
13721 api_input_acl_set_interface (vat_main_t * vam)
13722 {
13723   unformat_input_t *i = vam->input;
13724   vl_api_input_acl_set_interface_t *mp;
13725   u32 sw_if_index;
13726   int sw_if_index_set;
13727   u32 ip4_table_index = ~0;
13728   u32 ip6_table_index = ~0;
13729   u32 l2_table_index = ~0;
13730   u8 is_add = 1;
13731   int ret;
13732
13733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13734     {
13735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13736         sw_if_index_set = 1;
13737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13738         sw_if_index_set = 1;
13739       else if (unformat (i, "del"))
13740         is_add = 0;
13741       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13742         ;
13743       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13744         ;
13745       else if (unformat (i, "l2-table %d", &l2_table_index))
13746         ;
13747       else
13748         {
13749           clib_warning ("parse error '%U'", format_unformat_error, i);
13750           return -99;
13751         }
13752     }
13753
13754   if (sw_if_index_set == 0)
13755     {
13756       errmsg ("missing interface name or sw_if_index");
13757       return -99;
13758     }
13759
13760   M (INPUT_ACL_SET_INTERFACE, mp);
13761
13762   mp->sw_if_index = ntohl (sw_if_index);
13763   mp->ip4_table_index = ntohl (ip4_table_index);
13764   mp->ip6_table_index = ntohl (ip6_table_index);
13765   mp->l2_table_index = ntohl (l2_table_index);
13766   mp->is_add = is_add;
13767
13768   S (mp);
13769   W (ret);
13770   return ret;
13771 }
13772
13773 static int
13774 api_output_acl_set_interface (vat_main_t * vam)
13775 {
13776   unformat_input_t *i = vam->input;
13777   vl_api_output_acl_set_interface_t *mp;
13778   u32 sw_if_index;
13779   int sw_if_index_set;
13780   u32 ip4_table_index = ~0;
13781   u32 ip6_table_index = ~0;
13782   u32 l2_table_index = ~0;
13783   u8 is_add = 1;
13784   int ret;
13785
13786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13787     {
13788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13789         sw_if_index_set = 1;
13790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13791         sw_if_index_set = 1;
13792       else if (unformat (i, "del"))
13793         is_add = 0;
13794       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13795         ;
13796       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13797         ;
13798       else if (unformat (i, "l2-table %d", &l2_table_index))
13799         ;
13800       else
13801         {
13802           clib_warning ("parse error '%U'", format_unformat_error, i);
13803           return -99;
13804         }
13805     }
13806
13807   if (sw_if_index_set == 0)
13808     {
13809       errmsg ("missing interface name or sw_if_index");
13810       return -99;
13811     }
13812
13813   M (OUTPUT_ACL_SET_INTERFACE, mp);
13814
13815   mp->sw_if_index = ntohl (sw_if_index);
13816   mp->ip4_table_index = ntohl (ip4_table_index);
13817   mp->ip6_table_index = ntohl (ip6_table_index);
13818   mp->l2_table_index = ntohl (l2_table_index);
13819   mp->is_add = is_add;
13820
13821   S (mp);
13822   W (ret);
13823   return ret;
13824 }
13825
13826 static int
13827 api_ip_address_dump (vat_main_t * vam)
13828 {
13829   unformat_input_t *i = vam->input;
13830   vl_api_ip_address_dump_t *mp;
13831   vl_api_control_ping_t *mp_ping;
13832   u32 sw_if_index = ~0;
13833   u8 sw_if_index_set = 0;
13834   u8 ipv4_set = 0;
13835   u8 ipv6_set = 0;
13836   int ret;
13837
13838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13839     {
13840       if (unformat (i, "sw_if_index %d", &sw_if_index))
13841         sw_if_index_set = 1;
13842       else
13843         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13844         sw_if_index_set = 1;
13845       else if (unformat (i, "ipv4"))
13846         ipv4_set = 1;
13847       else if (unformat (i, "ipv6"))
13848         ipv6_set = 1;
13849       else
13850         break;
13851     }
13852
13853   if (ipv4_set && ipv6_set)
13854     {
13855       errmsg ("ipv4 and ipv6 flags cannot be both set");
13856       return -99;
13857     }
13858
13859   if ((!ipv4_set) && (!ipv6_set))
13860     {
13861       errmsg ("no ipv4 nor ipv6 flag set");
13862       return -99;
13863     }
13864
13865   if (sw_if_index_set == 0)
13866     {
13867       errmsg ("missing interface name or sw_if_index");
13868       return -99;
13869     }
13870
13871   vam->current_sw_if_index = sw_if_index;
13872   vam->is_ipv6 = ipv6_set;
13873
13874   M (IP_ADDRESS_DUMP, mp);
13875   mp->sw_if_index = ntohl (sw_if_index);
13876   mp->is_ipv6 = ipv6_set;
13877   S (mp);
13878
13879   /* Use a control ping for synchronization */
13880   MPING (CONTROL_PING, mp_ping);
13881   S (mp_ping);
13882
13883   W (ret);
13884   return ret;
13885 }
13886
13887 static int
13888 api_ip_dump (vat_main_t * vam)
13889 {
13890   vl_api_ip_dump_t *mp;
13891   vl_api_control_ping_t *mp_ping;
13892   unformat_input_t *in = vam->input;
13893   int ipv4_set = 0;
13894   int ipv6_set = 0;
13895   int is_ipv6;
13896   int i;
13897   int ret;
13898
13899   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13900     {
13901       if (unformat (in, "ipv4"))
13902         ipv4_set = 1;
13903       else if (unformat (in, "ipv6"))
13904         ipv6_set = 1;
13905       else
13906         break;
13907     }
13908
13909   if (ipv4_set && ipv6_set)
13910     {
13911       errmsg ("ipv4 and ipv6 flags cannot be both set");
13912       return -99;
13913     }
13914
13915   if ((!ipv4_set) && (!ipv6_set))
13916     {
13917       errmsg ("no ipv4 nor ipv6 flag set");
13918       return -99;
13919     }
13920
13921   is_ipv6 = ipv6_set;
13922   vam->is_ipv6 = is_ipv6;
13923
13924   /* free old data */
13925   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13926     {
13927       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13928     }
13929   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13930
13931   M (IP_DUMP, mp);
13932   mp->is_ipv6 = ipv6_set;
13933   S (mp);
13934
13935   /* Use a control ping for synchronization */
13936   MPING (CONTROL_PING, mp_ping);
13937   S (mp_ping);
13938
13939   W (ret);
13940   return ret;
13941 }
13942
13943 static int
13944 api_ipsec_spd_add_del (vat_main_t * vam)
13945 {
13946   unformat_input_t *i = vam->input;
13947   vl_api_ipsec_spd_add_del_t *mp;
13948   u32 spd_id = ~0;
13949   u8 is_add = 1;
13950   int ret;
13951
13952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13953     {
13954       if (unformat (i, "spd_id %d", &spd_id))
13955         ;
13956       else if (unformat (i, "del"))
13957         is_add = 0;
13958       else
13959         {
13960           clib_warning ("parse error '%U'", format_unformat_error, i);
13961           return -99;
13962         }
13963     }
13964   if (spd_id == ~0)
13965     {
13966       errmsg ("spd_id must be set");
13967       return -99;
13968     }
13969
13970   M (IPSEC_SPD_ADD_DEL, mp);
13971
13972   mp->spd_id = ntohl (spd_id);
13973   mp->is_add = is_add;
13974
13975   S (mp);
13976   W (ret);
13977   return ret;
13978 }
13979
13980 static int
13981 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13982 {
13983   unformat_input_t *i = vam->input;
13984   vl_api_ipsec_interface_add_del_spd_t *mp;
13985   u32 sw_if_index;
13986   u8 sw_if_index_set = 0;
13987   u32 spd_id = (u32) ~ 0;
13988   u8 is_add = 1;
13989   int ret;
13990
13991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13992     {
13993       if (unformat (i, "del"))
13994         is_add = 0;
13995       else if (unformat (i, "spd_id %d", &spd_id))
13996         ;
13997       else
13998         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13999         sw_if_index_set = 1;
14000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14001         sw_if_index_set = 1;
14002       else
14003         {
14004           clib_warning ("parse error '%U'", format_unformat_error, i);
14005           return -99;
14006         }
14007
14008     }
14009
14010   if (spd_id == (u32) ~ 0)
14011     {
14012       errmsg ("spd_id must be set");
14013       return -99;
14014     }
14015
14016   if (sw_if_index_set == 0)
14017     {
14018       errmsg ("missing interface name or sw_if_index");
14019       return -99;
14020     }
14021
14022   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14023
14024   mp->spd_id = ntohl (spd_id);
14025   mp->sw_if_index = ntohl (sw_if_index);
14026   mp->is_add = is_add;
14027
14028   S (mp);
14029   W (ret);
14030   return ret;
14031 }
14032
14033 static int
14034 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14035 {
14036   unformat_input_t *i = vam->input;
14037   vl_api_ipsec_spd_entry_add_del_t *mp;
14038   u8 is_add = 1, is_outbound = 0;
14039   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14040   i32 priority = 0;
14041   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14042   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14043   vl_api_address_t laddr_start = { }, laddr_stop =
14044   {
14045   }, raddr_start =
14046   {
14047   }, raddr_stop =
14048   {
14049   };
14050   int ret;
14051
14052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14053     {
14054       if (unformat (i, "del"))
14055         is_add = 0;
14056       if (unformat (i, "outbound"))
14057         is_outbound = 1;
14058       if (unformat (i, "inbound"))
14059         is_outbound = 0;
14060       else if (unformat (i, "spd_id %d", &spd_id))
14061         ;
14062       else if (unformat (i, "sa_id %d", &sa_id))
14063         ;
14064       else if (unformat (i, "priority %d", &priority))
14065         ;
14066       else if (unformat (i, "protocol %d", &protocol))
14067         ;
14068       else if (unformat (i, "lport_start %d", &lport_start))
14069         ;
14070       else if (unformat (i, "lport_stop %d", &lport_stop))
14071         ;
14072       else if (unformat (i, "rport_start %d", &rport_start))
14073         ;
14074       else if (unformat (i, "rport_stop %d", &rport_stop))
14075         ;
14076       else if (unformat (i, "laddr_start %U",
14077                          unformat_vl_api_address, &laddr_start))
14078         ;
14079       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14080                          &laddr_stop))
14081         ;
14082       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14083                          &raddr_start))
14084         ;
14085       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14086                          &raddr_stop))
14087         ;
14088       else
14089         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14090         {
14091           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14092             {
14093               clib_warning ("unsupported action: 'resolve'");
14094               return -99;
14095             }
14096         }
14097       else
14098         {
14099           clib_warning ("parse error '%U'", format_unformat_error, i);
14100           return -99;
14101         }
14102
14103     }
14104
14105   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14106
14107   mp->is_add = is_add;
14108
14109   mp->entry.spd_id = ntohl (spd_id);
14110   mp->entry.priority = ntohl (priority);
14111   mp->entry.is_outbound = is_outbound;
14112
14113   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14114                sizeof (vl_api_address_t));
14115   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14116                sizeof (vl_api_address_t));
14117   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14118                sizeof (vl_api_address_t));
14119   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14120                sizeof (vl_api_address_t));
14121
14122   mp->entry.protocol = (u8) protocol;
14123   mp->entry.local_port_start = ntohs ((u16) lport_start);
14124   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14125   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14126   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14127   mp->entry.policy = (u8) policy;
14128   mp->entry.sa_id = ntohl (sa_id);
14129
14130   S (mp);
14131   W (ret);
14132   return ret;
14133 }
14134
14135 static int
14136 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14137 {
14138   unformat_input_t *i = vam->input;
14139   vl_api_ipsec_sad_entry_add_del_t *mp;
14140   u32 sad_id = 0, spi = 0;
14141   u8 *ck = 0, *ik = 0;
14142   u8 is_add = 1;
14143
14144   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14145   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14146   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14147   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14148   vl_api_address_t tun_src, tun_dst;
14149   int ret;
14150
14151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14152     {
14153       if (unformat (i, "del"))
14154         is_add = 0;
14155       else if (unformat (i, "sad_id %d", &sad_id))
14156         ;
14157       else if (unformat (i, "spi %d", &spi))
14158         ;
14159       else if (unformat (i, "esp"))
14160         protocol = IPSEC_API_PROTO_ESP;
14161       else
14162         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14163         {
14164           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14165           if (ADDRESS_IP6 == tun_src.af)
14166             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14167         }
14168       else
14169         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14170         {
14171           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14172           if (ADDRESS_IP6 == tun_src.af)
14173             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14174         }
14175       else
14176         if (unformat (i, "crypto_alg %U",
14177                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14178         ;
14179       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14180         ;
14181       else if (unformat (i, "integ_alg %U",
14182                          unformat_ipsec_api_integ_alg, &integ_alg))
14183         ;
14184       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14185         ;
14186       else
14187         {
14188           clib_warning ("parse error '%U'", format_unformat_error, i);
14189           return -99;
14190         }
14191
14192     }
14193
14194   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14195
14196   mp->is_add = is_add;
14197   mp->entry.sad_id = ntohl (sad_id);
14198   mp->entry.protocol = protocol;
14199   mp->entry.spi = ntohl (spi);
14200   mp->entry.flags = flags;
14201
14202   mp->entry.crypto_algorithm = crypto_alg;
14203   mp->entry.integrity_algorithm = integ_alg;
14204   mp->entry.crypto_key.length = vec_len (ck);
14205   mp->entry.integrity_key.length = vec_len (ik);
14206
14207   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14208     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14209
14210   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14211     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14212
14213   if (ck)
14214     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14215   if (ik)
14216     clib_memcpy (mp->entry.integrity_key.data, ik,
14217                  mp->entry.integrity_key.length);
14218
14219   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14220     {
14221       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14222                    sizeof (mp->entry.tunnel_src));
14223       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14224                    sizeof (mp->entry.tunnel_dst));
14225     }
14226
14227   S (mp);
14228   W (ret);
14229   return ret;
14230 }
14231
14232 static int
14233 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14234 {
14235   unformat_input_t *i = vam->input;
14236   vl_api_ipsec_tunnel_if_add_del_t *mp;
14237   u32 local_spi = 0, remote_spi = 0;
14238   u32 crypto_alg = 0, integ_alg = 0;
14239   u8 *lck = NULL, *rck = NULL;
14240   u8 *lik = NULL, *rik = NULL;
14241   vl_api_address_t local_ip = { 0 };
14242   vl_api_address_t remote_ip = { 0 };
14243   f64 before = 0;
14244   u8 is_add = 1;
14245   u8 esn = 0;
14246   u8 anti_replay = 0;
14247   u8 renumber = 0;
14248   u32 instance = ~0;
14249   u32 count = 1, jj;
14250   int ret = -1;
14251
14252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14253     {
14254       if (unformat (i, "del"))
14255         is_add = 0;
14256       else if (unformat (i, "esn"))
14257         esn = 1;
14258       else if (unformat (i, "anti-replay"))
14259         anti_replay = 1;
14260       else if (unformat (i, "count %d", &count))
14261         ;
14262       else if (unformat (i, "local_spi %d", &local_spi))
14263         ;
14264       else if (unformat (i, "remote_spi %d", &remote_spi))
14265         ;
14266       else
14267         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14268         ;
14269       else
14270         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14271         ;
14272       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14273         ;
14274       else
14275         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14276         ;
14277       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14278         ;
14279       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14280         ;
14281       else
14282         if (unformat
14283             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14284         {
14285           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14286             {
14287               errmsg ("unsupported crypto-alg: '%U'\n",
14288                       format_ipsec_crypto_alg, crypto_alg);
14289               return -99;
14290             }
14291         }
14292       else
14293         if (unformat
14294             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14295         {
14296           if (integ_alg >= IPSEC_INTEG_N_ALG)
14297             {
14298               errmsg ("unsupported integ-alg: '%U'\n",
14299                       format_ipsec_integ_alg, integ_alg);
14300               return -99;
14301             }
14302         }
14303       else if (unformat (i, "instance %u", &instance))
14304         renumber = 1;
14305       else
14306         {
14307           errmsg ("parse error '%U'\n", format_unformat_error, i);
14308           return -99;
14309         }
14310     }
14311
14312   if (count > 1)
14313     {
14314       /* Turn on async mode */
14315       vam->async_mode = 1;
14316       vam->async_errors = 0;
14317       before = vat_time_now (vam);
14318     }
14319
14320   for (jj = 0; jj < count; jj++)
14321     {
14322       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14323
14324       mp->is_add = is_add;
14325       mp->esn = esn;
14326       mp->anti_replay = anti_replay;
14327
14328       if (jj > 0)
14329         increment_address (&remote_ip);
14330
14331       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14332       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14333
14334       mp->local_spi = htonl (local_spi + jj);
14335       mp->remote_spi = htonl (remote_spi + jj);
14336       mp->crypto_alg = (u8) crypto_alg;
14337
14338       mp->local_crypto_key_len = 0;
14339       if (lck)
14340         {
14341           mp->local_crypto_key_len = vec_len (lck);
14342           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14343             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14344           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14345         }
14346
14347       mp->remote_crypto_key_len = 0;
14348       if (rck)
14349         {
14350           mp->remote_crypto_key_len = vec_len (rck);
14351           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14352             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14353           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14354         }
14355
14356       mp->integ_alg = (u8) integ_alg;
14357
14358       mp->local_integ_key_len = 0;
14359       if (lik)
14360         {
14361           mp->local_integ_key_len = vec_len (lik);
14362           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14363             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14364           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14365         }
14366
14367       mp->remote_integ_key_len = 0;
14368       if (rik)
14369         {
14370           mp->remote_integ_key_len = vec_len (rik);
14371           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14372             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14373           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14374         }
14375
14376       if (renumber)
14377         {
14378           mp->renumber = renumber;
14379           mp->show_instance = ntohl (instance);
14380         }
14381       S (mp);
14382     }
14383
14384   /* When testing multiple add/del ops, use a control-ping to sync */
14385   if (count > 1)
14386     {
14387       vl_api_control_ping_t *mp_ping;
14388       f64 after;
14389       f64 timeout;
14390
14391       /* Shut off async mode */
14392       vam->async_mode = 0;
14393
14394       MPING (CONTROL_PING, mp_ping);
14395       S (mp_ping);
14396
14397       timeout = vat_time_now (vam) + 1.0;
14398       while (vat_time_now (vam) < timeout)
14399         if (vam->result_ready == 1)
14400           goto out;
14401       vam->retval = -99;
14402
14403     out:
14404       if (vam->retval == -99)
14405         errmsg ("timeout");
14406
14407       if (vam->async_errors > 0)
14408         {
14409           errmsg ("%d asynchronous errors", vam->async_errors);
14410           vam->retval = -98;
14411         }
14412       vam->async_errors = 0;
14413       after = vat_time_now (vam);
14414
14415       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14416       if (jj > 0)
14417         count = jj;
14418
14419       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14420              count, after - before, count / (after - before));
14421     }
14422   else
14423     {
14424       /* Wait for a reply... */
14425       W (ret);
14426       return ret;
14427     }
14428
14429   return ret;
14430 }
14431
14432 static void
14433 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14434 {
14435   vat_main_t *vam = &vat_main;
14436
14437   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14438          "crypto_key %U integ_alg %u integ_key %U flags %x "
14439          "tunnel_src_addr %U tunnel_dst_addr %U "
14440          "salt %u seq_outbound %lu last_seq_inbound %lu "
14441          "replay_window %lu\n",
14442          ntohl (mp->entry.sad_id),
14443          ntohl (mp->sw_if_index),
14444          ntohl (mp->entry.spi),
14445          ntohl (mp->entry.protocol),
14446          ntohl (mp->entry.crypto_algorithm),
14447          format_hex_bytes, mp->entry.crypto_key.data,
14448          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14449          format_hex_bytes, mp->entry.integrity_key.data,
14450          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14451          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14452          &mp->entry.tunnel_dst, ntohl (mp->salt),
14453          clib_net_to_host_u64 (mp->seq_outbound),
14454          clib_net_to_host_u64 (mp->last_seq_inbound),
14455          clib_net_to_host_u64 (mp->replay_window));
14456 }
14457
14458 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14459 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14460
14461 static void vl_api_ipsec_sa_details_t_handler_json
14462   (vl_api_ipsec_sa_details_t * mp)
14463 {
14464   vat_main_t *vam = &vat_main;
14465   vat_json_node_t *node = NULL;
14466   vl_api_ipsec_sad_flags_t flags;
14467
14468   if (VAT_JSON_ARRAY != vam->json_tree.type)
14469     {
14470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14471       vat_json_init_array (&vam->json_tree);
14472     }
14473   node = vat_json_array_add (&vam->json_tree);
14474
14475   vat_json_init_object (node);
14476   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14477   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14478   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14479   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14480   vat_json_object_add_uint (node, "crypto_alg",
14481                             ntohl (mp->entry.crypto_algorithm));
14482   vat_json_object_add_uint (node, "integ_alg",
14483                             ntohl (mp->entry.integrity_algorithm));
14484   flags = ntohl (mp->entry.flags);
14485   vat_json_object_add_uint (node, "use_esn",
14486                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14487   vat_json_object_add_uint (node, "use_anti_replay",
14488                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14489   vat_json_object_add_uint (node, "is_tunnel",
14490                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14491   vat_json_object_add_uint (node, "is_tunnel_ip6",
14492                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14493   vat_json_object_add_uint (node, "udp_encap",
14494                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14495   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14496                              mp->entry.crypto_key.length);
14497   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14498                              mp->entry.integrity_key.length);
14499   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14500   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14501   vat_json_object_add_uint (node, "replay_window",
14502                             clib_net_to_host_u64 (mp->replay_window));
14503 }
14504
14505 static int
14506 api_ipsec_sa_dump (vat_main_t * vam)
14507 {
14508   unformat_input_t *i = vam->input;
14509   vl_api_ipsec_sa_dump_t *mp;
14510   vl_api_control_ping_t *mp_ping;
14511   u32 sa_id = ~0;
14512   int ret;
14513
14514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14515     {
14516       if (unformat (i, "sa_id %d", &sa_id))
14517         ;
14518       else
14519         {
14520           clib_warning ("parse error '%U'", format_unformat_error, i);
14521           return -99;
14522         }
14523     }
14524
14525   M (IPSEC_SA_DUMP, mp);
14526
14527   mp->sa_id = ntohl (sa_id);
14528
14529   S (mp);
14530
14531   /* Use a control ping for synchronization */
14532   M (CONTROL_PING, mp_ping);
14533   S (mp_ping);
14534
14535   W (ret);
14536   return ret;
14537 }
14538
14539 static int
14540 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14541 {
14542   unformat_input_t *i = vam->input;
14543   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14544   u32 sw_if_index = ~0;
14545   u32 sa_id = ~0;
14546   u8 is_outbound = (u8) ~ 0;
14547   int ret;
14548
14549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14550     {
14551       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14552         ;
14553       else if (unformat (i, "sa_id %d", &sa_id))
14554         ;
14555       else if (unformat (i, "outbound"))
14556         is_outbound = 1;
14557       else if (unformat (i, "inbound"))
14558         is_outbound = 0;
14559       else
14560         {
14561           clib_warning ("parse error '%U'", format_unformat_error, i);
14562           return -99;
14563         }
14564     }
14565
14566   if (sw_if_index == ~0)
14567     {
14568       errmsg ("interface must be specified");
14569       return -99;
14570     }
14571
14572   if (sa_id == ~0)
14573     {
14574       errmsg ("SA ID must be specified");
14575       return -99;
14576     }
14577
14578   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14579
14580   mp->sw_if_index = htonl (sw_if_index);
14581   mp->sa_id = htonl (sa_id);
14582   mp->is_outbound = is_outbound;
14583
14584   S (mp);
14585   W (ret);
14586
14587   return ret;
14588 }
14589
14590 static int
14591 api_get_first_msg_id (vat_main_t * vam)
14592 {
14593   vl_api_get_first_msg_id_t *mp;
14594   unformat_input_t *i = vam->input;
14595   u8 *name;
14596   u8 name_set = 0;
14597   int ret;
14598
14599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14600     {
14601       if (unformat (i, "client %s", &name))
14602         name_set = 1;
14603       else
14604         break;
14605     }
14606
14607   if (name_set == 0)
14608     {
14609       errmsg ("missing client name");
14610       return -99;
14611     }
14612   vec_add1 (name, 0);
14613
14614   if (vec_len (name) > 63)
14615     {
14616       errmsg ("client name too long");
14617       return -99;
14618     }
14619
14620   M (GET_FIRST_MSG_ID, mp);
14621   clib_memcpy (mp->name, name, vec_len (name));
14622   S (mp);
14623   W (ret);
14624   return ret;
14625 }
14626
14627 static int
14628 api_cop_interface_enable_disable (vat_main_t * vam)
14629 {
14630   unformat_input_t *line_input = vam->input;
14631   vl_api_cop_interface_enable_disable_t *mp;
14632   u32 sw_if_index = ~0;
14633   u8 enable_disable = 1;
14634   int ret;
14635
14636   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (line_input, "disable"))
14639         enable_disable = 0;
14640       if (unformat (line_input, "enable"))
14641         enable_disable = 1;
14642       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14643                          vam, &sw_if_index))
14644         ;
14645       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14646         ;
14647       else
14648         break;
14649     }
14650
14651   if (sw_if_index == ~0)
14652     {
14653       errmsg ("missing interface name or sw_if_index");
14654       return -99;
14655     }
14656
14657   /* Construct the API message */
14658   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14659   mp->sw_if_index = ntohl (sw_if_index);
14660   mp->enable_disable = enable_disable;
14661
14662   /* send it... */
14663   S (mp);
14664   /* Wait for the reply */
14665   W (ret);
14666   return ret;
14667 }
14668
14669 static int
14670 api_cop_whitelist_enable_disable (vat_main_t * vam)
14671 {
14672   unformat_input_t *line_input = vam->input;
14673   vl_api_cop_whitelist_enable_disable_t *mp;
14674   u32 sw_if_index = ~0;
14675   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14676   u32 fib_id = 0;
14677   int ret;
14678
14679   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14680     {
14681       if (unformat (line_input, "ip4"))
14682         ip4 = 1;
14683       else if (unformat (line_input, "ip6"))
14684         ip6 = 1;
14685       else if (unformat (line_input, "default"))
14686         default_cop = 1;
14687       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14688                          vam, &sw_if_index))
14689         ;
14690       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14691         ;
14692       else if (unformat (line_input, "fib-id %d", &fib_id))
14693         ;
14694       else
14695         break;
14696     }
14697
14698   if (sw_if_index == ~0)
14699     {
14700       errmsg ("missing interface name or sw_if_index");
14701       return -99;
14702     }
14703
14704   /* Construct the API message */
14705   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14706   mp->sw_if_index = ntohl (sw_if_index);
14707   mp->fib_id = ntohl (fib_id);
14708   mp->ip4 = ip4;
14709   mp->ip6 = ip6;
14710   mp->default_cop = default_cop;
14711
14712   /* send it... */
14713   S (mp);
14714   /* Wait for the reply */
14715   W (ret);
14716   return ret;
14717 }
14718
14719 static int
14720 api_get_node_graph (vat_main_t * vam)
14721 {
14722   vl_api_get_node_graph_t *mp;
14723   int ret;
14724
14725   M (GET_NODE_GRAPH, mp);
14726
14727   /* send it... */
14728   S (mp);
14729   /* Wait for the reply */
14730   W (ret);
14731   return ret;
14732 }
14733
14734 /* *INDENT-OFF* */
14735 /** Used for parsing LISP eids */
14736 typedef CLIB_PACKED(struct{
14737   u8 addr[16];   /**< eid address */
14738   u32 len;       /**< prefix length if IP */
14739   u8 type;      /**< type of eid */
14740 }) lisp_eid_vat_t;
14741 /* *INDENT-ON* */
14742
14743 static uword
14744 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14745 {
14746   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14747
14748   clib_memset (a, 0, sizeof (a[0]));
14749
14750   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14751     {
14752       a->type = 0;              /* ipv4 type */
14753     }
14754   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14755     {
14756       a->type = 1;              /* ipv6 type */
14757     }
14758   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14759     {
14760       a->type = 2;              /* mac type */
14761     }
14762   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14763     {
14764       a->type = 3;              /* NSH type */
14765       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14766       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14767     }
14768   else
14769     {
14770       return 0;
14771     }
14772
14773   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14774     {
14775       return 0;
14776     }
14777
14778   return 1;
14779 }
14780
14781 static int
14782 lisp_eid_size_vat (u8 type)
14783 {
14784   switch (type)
14785     {
14786     case 0:
14787       return 4;
14788     case 1:
14789       return 16;
14790     case 2:
14791       return 6;
14792     case 3:
14793       return 5;
14794     }
14795   return 0;
14796 }
14797
14798 static void
14799 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14800 {
14801   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14802 }
14803
14804 static int
14805 api_one_add_del_locator_set (vat_main_t * vam)
14806 {
14807   unformat_input_t *input = vam->input;
14808   vl_api_one_add_del_locator_set_t *mp;
14809   u8 is_add = 1;
14810   u8 *locator_set_name = NULL;
14811   u8 locator_set_name_set = 0;
14812   vl_api_local_locator_t locator, *locators = 0;
14813   u32 sw_if_index, priority, weight;
14814   u32 data_len = 0;
14815
14816   int ret;
14817   /* Parse args required to build the message */
14818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14819     {
14820       if (unformat (input, "del"))
14821         {
14822           is_add = 0;
14823         }
14824       else if (unformat (input, "locator-set %s", &locator_set_name))
14825         {
14826           locator_set_name_set = 1;
14827         }
14828       else if (unformat (input, "sw_if_index %u p %u w %u",
14829                          &sw_if_index, &priority, &weight))
14830         {
14831           locator.sw_if_index = htonl (sw_if_index);
14832           locator.priority = priority;
14833           locator.weight = weight;
14834           vec_add1 (locators, locator);
14835         }
14836       else
14837         if (unformat
14838             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14839              &sw_if_index, &priority, &weight))
14840         {
14841           locator.sw_if_index = htonl (sw_if_index);
14842           locator.priority = priority;
14843           locator.weight = weight;
14844           vec_add1 (locators, locator);
14845         }
14846       else
14847         break;
14848     }
14849
14850   if (locator_set_name_set == 0)
14851     {
14852       errmsg ("missing locator-set name");
14853       vec_free (locators);
14854       return -99;
14855     }
14856
14857   if (vec_len (locator_set_name) > 64)
14858     {
14859       errmsg ("locator-set name too long");
14860       vec_free (locator_set_name);
14861       vec_free (locators);
14862       return -99;
14863     }
14864   vec_add1 (locator_set_name, 0);
14865
14866   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14867
14868   /* Construct the API message */
14869   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14870
14871   mp->is_add = is_add;
14872   clib_memcpy (mp->locator_set_name, locator_set_name,
14873                vec_len (locator_set_name));
14874   vec_free (locator_set_name);
14875
14876   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14877   if (locators)
14878     clib_memcpy (mp->locators, locators, data_len);
14879   vec_free (locators);
14880
14881   /* send it... */
14882   S (mp);
14883
14884   /* Wait for a reply... */
14885   W (ret);
14886   return ret;
14887 }
14888
14889 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14890
14891 static int
14892 api_one_add_del_locator (vat_main_t * vam)
14893 {
14894   unformat_input_t *input = vam->input;
14895   vl_api_one_add_del_locator_t *mp;
14896   u32 tmp_if_index = ~0;
14897   u32 sw_if_index = ~0;
14898   u8 sw_if_index_set = 0;
14899   u8 sw_if_index_if_name_set = 0;
14900   u32 priority = ~0;
14901   u8 priority_set = 0;
14902   u32 weight = ~0;
14903   u8 weight_set = 0;
14904   u8 is_add = 1;
14905   u8 *locator_set_name = NULL;
14906   u8 locator_set_name_set = 0;
14907   int ret;
14908
14909   /* Parse args required to build the message */
14910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14911     {
14912       if (unformat (input, "del"))
14913         {
14914           is_add = 0;
14915         }
14916       else if (unformat (input, "locator-set %s", &locator_set_name))
14917         {
14918           locator_set_name_set = 1;
14919         }
14920       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14921                          &tmp_if_index))
14922         {
14923           sw_if_index_if_name_set = 1;
14924           sw_if_index = tmp_if_index;
14925         }
14926       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14927         {
14928           sw_if_index_set = 1;
14929           sw_if_index = tmp_if_index;
14930         }
14931       else if (unformat (input, "p %d", &priority))
14932         {
14933           priority_set = 1;
14934         }
14935       else if (unformat (input, "w %d", &weight))
14936         {
14937           weight_set = 1;
14938         }
14939       else
14940         break;
14941     }
14942
14943   if (locator_set_name_set == 0)
14944     {
14945       errmsg ("missing locator-set name");
14946       return -99;
14947     }
14948
14949   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14950     {
14951       errmsg ("missing sw_if_index");
14952       vec_free (locator_set_name);
14953       return -99;
14954     }
14955
14956   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14957     {
14958       errmsg ("cannot use both params interface name and sw_if_index");
14959       vec_free (locator_set_name);
14960       return -99;
14961     }
14962
14963   if (priority_set == 0)
14964     {
14965       errmsg ("missing locator-set priority");
14966       vec_free (locator_set_name);
14967       return -99;
14968     }
14969
14970   if (weight_set == 0)
14971     {
14972       errmsg ("missing locator-set weight");
14973       vec_free (locator_set_name);
14974       return -99;
14975     }
14976
14977   if (vec_len (locator_set_name) > 64)
14978     {
14979       errmsg ("locator-set name too long");
14980       vec_free (locator_set_name);
14981       return -99;
14982     }
14983   vec_add1 (locator_set_name, 0);
14984
14985   /* Construct the API message */
14986   M (ONE_ADD_DEL_LOCATOR, mp);
14987
14988   mp->is_add = is_add;
14989   mp->sw_if_index = ntohl (sw_if_index);
14990   mp->priority = priority;
14991   mp->weight = weight;
14992   clib_memcpy (mp->locator_set_name, locator_set_name,
14993                vec_len (locator_set_name));
14994   vec_free (locator_set_name);
14995
14996   /* send it... */
14997   S (mp);
14998
14999   /* Wait for a reply... */
15000   W (ret);
15001   return ret;
15002 }
15003
15004 #define api_lisp_add_del_locator api_one_add_del_locator
15005
15006 uword
15007 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15008 {
15009   u32 *key_id = va_arg (*args, u32 *);
15010   u8 *s = 0;
15011
15012   if (unformat (input, "%s", &s))
15013     {
15014       if (!strcmp ((char *) s, "sha1"))
15015         key_id[0] = HMAC_SHA_1_96;
15016       else if (!strcmp ((char *) s, "sha256"))
15017         key_id[0] = HMAC_SHA_256_128;
15018       else
15019         {
15020           clib_warning ("invalid key_id: '%s'", s);
15021           key_id[0] = HMAC_NO_KEY;
15022         }
15023     }
15024   else
15025     return 0;
15026
15027   vec_free (s);
15028   return 1;
15029 }
15030
15031 static int
15032 api_one_add_del_local_eid (vat_main_t * vam)
15033 {
15034   unformat_input_t *input = vam->input;
15035   vl_api_one_add_del_local_eid_t *mp;
15036   u8 is_add = 1;
15037   u8 eid_set = 0;
15038   lisp_eid_vat_t _eid, *eid = &_eid;
15039   u8 *locator_set_name = 0;
15040   u8 locator_set_name_set = 0;
15041   u32 vni = 0;
15042   u16 key_id = 0;
15043   u8 *key = 0;
15044   int ret;
15045
15046   /* Parse args required to build the message */
15047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15048     {
15049       if (unformat (input, "del"))
15050         {
15051           is_add = 0;
15052         }
15053       else if (unformat (input, "vni %d", &vni))
15054         {
15055           ;
15056         }
15057       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15058         {
15059           eid_set = 1;
15060         }
15061       else if (unformat (input, "locator-set %s", &locator_set_name))
15062         {
15063           locator_set_name_set = 1;
15064         }
15065       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15066         ;
15067       else if (unformat (input, "secret-key %_%v%_", &key))
15068         ;
15069       else
15070         break;
15071     }
15072
15073   if (locator_set_name_set == 0)
15074     {
15075       errmsg ("missing locator-set name");
15076       return -99;
15077     }
15078
15079   if (0 == eid_set)
15080     {
15081       errmsg ("EID address not set!");
15082       vec_free (locator_set_name);
15083       return -99;
15084     }
15085
15086   if (key && (0 == key_id))
15087     {
15088       errmsg ("invalid key_id!");
15089       return -99;
15090     }
15091
15092   if (vec_len (key) > 64)
15093     {
15094       errmsg ("key too long");
15095       vec_free (key);
15096       return -99;
15097     }
15098
15099   if (vec_len (locator_set_name) > 64)
15100     {
15101       errmsg ("locator-set name too long");
15102       vec_free (locator_set_name);
15103       return -99;
15104     }
15105   vec_add1 (locator_set_name, 0);
15106
15107   /* Construct the API message */
15108   M (ONE_ADD_DEL_LOCAL_EID, mp);
15109
15110   mp->is_add = is_add;
15111   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15112   mp->eid_type = eid->type;
15113   mp->prefix_len = eid->len;
15114   mp->vni = clib_host_to_net_u32 (vni);
15115   mp->key_id = clib_host_to_net_u16 (key_id);
15116   clib_memcpy (mp->locator_set_name, locator_set_name,
15117                vec_len (locator_set_name));
15118   clib_memcpy (mp->key, key, vec_len (key));
15119
15120   vec_free (locator_set_name);
15121   vec_free (key);
15122
15123   /* send it... */
15124   S (mp);
15125
15126   /* Wait for a reply... */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15132
15133 static int
15134 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15135 {
15136   u32 dp_table = 0, vni = 0;;
15137   unformat_input_t *input = vam->input;
15138   vl_api_gpe_add_del_fwd_entry_t *mp;
15139   u8 is_add = 1;
15140   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15141   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15142   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15143   u32 action = ~0, w;
15144   ip4_address_t rmt_rloc4, lcl_rloc4;
15145   ip6_address_t rmt_rloc6, lcl_rloc6;
15146   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15147   int ret;
15148
15149   clib_memset (&rloc, 0, sizeof (rloc));
15150
15151   /* Parse args required to build the message */
15152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15153     {
15154       if (unformat (input, "del"))
15155         is_add = 0;
15156       else if (unformat (input, "add"))
15157         is_add = 1;
15158       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15159         {
15160           rmt_eid_set = 1;
15161         }
15162       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15163         {
15164           lcl_eid_set = 1;
15165         }
15166       else if (unformat (input, "vrf %d", &dp_table))
15167         ;
15168       else if (unformat (input, "bd %d", &dp_table))
15169         ;
15170       else if (unformat (input, "vni %d", &vni))
15171         ;
15172       else if (unformat (input, "w %d", &w))
15173         {
15174           if (!curr_rloc)
15175             {
15176               errmsg ("No RLOC configured for setting priority/weight!");
15177               return -99;
15178             }
15179           curr_rloc->weight = w;
15180         }
15181       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15182                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15183         {
15184           rloc.is_ip4 = 1;
15185
15186           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15187           rloc.weight = 0;
15188           vec_add1 (lcl_locs, rloc);
15189
15190           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15191           vec_add1 (rmt_locs, rloc);
15192           /* weight saved in rmt loc */
15193           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15194         }
15195       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15196                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15197         {
15198           rloc.is_ip4 = 0;
15199           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15200           rloc.weight = 0;
15201           vec_add1 (lcl_locs, rloc);
15202
15203           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15204           vec_add1 (rmt_locs, rloc);
15205           /* weight saved in rmt loc */
15206           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15207         }
15208       else if (unformat (input, "action %d", &action))
15209         {
15210           ;
15211         }
15212       else
15213         {
15214           clib_warning ("parse error '%U'", format_unformat_error, input);
15215           return -99;
15216         }
15217     }
15218
15219   if (!rmt_eid_set)
15220     {
15221       errmsg ("remote eid addresses not set");
15222       return -99;
15223     }
15224
15225   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15226     {
15227       errmsg ("eid types don't match");
15228       return -99;
15229     }
15230
15231   if (0 == rmt_locs && (u32) ~ 0 == action)
15232     {
15233       errmsg ("action not set for negative mapping");
15234       return -99;
15235     }
15236
15237   /* Construct the API message */
15238   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15239       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15240
15241   mp->is_add = is_add;
15242   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15243   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15244   mp->eid_type = rmt_eid->type;
15245   mp->dp_table = clib_host_to_net_u32 (dp_table);
15246   mp->vni = clib_host_to_net_u32 (vni);
15247   mp->rmt_len = rmt_eid->len;
15248   mp->lcl_len = lcl_eid->len;
15249   mp->action = action;
15250
15251   if (0 != rmt_locs && 0 != lcl_locs)
15252     {
15253       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15254       clib_memcpy (mp->locs, lcl_locs,
15255                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15256
15257       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15258       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15259                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15260     }
15261   vec_free (lcl_locs);
15262   vec_free (rmt_locs);
15263
15264   /* send it... */
15265   S (mp);
15266
15267   /* Wait for a reply... */
15268   W (ret);
15269   return ret;
15270 }
15271
15272 static int
15273 api_one_add_del_map_server (vat_main_t * vam)
15274 {
15275   unformat_input_t *input = vam->input;
15276   vl_api_one_add_del_map_server_t *mp;
15277   u8 is_add = 1;
15278   u8 ipv4_set = 0;
15279   u8 ipv6_set = 0;
15280   ip4_address_t ipv4;
15281   ip6_address_t ipv6;
15282   int ret;
15283
15284   /* Parse args required to build the message */
15285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15286     {
15287       if (unformat (input, "del"))
15288         {
15289           is_add = 0;
15290         }
15291       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15292         {
15293           ipv4_set = 1;
15294         }
15295       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15296         {
15297           ipv6_set = 1;
15298         }
15299       else
15300         break;
15301     }
15302
15303   if (ipv4_set && ipv6_set)
15304     {
15305       errmsg ("both eid v4 and v6 addresses set");
15306       return -99;
15307     }
15308
15309   if (!ipv4_set && !ipv6_set)
15310     {
15311       errmsg ("eid addresses not set");
15312       return -99;
15313     }
15314
15315   /* Construct the API message */
15316   M (ONE_ADD_DEL_MAP_SERVER, mp);
15317
15318   mp->is_add = is_add;
15319   if (ipv6_set)
15320     {
15321       mp->is_ipv6 = 1;
15322       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15323     }
15324   else
15325     {
15326       mp->is_ipv6 = 0;
15327       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15328     }
15329
15330   /* send it... */
15331   S (mp);
15332
15333   /* Wait for a reply... */
15334   W (ret);
15335   return ret;
15336 }
15337
15338 #define api_lisp_add_del_map_server api_one_add_del_map_server
15339
15340 static int
15341 api_one_add_del_map_resolver (vat_main_t * vam)
15342 {
15343   unformat_input_t *input = vam->input;
15344   vl_api_one_add_del_map_resolver_t *mp;
15345   u8 is_add = 1;
15346   u8 ipv4_set = 0;
15347   u8 ipv6_set = 0;
15348   ip4_address_t ipv4;
15349   ip6_address_t ipv6;
15350   int ret;
15351
15352   /* Parse args required to build the message */
15353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15354     {
15355       if (unformat (input, "del"))
15356         {
15357           is_add = 0;
15358         }
15359       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15360         {
15361           ipv4_set = 1;
15362         }
15363       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15364         {
15365           ipv6_set = 1;
15366         }
15367       else
15368         break;
15369     }
15370
15371   if (ipv4_set && ipv6_set)
15372     {
15373       errmsg ("both eid v4 and v6 addresses set");
15374       return -99;
15375     }
15376
15377   if (!ipv4_set && !ipv6_set)
15378     {
15379       errmsg ("eid addresses not set");
15380       return -99;
15381     }
15382
15383   /* Construct the API message */
15384   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15385
15386   mp->is_add = is_add;
15387   if (ipv6_set)
15388     {
15389       mp->is_ipv6 = 1;
15390       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15391     }
15392   else
15393     {
15394       mp->is_ipv6 = 0;
15395       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15396     }
15397
15398   /* send it... */
15399   S (mp);
15400
15401   /* Wait for a reply... */
15402   W (ret);
15403   return ret;
15404 }
15405
15406 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15407
15408 static int
15409 api_lisp_gpe_enable_disable (vat_main_t * vam)
15410 {
15411   unformat_input_t *input = vam->input;
15412   vl_api_gpe_enable_disable_t *mp;
15413   u8 is_set = 0;
15414   u8 is_en = 1;
15415   int ret;
15416
15417   /* Parse args required to build the message */
15418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15419     {
15420       if (unformat (input, "enable"))
15421         {
15422           is_set = 1;
15423           is_en = 1;
15424         }
15425       else if (unformat (input, "disable"))
15426         {
15427           is_set = 1;
15428           is_en = 0;
15429         }
15430       else
15431         break;
15432     }
15433
15434   if (is_set == 0)
15435     {
15436       errmsg ("Value not set");
15437       return -99;
15438     }
15439
15440   /* Construct the API message */
15441   M (GPE_ENABLE_DISABLE, mp);
15442
15443   mp->is_en = is_en;
15444
15445   /* send it... */
15446   S (mp);
15447
15448   /* Wait for a reply... */
15449   W (ret);
15450   return ret;
15451 }
15452
15453 static int
15454 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15455 {
15456   unformat_input_t *input = vam->input;
15457   vl_api_one_rloc_probe_enable_disable_t *mp;
15458   u8 is_set = 0;
15459   u8 is_en = 0;
15460   int ret;
15461
15462   /* Parse args required to build the message */
15463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15464     {
15465       if (unformat (input, "enable"))
15466         {
15467           is_set = 1;
15468           is_en = 1;
15469         }
15470       else if (unformat (input, "disable"))
15471         is_set = 1;
15472       else
15473         break;
15474     }
15475
15476   if (!is_set)
15477     {
15478       errmsg ("Value not set");
15479       return -99;
15480     }
15481
15482   /* Construct the API message */
15483   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15484
15485   mp->is_enabled = is_en;
15486
15487   /* send it... */
15488   S (mp);
15489
15490   /* Wait for a reply... */
15491   W (ret);
15492   return ret;
15493 }
15494
15495 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15496
15497 static int
15498 api_one_map_register_enable_disable (vat_main_t * vam)
15499 {
15500   unformat_input_t *input = vam->input;
15501   vl_api_one_map_register_enable_disable_t *mp;
15502   u8 is_set = 0;
15503   u8 is_en = 0;
15504   int ret;
15505
15506   /* Parse args required to build the message */
15507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (input, "enable"))
15510         {
15511           is_set = 1;
15512           is_en = 1;
15513         }
15514       else if (unformat (input, "disable"))
15515         is_set = 1;
15516       else
15517         break;
15518     }
15519
15520   if (!is_set)
15521     {
15522       errmsg ("Value not set");
15523       return -99;
15524     }
15525
15526   /* Construct the API message */
15527   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15528
15529   mp->is_enabled = is_en;
15530
15531   /* send it... */
15532   S (mp);
15533
15534   /* Wait for a reply... */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15540
15541 static int
15542 api_one_enable_disable (vat_main_t * vam)
15543 {
15544   unformat_input_t *input = vam->input;
15545   vl_api_one_enable_disable_t *mp;
15546   u8 is_set = 0;
15547   u8 is_en = 0;
15548   int ret;
15549
15550   /* Parse args required to build the message */
15551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15552     {
15553       if (unformat (input, "enable"))
15554         {
15555           is_set = 1;
15556           is_en = 1;
15557         }
15558       else if (unformat (input, "disable"))
15559         {
15560           is_set = 1;
15561         }
15562       else
15563         break;
15564     }
15565
15566   if (!is_set)
15567     {
15568       errmsg ("Value not set");
15569       return -99;
15570     }
15571
15572   /* Construct the API message */
15573   M (ONE_ENABLE_DISABLE, mp);
15574
15575   mp->is_en = is_en;
15576
15577   /* send it... */
15578   S (mp);
15579
15580   /* Wait for a reply... */
15581   W (ret);
15582   return ret;
15583 }
15584
15585 #define api_lisp_enable_disable api_one_enable_disable
15586
15587 static int
15588 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15589 {
15590   unformat_input_t *input = vam->input;
15591   vl_api_one_enable_disable_xtr_mode_t *mp;
15592   u8 is_set = 0;
15593   u8 is_en = 0;
15594   int ret;
15595
15596   /* Parse args required to build the message */
15597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15598     {
15599       if (unformat (input, "enable"))
15600         {
15601           is_set = 1;
15602           is_en = 1;
15603         }
15604       else if (unformat (input, "disable"))
15605         {
15606           is_set = 1;
15607         }
15608       else
15609         break;
15610     }
15611
15612   if (!is_set)
15613     {
15614       errmsg ("Value not set");
15615       return -99;
15616     }
15617
15618   /* Construct the API message */
15619   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15620
15621   mp->is_en = is_en;
15622
15623   /* send it... */
15624   S (mp);
15625
15626   /* Wait for a reply... */
15627   W (ret);
15628   return ret;
15629 }
15630
15631 static int
15632 api_one_show_xtr_mode (vat_main_t * vam)
15633 {
15634   vl_api_one_show_xtr_mode_t *mp;
15635   int ret;
15636
15637   /* Construct the API message */
15638   M (ONE_SHOW_XTR_MODE, mp);
15639
15640   /* send it... */
15641   S (mp);
15642
15643   /* Wait for a reply... */
15644   W (ret);
15645   return ret;
15646 }
15647
15648 static int
15649 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15650 {
15651   unformat_input_t *input = vam->input;
15652   vl_api_one_enable_disable_pitr_mode_t *mp;
15653   u8 is_set = 0;
15654   u8 is_en = 0;
15655   int ret;
15656
15657   /* Parse args required to build the message */
15658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15659     {
15660       if (unformat (input, "enable"))
15661         {
15662           is_set = 1;
15663           is_en = 1;
15664         }
15665       else if (unformat (input, "disable"))
15666         {
15667           is_set = 1;
15668         }
15669       else
15670         break;
15671     }
15672
15673   if (!is_set)
15674     {
15675       errmsg ("Value not set");
15676       return -99;
15677     }
15678
15679   /* Construct the API message */
15680   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15681
15682   mp->is_en = is_en;
15683
15684   /* send it... */
15685   S (mp);
15686
15687   /* Wait for a reply... */
15688   W (ret);
15689   return ret;
15690 }
15691
15692 static int
15693 api_one_show_pitr_mode (vat_main_t * vam)
15694 {
15695   vl_api_one_show_pitr_mode_t *mp;
15696   int ret;
15697
15698   /* Construct the API message */
15699   M (ONE_SHOW_PITR_MODE, mp);
15700
15701   /* send it... */
15702   S (mp);
15703
15704   /* Wait for a reply... */
15705   W (ret);
15706   return ret;
15707 }
15708
15709 static int
15710 api_one_enable_disable_petr_mode (vat_main_t * vam)
15711 {
15712   unformat_input_t *input = vam->input;
15713   vl_api_one_enable_disable_petr_mode_t *mp;
15714   u8 is_set = 0;
15715   u8 is_en = 0;
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, "enable"))
15722         {
15723           is_set = 1;
15724           is_en = 1;
15725         }
15726       else if (unformat (input, "disable"))
15727         {
15728           is_set = 1;
15729         }
15730       else
15731         break;
15732     }
15733
15734   if (!is_set)
15735     {
15736       errmsg ("Value not set");
15737       return -99;
15738     }
15739
15740   /* Construct the API message */
15741   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15742
15743   mp->is_en = is_en;
15744
15745   /* send it... */
15746   S (mp);
15747
15748   /* Wait for a reply... */
15749   W (ret);
15750   return ret;
15751 }
15752
15753 static int
15754 api_one_show_petr_mode (vat_main_t * vam)
15755 {
15756   vl_api_one_show_petr_mode_t *mp;
15757   int ret;
15758
15759   /* Construct the API message */
15760   M (ONE_SHOW_PETR_MODE, mp);
15761
15762   /* send it... */
15763   S (mp);
15764
15765   /* Wait for a reply... */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 static int
15771 api_show_one_map_register_state (vat_main_t * vam)
15772 {
15773   vl_api_show_one_map_register_state_t *mp;
15774   int ret;
15775
15776   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15777
15778   /* send */
15779   S (mp);
15780
15781   /* wait for reply */
15782   W (ret);
15783   return ret;
15784 }
15785
15786 #define api_show_lisp_map_register_state api_show_one_map_register_state
15787
15788 static int
15789 api_show_one_rloc_probe_state (vat_main_t * vam)
15790 {
15791   vl_api_show_one_rloc_probe_state_t *mp;
15792   int ret;
15793
15794   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15795
15796   /* send */
15797   S (mp);
15798
15799   /* wait for reply */
15800   W (ret);
15801   return ret;
15802 }
15803
15804 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15805
15806 static int
15807 api_one_add_del_ndp_entry (vat_main_t * vam)
15808 {
15809   vl_api_one_add_del_ndp_entry_t *mp;
15810   unformat_input_t *input = vam->input;
15811   u8 is_add = 1;
15812   u8 mac_set = 0;
15813   u8 bd_set = 0;
15814   u8 ip_set = 0;
15815   u8 mac[6] = { 0, };
15816   u8 ip6[16] = { 0, };
15817   u32 bd = ~0;
15818   int ret;
15819
15820   /* Parse args required to build the message */
15821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15822     {
15823       if (unformat (input, "del"))
15824         is_add = 0;
15825       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15826         mac_set = 1;
15827       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15828         ip_set = 1;
15829       else if (unformat (input, "bd %d", &bd))
15830         bd_set = 1;
15831       else
15832         {
15833           errmsg ("parse error '%U'", format_unformat_error, input);
15834           return -99;
15835         }
15836     }
15837
15838   if (!bd_set || !ip_set || (!mac_set && is_add))
15839     {
15840       errmsg ("Missing BD, IP or MAC!");
15841       return -99;
15842     }
15843
15844   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15845   mp->is_add = is_add;
15846   clib_memcpy (mp->mac, mac, 6);
15847   mp->bd = clib_host_to_net_u32 (bd);
15848   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15849
15850   /* send */
15851   S (mp);
15852
15853   /* wait for reply */
15854   W (ret);
15855   return ret;
15856 }
15857
15858 static int
15859 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15860 {
15861   vl_api_one_add_del_l2_arp_entry_t *mp;
15862   unformat_input_t *input = vam->input;
15863   u8 is_add = 1;
15864   u8 mac_set = 0;
15865   u8 bd_set = 0;
15866   u8 ip_set = 0;
15867   u8 mac[6] = { 0, };
15868   u32 ip4 = 0, bd = ~0;
15869   int ret;
15870
15871   /* Parse args required to build the message */
15872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15873     {
15874       if (unformat (input, "del"))
15875         is_add = 0;
15876       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15877         mac_set = 1;
15878       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15879         ip_set = 1;
15880       else if (unformat (input, "bd %d", &bd))
15881         bd_set = 1;
15882       else
15883         {
15884           errmsg ("parse error '%U'", format_unformat_error, input);
15885           return -99;
15886         }
15887     }
15888
15889   if (!bd_set || !ip_set || (!mac_set && is_add))
15890     {
15891       errmsg ("Missing BD, IP or MAC!");
15892       return -99;
15893     }
15894
15895   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15896   mp->is_add = is_add;
15897   clib_memcpy (mp->mac, mac, 6);
15898   mp->bd = clib_host_to_net_u32 (bd);
15899   mp->ip4 = ip4;
15900
15901   /* send */
15902   S (mp);
15903
15904   /* wait for reply */
15905   W (ret);
15906   return ret;
15907 }
15908
15909 static int
15910 api_one_ndp_bd_get (vat_main_t * vam)
15911 {
15912   vl_api_one_ndp_bd_get_t *mp;
15913   int ret;
15914
15915   M (ONE_NDP_BD_GET, mp);
15916
15917   /* send */
15918   S (mp);
15919
15920   /* wait for reply */
15921   W (ret);
15922   return ret;
15923 }
15924
15925 static int
15926 api_one_ndp_entries_get (vat_main_t * vam)
15927 {
15928   vl_api_one_ndp_entries_get_t *mp;
15929   unformat_input_t *input = vam->input;
15930   u8 bd_set = 0;
15931   u32 bd = ~0;
15932   int ret;
15933
15934   /* Parse args required to build the message */
15935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15936     {
15937       if (unformat (input, "bd %d", &bd))
15938         bd_set = 1;
15939       else
15940         {
15941           errmsg ("parse error '%U'", format_unformat_error, input);
15942           return -99;
15943         }
15944     }
15945
15946   if (!bd_set)
15947     {
15948       errmsg ("Expected bridge domain!");
15949       return -99;
15950     }
15951
15952   M (ONE_NDP_ENTRIES_GET, mp);
15953   mp->bd = clib_host_to_net_u32 (bd);
15954
15955   /* send */
15956   S (mp);
15957
15958   /* wait for reply */
15959   W (ret);
15960   return ret;
15961 }
15962
15963 static int
15964 api_one_l2_arp_bd_get (vat_main_t * vam)
15965 {
15966   vl_api_one_l2_arp_bd_get_t *mp;
15967   int ret;
15968
15969   M (ONE_L2_ARP_BD_GET, mp);
15970
15971   /* send */
15972   S (mp);
15973
15974   /* wait for reply */
15975   W (ret);
15976   return ret;
15977 }
15978
15979 static int
15980 api_one_l2_arp_entries_get (vat_main_t * vam)
15981 {
15982   vl_api_one_l2_arp_entries_get_t *mp;
15983   unformat_input_t *input = vam->input;
15984   u8 bd_set = 0;
15985   u32 bd = ~0;
15986   int ret;
15987
15988   /* Parse args required to build the message */
15989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15990     {
15991       if (unformat (input, "bd %d", &bd))
15992         bd_set = 1;
15993       else
15994         {
15995           errmsg ("parse error '%U'", format_unformat_error, input);
15996           return -99;
15997         }
15998     }
15999
16000   if (!bd_set)
16001     {
16002       errmsg ("Expected bridge domain!");
16003       return -99;
16004     }
16005
16006   M (ONE_L2_ARP_ENTRIES_GET, mp);
16007   mp->bd = clib_host_to_net_u32 (bd);
16008
16009   /* send */
16010   S (mp);
16011
16012   /* wait for reply */
16013   W (ret);
16014   return ret;
16015 }
16016
16017 static int
16018 api_one_stats_enable_disable (vat_main_t * vam)
16019 {
16020   vl_api_one_stats_enable_disable_t *mp;
16021   unformat_input_t *input = vam->input;
16022   u8 is_set = 0;
16023   u8 is_en = 0;
16024   int ret;
16025
16026   /* Parse args required to build the message */
16027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16028     {
16029       if (unformat (input, "enable"))
16030         {
16031           is_set = 1;
16032           is_en = 1;
16033         }
16034       else if (unformat (input, "disable"))
16035         {
16036           is_set = 1;
16037         }
16038       else
16039         break;
16040     }
16041
16042   if (!is_set)
16043     {
16044       errmsg ("Value not set");
16045       return -99;
16046     }
16047
16048   M (ONE_STATS_ENABLE_DISABLE, mp);
16049   mp->is_en = is_en;
16050
16051   /* send */
16052   S (mp);
16053
16054   /* wait for reply */
16055   W (ret);
16056   return ret;
16057 }
16058
16059 static int
16060 api_show_one_stats_enable_disable (vat_main_t * vam)
16061 {
16062   vl_api_show_one_stats_enable_disable_t *mp;
16063   int ret;
16064
16065   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16066
16067   /* send */
16068   S (mp);
16069
16070   /* wait for reply */
16071   W (ret);
16072   return ret;
16073 }
16074
16075 static int
16076 api_show_one_map_request_mode (vat_main_t * vam)
16077 {
16078   vl_api_show_one_map_request_mode_t *mp;
16079   int ret;
16080
16081   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16082
16083   /* send */
16084   S (mp);
16085
16086   /* wait for reply */
16087   W (ret);
16088   return ret;
16089 }
16090
16091 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16092
16093 static int
16094 api_one_map_request_mode (vat_main_t * vam)
16095 {
16096   unformat_input_t *input = vam->input;
16097   vl_api_one_map_request_mode_t *mp;
16098   u8 mode = 0;
16099   int ret;
16100
16101   /* Parse args required to build the message */
16102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16103     {
16104       if (unformat (input, "dst-only"))
16105         mode = 0;
16106       else if (unformat (input, "src-dst"))
16107         mode = 1;
16108       else
16109         {
16110           errmsg ("parse error '%U'", format_unformat_error, input);
16111           return -99;
16112         }
16113     }
16114
16115   M (ONE_MAP_REQUEST_MODE, mp);
16116
16117   mp->mode = mode;
16118
16119   /* send */
16120   S (mp);
16121
16122   /* wait for reply */
16123   W (ret);
16124   return ret;
16125 }
16126
16127 #define api_lisp_map_request_mode api_one_map_request_mode
16128
16129 /**
16130  * Enable/disable ONE proxy ITR.
16131  *
16132  * @param vam vpp API test context
16133  * @return return code
16134  */
16135 static int
16136 api_one_pitr_set_locator_set (vat_main_t * vam)
16137 {
16138   u8 ls_name_set = 0;
16139   unformat_input_t *input = vam->input;
16140   vl_api_one_pitr_set_locator_set_t *mp;
16141   u8 is_add = 1;
16142   u8 *ls_name = 0;
16143   int ret;
16144
16145   /* Parse args required to build the message */
16146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (input, "del"))
16149         is_add = 0;
16150       else if (unformat (input, "locator-set %s", &ls_name))
16151         ls_name_set = 1;
16152       else
16153         {
16154           errmsg ("parse error '%U'", format_unformat_error, input);
16155           return -99;
16156         }
16157     }
16158
16159   if (!ls_name_set)
16160     {
16161       errmsg ("locator-set name not set!");
16162       return -99;
16163     }
16164
16165   M (ONE_PITR_SET_LOCATOR_SET, mp);
16166
16167   mp->is_add = is_add;
16168   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16169   vec_free (ls_name);
16170
16171   /* send */
16172   S (mp);
16173
16174   /* wait for reply */
16175   W (ret);
16176   return ret;
16177 }
16178
16179 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16180
16181 static int
16182 api_one_nsh_set_locator_set (vat_main_t * vam)
16183 {
16184   u8 ls_name_set = 0;
16185   unformat_input_t *input = vam->input;
16186   vl_api_one_nsh_set_locator_set_t *mp;
16187   u8 is_add = 1;
16188   u8 *ls_name = 0;
16189   int ret;
16190
16191   /* Parse args required to build the message */
16192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16193     {
16194       if (unformat (input, "del"))
16195         is_add = 0;
16196       else if (unformat (input, "ls %s", &ls_name))
16197         ls_name_set = 1;
16198       else
16199         {
16200           errmsg ("parse error '%U'", format_unformat_error, input);
16201           return -99;
16202         }
16203     }
16204
16205   if (!ls_name_set && is_add)
16206     {
16207       errmsg ("locator-set name not set!");
16208       return -99;
16209     }
16210
16211   M (ONE_NSH_SET_LOCATOR_SET, mp);
16212
16213   mp->is_add = is_add;
16214   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16215   vec_free (ls_name);
16216
16217   /* send */
16218   S (mp);
16219
16220   /* wait for reply */
16221   W (ret);
16222   return ret;
16223 }
16224
16225 static int
16226 api_show_one_pitr (vat_main_t * vam)
16227 {
16228   vl_api_show_one_pitr_t *mp;
16229   int ret;
16230
16231   if (!vam->json_output)
16232     {
16233       print (vam->ofp, "%=20s", "lisp status:");
16234     }
16235
16236   M (SHOW_ONE_PITR, mp);
16237   /* send it... */
16238   S (mp);
16239
16240   /* Wait for a reply... */
16241   W (ret);
16242   return ret;
16243 }
16244
16245 #define api_show_lisp_pitr api_show_one_pitr
16246
16247 static int
16248 api_one_use_petr (vat_main_t * vam)
16249 {
16250   unformat_input_t *input = vam->input;
16251   vl_api_one_use_petr_t *mp;
16252   u8 is_add = 0;
16253   ip_address_t ip;
16254   int ret;
16255
16256   clib_memset (&ip, 0, sizeof (ip));
16257
16258   /* Parse args required to build the message */
16259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16260     {
16261       if (unformat (input, "disable"))
16262         is_add = 0;
16263       else
16264         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16265         {
16266           is_add = 1;
16267           ip_addr_version (&ip) = IP4;
16268         }
16269       else
16270         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16271         {
16272           is_add = 1;
16273           ip_addr_version (&ip) = IP6;
16274         }
16275       else
16276         {
16277           errmsg ("parse error '%U'", format_unformat_error, input);
16278           return -99;
16279         }
16280     }
16281
16282   M (ONE_USE_PETR, mp);
16283
16284   mp->is_add = is_add;
16285   if (is_add)
16286     {
16287       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16288       if (mp->is_ip4)
16289         clib_memcpy (mp->address, &ip, 4);
16290       else
16291         clib_memcpy (mp->address, &ip, 16);
16292     }
16293
16294   /* send */
16295   S (mp);
16296
16297   /* wait for reply */
16298   W (ret);
16299   return ret;
16300 }
16301
16302 #define api_lisp_use_petr api_one_use_petr
16303
16304 static int
16305 api_show_one_nsh_mapping (vat_main_t * vam)
16306 {
16307   vl_api_show_one_use_petr_t *mp;
16308   int ret;
16309
16310   if (!vam->json_output)
16311     {
16312       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16313     }
16314
16315   M (SHOW_ONE_NSH_MAPPING, mp);
16316   /* send it... */
16317   S (mp);
16318
16319   /* Wait for a reply... */
16320   W (ret);
16321   return ret;
16322 }
16323
16324 static int
16325 api_show_one_use_petr (vat_main_t * vam)
16326 {
16327   vl_api_show_one_use_petr_t *mp;
16328   int ret;
16329
16330   if (!vam->json_output)
16331     {
16332       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16333     }
16334
16335   M (SHOW_ONE_USE_PETR, mp);
16336   /* send it... */
16337   S (mp);
16338
16339   /* Wait for a reply... */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 #define api_show_lisp_use_petr api_show_one_use_petr
16345
16346 /**
16347  * Add/delete mapping between vni and vrf
16348  */
16349 static int
16350 api_one_eid_table_add_del_map (vat_main_t * vam)
16351 {
16352   unformat_input_t *input = vam->input;
16353   vl_api_one_eid_table_add_del_map_t *mp;
16354   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16355   u32 vni, vrf, bd_index;
16356   int ret;
16357
16358   /* Parse args required to build the message */
16359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (input, "del"))
16362         is_add = 0;
16363       else if (unformat (input, "vrf %d", &vrf))
16364         vrf_set = 1;
16365       else if (unformat (input, "bd_index %d", &bd_index))
16366         bd_index_set = 1;
16367       else if (unformat (input, "vni %d", &vni))
16368         vni_set = 1;
16369       else
16370         break;
16371     }
16372
16373   if (!vni_set || (!vrf_set && !bd_index_set))
16374     {
16375       errmsg ("missing arguments!");
16376       return -99;
16377     }
16378
16379   if (vrf_set && bd_index_set)
16380     {
16381       errmsg ("error: both vrf and bd entered!");
16382       return -99;
16383     }
16384
16385   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16386
16387   mp->is_add = is_add;
16388   mp->vni = htonl (vni);
16389   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16390   mp->is_l2 = bd_index_set;
16391
16392   /* send */
16393   S (mp);
16394
16395   /* wait for reply */
16396   W (ret);
16397   return ret;
16398 }
16399
16400 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16401
16402 uword
16403 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16404 {
16405   u32 *action = va_arg (*args, u32 *);
16406   u8 *s = 0;
16407
16408   if (unformat (input, "%s", &s))
16409     {
16410       if (!strcmp ((char *) s, "no-action"))
16411         action[0] = 0;
16412       else if (!strcmp ((char *) s, "natively-forward"))
16413         action[0] = 1;
16414       else if (!strcmp ((char *) s, "send-map-request"))
16415         action[0] = 2;
16416       else if (!strcmp ((char *) s, "drop"))
16417         action[0] = 3;
16418       else
16419         {
16420           clib_warning ("invalid action: '%s'", s);
16421           action[0] = 3;
16422         }
16423     }
16424   else
16425     return 0;
16426
16427   vec_free (s);
16428   return 1;
16429 }
16430
16431 /**
16432  * Add/del remote mapping to/from ONE control plane
16433  *
16434  * @param vam vpp API test context
16435  * @return return code
16436  */
16437 static int
16438 api_one_add_del_remote_mapping (vat_main_t * vam)
16439 {
16440   unformat_input_t *input = vam->input;
16441   vl_api_one_add_del_remote_mapping_t *mp;
16442   u32 vni = 0;
16443   lisp_eid_vat_t _eid, *eid = &_eid;
16444   lisp_eid_vat_t _seid, *seid = &_seid;
16445   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16446   u32 action = ~0, p, w, data_len;
16447   ip4_address_t rloc4;
16448   ip6_address_t rloc6;
16449   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16450   int ret;
16451
16452   clib_memset (&rloc, 0, sizeof (rloc));
16453
16454   /* Parse args required to build the message */
16455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16456     {
16457       if (unformat (input, "del-all"))
16458         {
16459           del_all = 1;
16460         }
16461       else if (unformat (input, "del"))
16462         {
16463           is_add = 0;
16464         }
16465       else if (unformat (input, "add"))
16466         {
16467           is_add = 1;
16468         }
16469       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16470         {
16471           eid_set = 1;
16472         }
16473       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16474         {
16475           seid_set = 1;
16476         }
16477       else if (unformat (input, "vni %d", &vni))
16478         {
16479           ;
16480         }
16481       else if (unformat (input, "p %d w %d", &p, &w))
16482         {
16483           if (!curr_rloc)
16484             {
16485               errmsg ("No RLOC configured for setting priority/weight!");
16486               return -99;
16487             }
16488           curr_rloc->priority = p;
16489           curr_rloc->weight = w;
16490         }
16491       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16492         {
16493           rloc.is_ip4 = 1;
16494           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16495           vec_add1 (rlocs, rloc);
16496           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16497         }
16498       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16499         {
16500           rloc.is_ip4 = 0;
16501           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16502           vec_add1 (rlocs, rloc);
16503           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16504         }
16505       else if (unformat (input, "action %U",
16506                          unformat_negative_mapping_action, &action))
16507         {
16508           ;
16509         }
16510       else
16511         {
16512           clib_warning ("parse error '%U'", format_unformat_error, input);
16513           return -99;
16514         }
16515     }
16516
16517   if (0 == eid_set)
16518     {
16519       errmsg ("missing params!");
16520       return -99;
16521     }
16522
16523   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16524     {
16525       errmsg ("no action set for negative map-reply!");
16526       return -99;
16527     }
16528
16529   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16530
16531   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16532   mp->is_add = is_add;
16533   mp->vni = htonl (vni);
16534   mp->action = (u8) action;
16535   mp->is_src_dst = seid_set;
16536   mp->eid_len = eid->len;
16537   mp->seid_len = seid->len;
16538   mp->del_all = del_all;
16539   mp->eid_type = eid->type;
16540   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16541   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16542
16543   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16544   clib_memcpy (mp->rlocs, rlocs, data_len);
16545   vec_free (rlocs);
16546
16547   /* send it... */
16548   S (mp);
16549
16550   /* Wait for a reply... */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16556
16557 /**
16558  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16559  * forwarding entries in data-plane accordingly.
16560  *
16561  * @param vam vpp API test context
16562  * @return return code
16563  */
16564 static int
16565 api_one_add_del_adjacency (vat_main_t * vam)
16566 {
16567   unformat_input_t *input = vam->input;
16568   vl_api_one_add_del_adjacency_t *mp;
16569   u32 vni = 0;
16570   ip4_address_t leid4, reid4;
16571   ip6_address_t leid6, reid6;
16572   u8 reid_mac[6] = { 0 };
16573   u8 leid_mac[6] = { 0 };
16574   u8 reid_type, leid_type;
16575   u32 leid_len = 0, reid_len = 0, len;
16576   u8 is_add = 1;
16577   int ret;
16578
16579   leid_type = reid_type = (u8) ~ 0;
16580
16581   /* Parse args required to build the message */
16582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16583     {
16584       if (unformat (input, "del"))
16585         {
16586           is_add = 0;
16587         }
16588       else if (unformat (input, "add"))
16589         {
16590           is_add = 1;
16591         }
16592       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16593                          &reid4, &len))
16594         {
16595           reid_type = 0;        /* ipv4 */
16596           reid_len = len;
16597         }
16598       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16599                          &reid6, &len))
16600         {
16601           reid_type = 1;        /* ipv6 */
16602           reid_len = len;
16603         }
16604       else if (unformat (input, "reid %U", unformat_ethernet_address,
16605                          reid_mac))
16606         {
16607           reid_type = 2;        /* mac */
16608         }
16609       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16610                          &leid4, &len))
16611         {
16612           leid_type = 0;        /* ipv4 */
16613           leid_len = len;
16614         }
16615       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16616                          &leid6, &len))
16617         {
16618           leid_type = 1;        /* ipv6 */
16619           leid_len = len;
16620         }
16621       else if (unformat (input, "leid %U", unformat_ethernet_address,
16622                          leid_mac))
16623         {
16624           leid_type = 2;        /* mac */
16625         }
16626       else if (unformat (input, "vni %d", &vni))
16627         {
16628           ;
16629         }
16630       else
16631         {
16632           errmsg ("parse error '%U'", format_unformat_error, input);
16633           return -99;
16634         }
16635     }
16636
16637   if ((u8) ~ 0 == reid_type)
16638     {
16639       errmsg ("missing params!");
16640       return -99;
16641     }
16642
16643   if (leid_type != reid_type)
16644     {
16645       errmsg ("remote and local EIDs are of different types!");
16646       return -99;
16647     }
16648
16649   M (ONE_ADD_DEL_ADJACENCY, mp);
16650   mp->is_add = is_add;
16651   mp->vni = htonl (vni);
16652   mp->leid_len = leid_len;
16653   mp->reid_len = reid_len;
16654   mp->eid_type = reid_type;
16655
16656   switch (mp->eid_type)
16657     {
16658     case 0:
16659       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16660       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16661       break;
16662     case 1:
16663       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16664       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16665       break;
16666     case 2:
16667       clib_memcpy (mp->leid, leid_mac, 6);
16668       clib_memcpy (mp->reid, reid_mac, 6);
16669       break;
16670     default:
16671       errmsg ("unknown EID type %d!", mp->eid_type);
16672       return 0;
16673     }
16674
16675   /* send it... */
16676   S (mp);
16677
16678   /* Wait for a reply... */
16679   W (ret);
16680   return ret;
16681 }
16682
16683 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16684
16685 uword
16686 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16687 {
16688   u32 *mode = va_arg (*args, u32 *);
16689
16690   if (unformat (input, "lisp"))
16691     *mode = 0;
16692   else if (unformat (input, "vxlan"))
16693     *mode = 1;
16694   else
16695     return 0;
16696
16697   return 1;
16698 }
16699
16700 static int
16701 api_gpe_get_encap_mode (vat_main_t * vam)
16702 {
16703   vl_api_gpe_get_encap_mode_t *mp;
16704   int ret;
16705
16706   /* Construct the API message */
16707   M (GPE_GET_ENCAP_MODE, mp);
16708
16709   /* send it... */
16710   S (mp);
16711
16712   /* Wait for a reply... */
16713   W (ret);
16714   return ret;
16715 }
16716
16717 static int
16718 api_gpe_set_encap_mode (vat_main_t * vam)
16719 {
16720   unformat_input_t *input = vam->input;
16721   vl_api_gpe_set_encap_mode_t *mp;
16722   int ret;
16723   u32 mode = 0;
16724
16725   /* Parse args required to build the message */
16726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16727     {
16728       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16729         ;
16730       else
16731         break;
16732     }
16733
16734   /* Construct the API message */
16735   M (GPE_SET_ENCAP_MODE, mp);
16736
16737   mp->mode = mode;
16738
16739   /* send it... */
16740   S (mp);
16741
16742   /* Wait for a reply... */
16743   W (ret);
16744   return ret;
16745 }
16746
16747 static int
16748 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16749 {
16750   unformat_input_t *input = vam->input;
16751   vl_api_gpe_add_del_iface_t *mp;
16752   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16753   u32 dp_table = 0, vni = 0;
16754   int ret;
16755
16756   /* Parse args required to build the message */
16757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16758     {
16759       if (unformat (input, "up"))
16760         {
16761           action_set = 1;
16762           is_add = 1;
16763         }
16764       else if (unformat (input, "down"))
16765         {
16766           action_set = 1;
16767           is_add = 0;
16768         }
16769       else if (unformat (input, "table_id %d", &dp_table))
16770         {
16771           dp_table_set = 1;
16772         }
16773       else if (unformat (input, "bd_id %d", &dp_table))
16774         {
16775           dp_table_set = 1;
16776           is_l2 = 1;
16777         }
16778       else if (unformat (input, "vni %d", &vni))
16779         {
16780           vni_set = 1;
16781         }
16782       else
16783         break;
16784     }
16785
16786   if (action_set == 0)
16787     {
16788       errmsg ("Action not set");
16789       return -99;
16790     }
16791   if (dp_table_set == 0 || vni_set == 0)
16792     {
16793       errmsg ("vni and dp_table must be set");
16794       return -99;
16795     }
16796
16797   /* Construct the API message */
16798   M (GPE_ADD_DEL_IFACE, mp);
16799
16800   mp->is_add = is_add;
16801   mp->dp_table = clib_host_to_net_u32 (dp_table);
16802   mp->is_l2 = is_l2;
16803   mp->vni = clib_host_to_net_u32 (vni);
16804
16805   /* send it... */
16806   S (mp);
16807
16808   /* Wait for a reply... */
16809   W (ret);
16810   return ret;
16811 }
16812
16813 static int
16814 api_one_map_register_fallback_threshold (vat_main_t * vam)
16815 {
16816   unformat_input_t *input = vam->input;
16817   vl_api_one_map_register_fallback_threshold_t *mp;
16818   u32 value = 0;
16819   u8 is_set = 0;
16820   int ret;
16821
16822   /* Parse args required to build the message */
16823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16824     {
16825       if (unformat (input, "%u", &value))
16826         is_set = 1;
16827       else
16828         {
16829           clib_warning ("parse error '%U'", format_unformat_error, input);
16830           return -99;
16831         }
16832     }
16833
16834   if (!is_set)
16835     {
16836       errmsg ("fallback threshold value is missing!");
16837       return -99;
16838     }
16839
16840   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16841   mp->value = clib_host_to_net_u32 (value);
16842
16843   /* send it... */
16844   S (mp);
16845
16846   /* Wait for a reply... */
16847   W (ret);
16848   return ret;
16849 }
16850
16851 static int
16852 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16853 {
16854   vl_api_show_one_map_register_fallback_threshold_t *mp;
16855   int ret;
16856
16857   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16858
16859   /* send it... */
16860   S (mp);
16861
16862   /* Wait for a reply... */
16863   W (ret);
16864   return ret;
16865 }
16866
16867 uword
16868 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16869 {
16870   u32 *proto = va_arg (*args, u32 *);
16871
16872   if (unformat (input, "udp"))
16873     *proto = 1;
16874   else if (unformat (input, "api"))
16875     *proto = 2;
16876   else
16877     return 0;
16878
16879   return 1;
16880 }
16881
16882 static int
16883 api_one_set_transport_protocol (vat_main_t * vam)
16884 {
16885   unformat_input_t *input = vam->input;
16886   vl_api_one_set_transport_protocol_t *mp;
16887   u8 is_set = 0;
16888   u32 protocol = 0;
16889   int ret;
16890
16891   /* Parse args required to build the message */
16892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16893     {
16894       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16895         is_set = 1;
16896       else
16897         {
16898           clib_warning ("parse error '%U'", format_unformat_error, input);
16899           return -99;
16900         }
16901     }
16902
16903   if (!is_set)
16904     {
16905       errmsg ("Transport protocol missing!");
16906       return -99;
16907     }
16908
16909   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16910   mp->protocol = (u8) protocol;
16911
16912   /* send it... */
16913   S (mp);
16914
16915   /* Wait for a reply... */
16916   W (ret);
16917   return ret;
16918 }
16919
16920 static int
16921 api_one_get_transport_protocol (vat_main_t * vam)
16922 {
16923   vl_api_one_get_transport_protocol_t *mp;
16924   int ret;
16925
16926   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16927
16928   /* send it... */
16929   S (mp);
16930
16931   /* Wait for a reply... */
16932   W (ret);
16933   return ret;
16934 }
16935
16936 static int
16937 api_one_map_register_set_ttl (vat_main_t * vam)
16938 {
16939   unformat_input_t *input = vam->input;
16940   vl_api_one_map_register_set_ttl_t *mp;
16941   u32 ttl = 0;
16942   u8 is_set = 0;
16943   int ret;
16944
16945   /* Parse args required to build the message */
16946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16947     {
16948       if (unformat (input, "%u", &ttl))
16949         is_set = 1;
16950       else
16951         {
16952           clib_warning ("parse error '%U'", format_unformat_error, input);
16953           return -99;
16954         }
16955     }
16956
16957   if (!is_set)
16958     {
16959       errmsg ("TTL value missing!");
16960       return -99;
16961     }
16962
16963   M (ONE_MAP_REGISTER_SET_TTL, mp);
16964   mp->ttl = clib_host_to_net_u32 (ttl);
16965
16966   /* send it... */
16967   S (mp);
16968
16969   /* Wait for a reply... */
16970   W (ret);
16971   return ret;
16972 }
16973
16974 static int
16975 api_show_one_map_register_ttl (vat_main_t * vam)
16976 {
16977   vl_api_show_one_map_register_ttl_t *mp;
16978   int ret;
16979
16980   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16981
16982   /* send it... */
16983   S (mp);
16984
16985   /* Wait for a reply... */
16986   W (ret);
16987   return ret;
16988 }
16989
16990 /**
16991  * Add/del map request itr rlocs from ONE control plane and updates
16992  *
16993  * @param vam vpp API test context
16994  * @return return code
16995  */
16996 static int
16997 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16998 {
16999   unformat_input_t *input = vam->input;
17000   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17001   u8 *locator_set_name = 0;
17002   u8 locator_set_name_set = 0;
17003   u8 is_add = 1;
17004   int ret;
17005
17006   /* Parse args required to build the message */
17007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17008     {
17009       if (unformat (input, "del"))
17010         {
17011           is_add = 0;
17012         }
17013       else if (unformat (input, "%_%v%_", &locator_set_name))
17014         {
17015           locator_set_name_set = 1;
17016         }
17017       else
17018         {
17019           clib_warning ("parse error '%U'", format_unformat_error, input);
17020           return -99;
17021         }
17022     }
17023
17024   if (is_add && !locator_set_name_set)
17025     {
17026       errmsg ("itr-rloc is not set!");
17027       return -99;
17028     }
17029
17030   if (is_add && vec_len (locator_set_name) > 64)
17031     {
17032       errmsg ("itr-rloc locator-set name too long");
17033       vec_free (locator_set_name);
17034       return -99;
17035     }
17036
17037   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17038   mp->is_add = is_add;
17039   if (is_add)
17040     {
17041       clib_memcpy (mp->locator_set_name, locator_set_name,
17042                    vec_len (locator_set_name));
17043     }
17044   else
17045     {
17046       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17047     }
17048   vec_free (locator_set_name);
17049
17050   /* send it... */
17051   S (mp);
17052
17053   /* Wait for a reply... */
17054   W (ret);
17055   return ret;
17056 }
17057
17058 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17059
17060 static int
17061 api_one_locator_dump (vat_main_t * vam)
17062 {
17063   unformat_input_t *input = vam->input;
17064   vl_api_one_locator_dump_t *mp;
17065   vl_api_control_ping_t *mp_ping;
17066   u8 is_index_set = 0, is_name_set = 0;
17067   u8 *ls_name = 0;
17068   u32 ls_index = ~0;
17069   int ret;
17070
17071   /* Parse args required to build the message */
17072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17073     {
17074       if (unformat (input, "ls_name %_%v%_", &ls_name))
17075         {
17076           is_name_set = 1;
17077         }
17078       else if (unformat (input, "ls_index %d", &ls_index))
17079         {
17080           is_index_set = 1;
17081         }
17082       else
17083         {
17084           errmsg ("parse error '%U'", format_unformat_error, input);
17085           return -99;
17086         }
17087     }
17088
17089   if (!is_index_set && !is_name_set)
17090     {
17091       errmsg ("error: expected one of index or name!");
17092       return -99;
17093     }
17094
17095   if (is_index_set && is_name_set)
17096     {
17097       errmsg ("error: only one param expected!");
17098       return -99;
17099     }
17100
17101   if (vec_len (ls_name) > 62)
17102     {
17103       errmsg ("error: locator set name too long!");
17104       return -99;
17105     }
17106
17107   if (!vam->json_output)
17108     {
17109       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17110     }
17111
17112   M (ONE_LOCATOR_DUMP, mp);
17113   mp->is_index_set = is_index_set;
17114
17115   if (is_index_set)
17116     mp->ls_index = clib_host_to_net_u32 (ls_index);
17117   else
17118     {
17119       vec_add1 (ls_name, 0);
17120       strncpy ((char *) mp->ls_name, (char *) ls_name,
17121                sizeof (mp->ls_name) - 1);
17122     }
17123
17124   /* send it... */
17125   S (mp);
17126
17127   /* Use a control ping for synchronization */
17128   MPING (CONTROL_PING, mp_ping);
17129   S (mp_ping);
17130
17131   /* Wait for a reply... */
17132   W (ret);
17133   return ret;
17134 }
17135
17136 #define api_lisp_locator_dump api_one_locator_dump
17137
17138 static int
17139 api_one_locator_set_dump (vat_main_t * vam)
17140 {
17141   vl_api_one_locator_set_dump_t *mp;
17142   vl_api_control_ping_t *mp_ping;
17143   unformat_input_t *input = vam->input;
17144   u8 filter = 0;
17145   int ret;
17146
17147   /* Parse args required to build the message */
17148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17149     {
17150       if (unformat (input, "local"))
17151         {
17152           filter = 1;
17153         }
17154       else if (unformat (input, "remote"))
17155         {
17156           filter = 2;
17157         }
17158       else
17159         {
17160           errmsg ("parse error '%U'", format_unformat_error, input);
17161           return -99;
17162         }
17163     }
17164
17165   if (!vam->json_output)
17166     {
17167       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17168     }
17169
17170   M (ONE_LOCATOR_SET_DUMP, mp);
17171
17172   mp->filter = filter;
17173
17174   /* send it... */
17175   S (mp);
17176
17177   /* Use a control ping for synchronization */
17178   MPING (CONTROL_PING, mp_ping);
17179   S (mp_ping);
17180
17181   /* Wait for a reply... */
17182   W (ret);
17183   return ret;
17184 }
17185
17186 #define api_lisp_locator_set_dump api_one_locator_set_dump
17187
17188 static int
17189 api_one_eid_table_map_dump (vat_main_t * vam)
17190 {
17191   u8 is_l2 = 0;
17192   u8 mode_set = 0;
17193   unformat_input_t *input = vam->input;
17194   vl_api_one_eid_table_map_dump_t *mp;
17195   vl_api_control_ping_t *mp_ping;
17196   int ret;
17197
17198   /* Parse args required to build the message */
17199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17200     {
17201       if (unformat (input, "l2"))
17202         {
17203           is_l2 = 1;
17204           mode_set = 1;
17205         }
17206       else if (unformat (input, "l3"))
17207         {
17208           is_l2 = 0;
17209           mode_set = 1;
17210         }
17211       else
17212         {
17213           errmsg ("parse error '%U'", format_unformat_error, input);
17214           return -99;
17215         }
17216     }
17217
17218   if (!mode_set)
17219     {
17220       errmsg ("expected one of 'l2' or 'l3' parameter!");
17221       return -99;
17222     }
17223
17224   if (!vam->json_output)
17225     {
17226       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17227     }
17228
17229   M (ONE_EID_TABLE_MAP_DUMP, mp);
17230   mp->is_l2 = is_l2;
17231
17232   /* send it... */
17233   S (mp);
17234
17235   /* Use a control ping for synchronization */
17236   MPING (CONTROL_PING, mp_ping);
17237   S (mp_ping);
17238
17239   /* Wait for a reply... */
17240   W (ret);
17241   return ret;
17242 }
17243
17244 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17245
17246 static int
17247 api_one_eid_table_vni_dump (vat_main_t * vam)
17248 {
17249   vl_api_one_eid_table_vni_dump_t *mp;
17250   vl_api_control_ping_t *mp_ping;
17251   int ret;
17252
17253   if (!vam->json_output)
17254     {
17255       print (vam->ofp, "VNI");
17256     }
17257
17258   M (ONE_EID_TABLE_VNI_DUMP, mp);
17259
17260   /* send it... */
17261   S (mp);
17262
17263   /* Use a control ping for synchronization */
17264   MPING (CONTROL_PING, mp_ping);
17265   S (mp_ping);
17266
17267   /* Wait for a reply... */
17268   W (ret);
17269   return ret;
17270 }
17271
17272 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17273
17274 static int
17275 api_one_eid_table_dump (vat_main_t * vam)
17276 {
17277   unformat_input_t *i = vam->input;
17278   vl_api_one_eid_table_dump_t *mp;
17279   vl_api_control_ping_t *mp_ping;
17280   struct in_addr ip4;
17281   struct in6_addr ip6;
17282   u8 mac[6];
17283   u8 eid_type = ~0, eid_set = 0;
17284   u32 prefix_length = ~0, t, vni = 0;
17285   u8 filter = 0;
17286   int ret;
17287   lisp_nsh_api_t nsh;
17288
17289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17290     {
17291       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17292         {
17293           eid_set = 1;
17294           eid_type = 0;
17295           prefix_length = t;
17296         }
17297       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17298         {
17299           eid_set = 1;
17300           eid_type = 1;
17301           prefix_length = t;
17302         }
17303       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17304         {
17305           eid_set = 1;
17306           eid_type = 2;
17307         }
17308       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17309         {
17310           eid_set = 1;
17311           eid_type = 3;
17312         }
17313       else if (unformat (i, "vni %d", &t))
17314         {
17315           vni = t;
17316         }
17317       else if (unformat (i, "local"))
17318         {
17319           filter = 1;
17320         }
17321       else if (unformat (i, "remote"))
17322         {
17323           filter = 2;
17324         }
17325       else
17326         {
17327           errmsg ("parse error '%U'", format_unformat_error, i);
17328           return -99;
17329         }
17330     }
17331
17332   if (!vam->json_output)
17333     {
17334       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17335              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17336     }
17337
17338   M (ONE_EID_TABLE_DUMP, mp);
17339
17340   mp->filter = filter;
17341   if (eid_set)
17342     {
17343       mp->eid_set = 1;
17344       mp->vni = htonl (vni);
17345       mp->eid_type = eid_type;
17346       switch (eid_type)
17347         {
17348         case 0:
17349           mp->prefix_length = prefix_length;
17350           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17351           break;
17352         case 1:
17353           mp->prefix_length = prefix_length;
17354           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17355           break;
17356         case 2:
17357           clib_memcpy (mp->eid, mac, sizeof (mac));
17358           break;
17359         case 3:
17360           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17361           break;
17362         default:
17363           errmsg ("unknown EID type %d!", eid_type);
17364           return -99;
17365         }
17366     }
17367
17368   /* send it... */
17369   S (mp);
17370
17371   /* Use a control ping for synchronization */
17372   MPING (CONTROL_PING, mp_ping);
17373   S (mp_ping);
17374
17375   /* Wait for a reply... */
17376   W (ret);
17377   return ret;
17378 }
17379
17380 #define api_lisp_eid_table_dump api_one_eid_table_dump
17381
17382 static int
17383 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17384 {
17385   unformat_input_t *i = vam->input;
17386   vl_api_gpe_fwd_entries_get_t *mp;
17387   u8 vni_set = 0;
17388   u32 vni = ~0;
17389   int ret;
17390
17391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17392     {
17393       if (unformat (i, "vni %d", &vni))
17394         {
17395           vni_set = 1;
17396         }
17397       else
17398         {
17399           errmsg ("parse error '%U'", format_unformat_error, i);
17400           return -99;
17401         }
17402     }
17403
17404   if (!vni_set)
17405     {
17406       errmsg ("vni not set!");
17407       return -99;
17408     }
17409
17410   if (!vam->json_output)
17411     {
17412       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17413              "leid", "reid");
17414     }
17415
17416   M (GPE_FWD_ENTRIES_GET, mp);
17417   mp->vni = clib_host_to_net_u32 (vni);
17418
17419   /* send it... */
17420   S (mp);
17421
17422   /* Wait for a reply... */
17423   W (ret);
17424   return ret;
17425 }
17426
17427 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17428 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17429 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17430 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17431 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17432 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17433 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17434 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17435
17436 static int
17437 api_one_adjacencies_get (vat_main_t * vam)
17438 {
17439   unformat_input_t *i = vam->input;
17440   vl_api_one_adjacencies_get_t *mp;
17441   u8 vni_set = 0;
17442   u32 vni = ~0;
17443   int ret;
17444
17445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17446     {
17447       if (unformat (i, "vni %d", &vni))
17448         {
17449           vni_set = 1;
17450         }
17451       else
17452         {
17453           errmsg ("parse error '%U'", format_unformat_error, i);
17454           return -99;
17455         }
17456     }
17457
17458   if (!vni_set)
17459     {
17460       errmsg ("vni not set!");
17461       return -99;
17462     }
17463
17464   if (!vam->json_output)
17465     {
17466       print (vam->ofp, "%s %40s", "leid", "reid");
17467     }
17468
17469   M (ONE_ADJACENCIES_GET, mp);
17470   mp->vni = clib_host_to_net_u32 (vni);
17471
17472   /* send it... */
17473   S (mp);
17474
17475   /* Wait for a reply... */
17476   W (ret);
17477   return ret;
17478 }
17479
17480 #define api_lisp_adjacencies_get api_one_adjacencies_get
17481
17482 static int
17483 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17484 {
17485   unformat_input_t *i = vam->input;
17486   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17487   int ret;
17488   u8 ip_family_set = 0, is_ip4 = 1;
17489
17490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17491     {
17492       if (unformat (i, "ip4"))
17493         {
17494           ip_family_set = 1;
17495           is_ip4 = 1;
17496         }
17497       else if (unformat (i, "ip6"))
17498         {
17499           ip_family_set = 1;
17500           is_ip4 = 0;
17501         }
17502       else
17503         {
17504           errmsg ("parse error '%U'", format_unformat_error, i);
17505           return -99;
17506         }
17507     }
17508
17509   if (!ip_family_set)
17510     {
17511       errmsg ("ip family not set!");
17512       return -99;
17513     }
17514
17515   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17516   mp->is_ip4 = is_ip4;
17517
17518   /* send it... */
17519   S (mp);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 static int
17527 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17528 {
17529   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17530   int ret;
17531
17532   if (!vam->json_output)
17533     {
17534       print (vam->ofp, "VNIs");
17535     }
17536
17537   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17538
17539   /* send it... */
17540   S (mp);
17541
17542   /* Wait for a reply... */
17543   W (ret);
17544   return ret;
17545 }
17546
17547 static int
17548 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17549 {
17550   unformat_input_t *i = vam->input;
17551   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17552   int ret = 0;
17553   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17554   struct in_addr ip4;
17555   struct in6_addr ip6;
17556   u32 table_id = 0, nh_sw_if_index = ~0;
17557
17558   clib_memset (&ip4, 0, sizeof (ip4));
17559   clib_memset (&ip6, 0, sizeof (ip6));
17560
17561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17562     {
17563       if (unformat (i, "del"))
17564         is_add = 0;
17565       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17566                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17567         {
17568           ip_set = 1;
17569           is_ip4 = 1;
17570         }
17571       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17572                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17573         {
17574           ip_set = 1;
17575           is_ip4 = 0;
17576         }
17577       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17578         {
17579           ip_set = 1;
17580           is_ip4 = 1;
17581           nh_sw_if_index = ~0;
17582         }
17583       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17584         {
17585           ip_set = 1;
17586           is_ip4 = 0;
17587           nh_sw_if_index = ~0;
17588         }
17589       else if (unformat (i, "table %d", &table_id))
17590         ;
17591       else
17592         {
17593           errmsg ("parse error '%U'", format_unformat_error, i);
17594           return -99;
17595         }
17596     }
17597
17598   if (!ip_set)
17599     {
17600       errmsg ("nh addr not set!");
17601       return -99;
17602     }
17603
17604   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17605   mp->is_add = is_add;
17606   mp->table_id = clib_host_to_net_u32 (table_id);
17607   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17608   mp->is_ip4 = is_ip4;
17609   if (is_ip4)
17610     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17611   else
17612     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17613
17614   /* send it... */
17615   S (mp);
17616
17617   /* Wait for a reply... */
17618   W (ret);
17619   return ret;
17620 }
17621
17622 static int
17623 api_one_map_server_dump (vat_main_t * vam)
17624 {
17625   vl_api_one_map_server_dump_t *mp;
17626   vl_api_control_ping_t *mp_ping;
17627   int ret;
17628
17629   if (!vam->json_output)
17630     {
17631       print (vam->ofp, "%=20s", "Map server");
17632     }
17633
17634   M (ONE_MAP_SERVER_DUMP, mp);
17635   /* send it... */
17636   S (mp);
17637
17638   /* Use a control ping for synchronization */
17639   MPING (CONTROL_PING, mp_ping);
17640   S (mp_ping);
17641
17642   /* Wait for a reply... */
17643   W (ret);
17644   return ret;
17645 }
17646
17647 #define api_lisp_map_server_dump api_one_map_server_dump
17648
17649 static int
17650 api_one_map_resolver_dump (vat_main_t * vam)
17651 {
17652   vl_api_one_map_resolver_dump_t *mp;
17653   vl_api_control_ping_t *mp_ping;
17654   int ret;
17655
17656   if (!vam->json_output)
17657     {
17658       print (vam->ofp, "%=20s", "Map resolver");
17659     }
17660
17661   M (ONE_MAP_RESOLVER_DUMP, mp);
17662   /* send it... */
17663   S (mp);
17664
17665   /* Use a control ping for synchronization */
17666   MPING (CONTROL_PING, mp_ping);
17667   S (mp_ping);
17668
17669   /* Wait for a reply... */
17670   W (ret);
17671   return ret;
17672 }
17673
17674 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17675
17676 static int
17677 api_one_stats_flush (vat_main_t * vam)
17678 {
17679   vl_api_one_stats_flush_t *mp;
17680   int ret = 0;
17681
17682   M (ONE_STATS_FLUSH, mp);
17683   S (mp);
17684   W (ret);
17685   return ret;
17686 }
17687
17688 static int
17689 api_one_stats_dump (vat_main_t * vam)
17690 {
17691   vl_api_one_stats_dump_t *mp;
17692   vl_api_control_ping_t *mp_ping;
17693   int ret;
17694
17695   M (ONE_STATS_DUMP, mp);
17696   /* send it... */
17697   S (mp);
17698
17699   /* Use a control ping for synchronization */
17700   MPING (CONTROL_PING, mp_ping);
17701   S (mp_ping);
17702
17703   /* Wait for a reply... */
17704   W (ret);
17705   return ret;
17706 }
17707
17708 static int
17709 api_show_one_status (vat_main_t * vam)
17710 {
17711   vl_api_show_one_status_t *mp;
17712   int ret;
17713
17714   if (!vam->json_output)
17715     {
17716       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17717     }
17718
17719   M (SHOW_ONE_STATUS, mp);
17720   /* send it... */
17721   S (mp);
17722   /* Wait for a reply... */
17723   W (ret);
17724   return ret;
17725 }
17726
17727 #define api_show_lisp_status api_show_one_status
17728
17729 static int
17730 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17731 {
17732   vl_api_gpe_fwd_entry_path_dump_t *mp;
17733   vl_api_control_ping_t *mp_ping;
17734   unformat_input_t *i = vam->input;
17735   u32 fwd_entry_index = ~0;
17736   int ret;
17737
17738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17739     {
17740       if (unformat (i, "index %d", &fwd_entry_index))
17741         ;
17742       else
17743         break;
17744     }
17745
17746   if (~0 == fwd_entry_index)
17747     {
17748       errmsg ("no index specified!");
17749       return -99;
17750     }
17751
17752   if (!vam->json_output)
17753     {
17754       print (vam->ofp, "first line");
17755     }
17756
17757   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17758
17759   /* send it... */
17760   S (mp);
17761   /* Use a control ping for synchronization */
17762   MPING (CONTROL_PING, mp_ping);
17763   S (mp_ping);
17764
17765   /* Wait for a reply... */
17766   W (ret);
17767   return ret;
17768 }
17769
17770 static int
17771 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17772 {
17773   vl_api_one_get_map_request_itr_rlocs_t *mp;
17774   int ret;
17775
17776   if (!vam->json_output)
17777     {
17778       print (vam->ofp, "%=20s", "itr-rlocs:");
17779     }
17780
17781   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17782   /* send it... */
17783   S (mp);
17784   /* Wait for a reply... */
17785   W (ret);
17786   return ret;
17787 }
17788
17789 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17790
17791 static int
17792 api_af_packet_create (vat_main_t * vam)
17793 {
17794   unformat_input_t *i = vam->input;
17795   vl_api_af_packet_create_t *mp;
17796   u8 *host_if_name = 0;
17797   u8 hw_addr[6];
17798   u8 random_hw_addr = 1;
17799   int ret;
17800
17801   clib_memset (hw_addr, 0, sizeof (hw_addr));
17802
17803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17804     {
17805       if (unformat (i, "name %s", &host_if_name))
17806         vec_add1 (host_if_name, 0);
17807       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17808         random_hw_addr = 0;
17809       else
17810         break;
17811     }
17812
17813   if (!vec_len (host_if_name))
17814     {
17815       errmsg ("host-interface name must be specified");
17816       return -99;
17817     }
17818
17819   if (vec_len (host_if_name) > 64)
17820     {
17821       errmsg ("host-interface name too long");
17822       return -99;
17823     }
17824
17825   M (AF_PACKET_CREATE, mp);
17826
17827   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17828   clib_memcpy (mp->hw_addr, hw_addr, 6);
17829   mp->use_random_hw_addr = random_hw_addr;
17830   vec_free (host_if_name);
17831
17832   S (mp);
17833
17834   /* *INDENT-OFF* */
17835   W2 (ret,
17836       ({
17837         if (ret == 0)
17838           fprintf (vam->ofp ? vam->ofp : stderr,
17839                    " new sw_if_index = %d\n", vam->sw_if_index);
17840       }));
17841   /* *INDENT-ON* */
17842   return ret;
17843 }
17844
17845 static int
17846 api_af_packet_delete (vat_main_t * vam)
17847 {
17848   unformat_input_t *i = vam->input;
17849   vl_api_af_packet_delete_t *mp;
17850   u8 *host_if_name = 0;
17851   int ret;
17852
17853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17854     {
17855       if (unformat (i, "name %s", &host_if_name))
17856         vec_add1 (host_if_name, 0);
17857       else
17858         break;
17859     }
17860
17861   if (!vec_len (host_if_name))
17862     {
17863       errmsg ("host-interface name must be specified");
17864       return -99;
17865     }
17866
17867   if (vec_len (host_if_name) > 64)
17868     {
17869       errmsg ("host-interface name too long");
17870       return -99;
17871     }
17872
17873   M (AF_PACKET_DELETE, mp);
17874
17875   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17876   vec_free (host_if_name);
17877
17878   S (mp);
17879   W (ret);
17880   return ret;
17881 }
17882
17883 static void vl_api_af_packet_details_t_handler
17884   (vl_api_af_packet_details_t * mp)
17885 {
17886   vat_main_t *vam = &vat_main;
17887
17888   print (vam->ofp, "%-16s %d",
17889          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17890 }
17891
17892 static void vl_api_af_packet_details_t_handler_json
17893   (vl_api_af_packet_details_t * mp)
17894 {
17895   vat_main_t *vam = &vat_main;
17896   vat_json_node_t *node = NULL;
17897
17898   if (VAT_JSON_ARRAY != vam->json_tree.type)
17899     {
17900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17901       vat_json_init_array (&vam->json_tree);
17902     }
17903   node = vat_json_array_add (&vam->json_tree);
17904
17905   vat_json_init_object (node);
17906   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17907   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17908 }
17909
17910 static int
17911 api_af_packet_dump (vat_main_t * vam)
17912 {
17913   vl_api_af_packet_dump_t *mp;
17914   vl_api_control_ping_t *mp_ping;
17915   int ret;
17916
17917   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17918   /* Get list of tap interfaces */
17919   M (AF_PACKET_DUMP, mp);
17920   S (mp);
17921
17922   /* Use a control ping for synchronization */
17923   MPING (CONTROL_PING, mp_ping);
17924   S (mp_ping);
17925
17926   W (ret);
17927   return ret;
17928 }
17929
17930 static int
17931 api_policer_add_del (vat_main_t * vam)
17932 {
17933   unformat_input_t *i = vam->input;
17934   vl_api_policer_add_del_t *mp;
17935   u8 is_add = 1;
17936   u8 *name = 0;
17937   u32 cir = 0;
17938   u32 eir = 0;
17939   u64 cb = 0;
17940   u64 eb = 0;
17941   u8 rate_type = 0;
17942   u8 round_type = 0;
17943   u8 type = 0;
17944   u8 color_aware = 0;
17945   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17946   int ret;
17947
17948   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17949   conform_action.dscp = 0;
17950   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17951   exceed_action.dscp = 0;
17952   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17953   violate_action.dscp = 0;
17954
17955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17956     {
17957       if (unformat (i, "del"))
17958         is_add = 0;
17959       else if (unformat (i, "name %s", &name))
17960         vec_add1 (name, 0);
17961       else if (unformat (i, "cir %u", &cir))
17962         ;
17963       else if (unformat (i, "eir %u", &eir))
17964         ;
17965       else if (unformat (i, "cb %u", &cb))
17966         ;
17967       else if (unformat (i, "eb %u", &eb))
17968         ;
17969       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17970                          &rate_type))
17971         ;
17972       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17973                          &round_type))
17974         ;
17975       else if (unformat (i, "type %U", unformat_policer_type, &type))
17976         ;
17977       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17978                          &conform_action))
17979         ;
17980       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17981                          &exceed_action))
17982         ;
17983       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17984                          &violate_action))
17985         ;
17986       else if (unformat (i, "color-aware"))
17987         color_aware = 1;
17988       else
17989         break;
17990     }
17991
17992   if (!vec_len (name))
17993     {
17994       errmsg ("policer name must be specified");
17995       return -99;
17996     }
17997
17998   if (vec_len (name) > 64)
17999     {
18000       errmsg ("policer name too long");
18001       return -99;
18002     }
18003
18004   M (POLICER_ADD_DEL, mp);
18005
18006   clib_memcpy (mp->name, name, vec_len (name));
18007   vec_free (name);
18008   mp->is_add = is_add;
18009   mp->cir = ntohl (cir);
18010   mp->eir = ntohl (eir);
18011   mp->cb = clib_net_to_host_u64 (cb);
18012   mp->eb = clib_net_to_host_u64 (eb);
18013   mp->rate_type = rate_type;
18014   mp->round_type = round_type;
18015   mp->type = type;
18016   mp->conform_action_type = conform_action.action_type;
18017   mp->conform_dscp = conform_action.dscp;
18018   mp->exceed_action_type = exceed_action.action_type;
18019   mp->exceed_dscp = exceed_action.dscp;
18020   mp->violate_action_type = violate_action.action_type;
18021   mp->violate_dscp = violate_action.dscp;
18022   mp->color_aware = color_aware;
18023
18024   S (mp);
18025   W (ret);
18026   return ret;
18027 }
18028
18029 static int
18030 api_policer_dump (vat_main_t * vam)
18031 {
18032   unformat_input_t *i = vam->input;
18033   vl_api_policer_dump_t *mp;
18034   vl_api_control_ping_t *mp_ping;
18035   u8 *match_name = 0;
18036   u8 match_name_valid = 0;
18037   int ret;
18038
18039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18040     {
18041       if (unformat (i, "name %s", &match_name))
18042         {
18043           vec_add1 (match_name, 0);
18044           match_name_valid = 1;
18045         }
18046       else
18047         break;
18048     }
18049
18050   M (POLICER_DUMP, mp);
18051   mp->match_name_valid = match_name_valid;
18052   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18053   vec_free (match_name);
18054   /* send it... */
18055   S (mp);
18056
18057   /* Use a control ping for synchronization */
18058   MPING (CONTROL_PING, mp_ping);
18059   S (mp_ping);
18060
18061   /* Wait for a reply... */
18062   W (ret);
18063   return ret;
18064 }
18065
18066 static int
18067 api_policer_classify_set_interface (vat_main_t * vam)
18068 {
18069   unformat_input_t *i = vam->input;
18070   vl_api_policer_classify_set_interface_t *mp;
18071   u32 sw_if_index;
18072   int sw_if_index_set;
18073   u32 ip4_table_index = ~0;
18074   u32 ip6_table_index = ~0;
18075   u32 l2_table_index = ~0;
18076   u8 is_add = 1;
18077   int ret;
18078
18079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18080     {
18081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18082         sw_if_index_set = 1;
18083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18084         sw_if_index_set = 1;
18085       else if (unformat (i, "del"))
18086         is_add = 0;
18087       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18088         ;
18089       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18090         ;
18091       else if (unformat (i, "l2-table %d", &l2_table_index))
18092         ;
18093       else
18094         {
18095           clib_warning ("parse error '%U'", format_unformat_error, i);
18096           return -99;
18097         }
18098     }
18099
18100   if (sw_if_index_set == 0)
18101     {
18102       errmsg ("missing interface name or sw_if_index");
18103       return -99;
18104     }
18105
18106   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18107
18108   mp->sw_if_index = ntohl (sw_if_index);
18109   mp->ip4_table_index = ntohl (ip4_table_index);
18110   mp->ip6_table_index = ntohl (ip6_table_index);
18111   mp->l2_table_index = ntohl (l2_table_index);
18112   mp->is_add = is_add;
18113
18114   S (mp);
18115   W (ret);
18116   return ret;
18117 }
18118
18119 static int
18120 api_policer_classify_dump (vat_main_t * vam)
18121 {
18122   unformat_input_t *i = vam->input;
18123   vl_api_policer_classify_dump_t *mp;
18124   vl_api_control_ping_t *mp_ping;
18125   u8 type = POLICER_CLASSIFY_N_TABLES;
18126   int ret;
18127
18128   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18129     ;
18130   else
18131     {
18132       errmsg ("classify table type must be specified");
18133       return -99;
18134     }
18135
18136   if (!vam->json_output)
18137     {
18138       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18139     }
18140
18141   M (POLICER_CLASSIFY_DUMP, mp);
18142   mp->type = type;
18143   /* send it... */
18144   S (mp);
18145
18146   /* Use a control ping for synchronization */
18147   MPING (CONTROL_PING, mp_ping);
18148   S (mp_ping);
18149
18150   /* Wait for a reply... */
18151   W (ret);
18152   return ret;
18153 }
18154
18155 static int
18156 api_netmap_create (vat_main_t * vam)
18157 {
18158   unformat_input_t *i = vam->input;
18159   vl_api_netmap_create_t *mp;
18160   u8 *if_name = 0;
18161   u8 hw_addr[6];
18162   u8 random_hw_addr = 1;
18163   u8 is_pipe = 0;
18164   u8 is_master = 0;
18165   int ret;
18166
18167   clib_memset (hw_addr, 0, sizeof (hw_addr));
18168
18169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18170     {
18171       if (unformat (i, "name %s", &if_name))
18172         vec_add1 (if_name, 0);
18173       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18174         random_hw_addr = 0;
18175       else if (unformat (i, "pipe"))
18176         is_pipe = 1;
18177       else if (unformat (i, "master"))
18178         is_master = 1;
18179       else if (unformat (i, "slave"))
18180         is_master = 0;
18181       else
18182         break;
18183     }
18184
18185   if (!vec_len (if_name))
18186     {
18187       errmsg ("interface name must be specified");
18188       return -99;
18189     }
18190
18191   if (vec_len (if_name) > 64)
18192     {
18193       errmsg ("interface name too long");
18194       return -99;
18195     }
18196
18197   M (NETMAP_CREATE, mp);
18198
18199   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18200   clib_memcpy (mp->hw_addr, hw_addr, 6);
18201   mp->use_random_hw_addr = random_hw_addr;
18202   mp->is_pipe = is_pipe;
18203   mp->is_master = is_master;
18204   vec_free (if_name);
18205
18206   S (mp);
18207   W (ret);
18208   return ret;
18209 }
18210
18211 static int
18212 api_netmap_delete (vat_main_t * vam)
18213 {
18214   unformat_input_t *i = vam->input;
18215   vl_api_netmap_delete_t *mp;
18216   u8 *if_name = 0;
18217   int ret;
18218
18219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18220     {
18221       if (unformat (i, "name %s", &if_name))
18222         vec_add1 (if_name, 0);
18223       else
18224         break;
18225     }
18226
18227   if (!vec_len (if_name))
18228     {
18229       errmsg ("interface name must be specified");
18230       return -99;
18231     }
18232
18233   if (vec_len (if_name) > 64)
18234     {
18235       errmsg ("interface name too long");
18236       return -99;
18237     }
18238
18239   M (NETMAP_DELETE, mp);
18240
18241   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18242   vec_free (if_name);
18243
18244   S (mp);
18245   W (ret);
18246   return ret;
18247 }
18248
18249 static u8 *
18250 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18251 {
18252   vl_api_fib_path_nh_proto_t proto =
18253     va_arg (*args, vl_api_fib_path_nh_proto_t);
18254
18255   switch (proto)
18256     {
18257     case FIB_API_PATH_NH_PROTO_IP4:
18258       s = format (s, "ip4");
18259       break;
18260     case FIB_API_PATH_NH_PROTO_IP6:
18261       s = format (s, "ip6");
18262       break;
18263     case FIB_API_PATH_NH_PROTO_MPLS:
18264       s = format (s, "mpls");
18265       break;
18266     case FIB_API_PATH_NH_PROTO_BIER:
18267       s = format (s, "bier");
18268       break;
18269     case FIB_API_PATH_NH_PROTO_ETHERNET:
18270       s = format (s, "ethernet");
18271       break;
18272     }
18273
18274   return (s);
18275 }
18276
18277 static u8 *
18278 format_vl_api_ip_address_union (u8 * s, va_list * args)
18279 {
18280   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18281   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18282
18283   switch (af)
18284     {
18285     case ADDRESS_IP4:
18286       s = format (s, "%U", format_ip4_address, u->ip4);
18287       break;
18288     case ADDRESS_IP6:
18289       s = format (s, "%U", format_ip6_address, u->ip6);
18290       break;
18291     }
18292   return (s);
18293 }
18294
18295 static u8 *
18296 format_vl_api_fib_path_type (u8 * s, va_list * args)
18297 {
18298   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18299
18300   switch (t)
18301     {
18302     case FIB_API_PATH_TYPE_NORMAL:
18303       s = format (s, "normal");
18304       break;
18305     case FIB_API_PATH_TYPE_LOCAL:
18306       s = format (s, "local");
18307       break;
18308     case FIB_API_PATH_TYPE_DROP:
18309       s = format (s, "drop");
18310       break;
18311     case FIB_API_PATH_TYPE_UDP_ENCAP:
18312       s = format (s, "udp-encap");
18313       break;
18314     case FIB_API_PATH_TYPE_BIER_IMP:
18315       s = format (s, "bier-imp");
18316       break;
18317     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18318       s = format (s, "unreach");
18319       break;
18320     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18321       s = format (s, "prohibit");
18322       break;
18323     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18324       s = format (s, "src-lookup");
18325       break;
18326     case FIB_API_PATH_TYPE_DVR:
18327       s = format (s, "dvr");
18328       break;
18329     case FIB_API_PATH_TYPE_INTERFACE_RX:
18330       s = format (s, "interface-rx");
18331       break;
18332     case FIB_API_PATH_TYPE_CLASSIFY:
18333       s = format (s, "classify");
18334       break;
18335     }
18336
18337   return (s);
18338 }
18339
18340 static void
18341 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18342 {
18343   print (vam->ofp,
18344          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18345          ntohl (fp->weight), ntohl (fp->sw_if_index),
18346          format_vl_api_fib_path_type, fp->type,
18347          format_fib_api_path_nh_proto, fp->proto,
18348          format_vl_api_ip_address_union, &fp->nh.address);
18349 }
18350
18351 static void
18352 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18353                                  vl_api_fib_path_t * fp)
18354 {
18355   struct in_addr ip4;
18356   struct in6_addr ip6;
18357
18358   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18359   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18360   vat_json_object_add_uint (node, "type", fp->type);
18361   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18362   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18363     {
18364       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18365       vat_json_object_add_ip4 (node, "next_hop", ip4);
18366     }
18367   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18368     {
18369       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18370       vat_json_object_add_ip6 (node, "next_hop", ip6);
18371     }
18372 }
18373
18374 static void
18375 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18376 {
18377   vat_main_t *vam = &vat_main;
18378   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18379   vl_api_fib_path_t *fp;
18380   i32 i;
18381
18382   print (vam->ofp, "sw_if_index %d via:",
18383          ntohl (mp->mt_tunnel.mt_sw_if_index));
18384   fp = mp->mt_tunnel.mt_paths;
18385   for (i = 0; i < count; i++)
18386     {
18387       vl_api_fib_path_print (vam, fp);
18388       fp++;
18389     }
18390
18391   print (vam->ofp, "");
18392 }
18393
18394 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18395 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18396
18397 static void
18398 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18399 {
18400   vat_main_t *vam = &vat_main;
18401   vat_json_node_t *node = NULL;
18402   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18403   vl_api_fib_path_t *fp;
18404   i32 i;
18405
18406   if (VAT_JSON_ARRAY != vam->json_tree.type)
18407     {
18408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18409       vat_json_init_array (&vam->json_tree);
18410     }
18411   node = vat_json_array_add (&vam->json_tree);
18412
18413   vat_json_init_object (node);
18414   vat_json_object_add_uint (node, "sw_if_index",
18415                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18416
18417   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18418
18419   fp = mp->mt_tunnel.mt_paths;
18420   for (i = 0; i < count; i++)
18421     {
18422       vl_api_mpls_fib_path_json_print (node, fp);
18423       fp++;
18424     }
18425 }
18426
18427 static int
18428 api_mpls_tunnel_dump (vat_main_t * vam)
18429 {
18430   vl_api_mpls_tunnel_dump_t *mp;
18431   vl_api_control_ping_t *mp_ping;
18432   int ret;
18433
18434   M (MPLS_TUNNEL_DUMP, mp);
18435
18436   S (mp);
18437
18438   /* Use a control ping for synchronization */
18439   MPING (CONTROL_PING, mp_ping);
18440   S (mp_ping);
18441
18442   W (ret);
18443   return ret;
18444 }
18445
18446 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18447 #define vl_api_mpls_table_details_t_print vl_noop_handler
18448
18449
18450 static void
18451 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18452 {
18453   vat_main_t *vam = &vat_main;
18454
18455   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18456 }
18457
18458 static void vl_api_mpls_table_details_t_handler_json
18459   (vl_api_mpls_table_details_t * mp)
18460 {
18461   vat_main_t *vam = &vat_main;
18462   vat_json_node_t *node = NULL;
18463
18464   if (VAT_JSON_ARRAY != vam->json_tree.type)
18465     {
18466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18467       vat_json_init_array (&vam->json_tree);
18468     }
18469   node = vat_json_array_add (&vam->json_tree);
18470
18471   vat_json_init_object (node);
18472   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18473 }
18474
18475 static int
18476 api_mpls_table_dump (vat_main_t * vam)
18477 {
18478   vl_api_mpls_table_dump_t *mp;
18479   vl_api_control_ping_t *mp_ping;
18480   int ret;
18481
18482   M (MPLS_TABLE_DUMP, mp);
18483   S (mp);
18484
18485   /* Use a control ping for synchronization */
18486   MPING (CONTROL_PING, mp_ping);
18487   S (mp_ping);
18488
18489   W (ret);
18490   return ret;
18491 }
18492
18493 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18494 #define vl_api_mpls_route_details_t_print vl_noop_handler
18495
18496 static void
18497 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18498 {
18499   vat_main_t *vam = &vat_main;
18500   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18501   vl_api_fib_path_t *fp;
18502   int i;
18503
18504   print (vam->ofp,
18505          "table-id %d, label %u, ess_bit %u",
18506          ntohl (mp->mr_route.mr_table_id),
18507          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18508   fp = mp->mr_route.mr_paths;
18509   for (i = 0; i < count; i++)
18510     {
18511       vl_api_fib_path_print (vam, fp);
18512       fp++;
18513     }
18514 }
18515
18516 static void vl_api_mpls_route_details_t_handler_json
18517   (vl_api_mpls_route_details_t * mp)
18518 {
18519   vat_main_t *vam = &vat_main;
18520   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18521   vat_json_node_t *node = NULL;
18522   vl_api_fib_path_t *fp;
18523   int i;
18524
18525   if (VAT_JSON_ARRAY != vam->json_tree.type)
18526     {
18527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18528       vat_json_init_array (&vam->json_tree);
18529     }
18530   node = vat_json_array_add (&vam->json_tree);
18531
18532   vat_json_init_object (node);
18533   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18534   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18535   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18536   vat_json_object_add_uint (node, "path_count", count);
18537   fp = mp->mr_route.mr_paths;
18538   for (i = 0; i < count; i++)
18539     {
18540       vl_api_mpls_fib_path_json_print (node, fp);
18541       fp++;
18542     }
18543 }
18544
18545 static int
18546 api_mpls_route_dump (vat_main_t * vam)
18547 {
18548   unformat_input_t *input = vam->input;
18549   vl_api_mpls_route_dump_t *mp;
18550   vl_api_control_ping_t *mp_ping;
18551   u32 table_id;
18552   int ret;
18553
18554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18555     {
18556       if (unformat (input, "table_id %d", &table_id))
18557         ;
18558       else
18559         break;
18560     }
18561   if (table_id == ~0)
18562     {
18563       errmsg ("missing table id");
18564       return -99;
18565     }
18566
18567   M (MPLS_ROUTE_DUMP, mp);
18568
18569   mp->table.mt_table_id = ntohl (table_id);
18570   S (mp);
18571
18572   /* Use a control ping for synchronization */
18573   MPING (CONTROL_PING, mp_ping);
18574   S (mp_ping);
18575
18576   W (ret);
18577   return ret;
18578 }
18579
18580 #define vl_api_ip_table_details_t_endian vl_noop_handler
18581 #define vl_api_ip_table_details_t_print vl_noop_handler
18582
18583 static void
18584 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18585 {
18586   vat_main_t *vam = &vat_main;
18587
18588   print (vam->ofp,
18589          "%s; table-id %d, prefix %U/%d",
18590          mp->table.name, ntohl (mp->table.table_id));
18591 }
18592
18593
18594 static void vl_api_ip_table_details_t_handler_json
18595   (vl_api_ip_table_details_t * mp)
18596 {
18597   vat_main_t *vam = &vat_main;
18598   vat_json_node_t *node = NULL;
18599
18600   if (VAT_JSON_ARRAY != vam->json_tree.type)
18601     {
18602       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18603       vat_json_init_array (&vam->json_tree);
18604     }
18605   node = vat_json_array_add (&vam->json_tree);
18606
18607   vat_json_init_object (node);
18608   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18609 }
18610
18611 static int
18612 api_ip_table_dump (vat_main_t * vam)
18613 {
18614   vl_api_ip_table_dump_t *mp;
18615   vl_api_control_ping_t *mp_ping;
18616   int ret;
18617
18618   M (IP_TABLE_DUMP, mp);
18619   S (mp);
18620
18621   /* Use a control ping for synchronization */
18622   MPING (CONTROL_PING, mp_ping);
18623   S (mp_ping);
18624
18625   W (ret);
18626   return ret;
18627 }
18628
18629 static int
18630 api_ip_mtable_dump (vat_main_t * vam)
18631 {
18632   vl_api_ip_mtable_dump_t *mp;
18633   vl_api_control_ping_t *mp_ping;
18634   int ret;
18635
18636   M (IP_MTABLE_DUMP, mp);
18637   S (mp);
18638
18639   /* Use a control ping for synchronization */
18640   MPING (CONTROL_PING, mp_ping);
18641   S (mp_ping);
18642
18643   W (ret);
18644   return ret;
18645 }
18646
18647 static int
18648 api_ip_mroute_dump (vat_main_t * vam)
18649 {
18650   unformat_input_t *input = vam->input;
18651   vl_api_control_ping_t *mp_ping;
18652   vl_api_ip_mroute_dump_t *mp;
18653   int ret, is_ip6;
18654   u32 table_id;
18655
18656   is_ip6 = 0;
18657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18658     {
18659       if (unformat (input, "table_id %d", &table_id))
18660         ;
18661       else if (unformat (input, "ip6"))
18662         is_ip6 = 1;
18663       else if (unformat (input, "ip4"))
18664         is_ip6 = 0;
18665       else
18666         break;
18667     }
18668   if (table_id == ~0)
18669     {
18670       errmsg ("missing table id");
18671       return -99;
18672     }
18673
18674   M (IP_MROUTE_DUMP, mp);
18675   mp->table.table_id = table_id;
18676   mp->table.is_ip6 = is_ip6;
18677   S (mp);
18678
18679   /* Use a control ping for synchronization */
18680   MPING (CONTROL_PING, mp_ping);
18681   S (mp_ping);
18682
18683   W (ret);
18684   return ret;
18685 }
18686
18687 static void vl_api_ip_neighbor_details_t_handler
18688   (vl_api_ip_neighbor_details_t * mp)
18689 {
18690   vat_main_t *vam = &vat_main;
18691
18692   print (vam->ofp, "%c %U %U",
18693          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18694          format_vl_api_mac_address, &mp->neighbor.mac_address,
18695          format_vl_api_address, &mp->neighbor.ip_address);
18696 }
18697
18698 static void vl_api_ip_neighbor_details_t_handler_json
18699   (vl_api_ip_neighbor_details_t * mp)
18700 {
18701
18702   vat_main_t *vam = &vat_main;
18703   vat_json_node_t *node;
18704
18705   if (VAT_JSON_ARRAY != vam->json_tree.type)
18706     {
18707       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18708       vat_json_init_array (&vam->json_tree);
18709     }
18710   node = vat_json_array_add (&vam->json_tree);
18711
18712   vat_json_init_object (node);
18713   vat_json_object_add_string_copy
18714     (node, "flag",
18715      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18716       (u8 *) "static" : (u8 *) "dynamic"));
18717
18718   vat_json_object_add_string_copy (node, "link_layer",
18719                                    format (0, "%U", format_vl_api_mac_address,
18720                                            &mp->neighbor.mac_address));
18721   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18722 }
18723
18724 static int
18725 api_ip_neighbor_dump (vat_main_t * vam)
18726 {
18727   unformat_input_t *i = vam->input;
18728   vl_api_ip_neighbor_dump_t *mp;
18729   vl_api_control_ping_t *mp_ping;
18730   u8 is_ipv6 = 0;
18731   u32 sw_if_index = ~0;
18732   int ret;
18733
18734   /* Parse args required to build the message */
18735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18736     {
18737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18738         ;
18739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18740         ;
18741       else if (unformat (i, "ip6"))
18742         is_ipv6 = 1;
18743       else
18744         break;
18745     }
18746
18747   if (sw_if_index == ~0)
18748     {
18749       errmsg ("missing interface name or sw_if_index");
18750       return -99;
18751     }
18752
18753   M (IP_NEIGHBOR_DUMP, mp);
18754   mp->is_ipv6 = (u8) is_ipv6;
18755   mp->sw_if_index = ntohl (sw_if_index);
18756   S (mp);
18757
18758   /* Use a control ping for synchronization */
18759   MPING (CONTROL_PING, mp_ping);
18760   S (mp_ping);
18761
18762   W (ret);
18763   return ret;
18764 }
18765
18766 #define vl_api_ip_route_details_t_endian vl_noop_handler
18767 #define vl_api_ip_route_details_t_print vl_noop_handler
18768
18769 static void
18770 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18771 {
18772   vat_main_t *vam = &vat_main;
18773   u8 count = mp->route.n_paths;
18774   vl_api_fib_path_t *fp;
18775   int i;
18776
18777   print (vam->ofp,
18778          "table-id %d, prefix %U/%d",
18779          ntohl (mp->route.table_id),
18780          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18781   for (i = 0; i < count; i++)
18782     {
18783       fp = &mp->route.paths[i];
18784
18785       vl_api_fib_path_print (vam, fp);
18786       fp++;
18787     }
18788 }
18789
18790 static void vl_api_ip_route_details_t_handler_json
18791   (vl_api_ip_route_details_t * mp)
18792 {
18793   vat_main_t *vam = &vat_main;
18794   u8 count = mp->route.n_paths;
18795   vat_json_node_t *node = NULL;
18796   struct in_addr ip4;
18797   struct in6_addr ip6;
18798   vl_api_fib_path_t *fp;
18799   int i;
18800
18801   if (VAT_JSON_ARRAY != vam->json_tree.type)
18802     {
18803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18804       vat_json_init_array (&vam->json_tree);
18805     }
18806   node = vat_json_array_add (&vam->json_tree);
18807
18808   vat_json_init_object (node);
18809   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18810   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18811     {
18812       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18813       vat_json_object_add_ip6 (node, "prefix", ip6);
18814     }
18815   else
18816     {
18817       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18818       vat_json_object_add_ip4 (node, "prefix", ip4);
18819     }
18820   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18821   vat_json_object_add_uint (node, "path_count", count);
18822   for (i = 0; i < count; i++)
18823     {
18824       fp = &mp->route.paths[i];
18825       vl_api_mpls_fib_path_json_print (node, fp);
18826     }
18827 }
18828
18829 static int
18830 api_ip_route_dump (vat_main_t * vam)
18831 {
18832   unformat_input_t *input = vam->input;
18833   vl_api_ip_route_dump_t *mp;
18834   vl_api_control_ping_t *mp_ping;
18835   u32 table_id;
18836   u8 is_ip6;
18837   int ret;
18838
18839   is_ip6 = 0;
18840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (input, "table_id %d", &table_id))
18843         ;
18844       else if (unformat (input, "ip6"))
18845         is_ip6 = 1;
18846       else if (unformat (input, "ip4"))
18847         is_ip6 = 0;
18848       else
18849         break;
18850     }
18851   if (table_id == ~0)
18852     {
18853       errmsg ("missing table id");
18854       return -99;
18855     }
18856
18857   M (IP_ROUTE_DUMP, mp);
18858
18859   mp->table.table_id = table_id;
18860   mp->table.is_ip6 = is_ip6;
18861
18862   S (mp);
18863
18864   /* Use a control ping for synchronization */
18865   MPING (CONTROL_PING, mp_ping);
18866   S (mp_ping);
18867
18868   W (ret);
18869   return ret;
18870 }
18871
18872 int
18873 api_classify_table_ids (vat_main_t * vam)
18874 {
18875   vl_api_classify_table_ids_t *mp;
18876   int ret;
18877
18878   /* Construct the API message */
18879   M (CLASSIFY_TABLE_IDS, mp);
18880   mp->context = 0;
18881
18882   S (mp);
18883   W (ret);
18884   return ret;
18885 }
18886
18887 int
18888 api_classify_table_by_interface (vat_main_t * vam)
18889 {
18890   unformat_input_t *input = vam->input;
18891   vl_api_classify_table_by_interface_t *mp;
18892
18893   u32 sw_if_index = ~0;
18894   int ret;
18895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18896     {
18897       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18898         ;
18899       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18900         ;
18901       else
18902         break;
18903     }
18904   if (sw_if_index == ~0)
18905     {
18906       errmsg ("missing interface name or sw_if_index");
18907       return -99;
18908     }
18909
18910   /* Construct the API message */
18911   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18912   mp->context = 0;
18913   mp->sw_if_index = ntohl (sw_if_index);
18914
18915   S (mp);
18916   W (ret);
18917   return ret;
18918 }
18919
18920 int
18921 api_classify_table_info (vat_main_t * vam)
18922 {
18923   unformat_input_t *input = vam->input;
18924   vl_api_classify_table_info_t *mp;
18925
18926   u32 table_id = ~0;
18927   int ret;
18928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18929     {
18930       if (unformat (input, "table_id %d", &table_id))
18931         ;
18932       else
18933         break;
18934     }
18935   if (table_id == ~0)
18936     {
18937       errmsg ("missing table id");
18938       return -99;
18939     }
18940
18941   /* Construct the API message */
18942   M (CLASSIFY_TABLE_INFO, mp);
18943   mp->context = 0;
18944   mp->table_id = ntohl (table_id);
18945
18946   S (mp);
18947   W (ret);
18948   return ret;
18949 }
18950
18951 int
18952 api_classify_session_dump (vat_main_t * vam)
18953 {
18954   unformat_input_t *input = vam->input;
18955   vl_api_classify_session_dump_t *mp;
18956   vl_api_control_ping_t *mp_ping;
18957
18958   u32 table_id = ~0;
18959   int ret;
18960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18961     {
18962       if (unformat (input, "table_id %d", &table_id))
18963         ;
18964       else
18965         break;
18966     }
18967   if (table_id == ~0)
18968     {
18969       errmsg ("missing table id");
18970       return -99;
18971     }
18972
18973   /* Construct the API message */
18974   M (CLASSIFY_SESSION_DUMP, mp);
18975   mp->context = 0;
18976   mp->table_id = ntohl (table_id);
18977   S (mp);
18978
18979   /* Use a control ping for synchronization */
18980   MPING (CONTROL_PING, mp_ping);
18981   S (mp_ping);
18982
18983   W (ret);
18984   return ret;
18985 }
18986
18987 static void
18988 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18989 {
18990   vat_main_t *vam = &vat_main;
18991
18992   print (vam->ofp, "collector_address %U, collector_port %d, "
18993          "src_address %U, vrf_id %d, path_mtu %u, "
18994          "template_interval %u, udp_checksum %d",
18995          format_ip4_address, mp->collector_address,
18996          ntohs (mp->collector_port),
18997          format_ip4_address, mp->src_address,
18998          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18999          ntohl (mp->template_interval), mp->udp_checksum);
19000
19001   vam->retval = 0;
19002   vam->result_ready = 1;
19003 }
19004
19005 static void
19006   vl_api_ipfix_exporter_details_t_handler_json
19007   (vl_api_ipfix_exporter_details_t * mp)
19008 {
19009   vat_main_t *vam = &vat_main;
19010   vat_json_node_t node;
19011   struct in_addr collector_address;
19012   struct in_addr src_address;
19013
19014   vat_json_init_object (&node);
19015   clib_memcpy (&collector_address, &mp->collector_address,
19016                sizeof (collector_address));
19017   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19018   vat_json_object_add_uint (&node, "collector_port",
19019                             ntohs (mp->collector_port));
19020   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19021   vat_json_object_add_ip4 (&node, "src_address", src_address);
19022   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19023   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19024   vat_json_object_add_uint (&node, "template_interval",
19025                             ntohl (mp->template_interval));
19026   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19027
19028   vat_json_print (vam->ofp, &node);
19029   vat_json_free (&node);
19030   vam->retval = 0;
19031   vam->result_ready = 1;
19032 }
19033
19034 int
19035 api_ipfix_exporter_dump (vat_main_t * vam)
19036 {
19037   vl_api_ipfix_exporter_dump_t *mp;
19038   int ret;
19039
19040   /* Construct the API message */
19041   M (IPFIX_EXPORTER_DUMP, mp);
19042   mp->context = 0;
19043
19044   S (mp);
19045   W (ret);
19046   return ret;
19047 }
19048
19049 static int
19050 api_ipfix_classify_stream_dump (vat_main_t * vam)
19051 {
19052   vl_api_ipfix_classify_stream_dump_t *mp;
19053   int ret;
19054
19055   /* Construct the API message */
19056   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19057   mp->context = 0;
19058
19059   S (mp);
19060   W (ret);
19061   return ret;
19062   /* NOTREACHED */
19063   return 0;
19064 }
19065
19066 static void
19067   vl_api_ipfix_classify_stream_details_t_handler
19068   (vl_api_ipfix_classify_stream_details_t * mp)
19069 {
19070   vat_main_t *vam = &vat_main;
19071   print (vam->ofp, "domain_id %d, src_port %d",
19072          ntohl (mp->domain_id), ntohs (mp->src_port));
19073   vam->retval = 0;
19074   vam->result_ready = 1;
19075 }
19076
19077 static void
19078   vl_api_ipfix_classify_stream_details_t_handler_json
19079   (vl_api_ipfix_classify_stream_details_t * mp)
19080 {
19081   vat_main_t *vam = &vat_main;
19082   vat_json_node_t node;
19083
19084   vat_json_init_object (&node);
19085   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19086   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19087
19088   vat_json_print (vam->ofp, &node);
19089   vat_json_free (&node);
19090   vam->retval = 0;
19091   vam->result_ready = 1;
19092 }
19093
19094 static int
19095 api_ipfix_classify_table_dump (vat_main_t * vam)
19096 {
19097   vl_api_ipfix_classify_table_dump_t *mp;
19098   vl_api_control_ping_t *mp_ping;
19099   int ret;
19100
19101   if (!vam->json_output)
19102     {
19103       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19104              "transport_protocol");
19105     }
19106
19107   /* Construct the API message */
19108   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19109
19110   /* send it... */
19111   S (mp);
19112
19113   /* Use a control ping for synchronization */
19114   MPING (CONTROL_PING, mp_ping);
19115   S (mp_ping);
19116
19117   W (ret);
19118   return ret;
19119 }
19120
19121 static void
19122   vl_api_ipfix_classify_table_details_t_handler
19123   (vl_api_ipfix_classify_table_details_t * mp)
19124 {
19125   vat_main_t *vam = &vat_main;
19126   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19127          mp->transport_protocol);
19128 }
19129
19130 static void
19131   vl_api_ipfix_classify_table_details_t_handler_json
19132   (vl_api_ipfix_classify_table_details_t * mp)
19133 {
19134   vat_json_node_t *node = NULL;
19135   vat_main_t *vam = &vat_main;
19136
19137   if (VAT_JSON_ARRAY != vam->json_tree.type)
19138     {
19139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19140       vat_json_init_array (&vam->json_tree);
19141     }
19142
19143   node = vat_json_array_add (&vam->json_tree);
19144   vat_json_init_object (node);
19145
19146   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19147   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19148   vat_json_object_add_uint (node, "transport_protocol",
19149                             mp->transport_protocol);
19150 }
19151
19152 static int
19153 api_sw_interface_span_enable_disable (vat_main_t * vam)
19154 {
19155   unformat_input_t *i = vam->input;
19156   vl_api_sw_interface_span_enable_disable_t *mp;
19157   u32 src_sw_if_index = ~0;
19158   u32 dst_sw_if_index = ~0;
19159   u8 state = 3;
19160   int ret;
19161   u8 is_l2 = 0;
19162
19163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19164     {
19165       if (unformat
19166           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19167         ;
19168       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19169         ;
19170       else
19171         if (unformat
19172             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19173         ;
19174       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19175         ;
19176       else if (unformat (i, "disable"))
19177         state = 0;
19178       else if (unformat (i, "rx"))
19179         state = 1;
19180       else if (unformat (i, "tx"))
19181         state = 2;
19182       else if (unformat (i, "both"))
19183         state = 3;
19184       else if (unformat (i, "l2"))
19185         is_l2 = 1;
19186       else
19187         break;
19188     }
19189
19190   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19191
19192   mp->sw_if_index_from = htonl (src_sw_if_index);
19193   mp->sw_if_index_to = htonl (dst_sw_if_index);
19194   mp->state = state;
19195   mp->is_l2 = is_l2;
19196
19197   S (mp);
19198   W (ret);
19199   return ret;
19200 }
19201
19202 static void
19203 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19204                                             * mp)
19205 {
19206   vat_main_t *vam = &vat_main;
19207   u8 *sw_if_from_name = 0;
19208   u8 *sw_if_to_name = 0;
19209   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19210   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19211   char *states[] = { "none", "rx", "tx", "both" };
19212   hash_pair_t *p;
19213
19214   /* *INDENT-OFF* */
19215   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19216   ({
19217     if ((u32) p->value[0] == sw_if_index_from)
19218       {
19219         sw_if_from_name = (u8 *)(p->key);
19220         if (sw_if_to_name)
19221           break;
19222       }
19223     if ((u32) p->value[0] == sw_if_index_to)
19224       {
19225         sw_if_to_name = (u8 *)(p->key);
19226         if (sw_if_from_name)
19227           break;
19228       }
19229   }));
19230   /* *INDENT-ON* */
19231   print (vam->ofp, "%20s => %20s (%s) %s",
19232          sw_if_from_name, sw_if_to_name, states[mp->state],
19233          mp->is_l2 ? "l2" : "device");
19234 }
19235
19236 static void
19237   vl_api_sw_interface_span_details_t_handler_json
19238   (vl_api_sw_interface_span_details_t * mp)
19239 {
19240   vat_main_t *vam = &vat_main;
19241   vat_json_node_t *node = NULL;
19242   u8 *sw_if_from_name = 0;
19243   u8 *sw_if_to_name = 0;
19244   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19245   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19246   hash_pair_t *p;
19247
19248   /* *INDENT-OFF* */
19249   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19250   ({
19251     if ((u32) p->value[0] == sw_if_index_from)
19252       {
19253         sw_if_from_name = (u8 *)(p->key);
19254         if (sw_if_to_name)
19255           break;
19256       }
19257     if ((u32) p->value[0] == sw_if_index_to)
19258       {
19259         sw_if_to_name = (u8 *)(p->key);
19260         if (sw_if_from_name)
19261           break;
19262       }
19263   }));
19264   /* *INDENT-ON* */
19265
19266   if (VAT_JSON_ARRAY != vam->json_tree.type)
19267     {
19268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19269       vat_json_init_array (&vam->json_tree);
19270     }
19271   node = vat_json_array_add (&vam->json_tree);
19272
19273   vat_json_init_object (node);
19274   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19275   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19276   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19277   if (0 != sw_if_to_name)
19278     {
19279       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19280     }
19281   vat_json_object_add_uint (node, "state", mp->state);
19282   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19283 }
19284
19285 static int
19286 api_sw_interface_span_dump (vat_main_t * vam)
19287 {
19288   unformat_input_t *input = vam->input;
19289   vl_api_sw_interface_span_dump_t *mp;
19290   vl_api_control_ping_t *mp_ping;
19291   u8 is_l2 = 0;
19292   int ret;
19293
19294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19295     {
19296       if (unformat (input, "l2"))
19297         is_l2 = 1;
19298       else
19299         break;
19300     }
19301
19302   M (SW_INTERFACE_SPAN_DUMP, mp);
19303   mp->is_l2 = is_l2;
19304   S (mp);
19305
19306   /* Use a control ping for synchronization */
19307   MPING (CONTROL_PING, mp_ping);
19308   S (mp_ping);
19309
19310   W (ret);
19311   return ret;
19312 }
19313
19314 int
19315 api_pg_create_interface (vat_main_t * vam)
19316 {
19317   unformat_input_t *input = vam->input;
19318   vl_api_pg_create_interface_t *mp;
19319
19320   u32 if_id = ~0, gso_size = 0;
19321   u8 gso_enabled = 0;
19322   int ret;
19323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19324     {
19325       if (unformat (input, "if_id %d", &if_id))
19326         ;
19327       else if (unformat (input, "gso-enabled"))
19328         {
19329           gso_enabled = 1;
19330           if (unformat (input, "gso-size %u", &gso_size))
19331             ;
19332           else
19333             {
19334               errmsg ("missing gso-size");
19335               return -99;
19336             }
19337         }
19338       else
19339         break;
19340     }
19341   if (if_id == ~0)
19342     {
19343       errmsg ("missing pg interface index");
19344       return -99;
19345     }
19346
19347   /* Construct the API message */
19348   M (PG_CREATE_INTERFACE, mp);
19349   mp->context = 0;
19350   mp->interface_id = ntohl (if_id);
19351   mp->gso_enabled = gso_enabled;
19352
19353   S (mp);
19354   W (ret);
19355   return ret;
19356 }
19357
19358 int
19359 api_pg_capture (vat_main_t * vam)
19360 {
19361   unformat_input_t *input = vam->input;
19362   vl_api_pg_capture_t *mp;
19363
19364   u32 if_id = ~0;
19365   u8 enable = 1;
19366   u32 count = 1;
19367   u8 pcap_file_set = 0;
19368   u8 *pcap_file = 0;
19369   int ret;
19370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19371     {
19372       if (unformat (input, "if_id %d", &if_id))
19373         ;
19374       else if (unformat (input, "pcap %s", &pcap_file))
19375         pcap_file_set = 1;
19376       else if (unformat (input, "count %d", &count))
19377         ;
19378       else if (unformat (input, "disable"))
19379         enable = 0;
19380       else
19381         break;
19382     }
19383   if (if_id == ~0)
19384     {
19385       errmsg ("missing pg interface index");
19386       return -99;
19387     }
19388   if (pcap_file_set > 0)
19389     {
19390       if (vec_len (pcap_file) > 255)
19391         {
19392           errmsg ("pcap file name is too long");
19393           return -99;
19394         }
19395     }
19396
19397   u32 name_len = vec_len (pcap_file);
19398   /* Construct the API message */
19399   M (PG_CAPTURE, mp);
19400   mp->context = 0;
19401   mp->interface_id = ntohl (if_id);
19402   mp->is_enabled = enable;
19403   mp->count = ntohl (count);
19404   mp->pcap_name_length = ntohl (name_len);
19405   if (pcap_file_set != 0)
19406     {
19407       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19408     }
19409   vec_free (pcap_file);
19410
19411   S (mp);
19412   W (ret);
19413   return ret;
19414 }
19415
19416 int
19417 api_pg_enable_disable (vat_main_t * vam)
19418 {
19419   unformat_input_t *input = vam->input;
19420   vl_api_pg_enable_disable_t *mp;
19421
19422   u8 enable = 1;
19423   u8 stream_name_set = 0;
19424   u8 *stream_name = 0;
19425   int ret;
19426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19427     {
19428       if (unformat (input, "stream %s", &stream_name))
19429         stream_name_set = 1;
19430       else if (unformat (input, "disable"))
19431         enable = 0;
19432       else
19433         break;
19434     }
19435
19436   if (stream_name_set > 0)
19437     {
19438       if (vec_len (stream_name) > 255)
19439         {
19440           errmsg ("stream name too long");
19441           return -99;
19442         }
19443     }
19444
19445   u32 name_len = vec_len (stream_name);
19446   /* Construct the API message */
19447   M (PG_ENABLE_DISABLE, mp);
19448   mp->context = 0;
19449   mp->is_enabled = enable;
19450   if (stream_name_set != 0)
19451     {
19452       mp->stream_name_length = ntohl (name_len);
19453       clib_memcpy (mp->stream_name, stream_name, name_len);
19454     }
19455   vec_free (stream_name);
19456
19457   S (mp);
19458   W (ret);
19459   return ret;
19460 }
19461
19462 int
19463 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19464 {
19465   unformat_input_t *input = vam->input;
19466   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19467
19468   u16 *low_ports = 0;
19469   u16 *high_ports = 0;
19470   u16 this_low;
19471   u16 this_hi;
19472   vl_api_prefix_t prefix;
19473   u32 tmp, tmp2;
19474   u8 prefix_set = 0;
19475   u32 vrf_id = ~0;
19476   u8 is_add = 1;
19477   int ret;
19478
19479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19480     {
19481       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19482         prefix_set = 1;
19483       else if (unformat (input, "vrf %d", &vrf_id))
19484         ;
19485       else if (unformat (input, "del"))
19486         is_add = 0;
19487       else if (unformat (input, "port %d", &tmp))
19488         {
19489           if (tmp == 0 || tmp > 65535)
19490             {
19491               errmsg ("port %d out of range", tmp);
19492               return -99;
19493             }
19494           this_low = tmp;
19495           this_hi = this_low + 1;
19496           vec_add1 (low_ports, this_low);
19497           vec_add1 (high_ports, this_hi);
19498         }
19499       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19500         {
19501           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19502             {
19503               errmsg ("incorrect range parameters");
19504               return -99;
19505             }
19506           this_low = tmp;
19507           /* Note: in debug CLI +1 is added to high before
19508              passing to real fn that does "the work"
19509              (ip_source_and_port_range_check_add_del).
19510              This fn is a wrapper around the binary API fn a
19511              control plane will call, which expects this increment
19512              to have occurred. Hence letting the binary API control
19513              plane fn do the increment for consistency between VAT
19514              and other control planes.
19515            */
19516           this_hi = tmp2;
19517           vec_add1 (low_ports, this_low);
19518           vec_add1 (high_ports, this_hi);
19519         }
19520       else
19521         break;
19522     }
19523
19524   if (prefix_set == 0)
19525     {
19526       errmsg ("<address>/<mask> not specified");
19527       return -99;
19528     }
19529
19530   if (vrf_id == ~0)
19531     {
19532       errmsg ("VRF ID required, not specified");
19533       return -99;
19534     }
19535
19536   if (vrf_id == 0)
19537     {
19538       errmsg
19539         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19540       return -99;
19541     }
19542
19543   if (vec_len (low_ports) == 0)
19544     {
19545       errmsg ("At least one port or port range required");
19546       return -99;
19547     }
19548
19549   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19550
19551   mp->is_add = is_add;
19552
19553   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19554
19555   mp->number_of_ranges = vec_len (low_ports);
19556
19557   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19558   vec_free (low_ports);
19559
19560   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19561   vec_free (high_ports);
19562
19563   mp->vrf_id = ntohl (vrf_id);
19564
19565   S (mp);
19566   W (ret);
19567   return ret;
19568 }
19569
19570 int
19571 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19572 {
19573   unformat_input_t *input = vam->input;
19574   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19575   u32 sw_if_index = ~0;
19576   int vrf_set = 0;
19577   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19578   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19579   u8 is_add = 1;
19580   int ret;
19581
19582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19583     {
19584       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19585         ;
19586       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19587         ;
19588       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19589         vrf_set = 1;
19590       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19591         vrf_set = 1;
19592       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19593         vrf_set = 1;
19594       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19595         vrf_set = 1;
19596       else if (unformat (input, "del"))
19597         is_add = 0;
19598       else
19599         break;
19600     }
19601
19602   if (sw_if_index == ~0)
19603     {
19604       errmsg ("Interface required but not specified");
19605       return -99;
19606     }
19607
19608   if (vrf_set == 0)
19609     {
19610       errmsg ("VRF ID required but not specified");
19611       return -99;
19612     }
19613
19614   if (tcp_out_vrf_id == 0
19615       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19616     {
19617       errmsg
19618         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19619       return -99;
19620     }
19621
19622   /* Construct the API message */
19623   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19624
19625   mp->sw_if_index = ntohl (sw_if_index);
19626   mp->is_add = is_add;
19627   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19628   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19629   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19630   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19631
19632   /* send it... */
19633   S (mp);
19634
19635   /* Wait for a reply... */
19636   W (ret);
19637   return ret;
19638 }
19639
19640 static int
19641 api_set_punt (vat_main_t * vam)
19642 {
19643   unformat_input_t *i = vam->input;
19644   vl_api_address_family_t af;
19645   vl_api_set_punt_t *mp;
19646   u32 protocol = ~0;
19647   u32 port = ~0;
19648   int is_add = 1;
19649   int ret;
19650
19651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19652     {
19653       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19654         ;
19655       else if (unformat (i, "protocol %d", &protocol))
19656         ;
19657       else if (unformat (i, "port %d", &port))
19658         ;
19659       else if (unformat (i, "del"))
19660         is_add = 0;
19661       else
19662         {
19663           clib_warning ("parse error '%U'", format_unformat_error, i);
19664           return -99;
19665         }
19666     }
19667
19668   M (SET_PUNT, mp);
19669
19670   mp->is_add = (u8) is_add;
19671   mp->punt.type = PUNT_API_TYPE_L4;
19672   mp->punt.punt.l4.af = af;
19673   mp->punt.punt.l4.protocol = (u8) protocol;
19674   mp->punt.punt.l4.port = htons ((u16) port);
19675
19676   S (mp);
19677   W (ret);
19678   return ret;
19679 }
19680
19681 static int
19682 api_delete_subif (vat_main_t * vam)
19683 {
19684   unformat_input_t *i = vam->input;
19685   vl_api_delete_subif_t *mp;
19686   u32 sw_if_index = ~0;
19687   int ret;
19688
19689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19690     {
19691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19692         ;
19693       if (unformat (i, "sw_if_index %d", &sw_if_index))
19694         ;
19695       else
19696         break;
19697     }
19698
19699   if (sw_if_index == ~0)
19700     {
19701       errmsg ("missing sw_if_index");
19702       return -99;
19703     }
19704
19705   /* Construct the API message */
19706   M (DELETE_SUBIF, mp);
19707   mp->sw_if_index = ntohl (sw_if_index);
19708
19709   S (mp);
19710   W (ret);
19711   return ret;
19712 }
19713
19714 #define foreach_pbb_vtr_op      \
19715 _("disable",  L2_VTR_DISABLED)  \
19716 _("pop",  L2_VTR_POP_2)         \
19717 _("push",  L2_VTR_PUSH_2)
19718
19719 static int
19720 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19721 {
19722   unformat_input_t *i = vam->input;
19723   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19724   u32 sw_if_index = ~0, vtr_op = ~0;
19725   u16 outer_tag = ~0;
19726   u8 dmac[6], smac[6];
19727   u8 dmac_set = 0, smac_set = 0;
19728   u16 vlanid = 0;
19729   u32 sid = ~0;
19730   u32 tmp;
19731   int ret;
19732
19733   /* Shut up coverity */
19734   clib_memset (dmac, 0, sizeof (dmac));
19735   clib_memset (smac, 0, sizeof (smac));
19736
19737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19738     {
19739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19740         ;
19741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19742         ;
19743       else if (unformat (i, "vtr_op %d", &vtr_op))
19744         ;
19745 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19746       foreach_pbb_vtr_op
19747 #undef _
19748         else if (unformat (i, "translate_pbb_stag"))
19749         {
19750           if (unformat (i, "%d", &tmp))
19751             {
19752               vtr_op = L2_VTR_TRANSLATE_2_1;
19753               outer_tag = tmp;
19754             }
19755           else
19756             {
19757               errmsg
19758                 ("translate_pbb_stag operation requires outer tag definition");
19759               return -99;
19760             }
19761         }
19762       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19763         dmac_set++;
19764       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19765         smac_set++;
19766       else if (unformat (i, "sid %d", &sid))
19767         ;
19768       else if (unformat (i, "vlanid %d", &tmp))
19769         vlanid = tmp;
19770       else
19771         {
19772           clib_warning ("parse error '%U'", format_unformat_error, i);
19773           return -99;
19774         }
19775     }
19776
19777   if ((sw_if_index == ~0) || (vtr_op == ~0))
19778     {
19779       errmsg ("missing sw_if_index or vtr operation");
19780       return -99;
19781     }
19782   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19783       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19784     {
19785       errmsg
19786         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19787       return -99;
19788     }
19789
19790   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19791   mp->sw_if_index = ntohl (sw_if_index);
19792   mp->vtr_op = ntohl (vtr_op);
19793   mp->outer_tag = ntohs (outer_tag);
19794   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19795   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19796   mp->b_vlanid = ntohs (vlanid);
19797   mp->i_sid = ntohl (sid);
19798
19799   S (mp);
19800   W (ret);
19801   return ret;
19802 }
19803
19804 static int
19805 api_flow_classify_set_interface (vat_main_t * vam)
19806 {
19807   unformat_input_t *i = vam->input;
19808   vl_api_flow_classify_set_interface_t *mp;
19809   u32 sw_if_index;
19810   int sw_if_index_set;
19811   u32 ip4_table_index = ~0;
19812   u32 ip6_table_index = ~0;
19813   u8 is_add = 1;
19814   int ret;
19815
19816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19817     {
19818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19819         sw_if_index_set = 1;
19820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19821         sw_if_index_set = 1;
19822       else if (unformat (i, "del"))
19823         is_add = 0;
19824       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19825         ;
19826       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19827         ;
19828       else
19829         {
19830           clib_warning ("parse error '%U'", format_unformat_error, i);
19831           return -99;
19832         }
19833     }
19834
19835   if (sw_if_index_set == 0)
19836     {
19837       errmsg ("missing interface name or sw_if_index");
19838       return -99;
19839     }
19840
19841   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19842
19843   mp->sw_if_index = ntohl (sw_if_index);
19844   mp->ip4_table_index = ntohl (ip4_table_index);
19845   mp->ip6_table_index = ntohl (ip6_table_index);
19846   mp->is_add = is_add;
19847
19848   S (mp);
19849   W (ret);
19850   return ret;
19851 }
19852
19853 static int
19854 api_flow_classify_dump (vat_main_t * vam)
19855 {
19856   unformat_input_t *i = vam->input;
19857   vl_api_flow_classify_dump_t *mp;
19858   vl_api_control_ping_t *mp_ping;
19859   u8 type = FLOW_CLASSIFY_N_TABLES;
19860   int ret;
19861
19862   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19863     ;
19864   else
19865     {
19866       errmsg ("classify table type must be specified");
19867       return -99;
19868     }
19869
19870   if (!vam->json_output)
19871     {
19872       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19873     }
19874
19875   M (FLOW_CLASSIFY_DUMP, mp);
19876   mp->type = type;
19877   /* send it... */
19878   S (mp);
19879
19880   /* Use a control ping for synchronization */
19881   MPING (CONTROL_PING, mp_ping);
19882   S (mp_ping);
19883
19884   /* Wait for a reply... */
19885   W (ret);
19886   return ret;
19887 }
19888
19889 static int
19890 api_feature_enable_disable (vat_main_t * vam)
19891 {
19892   unformat_input_t *i = vam->input;
19893   vl_api_feature_enable_disable_t *mp;
19894   u8 *arc_name = 0;
19895   u8 *feature_name = 0;
19896   u32 sw_if_index = ~0;
19897   u8 enable = 1;
19898   int ret;
19899
19900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19901     {
19902       if (unformat (i, "arc_name %s", &arc_name))
19903         ;
19904       else if (unformat (i, "feature_name %s", &feature_name))
19905         ;
19906       else
19907         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19908         ;
19909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19910         ;
19911       else if (unformat (i, "disable"))
19912         enable = 0;
19913       else
19914         break;
19915     }
19916
19917   if (arc_name == 0)
19918     {
19919       errmsg ("missing arc name");
19920       return -99;
19921     }
19922   if (vec_len (arc_name) > 63)
19923     {
19924       errmsg ("arc name too long");
19925     }
19926
19927   if (feature_name == 0)
19928     {
19929       errmsg ("missing feature name");
19930       return -99;
19931     }
19932   if (vec_len (feature_name) > 63)
19933     {
19934       errmsg ("feature name too long");
19935     }
19936
19937   if (sw_if_index == ~0)
19938     {
19939       errmsg ("missing interface name or sw_if_index");
19940       return -99;
19941     }
19942
19943   /* Construct the API message */
19944   M (FEATURE_ENABLE_DISABLE, mp);
19945   mp->sw_if_index = ntohl (sw_if_index);
19946   mp->enable = enable;
19947   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19948   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19949   vec_free (arc_name);
19950   vec_free (feature_name);
19951
19952   S (mp);
19953   W (ret);
19954   return ret;
19955 }
19956
19957 static int
19958 api_sw_interface_tag_add_del (vat_main_t * vam)
19959 {
19960   unformat_input_t *i = vam->input;
19961   vl_api_sw_interface_tag_add_del_t *mp;
19962   u32 sw_if_index = ~0;
19963   u8 *tag = 0;
19964   u8 enable = 1;
19965   int ret;
19966
19967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19968     {
19969       if (unformat (i, "tag %s", &tag))
19970         ;
19971       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19972         ;
19973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19974         ;
19975       else if (unformat (i, "del"))
19976         enable = 0;
19977       else
19978         break;
19979     }
19980
19981   if (sw_if_index == ~0)
19982     {
19983       errmsg ("missing interface name or sw_if_index");
19984       return -99;
19985     }
19986
19987   if (enable && (tag == 0))
19988     {
19989       errmsg ("no tag specified");
19990       return -99;
19991     }
19992
19993   /* Construct the API message */
19994   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19995   mp->sw_if_index = ntohl (sw_if_index);
19996   mp->is_add = enable;
19997   if (enable)
19998     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19999   vec_free (tag);
20000
20001   S (mp);
20002   W (ret);
20003   return ret;
20004 }
20005
20006 static int
20007 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20008 {
20009   unformat_input_t *i = vam->input;
20010   vl_api_mac_address_t mac = { 0 };
20011   vl_api_sw_interface_add_del_mac_address_t *mp;
20012   u32 sw_if_index = ~0;
20013   u8 is_add = 1;
20014   u8 mac_set = 0;
20015   int ret;
20016
20017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20018     {
20019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20020         ;
20021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20022         ;
20023       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20024         mac_set++;
20025       else if (unformat (i, "del"))
20026         is_add = 0;
20027       else
20028         break;
20029     }
20030
20031   if (sw_if_index == ~0)
20032     {
20033       errmsg ("missing interface name or sw_if_index");
20034       return -99;
20035     }
20036
20037   if (!mac_set)
20038     {
20039       errmsg ("missing MAC address");
20040       return -99;
20041     }
20042
20043   /* Construct the API message */
20044   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20045   mp->sw_if_index = ntohl (sw_if_index);
20046   mp->is_add = is_add;
20047   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20048
20049   S (mp);
20050   W (ret);
20051   return ret;
20052 }
20053
20054 static void vl_api_l2_xconnect_details_t_handler
20055   (vl_api_l2_xconnect_details_t * mp)
20056 {
20057   vat_main_t *vam = &vat_main;
20058
20059   print (vam->ofp, "%15d%15d",
20060          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20061 }
20062
20063 static void vl_api_l2_xconnect_details_t_handler_json
20064   (vl_api_l2_xconnect_details_t * mp)
20065 {
20066   vat_main_t *vam = &vat_main;
20067   vat_json_node_t *node = NULL;
20068
20069   if (VAT_JSON_ARRAY != vam->json_tree.type)
20070     {
20071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20072       vat_json_init_array (&vam->json_tree);
20073     }
20074   node = vat_json_array_add (&vam->json_tree);
20075
20076   vat_json_init_object (node);
20077   vat_json_object_add_uint (node, "rx_sw_if_index",
20078                             ntohl (mp->rx_sw_if_index));
20079   vat_json_object_add_uint (node, "tx_sw_if_index",
20080                             ntohl (mp->tx_sw_if_index));
20081 }
20082
20083 static int
20084 api_l2_xconnect_dump (vat_main_t * vam)
20085 {
20086   vl_api_l2_xconnect_dump_t *mp;
20087   vl_api_control_ping_t *mp_ping;
20088   int ret;
20089
20090   if (!vam->json_output)
20091     {
20092       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20093     }
20094
20095   M (L2_XCONNECT_DUMP, mp);
20096
20097   S (mp);
20098
20099   /* Use a control ping for synchronization */
20100   MPING (CONTROL_PING, mp_ping);
20101   S (mp_ping);
20102
20103   W (ret);
20104   return ret;
20105 }
20106
20107 static int
20108 api_hw_interface_set_mtu (vat_main_t * vam)
20109 {
20110   unformat_input_t *i = vam->input;
20111   vl_api_hw_interface_set_mtu_t *mp;
20112   u32 sw_if_index = ~0;
20113   u32 mtu = 0;
20114   int ret;
20115
20116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20117     {
20118       if (unformat (i, "mtu %d", &mtu))
20119         ;
20120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20121         ;
20122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20123         ;
20124       else
20125         break;
20126     }
20127
20128   if (sw_if_index == ~0)
20129     {
20130       errmsg ("missing interface name or sw_if_index");
20131       return -99;
20132     }
20133
20134   if (mtu == 0)
20135     {
20136       errmsg ("no mtu specified");
20137       return -99;
20138     }
20139
20140   /* Construct the API message */
20141   M (HW_INTERFACE_SET_MTU, mp);
20142   mp->sw_if_index = ntohl (sw_if_index);
20143   mp->mtu = ntohs ((u16) mtu);
20144
20145   S (mp);
20146   W (ret);
20147   return ret;
20148 }
20149
20150 static int
20151 api_p2p_ethernet_add (vat_main_t * vam)
20152 {
20153   unformat_input_t *i = vam->input;
20154   vl_api_p2p_ethernet_add_t *mp;
20155   u32 parent_if_index = ~0;
20156   u32 sub_id = ~0;
20157   u8 remote_mac[6];
20158   u8 mac_set = 0;
20159   int ret;
20160
20161   clib_memset (remote_mac, 0, sizeof (remote_mac));
20162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20163     {
20164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20165         ;
20166       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20167         ;
20168       else
20169         if (unformat
20170             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20171         mac_set++;
20172       else if (unformat (i, "sub_id %d", &sub_id))
20173         ;
20174       else
20175         {
20176           clib_warning ("parse error '%U'", format_unformat_error, i);
20177           return -99;
20178         }
20179     }
20180
20181   if (parent_if_index == ~0)
20182     {
20183       errmsg ("missing interface name or sw_if_index");
20184       return -99;
20185     }
20186   if (mac_set == 0)
20187     {
20188       errmsg ("missing remote mac address");
20189       return -99;
20190     }
20191   if (sub_id == ~0)
20192     {
20193       errmsg ("missing sub-interface id");
20194       return -99;
20195     }
20196
20197   M (P2P_ETHERNET_ADD, mp);
20198   mp->parent_if_index = ntohl (parent_if_index);
20199   mp->subif_id = ntohl (sub_id);
20200   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20201
20202   S (mp);
20203   W (ret);
20204   return ret;
20205 }
20206
20207 static int
20208 api_p2p_ethernet_del (vat_main_t * vam)
20209 {
20210   unformat_input_t *i = vam->input;
20211   vl_api_p2p_ethernet_del_t *mp;
20212   u32 parent_if_index = ~0;
20213   u8 remote_mac[6];
20214   u8 mac_set = 0;
20215   int ret;
20216
20217   clib_memset (remote_mac, 0, sizeof (remote_mac));
20218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20219     {
20220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20221         ;
20222       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20223         ;
20224       else
20225         if (unformat
20226             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20227         mac_set++;
20228       else
20229         {
20230           clib_warning ("parse error '%U'", format_unformat_error, i);
20231           return -99;
20232         }
20233     }
20234
20235   if (parent_if_index == ~0)
20236     {
20237       errmsg ("missing interface name or sw_if_index");
20238       return -99;
20239     }
20240   if (mac_set == 0)
20241     {
20242       errmsg ("missing remote mac address");
20243       return -99;
20244     }
20245
20246   M (P2P_ETHERNET_DEL, mp);
20247   mp->parent_if_index = ntohl (parent_if_index);
20248   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20249
20250   S (mp);
20251   W (ret);
20252   return ret;
20253 }
20254
20255 static int
20256 api_lldp_config (vat_main_t * vam)
20257 {
20258   unformat_input_t *i = vam->input;
20259   vl_api_lldp_config_t *mp;
20260   int tx_hold = 0;
20261   int tx_interval = 0;
20262   u8 *sys_name = NULL;
20263   int ret;
20264
20265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20266     {
20267       if (unformat (i, "system-name %s", &sys_name))
20268         ;
20269       else if (unformat (i, "tx-hold %d", &tx_hold))
20270         ;
20271       else if (unformat (i, "tx-interval %d", &tx_interval))
20272         ;
20273       else
20274         {
20275           clib_warning ("parse error '%U'", format_unformat_error, i);
20276           return -99;
20277         }
20278     }
20279
20280   vec_add1 (sys_name, 0);
20281
20282   M (LLDP_CONFIG, mp);
20283   mp->tx_hold = htonl (tx_hold);
20284   mp->tx_interval = htonl (tx_interval);
20285   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20286   vec_free (sys_name);
20287
20288   S (mp);
20289   W (ret);
20290   return ret;
20291 }
20292
20293 static int
20294 api_sw_interface_set_lldp (vat_main_t * vam)
20295 {
20296   unformat_input_t *i = vam->input;
20297   vl_api_sw_interface_set_lldp_t *mp;
20298   u32 sw_if_index = ~0;
20299   u32 enable = 1;
20300   u8 *port_desc = NULL, *mgmt_oid = NULL;
20301   ip4_address_t ip4_addr;
20302   ip6_address_t ip6_addr;
20303   int ret;
20304
20305   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20306   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20307
20308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20309     {
20310       if (unformat (i, "disable"))
20311         enable = 0;
20312       else
20313         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20314         ;
20315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20316         ;
20317       else if (unformat (i, "port-desc %s", &port_desc))
20318         ;
20319       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20320         ;
20321       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20322         ;
20323       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20324         ;
20325       else
20326         break;
20327     }
20328
20329   if (sw_if_index == ~0)
20330     {
20331       errmsg ("missing interface name or sw_if_index");
20332       return -99;
20333     }
20334
20335   /* Construct the API message */
20336   vec_add1 (port_desc, 0);
20337   vec_add1 (mgmt_oid, 0);
20338   M (SW_INTERFACE_SET_LLDP, mp);
20339   mp->sw_if_index = ntohl (sw_if_index);
20340   mp->enable = enable;
20341   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20342   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20343   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20344   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20345   vec_free (port_desc);
20346   vec_free (mgmt_oid);
20347
20348   S (mp);
20349   W (ret);
20350   return ret;
20351 }
20352
20353 static int
20354 api_tcp_configure_src_addresses (vat_main_t * vam)
20355 {
20356   vl_api_tcp_configure_src_addresses_t *mp;
20357   unformat_input_t *i = vam->input;
20358   ip4_address_t v4first, v4last;
20359   ip6_address_t v6first, v6last;
20360   u8 range_set = 0;
20361   u32 vrf_id = 0;
20362   int ret;
20363
20364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20365     {
20366       if (unformat (i, "%U - %U",
20367                     unformat_ip4_address, &v4first,
20368                     unformat_ip4_address, &v4last))
20369         {
20370           if (range_set)
20371             {
20372               errmsg ("one range per message (range already set)");
20373               return -99;
20374             }
20375           range_set = 1;
20376         }
20377       else if (unformat (i, "%U - %U",
20378                          unformat_ip6_address, &v6first,
20379                          unformat_ip6_address, &v6last))
20380         {
20381           if (range_set)
20382             {
20383               errmsg ("one range per message (range already set)");
20384               return -99;
20385             }
20386           range_set = 2;
20387         }
20388       else if (unformat (i, "vrf %d", &vrf_id))
20389         ;
20390       else
20391         break;
20392     }
20393
20394   if (range_set == 0)
20395     {
20396       errmsg ("address range not set");
20397       return -99;
20398     }
20399
20400   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20401   mp->vrf_id = ntohl (vrf_id);
20402   /* ipv6? */
20403   if (range_set == 2)
20404     {
20405       mp->is_ipv6 = 1;
20406       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20407       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20408     }
20409   else
20410     {
20411       mp->is_ipv6 = 0;
20412       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20413       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20414     }
20415   S (mp);
20416   W (ret);
20417   return ret;
20418 }
20419
20420 static void vl_api_app_namespace_add_del_reply_t_handler
20421   (vl_api_app_namespace_add_del_reply_t * mp)
20422 {
20423   vat_main_t *vam = &vat_main;
20424   i32 retval = ntohl (mp->retval);
20425   if (vam->async_mode)
20426     {
20427       vam->async_errors += (retval < 0);
20428     }
20429   else
20430     {
20431       vam->retval = retval;
20432       if (retval == 0)
20433         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20434       vam->result_ready = 1;
20435     }
20436 }
20437
20438 static void vl_api_app_namespace_add_del_reply_t_handler_json
20439   (vl_api_app_namespace_add_del_reply_t * mp)
20440 {
20441   vat_main_t *vam = &vat_main;
20442   vat_json_node_t node;
20443
20444   vat_json_init_object (&node);
20445   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20446   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20447
20448   vat_json_print (vam->ofp, &node);
20449   vat_json_free (&node);
20450
20451   vam->retval = ntohl (mp->retval);
20452   vam->result_ready = 1;
20453 }
20454
20455 static int
20456 api_app_namespace_add_del (vat_main_t * vam)
20457 {
20458   vl_api_app_namespace_add_del_t *mp;
20459   unformat_input_t *i = vam->input;
20460   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20461   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20462   u64 secret;
20463   int ret;
20464
20465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20466     {
20467       if (unformat (i, "id %_%v%_", &ns_id))
20468         ;
20469       else if (unformat (i, "secret %lu", &secret))
20470         secret_set = 1;
20471       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20472         sw_if_index_set = 1;
20473       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20474         ;
20475       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20476         ;
20477       else
20478         break;
20479     }
20480   if (!ns_id || !secret_set || !sw_if_index_set)
20481     {
20482       errmsg ("namespace id, secret and sw_if_index must be set");
20483       return -99;
20484     }
20485   if (vec_len (ns_id) > 64)
20486     {
20487       errmsg ("namespace id too long");
20488       return -99;
20489     }
20490   M (APP_NAMESPACE_ADD_DEL, mp);
20491
20492   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20493   mp->namespace_id_len = vec_len (ns_id);
20494   mp->secret = clib_host_to_net_u64 (secret);
20495   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20496   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20497   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20498   vec_free (ns_id);
20499   S (mp);
20500   W (ret);
20501   return ret;
20502 }
20503
20504 static int
20505 api_sock_init_shm (vat_main_t * vam)
20506 {
20507 #if VPP_API_TEST_BUILTIN == 0
20508   unformat_input_t *i = vam->input;
20509   vl_api_shm_elem_config_t *config = 0;
20510   u64 size = 64 << 20;
20511   int rv;
20512
20513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20514     {
20515       if (unformat (i, "size %U", unformat_memory_size, &size))
20516         ;
20517       else
20518         break;
20519     }
20520
20521   /*
20522    * Canned custom ring allocator config.
20523    * Should probably parse all of this
20524    */
20525   vec_validate (config, 6);
20526   config[0].type = VL_API_VLIB_RING;
20527   config[0].size = 256;
20528   config[0].count = 32;
20529
20530   config[1].type = VL_API_VLIB_RING;
20531   config[1].size = 1024;
20532   config[1].count = 16;
20533
20534   config[2].type = VL_API_VLIB_RING;
20535   config[2].size = 4096;
20536   config[2].count = 2;
20537
20538   config[3].type = VL_API_CLIENT_RING;
20539   config[3].size = 256;
20540   config[3].count = 32;
20541
20542   config[4].type = VL_API_CLIENT_RING;
20543   config[4].size = 1024;
20544   config[4].count = 16;
20545
20546   config[5].type = VL_API_CLIENT_RING;
20547   config[5].size = 4096;
20548   config[5].count = 2;
20549
20550   config[6].type = VL_API_QUEUE;
20551   config[6].count = 128;
20552   config[6].size = sizeof (uword);
20553
20554   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20555   if (!rv)
20556     vam->client_index_invalid = 1;
20557   return rv;
20558 #else
20559   return -99;
20560 #endif
20561 }
20562
20563 static void
20564 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20565 {
20566   vat_main_t *vam = &vat_main;
20567
20568   if (mp->is_ip4)
20569     {
20570       print (vam->ofp,
20571              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20572              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20573              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20574              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20575              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20576              clib_net_to_host_u32 (mp->action_index), mp->tag);
20577     }
20578   else
20579     {
20580       print (vam->ofp,
20581              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20582              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20583              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20584              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20585              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20586              clib_net_to_host_u32 (mp->action_index), mp->tag);
20587     }
20588 }
20589
20590 static void
20591 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20592                                              mp)
20593 {
20594   vat_main_t *vam = &vat_main;
20595   vat_json_node_t *node = NULL;
20596   struct in6_addr ip6;
20597   struct in_addr ip4;
20598
20599   if (VAT_JSON_ARRAY != vam->json_tree.type)
20600     {
20601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20602       vat_json_init_array (&vam->json_tree);
20603     }
20604   node = vat_json_array_add (&vam->json_tree);
20605   vat_json_init_object (node);
20606
20607   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20608   vat_json_object_add_uint (node, "appns_index",
20609                             clib_net_to_host_u32 (mp->appns_index));
20610   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20611   vat_json_object_add_uint (node, "scope", mp->scope);
20612   vat_json_object_add_uint (node, "action_index",
20613                             clib_net_to_host_u32 (mp->action_index));
20614   vat_json_object_add_uint (node, "lcl_port",
20615                             clib_net_to_host_u16 (mp->lcl_port));
20616   vat_json_object_add_uint (node, "rmt_port",
20617                             clib_net_to_host_u16 (mp->rmt_port));
20618   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20619   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20620   vat_json_object_add_string_copy (node, "tag", mp->tag);
20621   if (mp->is_ip4)
20622     {
20623       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20624       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20625       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20626       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20627     }
20628   else
20629     {
20630       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20631       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20632       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20633       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20634     }
20635 }
20636
20637 static int
20638 api_session_rule_add_del (vat_main_t * vam)
20639 {
20640   vl_api_session_rule_add_del_t *mp;
20641   unformat_input_t *i = vam->input;
20642   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20643   u32 appns_index = 0, scope = 0;
20644   ip4_address_t lcl_ip4, rmt_ip4;
20645   ip6_address_t lcl_ip6, rmt_ip6;
20646   u8 is_ip4 = 1, conn_set = 0;
20647   u8 is_add = 1, *tag = 0;
20648   int ret;
20649
20650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20651     {
20652       if (unformat (i, "del"))
20653         is_add = 0;
20654       else if (unformat (i, "add"))
20655         ;
20656       else if (unformat (i, "proto tcp"))
20657         proto = 0;
20658       else if (unformat (i, "proto udp"))
20659         proto = 1;
20660       else if (unformat (i, "appns %d", &appns_index))
20661         ;
20662       else if (unformat (i, "scope %d", &scope))
20663         ;
20664       else if (unformat (i, "tag %_%v%_", &tag))
20665         ;
20666       else
20667         if (unformat
20668             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20669              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20670              &rmt_port))
20671         {
20672           is_ip4 = 1;
20673           conn_set = 1;
20674         }
20675       else
20676         if (unformat
20677             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20678              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20679              &rmt_port))
20680         {
20681           is_ip4 = 0;
20682           conn_set = 1;
20683         }
20684       else if (unformat (i, "action %d", &action))
20685         ;
20686       else
20687         break;
20688     }
20689   if (proto == ~0 || !conn_set || action == ~0)
20690     {
20691       errmsg ("transport proto, connection and action must be set");
20692       return -99;
20693     }
20694
20695   if (scope > 3)
20696     {
20697       errmsg ("scope should be 0-3");
20698       return -99;
20699     }
20700
20701   M (SESSION_RULE_ADD_DEL, mp);
20702
20703   mp->is_ip4 = is_ip4;
20704   mp->transport_proto = proto;
20705   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20706   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20707   mp->lcl_plen = lcl_plen;
20708   mp->rmt_plen = rmt_plen;
20709   mp->action_index = clib_host_to_net_u32 (action);
20710   mp->appns_index = clib_host_to_net_u32 (appns_index);
20711   mp->scope = scope;
20712   mp->is_add = is_add;
20713   if (is_ip4)
20714     {
20715       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20716       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20717     }
20718   else
20719     {
20720       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20721       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20722     }
20723   if (tag)
20724     {
20725       clib_memcpy (mp->tag, tag, vec_len (tag));
20726       vec_free (tag);
20727     }
20728
20729   S (mp);
20730   W (ret);
20731   return ret;
20732 }
20733
20734 static int
20735 api_session_rules_dump (vat_main_t * vam)
20736 {
20737   vl_api_session_rules_dump_t *mp;
20738   vl_api_control_ping_t *mp_ping;
20739   int ret;
20740
20741   if (!vam->json_output)
20742     {
20743       print (vam->ofp, "%=20s", "Session Rules");
20744     }
20745
20746   M (SESSION_RULES_DUMP, mp);
20747   /* send it... */
20748   S (mp);
20749
20750   /* Use a control ping for synchronization */
20751   MPING (CONTROL_PING, mp_ping);
20752   S (mp_ping);
20753
20754   /* Wait for a reply... */
20755   W (ret);
20756   return ret;
20757 }
20758
20759 static int
20760 api_ip_container_proxy_add_del (vat_main_t * vam)
20761 {
20762   vl_api_ip_container_proxy_add_del_t *mp;
20763   unformat_input_t *i = vam->input;
20764   u32 sw_if_index = ~0;
20765   vl_api_prefix_t pfx = { };
20766   u8 is_add = 1;
20767   int ret;
20768
20769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20770     {
20771       if (unformat (i, "del"))
20772         is_add = 0;
20773       else if (unformat (i, "add"))
20774         ;
20775       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20776         ;
20777       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20778         ;
20779       else
20780         break;
20781     }
20782   if (sw_if_index == ~0 || pfx.len == 0)
20783     {
20784       errmsg ("address and sw_if_index must be set");
20785       return -99;
20786     }
20787
20788   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20789
20790   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20791   mp->is_add = is_add;
20792   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20793
20794   S (mp);
20795   W (ret);
20796   return ret;
20797 }
20798
20799 static int
20800 api_qos_record_enable_disable (vat_main_t * vam)
20801 {
20802   unformat_input_t *i = vam->input;
20803   vl_api_qos_record_enable_disable_t *mp;
20804   u32 sw_if_index, qs = 0xff;
20805   u8 sw_if_index_set = 0;
20806   u8 enable = 1;
20807   int ret;
20808
20809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20810     {
20811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20812         sw_if_index_set = 1;
20813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20814         sw_if_index_set = 1;
20815       else if (unformat (i, "%U", unformat_qos_source, &qs))
20816         ;
20817       else if (unformat (i, "disable"))
20818         enable = 0;
20819       else
20820         {
20821           clib_warning ("parse error '%U'", format_unformat_error, i);
20822           return -99;
20823         }
20824     }
20825
20826   if (sw_if_index_set == 0)
20827     {
20828       errmsg ("missing interface name or sw_if_index");
20829       return -99;
20830     }
20831   if (qs == 0xff)
20832     {
20833       errmsg ("input location must be specified");
20834       return -99;
20835     }
20836
20837   M (QOS_RECORD_ENABLE_DISABLE, mp);
20838
20839   mp->record.sw_if_index = ntohl (sw_if_index);
20840   mp->record.input_source = qs;
20841   mp->enable = enable;
20842
20843   S (mp);
20844   W (ret);
20845   return ret;
20846 }
20847
20848
20849 static int
20850 q_or_quit (vat_main_t * vam)
20851 {
20852 #if VPP_API_TEST_BUILTIN == 0
20853   longjmp (vam->jump_buf, 1);
20854 #endif
20855   return 0;                     /* not so much */
20856 }
20857
20858 static int
20859 q (vat_main_t * vam)
20860 {
20861   return q_or_quit (vam);
20862 }
20863
20864 static int
20865 quit (vat_main_t * vam)
20866 {
20867   return q_or_quit (vam);
20868 }
20869
20870 static int
20871 comment (vat_main_t * vam)
20872 {
20873   return 0;
20874 }
20875
20876 static int
20877 elog_save (vat_main_t * vam)
20878 {
20879 #if VPP_API_TEST_BUILTIN == 0
20880   elog_main_t *em = &vam->elog_main;
20881   unformat_input_t *i = vam->input;
20882   char *file, *chroot_file;
20883   clib_error_t *error;
20884
20885   if (!unformat (i, "%s", &file))
20886     {
20887       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20888       return 0;
20889     }
20890
20891   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20892   if (strstr (file, "..") || index (file, '/'))
20893     {
20894       errmsg ("illegal characters in filename '%s'", file);
20895       return 0;
20896     }
20897
20898   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20899
20900   vec_free (file);
20901
20902   errmsg ("Saving %wd of %wd events to %s",
20903           elog_n_events_in_buffer (em),
20904           elog_buffer_capacity (em), chroot_file);
20905
20906   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20907   vec_free (chroot_file);
20908
20909   if (error)
20910     clib_error_report (error);
20911 #else
20912   errmsg ("Use the vpp event loger...");
20913 #endif
20914
20915   return 0;
20916 }
20917
20918 static int
20919 elog_setup (vat_main_t * vam)
20920 {
20921 #if VPP_API_TEST_BUILTIN == 0
20922   elog_main_t *em = &vam->elog_main;
20923   unformat_input_t *i = vam->input;
20924   u32 nevents = 128 << 10;
20925
20926   (void) unformat (i, "nevents %d", &nevents);
20927
20928   elog_init (em, nevents);
20929   vl_api_set_elog_main (em);
20930   vl_api_set_elog_trace_api_messages (1);
20931   errmsg ("Event logger initialized with %u events", nevents);
20932 #else
20933   errmsg ("Use the vpp event loger...");
20934 #endif
20935   return 0;
20936 }
20937
20938 static int
20939 elog_enable (vat_main_t * vam)
20940 {
20941 #if VPP_API_TEST_BUILTIN == 0
20942   elog_main_t *em = &vam->elog_main;
20943
20944   elog_enable_disable (em, 1 /* enable */ );
20945   vl_api_set_elog_trace_api_messages (1);
20946   errmsg ("Event logger enabled...");
20947 #else
20948   errmsg ("Use the vpp event loger...");
20949 #endif
20950   return 0;
20951 }
20952
20953 static int
20954 elog_disable (vat_main_t * vam)
20955 {
20956 #if VPP_API_TEST_BUILTIN == 0
20957   elog_main_t *em = &vam->elog_main;
20958
20959   elog_enable_disable (em, 0 /* enable */ );
20960   vl_api_set_elog_trace_api_messages (1);
20961   errmsg ("Event logger disabled...");
20962 #else
20963   errmsg ("Use the vpp event loger...");
20964 #endif
20965   return 0;
20966 }
20967
20968 static int
20969 statseg (vat_main_t * vam)
20970 {
20971   ssvm_private_t *ssvmp = &vam->stat_segment;
20972   ssvm_shared_header_t *shared_header = ssvmp->sh;
20973   vlib_counter_t **counters;
20974   u64 thread0_index1_packets;
20975   u64 thread0_index1_bytes;
20976   f64 vector_rate, input_rate;
20977   uword *p;
20978
20979   uword *counter_vector_by_name;
20980   if (vam->stat_segment_lockp == 0)
20981     {
20982       errmsg ("Stat segment not mapped...");
20983       return -99;
20984     }
20985
20986   /* look up "/if/rx for sw_if_index 1 as a test */
20987
20988   clib_spinlock_lock (vam->stat_segment_lockp);
20989
20990   counter_vector_by_name = (uword *) shared_header->opaque[1];
20991
20992   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20993   if (p == 0)
20994     {
20995       clib_spinlock_unlock (vam->stat_segment_lockp);
20996       errmsg ("/if/tx not found?");
20997       return -99;
20998     }
20999
21000   /* Fish per-thread vector of combined counters from shared memory */
21001   counters = (vlib_counter_t **) p[0];
21002
21003   if (vec_len (counters[0]) < 2)
21004     {
21005       clib_spinlock_unlock (vam->stat_segment_lockp);
21006       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21007       return -99;
21008     }
21009
21010   /* Read thread 0 sw_if_index 1 counter */
21011   thread0_index1_packets = counters[0][1].packets;
21012   thread0_index1_bytes = counters[0][1].bytes;
21013
21014   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21015   if (p == 0)
21016     {
21017       clib_spinlock_unlock (vam->stat_segment_lockp);
21018       errmsg ("vector_rate not found?");
21019       return -99;
21020     }
21021
21022   vector_rate = *(f64 *) (p[0]);
21023   p = hash_get_mem (counter_vector_by_name, "input_rate");
21024   if (p == 0)
21025     {
21026       clib_spinlock_unlock (vam->stat_segment_lockp);
21027       errmsg ("input_rate not found?");
21028       return -99;
21029     }
21030   input_rate = *(f64 *) (p[0]);
21031
21032   clib_spinlock_unlock (vam->stat_segment_lockp);
21033
21034   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21035          vector_rate, input_rate);
21036   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21037          thread0_index1_packets, thread0_index1_bytes);
21038
21039   return 0;
21040 }
21041
21042 static int
21043 cmd_cmp (void *a1, void *a2)
21044 {
21045   u8 **c1 = a1;
21046   u8 **c2 = a2;
21047
21048   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21049 }
21050
21051 static int
21052 help (vat_main_t * vam)
21053 {
21054   u8 **cmds = 0;
21055   u8 *name = 0;
21056   hash_pair_t *p;
21057   unformat_input_t *i = vam->input;
21058   int j;
21059
21060   if (unformat (i, "%s", &name))
21061     {
21062       uword *hs;
21063
21064       vec_add1 (name, 0);
21065
21066       hs = hash_get_mem (vam->help_by_name, name);
21067       if (hs)
21068         print (vam->ofp, "usage: %s %s", name, hs[0]);
21069       else
21070         print (vam->ofp, "No such msg / command '%s'", name);
21071       vec_free (name);
21072       return 0;
21073     }
21074
21075   print (vam->ofp, "Help is available for the following:");
21076
21077     /* *INDENT-OFF* */
21078     hash_foreach_pair (p, vam->function_by_name,
21079     ({
21080       vec_add1 (cmds, (u8 *)(p->key));
21081     }));
21082     /* *INDENT-ON* */
21083
21084   vec_sort_with_function (cmds, cmd_cmp);
21085
21086   for (j = 0; j < vec_len (cmds); j++)
21087     print (vam->ofp, "%s", cmds[j]);
21088
21089   vec_free (cmds);
21090   return 0;
21091 }
21092
21093 static int
21094 set (vat_main_t * vam)
21095 {
21096   u8 *name = 0, *value = 0;
21097   unformat_input_t *i = vam->input;
21098
21099   if (unformat (i, "%s", &name))
21100     {
21101       /* The input buffer is a vector, not a string. */
21102       value = vec_dup (i->buffer);
21103       vec_delete (value, i->index, 0);
21104       /* Almost certainly has a trailing newline */
21105       if (value[vec_len (value) - 1] == '\n')
21106         value[vec_len (value) - 1] = 0;
21107       /* Make sure it's a proper string, one way or the other */
21108       vec_add1 (value, 0);
21109       (void) clib_macro_set_value (&vam->macro_main,
21110                                    (char *) name, (char *) value);
21111     }
21112   else
21113     errmsg ("usage: set <name> <value>");
21114
21115   vec_free (name);
21116   vec_free (value);
21117   return 0;
21118 }
21119
21120 static int
21121 unset (vat_main_t * vam)
21122 {
21123   u8 *name = 0;
21124
21125   if (unformat (vam->input, "%s", &name))
21126     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21127       errmsg ("unset: %s wasn't set", name);
21128   vec_free (name);
21129   return 0;
21130 }
21131
21132 typedef struct
21133 {
21134   u8 *name;
21135   u8 *value;
21136 } macro_sort_t;
21137
21138
21139 static int
21140 macro_sort_cmp (void *a1, void *a2)
21141 {
21142   macro_sort_t *s1 = a1;
21143   macro_sort_t *s2 = a2;
21144
21145   return strcmp ((char *) (s1->name), (char *) (s2->name));
21146 }
21147
21148 static int
21149 dump_macro_table (vat_main_t * vam)
21150 {
21151   macro_sort_t *sort_me = 0, *sm;
21152   int i;
21153   hash_pair_t *p;
21154
21155     /* *INDENT-OFF* */
21156     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21157     ({
21158       vec_add2 (sort_me, sm, 1);
21159       sm->name = (u8 *)(p->key);
21160       sm->value = (u8 *) (p->value[0]);
21161     }));
21162     /* *INDENT-ON* */
21163
21164   vec_sort_with_function (sort_me, macro_sort_cmp);
21165
21166   if (vec_len (sort_me))
21167     print (vam->ofp, "%-15s%s", "Name", "Value");
21168   else
21169     print (vam->ofp, "The macro table is empty...");
21170
21171   for (i = 0; i < vec_len (sort_me); i++)
21172     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21173   return 0;
21174 }
21175
21176 static int
21177 dump_node_table (vat_main_t * vam)
21178 {
21179   int i, j;
21180   vlib_node_t *node, *next_node;
21181
21182   if (vec_len (vam->graph_nodes) == 0)
21183     {
21184       print (vam->ofp, "Node table empty, issue get_node_graph...");
21185       return 0;
21186     }
21187
21188   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21189     {
21190       node = vam->graph_nodes[0][i];
21191       print (vam->ofp, "[%d] %s", i, node->name);
21192       for (j = 0; j < vec_len (node->next_nodes); j++)
21193         {
21194           if (node->next_nodes[j] != ~0)
21195             {
21196               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21197               print (vam->ofp, "  [%d] %s", j, next_node->name);
21198             }
21199         }
21200     }
21201   return 0;
21202 }
21203
21204 static int
21205 value_sort_cmp (void *a1, void *a2)
21206 {
21207   name_sort_t *n1 = a1;
21208   name_sort_t *n2 = a2;
21209
21210   if (n1->value < n2->value)
21211     return -1;
21212   if (n1->value > n2->value)
21213     return 1;
21214   return 0;
21215 }
21216
21217
21218 static int
21219 dump_msg_api_table (vat_main_t * vam)
21220 {
21221   api_main_t *am = &api_main;
21222   name_sort_t *nses = 0, *ns;
21223   hash_pair_t *hp;
21224   int i;
21225
21226   /* *INDENT-OFF* */
21227   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21228   ({
21229     vec_add2 (nses, ns, 1);
21230     ns->name = (u8 *)(hp->key);
21231     ns->value = (u32) hp->value[0];
21232   }));
21233   /* *INDENT-ON* */
21234
21235   vec_sort_with_function (nses, value_sort_cmp);
21236
21237   for (i = 0; i < vec_len (nses); i++)
21238     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21239   vec_free (nses);
21240   return 0;
21241 }
21242
21243 static int
21244 get_msg_id (vat_main_t * vam)
21245 {
21246   u8 *name_and_crc;
21247   u32 message_index;
21248
21249   if (unformat (vam->input, "%s", &name_and_crc))
21250     {
21251       message_index = vl_msg_api_get_msg_index (name_and_crc);
21252       if (message_index == ~0)
21253         {
21254           print (vam->ofp, " '%s' not found", name_and_crc);
21255           return 0;
21256         }
21257       print (vam->ofp, " '%s' has message index %d",
21258              name_and_crc, message_index);
21259       return 0;
21260     }
21261   errmsg ("name_and_crc required...");
21262   return 0;
21263 }
21264
21265 static int
21266 search_node_table (vat_main_t * vam)
21267 {
21268   unformat_input_t *line_input = vam->input;
21269   u8 *node_to_find;
21270   int j;
21271   vlib_node_t *node, *next_node;
21272   uword *p;
21273
21274   if (vam->graph_node_index_by_name == 0)
21275     {
21276       print (vam->ofp, "Node table empty, issue get_node_graph...");
21277       return 0;
21278     }
21279
21280   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21281     {
21282       if (unformat (line_input, "%s", &node_to_find))
21283         {
21284           vec_add1 (node_to_find, 0);
21285           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21286           if (p == 0)
21287             {
21288               print (vam->ofp, "%s not found...", node_to_find);
21289               goto out;
21290             }
21291           node = vam->graph_nodes[0][p[0]];
21292           print (vam->ofp, "[%d] %s", p[0], node->name);
21293           for (j = 0; j < vec_len (node->next_nodes); j++)
21294             {
21295               if (node->next_nodes[j] != ~0)
21296                 {
21297                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21298                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21299                 }
21300             }
21301         }
21302
21303       else
21304         {
21305           clib_warning ("parse error '%U'", format_unformat_error,
21306                         line_input);
21307           return -99;
21308         }
21309
21310     out:
21311       vec_free (node_to_find);
21312
21313     }
21314
21315   return 0;
21316 }
21317
21318
21319 static int
21320 script (vat_main_t * vam)
21321 {
21322 #if (VPP_API_TEST_BUILTIN==0)
21323   u8 *s = 0;
21324   char *save_current_file;
21325   unformat_input_t save_input;
21326   jmp_buf save_jump_buf;
21327   u32 save_line_number;
21328
21329   FILE *new_fp, *save_ifp;
21330
21331   if (unformat (vam->input, "%s", &s))
21332     {
21333       new_fp = fopen ((char *) s, "r");
21334       if (new_fp == 0)
21335         {
21336           errmsg ("Couldn't open script file %s", s);
21337           vec_free (s);
21338           return -99;
21339         }
21340     }
21341   else
21342     {
21343       errmsg ("Missing script name");
21344       return -99;
21345     }
21346
21347   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21348   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21349   save_ifp = vam->ifp;
21350   save_line_number = vam->input_line_number;
21351   save_current_file = (char *) vam->current_file;
21352
21353   vam->input_line_number = 0;
21354   vam->ifp = new_fp;
21355   vam->current_file = s;
21356   do_one_file (vam);
21357
21358   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21359   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21360   vam->ifp = save_ifp;
21361   vam->input_line_number = save_line_number;
21362   vam->current_file = (u8 *) save_current_file;
21363   vec_free (s);
21364
21365   return 0;
21366 #else
21367   clib_warning ("use the exec command...");
21368   return -99;
21369 #endif
21370 }
21371
21372 static int
21373 echo (vat_main_t * vam)
21374 {
21375   print (vam->ofp, "%v", vam->input->buffer);
21376   return 0;
21377 }
21378
21379 /* List of API message constructors, CLI names map to api_xxx */
21380 #define foreach_vpe_api_msg                                             \
21381 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21382 _(sw_interface_dump,"")                                                 \
21383 _(sw_interface_set_flags,                                               \
21384   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21385 _(sw_interface_add_del_address,                                         \
21386   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21387 _(sw_interface_set_rx_mode,                                             \
21388   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21389 _(sw_interface_set_rx_placement,                                        \
21390   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21391 _(sw_interface_rx_placement_dump,                                       \
21392   "[<intfc> | sw_if_index <id>]")                                         \
21393 _(sw_interface_set_table,                                               \
21394   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21395 _(sw_interface_set_mpls_enable,                                         \
21396   "<intfc> | sw_if_index [disable | dis]")                              \
21397 _(sw_interface_set_vpath,                                               \
21398   "<intfc> | sw_if_index <id> enable | disable")                        \
21399 _(sw_interface_set_vxlan_bypass,                                        \
21400   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21401 _(sw_interface_set_geneve_bypass,                                       \
21402   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21403 _(sw_interface_set_l2_xconnect,                                         \
21404   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21405   "enable | disable")                                                   \
21406 _(sw_interface_set_l2_bridge,                                           \
21407   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21408   "[shg <split-horizon-group>] [bvi]\n"                                 \
21409   "enable | disable")                                                   \
21410 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21411 _(bridge_domain_add_del,                                                \
21412   "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") \
21413 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21414 _(l2fib_add_del,                                                        \
21415   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21416 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21417 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21418 _(l2_flags,                                                             \
21419   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21420 _(bridge_flags,                                                         \
21421   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21422 _(tap_create_v2,                                                        \
21423   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21424 _(tap_delete_v2,                                                        \
21425   "<vpp-if-name> | sw_if_index <id>")                                   \
21426 _(sw_interface_tap_v2_dump, "")                                         \
21427 _(virtio_pci_create,                                                    \
21428   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21429 _(virtio_pci_delete,                                                    \
21430   "<vpp-if-name> | sw_if_index <id>")                                   \
21431 _(sw_interface_virtio_pci_dump, "")                                     \
21432 _(bond_create,                                                          \
21433   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21434   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21435   "[id <if-id>]")                                                       \
21436 _(bond_delete,                                                          \
21437   "<vpp-if-name> | sw_if_index <id>")                                   \
21438 _(bond_enslave,                                                         \
21439   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21440 _(bond_detach_slave,                                                    \
21441   "sw_if_index <n>")                                                    \
21442  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21443 _(sw_interface_bond_dump, "")                                           \
21444 _(sw_interface_slave_dump,                                              \
21445   "<vpp-if-name> | sw_if_index <id>")                                   \
21446 _(ip_table_add_del,                                                     \
21447   "table <n> [ipv6] [add | del]\n")                                     \
21448 _(ip_route_add_del,                                                     \
21449   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21450   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21451   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21452   "[multipath] [count <n>] [del]")                                      \
21453 _(ip_mroute_add_del,                                                    \
21454   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21455   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21456 _(mpls_table_add_del,                                                   \
21457   "table <n> [add | del]\n")                                            \
21458 _(mpls_route_add_del,                                                   \
21459   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21460   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21461   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21462   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21463   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21464   "[count <n>] [del]")                                                  \
21465 _(mpls_ip_bind_unbind,                                                  \
21466   "<label> <addr/len>")                                                 \
21467 _(mpls_tunnel_add_del,                                                  \
21468   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21469   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21470   "[l2-only]  [out-label <n>]")                                         \
21471 _(sr_mpls_policy_add,                                                   \
21472   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21473 _(sr_mpls_policy_del,                                                   \
21474   "bsid <id>")                                                          \
21475 _(bier_table_add_del,                                                   \
21476   "<label> <sub-domain> <set> <bsl> [del]")                             \
21477 _(bier_route_add_del,                                                   \
21478   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21479   "[<intfc> | sw_if_index <id>]"                                        \
21480   "[weight <n>] [del] [multipath]")                                     \
21481 _(proxy_arp_add_del,                                                    \
21482   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21483 _(proxy_arp_intfc_enable_disable,                                       \
21484   "<intfc> | sw_if_index <id> enable | disable")                        \
21485 _(sw_interface_set_unnumbered,                                          \
21486   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21487 _(ip_neighbor_add_del,                                                  \
21488   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21489   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21490 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21491 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21492   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21493   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21494   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21495 _(reset_fib, "vrf <n> [ipv6]")                                          \
21496 _(set_ip_flow_hash,                                                     \
21497   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21498 _(sw_interface_ip6_enable_disable,                                      \
21499   "<intfc> | sw_if_index <id> enable | disable")                        \
21500 _(ip6nd_proxy_add_del,                                                  \
21501   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21502 _(ip6nd_proxy_dump, "")                                                 \
21503 _(sw_interface_ip6nd_ra_prefix,                                         \
21504   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21505   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21506   "[nolink] [isno]")                                                    \
21507 _(sw_interface_ip6nd_ra_config,                                         \
21508   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21509   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21510   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21511 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21512 _(l2_patch_add_del,                                                     \
21513   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21514   "enable | disable")                                                   \
21515 _(sr_localsid_add_del,                                                  \
21516   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21517   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21518 _(classify_add_del_table,                                               \
21519   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21520   " [del] [del-chain] mask <mask-value>\n"                              \
21521   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21522   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21523 _(classify_add_del_session,                                             \
21524   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21525   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21526   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21527   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21528 _(classify_set_interface_ip_table,                                      \
21529   "<intfc> | sw_if_index <nn> table <nn>")                              \
21530 _(classify_set_interface_l2_tables,                                     \
21531   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21532   "  [other-table <nn>]")                                               \
21533 _(get_node_index, "node <node-name")                                    \
21534 _(add_node_next, "node <node-name> next <next-node-name>")              \
21535 _(l2tpv3_create_tunnel,                                                 \
21536   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21537   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21538   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21539 _(l2tpv3_set_tunnel_cookies,                                            \
21540   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21541   "[new_remote_cookie <nn>]\n")                                         \
21542 _(l2tpv3_interface_enable_disable,                                      \
21543   "<intfc> | sw_if_index <nn> enable | disable")                        \
21544 _(l2tpv3_set_lookup_key,                                                \
21545   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21546 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21547 _(vxlan_offload_rx,                                                     \
21548   "hw { <interface name> | hw_if_index <nn>} "                          \
21549   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21550 _(vxlan_add_del_tunnel,                                                 \
21551   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21552   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21553   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21554 _(geneve_add_del_tunnel,                                                \
21555   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21556   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21557   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21558 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21559 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21560 _(gre_tunnel_add_del,                                                   \
21561   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21562   "[teb | erspan <session-id>] [del]")                                  \
21563 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21564 _(l2_fib_clear_table, "")                                               \
21565 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21566 _(l2_interface_vlan_tag_rewrite,                                        \
21567   "<intfc> | sw_if_index <nn> \n"                                       \
21568   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21569   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21570 _(create_vhost_user_if,                                                 \
21571         "socket <filename> [server] [renumber <dev_instance>] "         \
21572         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21573         "[mac <mac_address>]")                                          \
21574 _(modify_vhost_user_if,                                                 \
21575         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21576         "[server] [renumber <dev_instance>] [gso]")                     \
21577 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21578 _(sw_interface_vhost_user_dump, "")                                     \
21579 _(show_version, "")                                                     \
21580 _(show_threads, "")                                                     \
21581 _(vxlan_gpe_add_del_tunnel,                                             \
21582   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21583   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21584   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21585   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21586 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21587 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21588 _(interface_name_renumber,                                              \
21589   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21590 _(input_acl_set_interface,                                              \
21591   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21592   "  [l2-table <nn>] [del]")                                            \
21593 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21594 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21595   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21596 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21597 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21598 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21599 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21600 _(ip_dump, "ipv4 | ipv6")                                               \
21601 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21602 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21603   "  spid_id <n> ")                                                     \
21604 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21605   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21606   "  integ_alg <alg> integ_key <hex>")                                  \
21607 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21608   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21609   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21610   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21611 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21612   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21613   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21614   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21615   "  [instance <n>]")     \
21616 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21617 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21618 _(delete_loopback,"sw_if_index <nn>")                                   \
21619 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21620 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21621 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21622 _(want_interface_events,  "enable|disable")                             \
21623 _(get_first_msg_id, "client <name>")                                    \
21624 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21625 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21626   "fib-id <nn> [ip4][ip6][default]")                                    \
21627 _(get_node_graph, " ")                                                  \
21628 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21629 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21630 _(ioam_disable, "")                                                     \
21631 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21632                             " sw_if_index <sw_if_index> p <priority> "  \
21633                             "w <weight>] [del]")                        \
21634 _(one_add_del_locator, "locator-set <locator_name> "                    \
21635                         "iface <intf> | sw_if_index <sw_if_index> "     \
21636                         "p <priority> w <weight> [del]")                \
21637 _(one_add_del_local_eid,"vni <vni> eid "                                \
21638                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21639                          "locator-set <locator_name> [del]"             \
21640                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21641 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21642 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21643 _(one_enable_disable, "enable|disable")                                 \
21644 _(one_map_register_enable_disable, "enable|disable")                    \
21645 _(one_map_register_fallback_threshold, "<value>")                       \
21646 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21647 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21648                                "[seid <seid>] "                         \
21649                                "rloc <locator> p <prio> "               \
21650                                "w <weight> [rloc <loc> ... ] "          \
21651                                "action <action> [del-all]")             \
21652 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21653                           "<local-eid>")                                \
21654 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21655 _(one_use_petr, "ip-address> | disable")                                \
21656 _(one_map_request_mode, "src-dst|dst-only")                             \
21657 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21658 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21659 _(one_locator_set_dump, "[local | remote]")                             \
21660 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21661 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21662                        "[local] | [remote]")                            \
21663 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21664 _(one_ndp_bd_get, "")                                                   \
21665 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21666 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21667 _(one_l2_arp_bd_get, "")                                                \
21668 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21669 _(one_stats_enable_disable, "enable|disable")                           \
21670 _(show_one_stats_enable_disable, "")                                    \
21671 _(one_eid_table_vni_dump, "")                                           \
21672 _(one_eid_table_map_dump, "l2|l3")                                      \
21673 _(one_map_resolver_dump, "")                                            \
21674 _(one_map_server_dump, "")                                              \
21675 _(one_adjacencies_get, "vni <vni>")                                     \
21676 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21677 _(show_one_rloc_probe_state, "")                                        \
21678 _(show_one_map_register_state, "")                                      \
21679 _(show_one_status, "")                                                  \
21680 _(one_stats_dump, "")                                                   \
21681 _(one_stats_flush, "")                                                  \
21682 _(one_get_map_request_itr_rlocs, "")                                    \
21683 _(one_map_register_set_ttl, "<ttl>")                                    \
21684 _(one_set_transport_protocol, "udp|api")                                \
21685 _(one_get_transport_protocol, "")                                       \
21686 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21687 _(one_show_xtr_mode, "")                                                \
21688 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21689 _(one_show_pitr_mode, "")                                               \
21690 _(one_enable_disable_petr_mode, "enable|disable")                       \
21691 _(one_show_petr_mode, "")                                               \
21692 _(show_one_nsh_mapping, "")                                             \
21693 _(show_one_pitr, "")                                                    \
21694 _(show_one_use_petr, "")                                                \
21695 _(show_one_map_request_mode, "")                                        \
21696 _(show_one_map_register_ttl, "")                                        \
21697 _(show_one_map_register_fallback_threshold, "")                         \
21698 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21699                             " sw_if_index <sw_if_index> p <priority> "  \
21700                             "w <weight>] [del]")                        \
21701 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21702                         "iface <intf> | sw_if_index <sw_if_index> "     \
21703                         "p <priority> w <weight> [del]")                \
21704 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21705                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21706                          "locator-set <locator_name> [del]"             \
21707                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21708 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21709 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21710 _(lisp_enable_disable, "enable|disable")                                \
21711 _(lisp_map_register_enable_disable, "enable|disable")                   \
21712 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21713 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21714                                "[seid <seid>] "                         \
21715                                "rloc <locator> p <prio> "               \
21716                                "w <weight> [rloc <loc> ... ] "          \
21717                                "action <action> [del-all]")             \
21718 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21719                           "<local-eid>")                                \
21720 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21721 _(lisp_use_petr, "<ip-address> | disable")                              \
21722 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21723 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21724 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21725 _(lisp_locator_set_dump, "[local | remote]")                            \
21726 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21727 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21728                        "[local] | [remote]")                            \
21729 _(lisp_eid_table_vni_dump, "")                                          \
21730 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21731 _(lisp_map_resolver_dump, "")                                           \
21732 _(lisp_map_server_dump, "")                                             \
21733 _(lisp_adjacencies_get, "vni <vni>")                                    \
21734 _(gpe_fwd_entry_vnis_get, "")                                           \
21735 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21736 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21737                                 "[table <table-id>]")                   \
21738 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21739 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21740 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21741 _(gpe_get_encap_mode, "")                                               \
21742 _(lisp_gpe_add_del_iface, "up|down")                                    \
21743 _(lisp_gpe_enable_disable, "enable|disable")                            \
21744 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21745   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21746 _(show_lisp_rloc_probe_state, "")                                       \
21747 _(show_lisp_map_register_state, "")                                     \
21748 _(show_lisp_status, "")                                                 \
21749 _(lisp_get_map_request_itr_rlocs, "")                                   \
21750 _(show_lisp_pitr, "")                                                   \
21751 _(show_lisp_use_petr, "")                                               \
21752 _(show_lisp_map_request_mode, "")                                       \
21753 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21754 _(af_packet_delete, "name <host interface name>")                       \
21755 _(af_packet_dump, "")                                                   \
21756 _(policer_add_del, "name <policer name> <params> [del]")                \
21757 _(policer_dump, "[name <policer name>]")                                \
21758 _(policer_classify_set_interface,                                       \
21759   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21760   "  [l2-table <nn>] [del]")                                            \
21761 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21762 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21763     "[master|slave]")                                                   \
21764 _(netmap_delete, "name <interface name>")                               \
21765 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21766 _(mpls_table_dump, "")                                                  \
21767 _(mpls_route_dump, "table-id <ID>")                                     \
21768 _(classify_table_ids, "")                                               \
21769 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21770 _(classify_table_info, "table_id <nn>")                                 \
21771 _(classify_session_dump, "table_id <nn>")                               \
21772 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21773     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21774     "[template_interval <nn>] [udp_checksum]")                          \
21775 _(ipfix_exporter_dump, "")                                              \
21776 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21777 _(ipfix_classify_stream_dump, "")                                       \
21778 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21779 _(ipfix_classify_table_dump, "")                                        \
21780 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21781 _(sw_interface_span_dump, "[l2]")                                           \
21782 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21783 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21784 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21785 _(pg_enable_disable, "[stream <id>] disable")                           \
21786 _(ip_source_and_port_range_check_add_del,                               \
21787   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21788 _(ip_source_and_port_range_check_interface_add_del,                     \
21789   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21790   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21791 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21792 _(l2_interface_pbb_tag_rewrite,                                         \
21793   "<intfc> | sw_if_index <nn> \n"                                       \
21794   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21795   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21796 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21797 _(flow_classify_set_interface,                                          \
21798   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21799 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21800 _(ip_table_dump, "")                                                    \
21801 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21802 _(ip_mtable_dump, "")                                                   \
21803 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21804 _(feature_enable_disable, "arc_name <arc_name> "                        \
21805   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21806 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21807 "[disable]")                                                            \
21808 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21809   "mac <mac-address> [del]")                                            \
21810 _(l2_xconnect_dump, "")                                                 \
21811 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21812 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21813 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21814 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21815 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21816 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21817 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21818   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21819 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21820 _(sock_init_shm, "size <nnn>")                                          \
21821 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21822 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21823   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21824 _(session_rules_dump, "")                                               \
21825 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21826 _(output_acl_set_interface,                                             \
21827   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21828   "  [l2-table <nn>] [del]")                                            \
21829 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21830
21831 /* List of command functions, CLI names map directly to functions */
21832 #define foreach_cli_function                                    \
21833 _(comment, "usage: comment <ignore-rest-of-line>")              \
21834 _(dump_interface_table, "usage: dump_interface_table")          \
21835 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21836 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21837 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21838 _(dump_macro_table, "usage: dump_macro_table ")                 \
21839 _(dump_node_table, "usage: dump_node_table")                    \
21840 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21841 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21842 _(elog_disable, "usage: elog_disable")                          \
21843 _(elog_enable, "usage: elog_enable")                            \
21844 _(elog_save, "usage: elog_save <filename>")                     \
21845 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21846 _(echo, "usage: echo <message>")                                \
21847 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21848 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21849 _(help, "usage: help")                                          \
21850 _(q, "usage: quit")                                             \
21851 _(quit, "usage: quit")                                          \
21852 _(search_node_table, "usage: search_node_table <name>...")      \
21853 _(set, "usage: set <variable-name> <value>")                    \
21854 _(script, "usage: script <file-name>")                          \
21855 _(statseg, "usage: statseg")                                    \
21856 _(unset, "usage: unset <variable-name>")
21857
21858 #define _(N,n)                                  \
21859     static void vl_api_##n##_t_handler_uni      \
21860     (vl_api_##n##_t * mp)                       \
21861     {                                           \
21862         vat_main_t * vam = &vat_main;           \
21863         if (vam->json_output) {                 \
21864             vl_api_##n##_t_handler_json(mp);    \
21865         } else {                                \
21866             vl_api_##n##_t_handler(mp);         \
21867         }                                       \
21868     }
21869 foreach_vpe_api_reply_msg;
21870 #if VPP_API_TEST_BUILTIN == 0
21871 foreach_standalone_reply_msg;
21872 #endif
21873 #undef _
21874
21875 void
21876 vat_api_hookup (vat_main_t * vam)
21877 {
21878 #define _(N,n)                                                  \
21879     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21880                            vl_api_##n##_t_handler_uni,          \
21881                            vl_noop_handler,                     \
21882                            vl_api_##n##_t_endian,               \
21883                            vl_api_##n##_t_print,                \
21884                            sizeof(vl_api_##n##_t), 1);
21885   foreach_vpe_api_reply_msg;
21886 #if VPP_API_TEST_BUILTIN == 0
21887   foreach_standalone_reply_msg;
21888 #endif
21889 #undef _
21890
21891 #if (VPP_API_TEST_BUILTIN==0)
21892   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21893
21894   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21895
21896   vam->function_by_name = hash_create_string (0, sizeof (uword));
21897
21898   vam->help_by_name = hash_create_string (0, sizeof (uword));
21899 #endif
21900
21901   /* API messages we can send */
21902 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21903   foreach_vpe_api_msg;
21904 #undef _
21905
21906   /* Help strings */
21907 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21908   foreach_vpe_api_msg;
21909 #undef _
21910
21911   /* CLI functions */
21912 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21913   foreach_cli_function;
21914 #undef _
21915
21916   /* Help strings */
21917 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21918   foreach_cli_function;
21919 #undef _
21920 }
21921
21922 #if VPP_API_TEST_BUILTIN
21923 static clib_error_t *
21924 vat_api_hookup_shim (vlib_main_t * vm)
21925 {
21926   vat_api_hookup (&vat_main);
21927   return 0;
21928 }
21929
21930 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21931 #endif
21932
21933 /*
21934  * fd.io coding-style-patch-verification: ON
21935  *
21936  * Local Variables:
21937  * eval: (c-set-style "gnu")
21938  * End:
21939  */