gso: Add gso feature arc
[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 _(feature_gso_enable_disable_reply)                     \
5178 _(sw_interface_tag_add_del_reply)                       \
5179 _(sw_interface_add_del_mac_address_reply)               \
5180 _(hw_interface_set_mtu_reply)                           \
5181 _(p2p_ethernet_add_reply)                               \
5182 _(p2p_ethernet_del_reply)                               \
5183 _(lldp_config_reply)                                    \
5184 _(sw_interface_set_lldp_reply)                          \
5185 _(tcp_configure_src_addresses_reply)                    \
5186 _(session_rule_add_del_reply)                           \
5187 _(ip_container_proxy_add_del_reply)                     \
5188 _(output_acl_set_interface_reply)                       \
5189 _(qos_record_enable_disable_reply)
5190
5191 #define _(n)                                    \
5192     static void vl_api_##n##_t_handler          \
5193     (vl_api_##n##_t * mp)                       \
5194     {                                           \
5195         vat_main_t * vam = &vat_main;           \
5196         i32 retval = ntohl(mp->retval);         \
5197         if (vam->async_mode) {                  \
5198             vam->async_errors += (retval < 0);  \
5199         } else {                                \
5200             vam->retval = retval;               \
5201             vam->result_ready = 1;              \
5202         }                                       \
5203     }
5204 foreach_standard_reply_retval_handler;
5205 #undef _
5206
5207 #define _(n)                                    \
5208     static void vl_api_##n##_t_handler_json     \
5209     (vl_api_##n##_t * mp)                       \
5210     {                                           \
5211         vat_main_t * vam = &vat_main;           \
5212         vat_json_node_t node;                   \
5213         vat_json_init_object(&node);            \
5214         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5215         vat_json_print(vam->ofp, &node);        \
5216         vam->retval = ntohl(mp->retval);        \
5217         vam->result_ready = 1;                  \
5218     }
5219 foreach_standard_reply_retval_handler;
5220 #undef _
5221
5222 /*
5223  * Table of message reply handlers, must include boilerplate handlers
5224  * we just generated
5225  */
5226
5227 #define foreach_vpe_api_reply_msg                                       \
5228 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5229 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5230 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5231 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5232 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5233 _(CLI_REPLY, cli_reply)                                                 \
5234 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5235 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5236   sw_interface_add_del_address_reply)                                   \
5237 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5238 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5239 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5240 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5241 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5242 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5243 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5244 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5245 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5246 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5247   sw_interface_set_l2_xconnect_reply)                                   \
5248 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5249   sw_interface_set_l2_bridge_reply)                                     \
5250 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5251 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5252 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5253 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5254 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5255 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5256 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5257 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5258 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5259 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5260 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5261 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5262 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5263 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5264 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5265 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5266 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5267 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5268 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5269 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5270 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5271 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5272 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5273 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5274 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5275 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5276 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5277 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5278 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5279 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5280 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5281   proxy_arp_intfc_enable_disable_reply)                                 \
5282 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5283 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5284   sw_interface_set_unnumbered_reply)                                    \
5285 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5286 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5287 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5288 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5289 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5290 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5291   sw_interface_ip6_enable_disable_reply)                                \
5292 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5293 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5294 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5295   sw_interface_ip6nd_ra_prefix_reply)                                   \
5296 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5297   sw_interface_ip6nd_ra_config_reply)                                   \
5298 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5299 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5300 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5301 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5302 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5303 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5304 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5305 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5306 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5307 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5308 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5309 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5310 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5311 classify_set_interface_ip_table_reply)                                  \
5312 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5313   classify_set_interface_l2_tables_reply)                               \
5314 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5315 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5316 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5317 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5318 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5319   l2tpv3_interface_enable_disable_reply)                                \
5320 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5321 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5322 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5323 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5324 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5325 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5326 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5327 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5328 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5329 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5330 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5331 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5332 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5333 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5334 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5335 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5336 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5337 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5338 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5339 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5340 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5341 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5342 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5343 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5344 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5345 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5346 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5347 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5348 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5349 _(L2_MACS_EVENT, l2_macs_event)                                         \
5350 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5351 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5352 _(IP_DETAILS, ip_details)                                               \
5353 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5354 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5355 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5356 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5357 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5358 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5359 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5360 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5361 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5362 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5363 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5364 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5365 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5366 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5367 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5368 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5369 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5370 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5371 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5372 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5373 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5374 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5375 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5376 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5377 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5378 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5379 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5380 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5381   one_map_register_enable_disable_reply)                                \
5382 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5383 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5384 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5385 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5386   one_map_register_fallback_threshold_reply)                            \
5387 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5388   one_rloc_probe_enable_disable_reply)                                  \
5389 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5390 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5391 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5392 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5393 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5394 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5395 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5396 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5397 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5398 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5399 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5400 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5401 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5402 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5403 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5404 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5405   show_one_stats_enable_disable_reply)                                  \
5406 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5407 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5408 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5409 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5410 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5411 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5412 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5413 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5414   one_enable_disable_pitr_mode_reply)                                   \
5415 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5416   one_enable_disable_petr_mode_reply)                                   \
5417 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5418 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5419 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5420 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5421 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5422 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5423 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5424 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5425 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5426 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5427 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5428 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5429   gpe_add_del_native_fwd_rpath_reply)                                   \
5430 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5431   gpe_fwd_entry_path_details)                                           \
5432 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5433 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5434   one_add_del_map_request_itr_rlocs_reply)                              \
5435 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5436   one_get_map_request_itr_rlocs_reply)                                  \
5437 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5438 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5439 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5440 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5441 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5442 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5443   show_one_map_register_state_reply)                                    \
5444 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5445 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5446   show_one_map_register_fallback_threshold_reply)                       \
5447 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5448 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5449 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5450 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5451 _(POLICER_DETAILS, policer_details)                                     \
5452 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5453 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5454 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5455 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5456 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5457 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5458 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5459 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5460 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5461 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5462 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5463 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5464 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5465 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5466 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5467 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5468 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5469 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5470 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5471 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5472 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5473 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5474 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5475 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5476 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5477 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5478  ip_source_and_port_range_check_add_del_reply)                          \
5479 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5480  ip_source_and_port_range_check_interface_add_del_reply)                \
5481 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5482 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5483 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5484 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5485 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5486 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5487 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5488 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5489 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5490 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5491 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5492 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5493 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5494 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5495 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5496 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5497 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5498 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5499 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5500 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5501 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5502 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5503 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5504 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5505
5506 #define foreach_standalone_reply_msg                                    \
5507 _(SW_INTERFACE_EVENT, sw_interface_event)
5508
5509 typedef struct
5510 {
5511   u8 *name;
5512   u32 value;
5513 } name_sort_t;
5514
5515 #define STR_VTR_OP_CASE(op)     \
5516     case L2_VTR_ ## op:         \
5517         return "" # op;
5518
5519 static const char *
5520 str_vtr_op (u32 vtr_op)
5521 {
5522   switch (vtr_op)
5523     {
5524       STR_VTR_OP_CASE (DISABLED);
5525       STR_VTR_OP_CASE (PUSH_1);
5526       STR_VTR_OP_CASE (PUSH_2);
5527       STR_VTR_OP_CASE (POP_1);
5528       STR_VTR_OP_CASE (POP_2);
5529       STR_VTR_OP_CASE (TRANSLATE_1_1);
5530       STR_VTR_OP_CASE (TRANSLATE_1_2);
5531       STR_VTR_OP_CASE (TRANSLATE_2_1);
5532       STR_VTR_OP_CASE (TRANSLATE_2_2);
5533     }
5534
5535   return "UNKNOWN";
5536 }
5537
5538 static int
5539 dump_sub_interface_table (vat_main_t * vam)
5540 {
5541   const sw_interface_subif_t *sub = NULL;
5542
5543   if (vam->json_output)
5544     {
5545       clib_warning
5546         ("JSON output supported only for VPE API calls and dump_stats_table");
5547       return -99;
5548     }
5549
5550   print (vam->ofp,
5551          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5552          "Interface", "sw_if_index",
5553          "sub id", "dot1ad", "tags", "outer id",
5554          "inner id", "exact", "default", "outer any", "inner any");
5555
5556   vec_foreach (sub, vam->sw_if_subif_table)
5557   {
5558     print (vam->ofp,
5559            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5560            sub->interface_name,
5561            sub->sw_if_index,
5562            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5563            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5564            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5565            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5566     if (sub->vtr_op != L2_VTR_DISABLED)
5567       {
5568         print (vam->ofp,
5569                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5570                "tag1: %d tag2: %d ]",
5571                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5572                sub->vtr_tag1, sub->vtr_tag2);
5573       }
5574   }
5575
5576   return 0;
5577 }
5578
5579 static int
5580 name_sort_cmp (void *a1, void *a2)
5581 {
5582   name_sort_t *n1 = a1;
5583   name_sort_t *n2 = a2;
5584
5585   return strcmp ((char *) n1->name, (char *) n2->name);
5586 }
5587
5588 static int
5589 dump_interface_table (vat_main_t * vam)
5590 {
5591   hash_pair_t *p;
5592   name_sort_t *nses = 0, *ns;
5593
5594   if (vam->json_output)
5595     {
5596       clib_warning
5597         ("JSON output supported only for VPE API calls and dump_stats_table");
5598       return -99;
5599     }
5600
5601   /* *INDENT-OFF* */
5602   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5603   ({
5604     vec_add2 (nses, ns, 1);
5605     ns->name = (u8 *)(p->key);
5606     ns->value = (u32) p->value[0];
5607   }));
5608   /* *INDENT-ON* */
5609
5610   vec_sort_with_function (nses, name_sort_cmp);
5611
5612   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5613   vec_foreach (ns, nses)
5614   {
5615     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5616   }
5617   vec_free (nses);
5618   return 0;
5619 }
5620
5621 static int
5622 dump_ip_table (vat_main_t * vam, int is_ipv6)
5623 {
5624   const ip_details_t *det = NULL;
5625   const ip_address_details_t *address = NULL;
5626   u32 i = ~0;
5627
5628   print (vam->ofp, "%-12s", "sw_if_index");
5629
5630   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5631   {
5632     i++;
5633     if (!det->present)
5634       {
5635         continue;
5636       }
5637     print (vam->ofp, "%-12d", i);
5638     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5639     if (!det->addr)
5640       {
5641         continue;
5642       }
5643     vec_foreach (address, det->addr)
5644     {
5645       print (vam->ofp,
5646              "            %-30U%-13d",
5647              is_ipv6 ? format_ip6_address : format_ip4_address,
5648              address->ip, address->prefix_length);
5649     }
5650   }
5651
5652   return 0;
5653 }
5654
5655 static int
5656 dump_ipv4_table (vat_main_t * vam)
5657 {
5658   if (vam->json_output)
5659     {
5660       clib_warning
5661         ("JSON output supported only for VPE API calls and dump_stats_table");
5662       return -99;
5663     }
5664
5665   return dump_ip_table (vam, 0);
5666 }
5667
5668 static int
5669 dump_ipv6_table (vat_main_t * vam)
5670 {
5671   if (vam->json_output)
5672     {
5673       clib_warning
5674         ("JSON output supported only for VPE API calls and dump_stats_table");
5675       return -99;
5676     }
5677
5678   return dump_ip_table (vam, 1);
5679 }
5680
5681 /*
5682  * Pass CLI buffers directly in the CLI_INBAND API message,
5683  * instead of an additional shared memory area.
5684  */
5685 static int
5686 exec_inband (vat_main_t * vam)
5687 {
5688   vl_api_cli_inband_t *mp;
5689   unformat_input_t *i = vam->input;
5690   int ret;
5691
5692   if (vec_len (i->buffer) == 0)
5693     return -1;
5694
5695   if (vam->exec_mode == 0 && unformat (i, "mode"))
5696     {
5697       vam->exec_mode = 1;
5698       return 0;
5699     }
5700   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5701     {
5702       vam->exec_mode = 0;
5703       return 0;
5704     }
5705
5706   /*
5707    * In order for the CLI command to work, it
5708    * must be a vector ending in \n, not a C-string ending
5709    * in \n\0.
5710    */
5711   u32 len = vec_len (vam->input->buffer);
5712   M2 (CLI_INBAND, mp, len);
5713   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5714
5715   S (mp);
5716   W (ret);
5717   /* json responses may or may not include a useful reply... */
5718   if (vec_len (vam->cmd_reply))
5719     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5720   return ret;
5721 }
5722
5723 int
5724 exec (vat_main_t * vam)
5725 {
5726   return exec_inband (vam);
5727 }
5728
5729 static int
5730 api_create_loopback (vat_main_t * vam)
5731 {
5732   unformat_input_t *i = vam->input;
5733   vl_api_create_loopback_t *mp;
5734   vl_api_create_loopback_instance_t *mp_lbi;
5735   u8 mac_address[6];
5736   u8 mac_set = 0;
5737   u8 is_specified = 0;
5738   u32 user_instance = 0;
5739   int ret;
5740
5741   clib_memset (mac_address, 0, sizeof (mac_address));
5742
5743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5744     {
5745       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5746         mac_set = 1;
5747       if (unformat (i, "instance %d", &user_instance))
5748         is_specified = 1;
5749       else
5750         break;
5751     }
5752
5753   if (is_specified)
5754     {
5755       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5756       mp_lbi->is_specified = is_specified;
5757       if (is_specified)
5758         mp_lbi->user_instance = htonl (user_instance);
5759       if (mac_set)
5760         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5761       S (mp_lbi);
5762     }
5763   else
5764     {
5765       /* Construct the API message */
5766       M (CREATE_LOOPBACK, mp);
5767       if (mac_set)
5768         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5769       S (mp);
5770     }
5771
5772   W (ret);
5773   return ret;
5774 }
5775
5776 static int
5777 api_delete_loopback (vat_main_t * vam)
5778 {
5779   unformat_input_t *i = vam->input;
5780   vl_api_delete_loopback_t *mp;
5781   u32 sw_if_index = ~0;
5782   int ret;
5783
5784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5785     {
5786       if (unformat (i, "sw_if_index %d", &sw_if_index))
5787         ;
5788       else
5789         break;
5790     }
5791
5792   if (sw_if_index == ~0)
5793     {
5794       errmsg ("missing sw_if_index");
5795       return -99;
5796     }
5797
5798   /* Construct the API message */
5799   M (DELETE_LOOPBACK, mp);
5800   mp->sw_if_index = ntohl (sw_if_index);
5801
5802   S (mp);
5803   W (ret);
5804   return ret;
5805 }
5806
5807 static int
5808 api_want_interface_events (vat_main_t * vam)
5809 {
5810   unformat_input_t *i = vam->input;
5811   vl_api_want_interface_events_t *mp;
5812   int enable = -1;
5813   int ret;
5814
5815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5816     {
5817       if (unformat (i, "enable"))
5818         enable = 1;
5819       else if (unformat (i, "disable"))
5820         enable = 0;
5821       else
5822         break;
5823     }
5824
5825   if (enable == -1)
5826     {
5827       errmsg ("missing enable|disable");
5828       return -99;
5829     }
5830
5831   M (WANT_INTERFACE_EVENTS, mp);
5832   mp->enable_disable = enable;
5833
5834   vam->interface_event_display = enable;
5835
5836   S (mp);
5837   W (ret);
5838   return ret;
5839 }
5840
5841
5842 /* Note: non-static, called once to set up the initial intfc table */
5843 int
5844 api_sw_interface_dump (vat_main_t * vam)
5845 {
5846   vl_api_sw_interface_dump_t *mp;
5847   vl_api_control_ping_t *mp_ping;
5848   hash_pair_t *p;
5849   name_sort_t *nses = 0, *ns;
5850   sw_interface_subif_t *sub = NULL;
5851   int ret;
5852
5853   /* Toss the old name table */
5854   /* *INDENT-OFF* */
5855   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5856   ({
5857     vec_add2 (nses, ns, 1);
5858     ns->name = (u8 *)(p->key);
5859     ns->value = (u32) p->value[0];
5860   }));
5861   /* *INDENT-ON* */
5862
5863   hash_free (vam->sw_if_index_by_interface_name);
5864
5865   vec_foreach (ns, nses) vec_free (ns->name);
5866
5867   vec_free (nses);
5868
5869   vec_foreach (sub, vam->sw_if_subif_table)
5870   {
5871     vec_free (sub->interface_name);
5872   }
5873   vec_free (vam->sw_if_subif_table);
5874
5875   /* recreate the interface name hash table */
5876   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5877
5878   /*
5879    * Ask for all interface names. Otherwise, the epic catalog of
5880    * name filters becomes ridiculously long, and vat ends up needing
5881    * to be taught about new interface types.
5882    */
5883   M (SW_INTERFACE_DUMP, mp);
5884   S (mp);
5885
5886   /* Use a control ping for synchronization */
5887   MPING (CONTROL_PING, mp_ping);
5888   S (mp_ping);
5889
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_sw_interface_set_flags (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_flags_t *mp;
5899   u32 sw_if_index;
5900   u8 sw_if_index_set = 0;
5901   u8 admin_up = 0;
5902   int ret;
5903
5904   /* Parse args required to build the message */
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "admin-up"))
5908         admin_up = 1;
5909       else if (unformat (i, "admin-down"))
5910         admin_up = 0;
5911       else
5912         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5913         sw_if_index_set = 1;
5914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5915         sw_if_index_set = 1;
5916       else
5917         break;
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing interface name or sw_if_index");
5923       return -99;
5924     }
5925
5926   /* Construct the API message */
5927   M (SW_INTERFACE_SET_FLAGS, mp);
5928   mp->sw_if_index = ntohl (sw_if_index);
5929   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5930
5931   /* send it... */
5932   S (mp);
5933
5934   /* Wait for a reply, return the good/bad news... */
5935   W (ret);
5936   return ret;
5937 }
5938
5939 static int
5940 api_sw_interface_set_rx_mode (vat_main_t * vam)
5941 {
5942   unformat_input_t *i = vam->input;
5943   vl_api_sw_interface_set_rx_mode_t *mp;
5944   u32 sw_if_index;
5945   u8 sw_if_index_set = 0;
5946   int ret;
5947   u8 queue_id_valid = 0;
5948   u32 queue_id;
5949   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5950
5951   /* Parse args required to build the message */
5952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5953     {
5954       if (unformat (i, "queue %d", &queue_id))
5955         queue_id_valid = 1;
5956       else if (unformat (i, "polling"))
5957         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5958       else if (unformat (i, "interrupt"))
5959         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5960       else if (unformat (i, "adaptive"))
5961         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5962       else
5963         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5964         sw_if_index_set = 1;
5965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5966         sw_if_index_set = 1;
5967       else
5968         break;
5969     }
5970
5971   if (sw_if_index_set == 0)
5972     {
5973       errmsg ("missing interface name or sw_if_index");
5974       return -99;
5975     }
5976   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5977     {
5978       errmsg ("missing rx-mode");
5979       return -99;
5980     }
5981
5982   /* Construct the API message */
5983   M (SW_INTERFACE_SET_RX_MODE, mp);
5984   mp->sw_if_index = ntohl (sw_if_index);
5985   mp->mode = (vl_api_rx_mode_t) mode;
5986   mp->queue_id_valid = queue_id_valid;
5987   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5988
5989   /* send it... */
5990   S (mp);
5991
5992   /* Wait for a reply, return the good/bad news... */
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static int
5998 api_sw_interface_set_rx_placement (vat_main_t * vam)
5999 {
6000   unformat_input_t *i = vam->input;
6001   vl_api_sw_interface_set_rx_placement_t *mp;
6002   u32 sw_if_index;
6003   u8 sw_if_index_set = 0;
6004   int ret;
6005   u8 is_main = 0;
6006   u32 queue_id, thread_index;
6007
6008   /* Parse args required to build the message */
6009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6010     {
6011       if (unformat (i, "queue %d", &queue_id))
6012         ;
6013       else if (unformat (i, "main"))
6014         is_main = 1;
6015       else if (unformat (i, "worker %d", &thread_index))
6016         ;
6017       else
6018         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6019         sw_if_index_set = 1;
6020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6021         sw_if_index_set = 1;
6022       else
6023         break;
6024     }
6025
6026   if (sw_if_index_set == 0)
6027     {
6028       errmsg ("missing interface name or sw_if_index");
6029       return -99;
6030     }
6031
6032   if (is_main)
6033     thread_index = 0;
6034   /* Construct the API message */
6035   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6036   mp->sw_if_index = ntohl (sw_if_index);
6037   mp->worker_id = ntohl (thread_index);
6038   mp->queue_id = ntohl (queue_id);
6039   mp->is_main = is_main;
6040
6041   /* send it... */
6042   S (mp);
6043   /* Wait for a reply, return the good/bad news... */
6044   W (ret);
6045   return ret;
6046 }
6047
6048 static void vl_api_sw_interface_rx_placement_details_t_handler
6049   (vl_api_sw_interface_rx_placement_details_t * mp)
6050 {
6051   vat_main_t *vam = &vat_main;
6052   u32 worker_id = ntohl (mp->worker_id);
6053
6054   print (vam->ofp,
6055          "\n%-11d %-11s %-6d %-5d %-9s",
6056          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6057          worker_id, ntohl (mp->queue_id),
6058          (mp->mode ==
6059           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6060 }
6061
6062 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6063   (vl_api_sw_interface_rx_placement_details_t * mp)
6064 {
6065   vat_main_t *vam = &vat_main;
6066   vat_json_node_t *node = NULL;
6067
6068   if (VAT_JSON_ARRAY != vam->json_tree.type)
6069     {
6070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6071       vat_json_init_array (&vam->json_tree);
6072     }
6073   node = vat_json_array_add (&vam->json_tree);
6074
6075   vat_json_init_object (node);
6076   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6077   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6078   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6079   vat_json_object_add_uint (node, "mode", mp->mode);
6080 }
6081
6082 static int
6083 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6084 {
6085   unformat_input_t *i = vam->input;
6086   vl_api_sw_interface_rx_placement_dump_t *mp;
6087   vl_api_control_ping_t *mp_ping;
6088   int ret;
6089   u32 sw_if_index;
6090   u8 sw_if_index_set = 0;
6091
6092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6093     {
6094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6095         sw_if_index_set++;
6096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set++;
6098       else
6099         break;
6100     }
6101
6102   print (vam->ofp,
6103          "\n%-11s %-11s %-6s %-5s %-4s",
6104          "sw_if_index", "main/worker", "thread", "queue", "mode");
6105
6106   /* Dump Interface rx placement */
6107   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6108
6109   if (sw_if_index_set)
6110     mp->sw_if_index = htonl (sw_if_index);
6111   else
6112     mp->sw_if_index = ~0;
6113
6114   S (mp);
6115
6116   /* Use a control ping for synchronization */
6117   MPING (CONTROL_PING, mp_ping);
6118   S (mp_ping);
6119
6120   W (ret);
6121   return ret;
6122 }
6123
6124 static int
6125 api_sw_interface_clear_stats (vat_main_t * vam)
6126 {
6127   unformat_input_t *i = vam->input;
6128   vl_api_sw_interface_clear_stats_t *mp;
6129   u32 sw_if_index;
6130   u8 sw_if_index_set = 0;
6131   int ret;
6132
6133   /* Parse args required to build the message */
6134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6135     {
6136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6137         sw_if_index_set = 1;
6138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6139         sw_if_index_set = 1;
6140       else
6141         break;
6142     }
6143
6144   /* Construct the API message */
6145   M (SW_INTERFACE_CLEAR_STATS, mp);
6146
6147   if (sw_if_index_set == 1)
6148     mp->sw_if_index = ntohl (sw_if_index);
6149   else
6150     mp->sw_if_index = ~0;
6151
6152   /* send it... */
6153   S (mp);
6154
6155   /* Wait for a reply, return the good/bad news... */
6156   W (ret);
6157   return ret;
6158 }
6159
6160 static int
6161 api_sw_interface_add_del_address (vat_main_t * vam)
6162 {
6163   unformat_input_t *i = vam->input;
6164   vl_api_sw_interface_add_del_address_t *mp;
6165   u32 sw_if_index;
6166   u8 sw_if_index_set = 0;
6167   u8 is_add = 1, del_all = 0;
6168   u32 address_length = 0;
6169   u8 v4_address_set = 0;
6170   u8 v6_address_set = 0;
6171   ip4_address_t v4address;
6172   ip6_address_t v6address;
6173   int ret;
6174
6175   /* Parse args required to build the message */
6176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6177     {
6178       if (unformat (i, "del-all"))
6179         del_all = 1;
6180       else if (unformat (i, "del"))
6181         is_add = 0;
6182       else
6183         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6184         sw_if_index_set = 1;
6185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6186         sw_if_index_set = 1;
6187       else if (unformat (i, "%U/%d",
6188                          unformat_ip4_address, &v4address, &address_length))
6189         v4_address_set = 1;
6190       else if (unformat (i, "%U/%d",
6191                          unformat_ip6_address, &v6address, &address_length))
6192         v6_address_set = 1;
6193       else
6194         break;
6195     }
6196
6197   if (sw_if_index_set == 0)
6198     {
6199       errmsg ("missing interface name or sw_if_index");
6200       return -99;
6201     }
6202   if (v4_address_set && v6_address_set)
6203     {
6204       errmsg ("both v4 and v6 addresses set");
6205       return -99;
6206     }
6207   if (!v4_address_set && !v6_address_set && !del_all)
6208     {
6209       errmsg ("no addresses set");
6210       return -99;
6211     }
6212
6213   /* Construct the API message */
6214   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6215
6216   mp->sw_if_index = ntohl (sw_if_index);
6217   mp->is_add = is_add;
6218   mp->del_all = del_all;
6219   if (v6_address_set)
6220     {
6221       mp->prefix.address.af = ADDRESS_IP6;
6222       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6223     }
6224   else
6225     {
6226       mp->prefix.address.af = ADDRESS_IP4;
6227       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6228     }
6229   mp->prefix.len = address_length;
6230
6231   /* send it... */
6232   S (mp);
6233
6234   /* Wait for a reply, return good/bad news  */
6235   W (ret);
6236   return ret;
6237 }
6238
6239 static int
6240 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6241 {
6242   unformat_input_t *i = vam->input;
6243   vl_api_sw_interface_set_mpls_enable_t *mp;
6244   u32 sw_if_index;
6245   u8 sw_if_index_set = 0;
6246   u8 enable = 1;
6247   int ret;
6248
6249   /* Parse args required to build the message */
6250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6251     {
6252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6255         sw_if_index_set = 1;
6256       else if (unformat (i, "disable"))
6257         enable = 0;
6258       else if (unformat (i, "dis"))
6259         enable = 0;
6260       else
6261         break;
6262     }
6263
6264   if (sw_if_index_set == 0)
6265     {
6266       errmsg ("missing interface name or sw_if_index");
6267       return -99;
6268     }
6269
6270   /* Construct the API message */
6271   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6272
6273   mp->sw_if_index = ntohl (sw_if_index);
6274   mp->enable = enable;
6275
6276   /* send it... */
6277   S (mp);
6278
6279   /* Wait for a reply... */
6280   W (ret);
6281   return ret;
6282 }
6283
6284 static int
6285 api_sw_interface_set_table (vat_main_t * vam)
6286 {
6287   unformat_input_t *i = vam->input;
6288   vl_api_sw_interface_set_table_t *mp;
6289   u32 sw_if_index, vrf_id = 0;
6290   u8 sw_if_index_set = 0;
6291   u8 is_ipv6 = 0;
6292   int ret;
6293
6294   /* Parse args required to build the message */
6295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6296     {
6297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6300         sw_if_index_set = 1;
6301       else if (unformat (i, "vrf %d", &vrf_id))
6302         ;
6303       else if (unformat (i, "ipv6"))
6304         is_ipv6 = 1;
6305       else
6306         break;
6307     }
6308
6309   if (sw_if_index_set == 0)
6310     {
6311       errmsg ("missing interface name or sw_if_index");
6312       return -99;
6313     }
6314
6315   /* Construct the API message */
6316   M (SW_INTERFACE_SET_TABLE, mp);
6317
6318   mp->sw_if_index = ntohl (sw_if_index);
6319   mp->is_ipv6 = is_ipv6;
6320   mp->vrf_id = ntohl (vrf_id);
6321
6322   /* send it... */
6323   S (mp);
6324
6325   /* Wait for a reply... */
6326   W (ret);
6327   return ret;
6328 }
6329
6330 static void vl_api_sw_interface_get_table_reply_t_handler
6331   (vl_api_sw_interface_get_table_reply_t * mp)
6332 {
6333   vat_main_t *vam = &vat_main;
6334
6335   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6336
6337   vam->retval = ntohl (mp->retval);
6338   vam->result_ready = 1;
6339
6340 }
6341
6342 static void vl_api_sw_interface_get_table_reply_t_handler_json
6343   (vl_api_sw_interface_get_table_reply_t * mp)
6344 {
6345   vat_main_t *vam = &vat_main;
6346   vat_json_node_t node;
6347
6348   vat_json_init_object (&node);
6349   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6350   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6351
6352   vat_json_print (vam->ofp, &node);
6353   vat_json_free (&node);
6354
6355   vam->retval = ntohl (mp->retval);
6356   vam->result_ready = 1;
6357 }
6358
6359 static int
6360 api_sw_interface_get_table (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_sw_interface_get_table_t *mp;
6364   u32 sw_if_index;
6365   u8 sw_if_index_set = 0;
6366   u8 is_ipv6 = 0;
6367   int ret;
6368
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "ipv6"))
6376         is_ipv6 = 1;
6377       else
6378         break;
6379     }
6380
6381   if (sw_if_index_set == 0)
6382     {
6383       errmsg ("missing interface name or sw_if_index");
6384       return -99;
6385     }
6386
6387   M (SW_INTERFACE_GET_TABLE, mp);
6388   mp->sw_if_index = htonl (sw_if_index);
6389   mp->is_ipv6 = is_ipv6;
6390
6391   S (mp);
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_vpath (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_vpath_t *mp;
6401   u32 sw_if_index = 0;
6402   u8 sw_if_index_set = 0;
6403   u8 is_enable = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6412         sw_if_index_set = 1;
6413       else if (unformat (i, "enable"))
6414         is_enable = 1;
6415       else if (unformat (i, "disable"))
6416         is_enable = 0;
6417       else
6418         break;
6419     }
6420
6421   if (sw_if_index_set == 0)
6422     {
6423       errmsg ("missing interface name or sw_if_index");
6424       return -99;
6425     }
6426
6427   /* Construct the API message */
6428   M (SW_INTERFACE_SET_VPATH, mp);
6429
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->enable = is_enable;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6446   u32 sw_if_index = 0;
6447   u8 sw_if_index_set = 0;
6448   u8 is_enable = 1;
6449   u8 is_ipv6 = 0;
6450   int ret;
6451
6452   /* Parse args required to build the message */
6453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6454     {
6455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "enable"))
6460         is_enable = 1;
6461       else if (unformat (i, "disable"))
6462         is_enable = 0;
6463       else if (unformat (i, "ip4"))
6464         is_ipv6 = 0;
6465       else if (unformat (i, "ip6"))
6466         is_ipv6 = 1;
6467       else
6468         break;
6469     }
6470
6471   if (sw_if_index_set == 0)
6472     {
6473       errmsg ("missing interface name or sw_if_index");
6474       return -99;
6475     }
6476
6477   /* Construct the API message */
6478   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6479
6480   mp->sw_if_index = ntohl (sw_if_index);
6481   mp->enable = is_enable;
6482   mp->is_ipv6 = is_ipv6;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_set_geneve_bypass_t *mp;
6497   u32 sw_if_index = 0;
6498   u8 sw_if_index_set = 0;
6499   u8 is_enable = 1;
6500   u8 is_ipv6 = 0;
6501   int ret;
6502
6503   /* Parse args required to build the message */
6504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6505     {
6506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6507         sw_if_index_set = 1;
6508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6509         sw_if_index_set = 1;
6510       else if (unformat (i, "enable"))
6511         is_enable = 1;
6512       else if (unformat (i, "disable"))
6513         is_enable = 0;
6514       else if (unformat (i, "ip4"))
6515         is_ipv6 = 0;
6516       else if (unformat (i, "ip6"))
6517         is_ipv6 = 1;
6518       else
6519         break;
6520     }
6521
6522   if (sw_if_index_set == 0)
6523     {
6524       errmsg ("missing interface name or sw_if_index");
6525       return -99;
6526     }
6527
6528   /* Construct the API message */
6529   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6530
6531   mp->sw_if_index = ntohl (sw_if_index);
6532   mp->enable = is_enable;
6533   mp->is_ipv6 = is_ipv6;
6534
6535   /* send it... */
6536   S (mp);
6537
6538   /* Wait for a reply... */
6539   W (ret);
6540   return ret;
6541 }
6542
6543 static int
6544 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6545 {
6546   unformat_input_t *i = vam->input;
6547   vl_api_sw_interface_set_l2_xconnect_t *mp;
6548   u32 rx_sw_if_index;
6549   u8 rx_sw_if_index_set = 0;
6550   u32 tx_sw_if_index;
6551   u8 tx_sw_if_index_set = 0;
6552   u8 enable = 1;
6553   int ret;
6554
6555   /* Parse args required to build the message */
6556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6557     {
6558       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6559         rx_sw_if_index_set = 1;
6560       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6561         tx_sw_if_index_set = 1;
6562       else if (unformat (i, "rx"))
6563         {
6564           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565             {
6566               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6567                             &rx_sw_if_index))
6568                 rx_sw_if_index_set = 1;
6569             }
6570           else
6571             break;
6572         }
6573       else if (unformat (i, "tx"))
6574         {
6575           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6576             {
6577               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6578                             &tx_sw_if_index))
6579                 tx_sw_if_index_set = 1;
6580             }
6581           else
6582             break;
6583         }
6584       else if (unformat (i, "enable"))
6585         enable = 1;
6586       else if (unformat (i, "disable"))
6587         enable = 0;
6588       else
6589         break;
6590     }
6591
6592   if (rx_sw_if_index_set == 0)
6593     {
6594       errmsg ("missing rx interface name or rx_sw_if_index");
6595       return -99;
6596     }
6597
6598   if (enable && (tx_sw_if_index_set == 0))
6599     {
6600       errmsg ("missing tx interface name or tx_sw_if_index");
6601       return -99;
6602     }
6603
6604   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6605
6606   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6607   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_sw_interface_set_l2_bridge_t *mp;
6620   vl_api_l2_port_type_t port_type;
6621   u32 rx_sw_if_index;
6622   u8 rx_sw_if_index_set = 0;
6623   u32 bd_id;
6624   u8 bd_id_set = 0;
6625   u32 shg = 0;
6626   u8 enable = 1;
6627   int ret;
6628
6629   port_type = L2_API_PORT_TYPE_NORMAL;
6630
6631   /* Parse args required to build the message */
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6635         rx_sw_if_index_set = 1;
6636       else if (unformat (i, "bd_id %d", &bd_id))
6637         bd_id_set = 1;
6638       else
6639         if (unformat
6640             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6641         rx_sw_if_index_set = 1;
6642       else if (unformat (i, "shg %d", &shg))
6643         ;
6644       else if (unformat (i, "bvi"))
6645         port_type = L2_API_PORT_TYPE_BVI;
6646       else if (unformat (i, "uu-fwd"))
6647         port_type = L2_API_PORT_TYPE_UU_FWD;
6648       else if (unformat (i, "enable"))
6649         enable = 1;
6650       else if (unformat (i, "disable"))
6651         enable = 0;
6652       else
6653         break;
6654     }
6655
6656   if (rx_sw_if_index_set == 0)
6657     {
6658       errmsg ("missing rx interface name or sw_if_index");
6659       return -99;
6660     }
6661
6662   if (enable && (bd_id_set == 0))
6663     {
6664       errmsg ("missing bridge domain");
6665       return -99;
6666     }
6667
6668   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6669
6670   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6671   mp->bd_id = ntohl (bd_id);
6672   mp->shg = (u8) shg;
6673   mp->port_type = ntohl (port_type);
6674   mp->enable = enable;
6675
6676   S (mp);
6677   W (ret);
6678   return ret;
6679 }
6680
6681 static int
6682 api_bridge_domain_dump (vat_main_t * vam)
6683 {
6684   unformat_input_t *i = vam->input;
6685   vl_api_bridge_domain_dump_t *mp;
6686   vl_api_control_ping_t *mp_ping;
6687   u32 bd_id = ~0;
6688   int ret;
6689
6690   /* Parse args required to build the message */
6691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6692     {
6693       if (unformat (i, "bd_id %d", &bd_id))
6694         ;
6695       else
6696         break;
6697     }
6698
6699   M (BRIDGE_DOMAIN_DUMP, mp);
6700   mp->bd_id = ntohl (bd_id);
6701   S (mp);
6702
6703   /* Use a control ping for synchronization */
6704   MPING (CONTROL_PING, mp_ping);
6705   S (mp_ping);
6706
6707   W (ret);
6708   return ret;
6709 }
6710
6711 static int
6712 api_bridge_domain_add_del (vat_main_t * vam)
6713 {
6714   unformat_input_t *i = vam->input;
6715   vl_api_bridge_domain_add_del_t *mp;
6716   u32 bd_id = ~0;
6717   u8 is_add = 1;
6718   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6719   u8 *bd_tag = NULL;
6720   u32 mac_age = 0;
6721   int ret;
6722
6723   /* Parse args required to build the message */
6724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725     {
6726       if (unformat (i, "bd_id %d", &bd_id))
6727         ;
6728       else if (unformat (i, "flood %d", &flood))
6729         ;
6730       else if (unformat (i, "uu-flood %d", &uu_flood))
6731         ;
6732       else if (unformat (i, "forward %d", &forward))
6733         ;
6734       else if (unformat (i, "learn %d", &learn))
6735         ;
6736       else if (unformat (i, "arp-term %d", &arp_term))
6737         ;
6738       else if (unformat (i, "mac-age %d", &mac_age))
6739         ;
6740       else if (unformat (i, "bd-tag %s", &bd_tag))
6741         ;
6742       else if (unformat (i, "del"))
6743         {
6744           is_add = 0;
6745           flood = uu_flood = forward = learn = 0;
6746         }
6747       else
6748         break;
6749     }
6750
6751   if (bd_id == ~0)
6752     {
6753       errmsg ("missing bridge domain");
6754       ret = -99;
6755       goto done;
6756     }
6757
6758   if (mac_age > 255)
6759     {
6760       errmsg ("mac age must be less than 256 ");
6761       ret = -99;
6762       goto done;
6763     }
6764
6765   if ((bd_tag) && (vec_len (bd_tag) > 63))
6766     {
6767       errmsg ("bd-tag cannot be longer than 63");
6768       ret = -99;
6769       goto done;
6770     }
6771
6772   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6773
6774   mp->bd_id = ntohl (bd_id);
6775   mp->flood = flood;
6776   mp->uu_flood = uu_flood;
6777   mp->forward = forward;
6778   mp->learn = learn;
6779   mp->arp_term = arp_term;
6780   mp->is_add = is_add;
6781   mp->mac_age = (u8) mac_age;
6782   if (bd_tag)
6783     {
6784       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6785       mp->bd_tag[vec_len (bd_tag)] = 0;
6786     }
6787   S (mp);
6788   W (ret);
6789
6790 done:
6791   vec_free (bd_tag);
6792   return ret;
6793 }
6794
6795 static int
6796 api_l2fib_flush_bd (vat_main_t * vam)
6797 {
6798   unformat_input_t *i = vam->input;
6799   vl_api_l2fib_flush_bd_t *mp;
6800   u32 bd_id = ~0;
6801   int ret;
6802
6803   /* Parse args required to build the message */
6804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6805     {
6806       if (unformat (i, "bd_id %d", &bd_id));
6807       else
6808         break;
6809     }
6810
6811   if (bd_id == ~0)
6812     {
6813       errmsg ("missing bridge domain");
6814       return -99;
6815     }
6816
6817   M (L2FIB_FLUSH_BD, mp);
6818
6819   mp->bd_id = htonl (bd_id);
6820
6821   S (mp);
6822   W (ret);
6823   return ret;
6824 }
6825
6826 static int
6827 api_l2fib_flush_int (vat_main_t * vam)
6828 {
6829   unformat_input_t *i = vam->input;
6830   vl_api_l2fib_flush_int_t *mp;
6831   u32 sw_if_index = ~0;
6832   int ret;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "sw_if_index %d", &sw_if_index));
6838       else
6839         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6840       else
6841         break;
6842     }
6843
6844   if (sw_if_index == ~0)
6845     {
6846       errmsg ("missing interface name or sw_if_index");
6847       return -99;
6848     }
6849
6850   M (L2FIB_FLUSH_INT, mp);
6851
6852   mp->sw_if_index = ntohl (sw_if_index);
6853
6854   S (mp);
6855   W (ret);
6856   return ret;
6857 }
6858
6859 static int
6860 api_l2fib_add_del (vat_main_t * vam)
6861 {
6862   unformat_input_t *i = vam->input;
6863   vl_api_l2fib_add_del_t *mp;
6864   f64 timeout;
6865   u8 mac[6] = { 0 };
6866   u8 mac_set = 0;
6867   u32 bd_id;
6868   u8 bd_id_set = 0;
6869   u32 sw_if_index = 0;
6870   u8 sw_if_index_set = 0;
6871   u8 is_add = 1;
6872   u8 static_mac = 0;
6873   u8 filter_mac = 0;
6874   u8 bvi_mac = 0;
6875   int count = 1;
6876   f64 before = 0;
6877   int j;
6878
6879   /* Parse args required to build the message */
6880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881     {
6882       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6883         mac_set = 1;
6884       else if (unformat (i, "bd_id %d", &bd_id))
6885         bd_id_set = 1;
6886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6887         sw_if_index_set = 1;
6888       else if (unformat (i, "sw_if"))
6889         {
6890           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891             {
6892               if (unformat
6893                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6894                 sw_if_index_set = 1;
6895             }
6896           else
6897             break;
6898         }
6899       else if (unformat (i, "static"))
6900         static_mac = 1;
6901       else if (unformat (i, "filter"))
6902         {
6903           filter_mac = 1;
6904           static_mac = 1;
6905         }
6906       else if (unformat (i, "bvi"))
6907         {
6908           bvi_mac = 1;
6909           static_mac = 1;
6910         }
6911       else if (unformat (i, "del"))
6912         is_add = 0;
6913       else if (unformat (i, "count %d", &count))
6914         ;
6915       else
6916         break;
6917     }
6918
6919   if (mac_set == 0)
6920     {
6921       errmsg ("missing mac address");
6922       return -99;
6923     }
6924
6925   if (bd_id_set == 0)
6926     {
6927       errmsg ("missing bridge domain");
6928       return -99;
6929     }
6930
6931   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6932     {
6933       errmsg ("missing interface name or sw_if_index");
6934       return -99;
6935     }
6936
6937   if (count > 1)
6938     {
6939       /* Turn on async mode */
6940       vam->async_mode = 1;
6941       vam->async_errors = 0;
6942       before = vat_time_now (vam);
6943     }
6944
6945   for (j = 0; j < count; j++)
6946     {
6947       M (L2FIB_ADD_DEL, mp);
6948
6949       clib_memcpy (mp->mac, mac, 6);
6950       mp->bd_id = ntohl (bd_id);
6951       mp->is_add = is_add;
6952       mp->sw_if_index = ntohl (sw_if_index);
6953
6954       if (is_add)
6955         {
6956           mp->static_mac = static_mac;
6957           mp->filter_mac = filter_mac;
6958           mp->bvi_mac = bvi_mac;
6959         }
6960       increment_mac_address (mac);
6961       /* send it... */
6962       S (mp);
6963     }
6964
6965   if (count > 1)
6966     {
6967       vl_api_control_ping_t *mp_ping;
6968       f64 after;
6969
6970       /* Shut off async mode */
6971       vam->async_mode = 0;
6972
6973       MPING (CONTROL_PING, mp_ping);
6974       S (mp_ping);
6975
6976       timeout = vat_time_now (vam) + 1.0;
6977       while (vat_time_now (vam) < timeout)
6978         if (vam->result_ready == 1)
6979           goto out;
6980       vam->retval = -99;
6981
6982     out:
6983       if (vam->retval == -99)
6984         errmsg ("timeout");
6985
6986       if (vam->async_errors > 0)
6987         {
6988           errmsg ("%d asynchronous errors", vam->async_errors);
6989           vam->retval = -98;
6990         }
6991       vam->async_errors = 0;
6992       after = vat_time_now (vam);
6993
6994       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6995              count, after - before, count / (after - before));
6996     }
6997   else
6998     {
6999       int ret;
7000
7001       /* Wait for a reply... */
7002       W (ret);
7003       return ret;
7004     }
7005   /* Return the good/bad news */
7006   return (vam->retval);
7007 }
7008
7009 static int
7010 api_bridge_domain_set_mac_age (vat_main_t * vam)
7011 {
7012   unformat_input_t *i = vam->input;
7013   vl_api_bridge_domain_set_mac_age_t *mp;
7014   u32 bd_id = ~0;
7015   u32 mac_age = 0;
7016   int ret;
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "bd_id %d", &bd_id));
7022       else if (unformat (i, "mac-age %d", &mac_age));
7023       else
7024         break;
7025     }
7026
7027   if (bd_id == ~0)
7028     {
7029       errmsg ("missing bridge domain");
7030       return -99;
7031     }
7032
7033   if (mac_age > 255)
7034     {
7035       errmsg ("mac age must be less than 256 ");
7036       return -99;
7037     }
7038
7039   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7040
7041   mp->bd_id = htonl (bd_id);
7042   mp->mac_age = (u8) mac_age;
7043
7044   S (mp);
7045   W (ret);
7046   return ret;
7047 }
7048
7049 static int
7050 api_l2_flags (vat_main_t * vam)
7051 {
7052   unformat_input_t *i = vam->input;
7053   vl_api_l2_flags_t *mp;
7054   u32 sw_if_index;
7055   u32 flags = 0;
7056   u8 sw_if_index_set = 0;
7057   u8 is_set = 0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "sw_if_index %d", &sw_if_index))
7064         sw_if_index_set = 1;
7065       else if (unformat (i, "sw_if"))
7066         {
7067           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068             {
7069               if (unformat
7070                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7071                 sw_if_index_set = 1;
7072             }
7073           else
7074             break;
7075         }
7076       else if (unformat (i, "learn"))
7077         flags |= L2_LEARN;
7078       else if (unformat (i, "forward"))
7079         flags |= L2_FWD;
7080       else if (unformat (i, "flood"))
7081         flags |= L2_FLOOD;
7082       else if (unformat (i, "uu-flood"))
7083         flags |= L2_UU_FLOOD;
7084       else if (unformat (i, "arp-term"))
7085         flags |= L2_ARP_TERM;
7086       else if (unformat (i, "off"))
7087         is_set = 0;
7088       else if (unformat (i, "disable"))
7089         is_set = 0;
7090       else
7091         break;
7092     }
7093
7094   if (sw_if_index_set == 0)
7095     {
7096       errmsg ("missing interface name or sw_if_index");
7097       return -99;
7098     }
7099
7100   M (L2_FLAGS, mp);
7101
7102   mp->sw_if_index = ntohl (sw_if_index);
7103   mp->feature_bitmap = ntohl (flags);
7104   mp->is_set = is_set;
7105
7106   S (mp);
7107   W (ret);
7108   return ret;
7109 }
7110
7111 static int
7112 api_bridge_flags (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_bridge_flags_t *mp;
7116   u32 bd_id;
7117   u8 bd_id_set = 0;
7118   u8 is_set = 1;
7119   bd_flags_t flags = 0;
7120   int ret;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "bd_id %d", &bd_id))
7126         bd_id_set = 1;
7127       else if (unformat (i, "learn"))
7128         flags |= BRIDGE_API_FLAG_LEARN;
7129       else if (unformat (i, "forward"))
7130         flags |= BRIDGE_API_FLAG_FWD;
7131       else if (unformat (i, "flood"))
7132         flags |= BRIDGE_API_FLAG_FLOOD;
7133       else if (unformat (i, "uu-flood"))
7134         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7135       else if (unformat (i, "arp-term"))
7136         flags |= BRIDGE_API_FLAG_ARP_TERM;
7137       else if (unformat (i, "off"))
7138         is_set = 0;
7139       else if (unformat (i, "disable"))
7140         is_set = 0;
7141       else
7142         break;
7143     }
7144
7145   if (bd_id_set == 0)
7146     {
7147       errmsg ("missing bridge domain");
7148       return -99;
7149     }
7150
7151   M (BRIDGE_FLAGS, mp);
7152
7153   mp->bd_id = ntohl (bd_id);
7154   mp->flags = ntohl (flags);
7155   mp->is_set = is_set;
7156
7157   S (mp);
7158   W (ret);
7159   return ret;
7160 }
7161
7162 static int
7163 api_bd_ip_mac_add_del (vat_main_t * vam)
7164 {
7165   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7166   vl_api_mac_address_t mac = { 0 };
7167   unformat_input_t *i = vam->input;
7168   vl_api_bd_ip_mac_add_del_t *mp;
7169   u32 bd_id;
7170   u8 is_add = 1;
7171   u8 bd_id_set = 0;
7172   u8 ip_set = 0;
7173   u8 mac_set = 0;
7174   int ret;
7175
7176
7177   /* Parse args required to build the message */
7178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7179     {
7180       if (unformat (i, "bd_id %d", &bd_id))
7181         {
7182           bd_id_set++;
7183         }
7184       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7185         {
7186           ip_set++;
7187         }
7188       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7189         {
7190           mac_set++;
7191         }
7192       else if (unformat (i, "del"))
7193         is_add = 0;
7194       else
7195         break;
7196     }
7197
7198   if (bd_id_set == 0)
7199     {
7200       errmsg ("missing bridge domain");
7201       return -99;
7202     }
7203   else if (ip_set == 0)
7204     {
7205       errmsg ("missing IP address");
7206       return -99;
7207     }
7208   else if (mac_set == 0)
7209     {
7210       errmsg ("missing MAC address");
7211       return -99;
7212     }
7213
7214   M (BD_IP_MAC_ADD_DEL, mp);
7215
7216   mp->entry.bd_id = ntohl (bd_id);
7217   mp->is_add = is_add;
7218
7219   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7220   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7221
7222   S (mp);
7223   W (ret);
7224   return ret;
7225 }
7226
7227 static int
7228 api_bd_ip_mac_flush (vat_main_t * vam)
7229 {
7230   unformat_input_t *i = vam->input;
7231   vl_api_bd_ip_mac_flush_t *mp;
7232   u32 bd_id;
7233   u8 bd_id_set = 0;
7234   int ret;
7235
7236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7237     {
7238       if (unformat (i, "bd_id %d", &bd_id))
7239         {
7240           bd_id_set++;
7241         }
7242       else
7243         break;
7244     }
7245
7246   if (bd_id_set == 0)
7247     {
7248       errmsg ("missing bridge domain");
7249       return -99;
7250     }
7251
7252   M (BD_IP_MAC_FLUSH, mp);
7253
7254   mp->bd_id = ntohl (bd_id);
7255
7256   S (mp);
7257   W (ret);
7258   return ret;
7259 }
7260
7261 static void vl_api_bd_ip_mac_details_t_handler
7262   (vl_api_bd_ip_mac_details_t * mp)
7263 {
7264   vat_main_t *vam = &vat_main;
7265
7266   print (vam->ofp,
7267          "\n%-5d %U %U",
7268          ntohl (mp->entry.bd_id),
7269          format_vl_api_mac_address, mp->entry.mac,
7270          format_vl_api_address, &mp->entry.ip);
7271 }
7272
7273 static void vl_api_bd_ip_mac_details_t_handler_json
7274   (vl_api_bd_ip_mac_details_t * mp)
7275 {
7276   vat_main_t *vam = &vat_main;
7277   vat_json_node_t *node = NULL;
7278
7279   if (VAT_JSON_ARRAY != vam->json_tree.type)
7280     {
7281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7282       vat_json_init_array (&vam->json_tree);
7283     }
7284   node = vat_json_array_add (&vam->json_tree);
7285
7286   vat_json_init_object (node);
7287   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7288   vat_json_object_add_string_copy (node, "mac_address",
7289                                    format (0, "%U", format_vl_api_mac_address,
7290                                            &mp->entry.mac));
7291   u8 *ip = 0;
7292
7293   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7294   vat_json_object_add_string_copy (node, "ip_address", ip);
7295   vec_free (ip);
7296 }
7297
7298 static int
7299 api_bd_ip_mac_dump (vat_main_t * vam)
7300 {
7301   unformat_input_t *i = vam->input;
7302   vl_api_bd_ip_mac_dump_t *mp;
7303   vl_api_control_ping_t *mp_ping;
7304   int ret;
7305   u32 bd_id;
7306   u8 bd_id_set = 0;
7307
7308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7309     {
7310       if (unformat (i, "bd_id %d", &bd_id))
7311         {
7312           bd_id_set++;
7313         }
7314       else
7315         break;
7316     }
7317
7318   print (vam->ofp,
7319          "\n%-5s %-7s %-20s %-30s",
7320          "bd_id", "is_ipv6", "mac_address", "ip_address");
7321
7322   /* Dump Bridge Domain Ip to Mac entries */
7323   M (BD_IP_MAC_DUMP, mp);
7324
7325   if (bd_id_set)
7326     mp->bd_id = htonl (bd_id);
7327   else
7328     mp->bd_id = ~0;
7329
7330   S (mp);
7331
7332   /* Use a control ping for synchronization */
7333   MPING (CONTROL_PING, mp_ping);
7334   S (mp_ping);
7335
7336   W (ret);
7337   return ret;
7338 }
7339
7340 static int
7341 api_tap_create_v2 (vat_main_t * vam)
7342 {
7343   unformat_input_t *i = vam->input;
7344   vl_api_tap_create_v2_t *mp;
7345 #define TAP_FLAG_GSO (1 << 0)
7346   u8 mac_address[6];
7347   u8 random_mac = 1;
7348   u32 id = ~0;
7349   u8 *host_if_name = 0;
7350   u8 *host_ns = 0;
7351   u8 host_mac_addr[6];
7352   u8 host_mac_addr_set = 0;
7353   u8 *host_bridge = 0;
7354   ip4_address_t host_ip4_addr;
7355   ip4_address_t host_ip4_gw;
7356   u8 host_ip4_gw_set = 0;
7357   u32 host_ip4_prefix_len = 0;
7358   ip6_address_t host_ip6_addr;
7359   ip6_address_t host_ip6_gw;
7360   u8 host_ip6_gw_set = 0;
7361   u32 host_ip6_prefix_len = 0;
7362   u8 host_mtu_set = 0;
7363   u32 host_mtu_size = 0;
7364   u32 tap_flags = 0;
7365   int ret;
7366   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7367
7368   clib_memset (mac_address, 0, sizeof (mac_address));
7369
7370   /* Parse args required to build the message */
7371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7374         {
7375           random_mac = 0;
7376         }
7377       else if (unformat (i, "id %u", &id))
7378         ;
7379       else if (unformat (i, "host-if-name %s", &host_if_name))
7380         ;
7381       else if (unformat (i, "host-ns %s", &host_ns))
7382         ;
7383       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7384                          host_mac_addr))
7385         host_mac_addr_set = 1;
7386       else if (unformat (i, "host-bridge %s", &host_bridge))
7387         ;
7388       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7389                          &host_ip4_addr, &host_ip4_prefix_len))
7390         ;
7391       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7392                          &host_ip6_addr, &host_ip6_prefix_len))
7393         ;
7394       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7395                          &host_ip4_gw))
7396         host_ip4_gw_set = 1;
7397       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7398                          &host_ip6_gw))
7399         host_ip6_gw_set = 1;
7400       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7401         ;
7402       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7403         ;
7404       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7405         host_mtu_set = 1;
7406       else if (unformat (i, "no-gso"))
7407         tap_flags &= ~TAP_FLAG_GSO;
7408       else if (unformat (i, "gso"))
7409         tap_flags |= TAP_FLAG_GSO;
7410       else
7411         break;
7412     }
7413
7414   if (vec_len (host_if_name) > 63)
7415     {
7416       errmsg ("tap name too long. ");
7417       return -99;
7418     }
7419   if (vec_len (host_ns) > 63)
7420     {
7421       errmsg ("host name space too long. ");
7422       return -99;
7423     }
7424   if (vec_len (host_bridge) > 63)
7425     {
7426       errmsg ("host bridge name too long. ");
7427       return -99;
7428     }
7429   if (host_ip4_prefix_len > 32)
7430     {
7431       errmsg ("host ip4 prefix length not valid. ");
7432       return -99;
7433     }
7434   if (host_ip6_prefix_len > 128)
7435     {
7436       errmsg ("host ip6 prefix length not valid. ");
7437       return -99;
7438     }
7439   if (!is_pow2 (rx_ring_sz))
7440     {
7441       errmsg ("rx ring size must be power of 2. ");
7442       return -99;
7443     }
7444   if (rx_ring_sz > 32768)
7445     {
7446       errmsg ("rx ring size must be 32768 or lower. ");
7447       return -99;
7448     }
7449   if (!is_pow2 (tx_ring_sz))
7450     {
7451       errmsg ("tx ring size must be power of 2. ");
7452       return -99;
7453     }
7454   if (tx_ring_sz > 32768)
7455     {
7456       errmsg ("tx ring size must be 32768 or lower. ");
7457       return -99;
7458     }
7459   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7460     {
7461       errmsg ("host MTU size must be in between 64 and 65355. ");
7462       return -99;
7463     }
7464
7465   /* Construct the API message */
7466   M (TAP_CREATE_V2, mp);
7467
7468   mp->use_random_mac = random_mac;
7469
7470   mp->id = ntohl (id);
7471   mp->host_namespace_set = host_ns != 0;
7472   mp->host_bridge_set = host_bridge != 0;
7473   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7474   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7475   mp->rx_ring_sz = ntohs (rx_ring_sz);
7476   mp->tx_ring_sz = ntohs (tx_ring_sz);
7477   mp->host_mtu_set = host_mtu_set;
7478   mp->host_mtu_size = ntohl (host_mtu_size);
7479   mp->tap_flags = ntohl (tap_flags);
7480
7481   if (random_mac == 0)
7482     clib_memcpy (mp->mac_address, mac_address, 6);
7483   if (host_mac_addr_set)
7484     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7485   if (host_if_name)
7486     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7487   if (host_ns)
7488     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7489   if (host_bridge)
7490     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7491   if (host_ip4_prefix_len)
7492     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7493   if (host_ip6_prefix_len)
7494     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7495   if (host_ip4_gw_set)
7496     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7497   if (host_ip6_gw_set)
7498     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7499
7500   vec_free (host_ns);
7501   vec_free (host_if_name);
7502   vec_free (host_bridge);
7503
7504   /* send it... */
7505   S (mp);
7506
7507   /* Wait for a reply... */
7508   W (ret);
7509   return ret;
7510 }
7511
7512 static int
7513 api_tap_delete_v2 (vat_main_t * vam)
7514 {
7515   unformat_input_t *i = vam->input;
7516   vl_api_tap_delete_v2_t *mp;
7517   u32 sw_if_index = ~0;
7518   u8 sw_if_index_set = 0;
7519   int ret;
7520
7521   /* Parse args required to build the message */
7522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7523     {
7524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7525         sw_if_index_set = 1;
7526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7527         sw_if_index_set = 1;
7528       else
7529         break;
7530     }
7531
7532   if (sw_if_index_set == 0)
7533     {
7534       errmsg ("missing vpp interface name. ");
7535       return -99;
7536     }
7537
7538   /* Construct the API message */
7539   M (TAP_DELETE_V2, mp);
7540
7541   mp->sw_if_index = ntohl (sw_if_index);
7542
7543   /* send it... */
7544   S (mp);
7545
7546   /* Wait for a reply... */
7547   W (ret);
7548   return ret;
7549 }
7550
7551 uword
7552 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7553 {
7554   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7555   u32 x[4];
7556
7557   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7558     return 0;
7559
7560   addr->domain = x[0];
7561   addr->bus = x[1];
7562   addr->slot = x[2];
7563   addr->function = x[3];
7564
7565   return 1;
7566 }
7567
7568 static int
7569 api_virtio_pci_create (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_virtio_pci_create_t *mp;
7573   u8 mac_address[6];
7574   u8 random_mac = 1;
7575   u8 gso_enabled = 0;
7576   u32 pci_addr = 0;
7577   u64 features = (u64) ~ (0ULL);
7578   int ret;
7579
7580   clib_memset (mac_address, 0, sizeof (mac_address));
7581
7582   /* Parse args required to build the message */
7583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7584     {
7585       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7586         {
7587           random_mac = 0;
7588         }
7589       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7590         ;
7591       else if (unformat (i, "features 0x%llx", &features))
7592         ;
7593       else if (unformat (i, "gso-enabled"))
7594         gso_enabled = 1;
7595       else
7596         break;
7597     }
7598
7599   if (pci_addr == 0)
7600     {
7601       errmsg ("pci address must be non zero. ");
7602       return -99;
7603     }
7604
7605   /* Construct the API message */
7606   M (VIRTIO_PCI_CREATE, mp);
7607
7608   mp->use_random_mac = random_mac;
7609
7610   mp->pci_addr = htonl (pci_addr);
7611   mp->features = clib_host_to_net_u64 (features);
7612   mp->gso_enabled = gso_enabled;
7613
7614   if (random_mac == 0)
7615     clib_memcpy (mp->mac_address, mac_address, 6);
7616
7617   /* send it... */
7618   S (mp);
7619
7620   /* Wait for a reply... */
7621   W (ret);
7622   return ret;
7623 }
7624
7625 static int
7626 api_virtio_pci_delete (vat_main_t * vam)
7627 {
7628   unformat_input_t *i = vam->input;
7629   vl_api_virtio_pci_delete_t *mp;
7630   u32 sw_if_index = ~0;
7631   u8 sw_if_index_set = 0;
7632   int ret;
7633
7634   /* Parse args required to build the message */
7635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7636     {
7637       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7638         sw_if_index_set = 1;
7639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7640         sw_if_index_set = 1;
7641       else
7642         break;
7643     }
7644
7645   if (sw_if_index_set == 0)
7646     {
7647       errmsg ("missing vpp interface name. ");
7648       return -99;
7649     }
7650
7651   /* Construct the API message */
7652   M (VIRTIO_PCI_DELETE, mp);
7653
7654   mp->sw_if_index = htonl (sw_if_index);
7655
7656   /* send it... */
7657   S (mp);
7658
7659   /* Wait for a reply... */
7660   W (ret);
7661   return ret;
7662 }
7663
7664 static int
7665 api_bond_create (vat_main_t * vam)
7666 {
7667   unformat_input_t *i = vam->input;
7668   vl_api_bond_create_t *mp;
7669   u8 mac_address[6];
7670   u8 custom_mac = 0;
7671   int ret;
7672   u8 mode;
7673   u8 lb;
7674   u8 mode_is_set = 0;
7675   u32 id = ~0;
7676   u8 numa_only = 0;
7677
7678   clib_memset (mac_address, 0, sizeof (mac_address));
7679   lb = BOND_LB_L2;
7680
7681   /* Parse args required to build the message */
7682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7683     {
7684       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7685         mode_is_set = 1;
7686       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7687                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7688         ;
7689       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7690                          mac_address))
7691         custom_mac = 1;
7692       else if (unformat (i, "numa-only"))
7693         numa_only = 1;
7694       else if (unformat (i, "id %u", &id))
7695         ;
7696       else
7697         break;
7698     }
7699
7700   if (mode_is_set == 0)
7701     {
7702       errmsg ("Missing bond mode. ");
7703       return -99;
7704     }
7705
7706   /* Construct the API message */
7707   M (BOND_CREATE, mp);
7708
7709   mp->use_custom_mac = custom_mac;
7710
7711   mp->mode = htonl (mode);
7712   mp->lb = htonl (lb);
7713   mp->id = htonl (id);
7714   mp->numa_only = numa_only;
7715
7716   if (custom_mac)
7717     clib_memcpy (mp->mac_address, mac_address, 6);
7718
7719   /* send it... */
7720   S (mp);
7721
7722   /* Wait for a reply... */
7723   W (ret);
7724   return ret;
7725 }
7726
7727 static int
7728 api_bond_delete (vat_main_t * vam)
7729 {
7730   unformat_input_t *i = vam->input;
7731   vl_api_bond_delete_t *mp;
7732   u32 sw_if_index = ~0;
7733   u8 sw_if_index_set = 0;
7734   int ret;
7735
7736   /* Parse args required to build the message */
7737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738     {
7739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7740         sw_if_index_set = 1;
7741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7742         sw_if_index_set = 1;
7743       else
7744         break;
7745     }
7746
7747   if (sw_if_index_set == 0)
7748     {
7749       errmsg ("missing vpp interface name. ");
7750       return -99;
7751     }
7752
7753   /* Construct the API message */
7754   M (BOND_DELETE, mp);
7755
7756   mp->sw_if_index = ntohl (sw_if_index);
7757
7758   /* send it... */
7759   S (mp);
7760
7761   /* Wait for a reply... */
7762   W (ret);
7763   return ret;
7764 }
7765
7766 static int
7767 api_bond_enslave (vat_main_t * vam)
7768 {
7769   unformat_input_t *i = vam->input;
7770   vl_api_bond_enslave_t *mp;
7771   u32 bond_sw_if_index;
7772   int ret;
7773   u8 is_passive;
7774   u8 is_long_timeout;
7775   u32 bond_sw_if_index_is_set = 0;
7776   u32 sw_if_index;
7777   u8 sw_if_index_is_set = 0;
7778
7779   /* Parse args required to build the message */
7780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7781     {
7782       if (unformat (i, "sw_if_index %d", &sw_if_index))
7783         sw_if_index_is_set = 1;
7784       else if (unformat (i, "bond %u", &bond_sw_if_index))
7785         bond_sw_if_index_is_set = 1;
7786       else if (unformat (i, "passive %d", &is_passive))
7787         ;
7788       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7789         ;
7790       else
7791         break;
7792     }
7793
7794   if (bond_sw_if_index_is_set == 0)
7795     {
7796       errmsg ("Missing bond sw_if_index. ");
7797       return -99;
7798     }
7799   if (sw_if_index_is_set == 0)
7800     {
7801       errmsg ("Missing slave sw_if_index. ");
7802       return -99;
7803     }
7804
7805   /* Construct the API message */
7806   M (BOND_ENSLAVE, mp);
7807
7808   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7809   mp->sw_if_index = ntohl (sw_if_index);
7810   mp->is_long_timeout = is_long_timeout;
7811   mp->is_passive = is_passive;
7812
7813   /* send it... */
7814   S (mp);
7815
7816   /* Wait for a reply... */
7817   W (ret);
7818   return ret;
7819 }
7820
7821 static int
7822 api_bond_detach_slave (vat_main_t * vam)
7823 {
7824   unformat_input_t *i = vam->input;
7825   vl_api_bond_detach_slave_t *mp;
7826   u32 sw_if_index = ~0;
7827   u8 sw_if_index_set = 0;
7828   int ret;
7829
7830   /* Parse args required to build the message */
7831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7832     {
7833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7834         sw_if_index_set = 1;
7835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7836         sw_if_index_set = 1;
7837       else
7838         break;
7839     }
7840
7841   if (sw_if_index_set == 0)
7842     {
7843       errmsg ("missing vpp interface name. ");
7844       return -99;
7845     }
7846
7847   /* Construct the API message */
7848   M (BOND_DETACH_SLAVE, mp);
7849
7850   mp->sw_if_index = ntohl (sw_if_index);
7851
7852   /* send it... */
7853   S (mp);
7854
7855   /* Wait for a reply... */
7856   W (ret);
7857   return ret;
7858 }
7859
7860 static int
7861 api_ip_table_add_del (vat_main_t * vam)
7862 {
7863   unformat_input_t *i = vam->input;
7864   vl_api_ip_table_add_del_t *mp;
7865   u32 table_id = ~0;
7866   u8 is_ipv6 = 0;
7867   u8 is_add = 1;
7868   int ret = 0;
7869
7870   /* Parse args required to build the message */
7871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7872     {
7873       if (unformat (i, "ipv6"))
7874         is_ipv6 = 1;
7875       else if (unformat (i, "del"))
7876         is_add = 0;
7877       else if (unformat (i, "add"))
7878         is_add = 1;
7879       else if (unformat (i, "table %d", &table_id))
7880         ;
7881       else
7882         {
7883           clib_warning ("parse error '%U'", format_unformat_error, i);
7884           return -99;
7885         }
7886     }
7887
7888   if (~0 == table_id)
7889     {
7890       errmsg ("missing table-ID");
7891       return -99;
7892     }
7893
7894   /* Construct the API message */
7895   M (IP_TABLE_ADD_DEL, mp);
7896
7897   mp->table.table_id = ntohl (table_id);
7898   mp->table.is_ip6 = is_ipv6;
7899   mp->is_add = is_add;
7900
7901   /* send it... */
7902   S (mp);
7903
7904   /* Wait for a reply... */
7905   W (ret);
7906
7907   return ret;
7908 }
7909
7910 uword
7911 unformat_fib_path (unformat_input_t * input, va_list * args)
7912 {
7913   vat_main_t *vam = va_arg (*args, vat_main_t *);
7914   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7915   u32 weight, preference;
7916   mpls_label_t out_label;
7917
7918   clib_memset (path, 0, sizeof (*path));
7919   path->weight = 1;
7920   path->sw_if_index = ~0;
7921   path->rpf_id = ~0;
7922   path->n_labels = 0;
7923
7924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7925     {
7926       if (unformat (input, "%U %U",
7927                     unformat_vl_api_ip4_address,
7928                     &path->nh.address.ip4,
7929                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7930         {
7931           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7932         }
7933       else if (unformat (input, "%U %U",
7934                          unformat_vl_api_ip6_address,
7935                          &path->nh.address.ip6,
7936                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7939         }
7940       else if (unformat (input, "weight %u", &weight))
7941         {
7942           path->weight = weight;
7943         }
7944       else if (unformat (input, "preference %u", &preference))
7945         {
7946           path->preference = preference;
7947         }
7948       else if (unformat (input, "%U next-hop-table %d",
7949                          unformat_vl_api_ip4_address,
7950                          &path->nh.address.ip4, &path->table_id))
7951         {
7952           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7953         }
7954       else if (unformat (input, "%U next-hop-table %d",
7955                          unformat_vl_api_ip6_address,
7956                          &path->nh.address.ip6, &path->table_id))
7957         {
7958           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7959         }
7960       else if (unformat (input, "%U",
7961                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7962         {
7963           /*
7964            * the recursive next-hops are by default in the default table
7965            */
7966           path->table_id = 0;
7967           path->sw_if_index = ~0;
7968           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7969         }
7970       else if (unformat (input, "%U",
7971                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7972         {
7973           /*
7974            * the recursive next-hops are by default in the default table
7975            */
7976           path->table_id = 0;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7979         }
7980       else if (unformat (input, "resolve-via-host"))
7981         {
7982           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7983         }
7984       else if (unformat (input, "resolve-via-attached"))
7985         {
7986           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7987         }
7988       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7989         {
7990           path->type = FIB_API_PATH_TYPE_LOCAL;
7991           path->sw_if_index = ~0;
7992           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7993         }
7994       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7995         {
7996           path->type = FIB_API_PATH_TYPE_LOCAL;
7997           path->sw_if_index = ~0;
7998           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7999         }
8000       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8001         ;
8002       else if (unformat (input, "via-label %d", &path->nh.via_label))
8003         {
8004           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8005           path->sw_if_index = ~0;
8006         }
8007       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8008         {
8009           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8010           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8011         }
8012       else if (unformat (input, "local"))
8013         {
8014           path->type = FIB_API_PATH_TYPE_LOCAL;
8015         }
8016       else if (unformat (input, "out-labels"))
8017         {
8018           while (unformat (input, "%d", &out_label))
8019             {
8020               path->label_stack[path->n_labels].label = out_label;
8021               path->label_stack[path->n_labels].is_uniform = 0;
8022               path->label_stack[path->n_labels].ttl = 64;
8023               path->n_labels++;
8024             }
8025         }
8026       else if (unformat (input, "via"))
8027         {
8028           /* new path, back up and return */
8029           unformat_put_input (input);
8030           unformat_put_input (input);
8031           unformat_put_input (input);
8032           unformat_put_input (input);
8033           break;
8034         }
8035       else
8036         {
8037           return (0);
8038         }
8039     }
8040
8041   path->proto = ntohl (path->proto);
8042   path->type = ntohl (path->type);
8043   path->flags = ntohl (path->flags);
8044   path->table_id = ntohl (path->table_id);
8045   path->sw_if_index = ntohl (path->sw_if_index);
8046
8047   return (1);
8048 }
8049
8050 static int
8051 api_ip_route_add_del (vat_main_t * vam)
8052 {
8053   unformat_input_t *i = vam->input;
8054   vl_api_ip_route_add_del_t *mp;
8055   u32 vrf_id = 0;
8056   u8 is_add = 1;
8057   u8 is_multipath = 0;
8058   u8 prefix_set = 0;
8059   u8 path_count = 0;
8060   vl_api_prefix_t pfx = { };
8061   vl_api_fib_path_t paths[8];
8062   int count = 1;
8063   int j;
8064   f64 before = 0;
8065   u32 random_add_del = 0;
8066   u32 *random_vector = 0;
8067   u32 random_seed = 0xdeaddabe;
8068
8069   /* Parse args required to build the message */
8070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8073         prefix_set = 1;
8074       else if (unformat (i, "del"))
8075         is_add = 0;
8076       else if (unformat (i, "add"))
8077         is_add = 1;
8078       else if (unformat (i, "vrf %d", &vrf_id))
8079         ;
8080       else if (unformat (i, "count %d", &count))
8081         ;
8082       else if (unformat (i, "random"))
8083         random_add_del = 1;
8084       else if (unformat (i, "multipath"))
8085         is_multipath = 1;
8086       else if (unformat (i, "seed %d", &random_seed))
8087         ;
8088       else
8089         if (unformat
8090             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8091         {
8092           path_count++;
8093           if (8 == path_count)
8094             {
8095               errmsg ("max 8 paths");
8096               return -99;
8097             }
8098         }
8099       else
8100         {
8101           clib_warning ("parse error '%U'", format_unformat_error, i);
8102           return -99;
8103         }
8104     }
8105
8106   if (!path_count)
8107     {
8108       errmsg ("specify a path; via ...");
8109       return -99;
8110     }
8111   if (prefix_set == 0)
8112     {
8113       errmsg ("missing prefix");
8114       return -99;
8115     }
8116
8117   /* Generate a pile of unique, random routes */
8118   if (random_add_del)
8119     {
8120       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8121       u32 this_random_address;
8122       uword *random_hash;
8123
8124       random_hash = hash_create (count, sizeof (uword));
8125
8126       hash_set (random_hash, i->as_u32, 1);
8127       for (j = 0; j <= count; j++)
8128         {
8129           do
8130             {
8131               this_random_address = random_u32 (&random_seed);
8132               this_random_address =
8133                 clib_host_to_net_u32 (this_random_address);
8134             }
8135           while (hash_get (random_hash, this_random_address));
8136           vec_add1 (random_vector, this_random_address);
8137           hash_set (random_hash, this_random_address, 1);
8138         }
8139       hash_free (random_hash);
8140       set_ip4_address (&pfx.address, random_vector[0]);
8141     }
8142
8143   if (count > 1)
8144     {
8145       /* Turn on async mode */
8146       vam->async_mode = 1;
8147       vam->async_errors = 0;
8148       before = vat_time_now (vam);
8149     }
8150
8151   for (j = 0; j < count; j++)
8152     {
8153       /* Construct the API message */
8154       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8155
8156       mp->is_add = is_add;
8157       mp->is_multipath = is_multipath;
8158
8159       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8160       mp->route.table_id = ntohl (vrf_id);
8161       mp->route.n_paths = path_count;
8162
8163       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8164
8165       if (random_add_del)
8166         set_ip4_address (&pfx.address, random_vector[j + 1]);
8167       else
8168         increment_address (&pfx.address);
8169       /* send it... */
8170       S (mp);
8171       /* If we receive SIGTERM, stop now... */
8172       if (vam->do_exit)
8173         break;
8174     }
8175
8176   /* When testing multiple add/del ops, use a control-ping to sync */
8177   if (count > 1)
8178     {
8179       vl_api_control_ping_t *mp_ping;
8180       f64 after;
8181       f64 timeout;
8182
8183       /* Shut off async mode */
8184       vam->async_mode = 0;
8185
8186       MPING (CONTROL_PING, mp_ping);
8187       S (mp_ping);
8188
8189       timeout = vat_time_now (vam) + 1.0;
8190       while (vat_time_now (vam) < timeout)
8191         if (vam->result_ready == 1)
8192           goto out;
8193       vam->retval = -99;
8194
8195     out:
8196       if (vam->retval == -99)
8197         errmsg ("timeout");
8198
8199       if (vam->async_errors > 0)
8200         {
8201           errmsg ("%d asynchronous errors", vam->async_errors);
8202           vam->retval = -98;
8203         }
8204       vam->async_errors = 0;
8205       after = vat_time_now (vam);
8206
8207       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8208       if (j > 0)
8209         count = j;
8210
8211       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8212              count, after - before, count / (after - before));
8213     }
8214   else
8215     {
8216       int ret;
8217
8218       /* Wait for a reply... */
8219       W (ret);
8220       return ret;
8221     }
8222
8223   /* Return the good/bad news */
8224   return (vam->retval);
8225 }
8226
8227 static int
8228 api_ip_mroute_add_del (vat_main_t * vam)
8229 {
8230   unformat_input_t *i = vam->input;
8231   u8 path_set = 0, prefix_set = 0, is_add = 1;
8232   vl_api_ip_mroute_add_del_t *mp;
8233   mfib_entry_flags_t eflags = 0;
8234   vl_api_mfib_path_t path;
8235   vl_api_mprefix_t pfx = { };
8236   u32 vrf_id = 0;
8237   int ret;
8238
8239   /* Parse args required to build the message */
8240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8241     {
8242       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8243         {
8244           prefix_set = 1;
8245           pfx.grp_address_length = htons (pfx.grp_address_length);
8246         }
8247       else if (unformat (i, "del"))
8248         is_add = 0;
8249       else if (unformat (i, "add"))
8250         is_add = 1;
8251       else if (unformat (i, "vrf %d", &vrf_id))
8252         ;
8253       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8254         path.itf_flags = htonl (path.itf_flags);
8255       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8256         ;
8257       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8258         path_set = 1;
8259       else
8260         {
8261           clib_warning ("parse error '%U'", format_unformat_error, i);
8262           return -99;
8263         }
8264     }
8265
8266   if (prefix_set == 0)
8267     {
8268       errmsg ("missing addresses\n");
8269       return -99;
8270     }
8271   if (path_set == 0)
8272     {
8273       errmsg ("missing path\n");
8274       return -99;
8275     }
8276
8277   /* Construct the API message */
8278   M (IP_MROUTE_ADD_DEL, mp);
8279
8280   mp->is_add = is_add;
8281   mp->is_multipath = 1;
8282
8283   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8284   mp->route.table_id = htonl (vrf_id);
8285   mp->route.n_paths = 1;
8286   mp->route.entry_flags = htonl (eflags);
8287
8288   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8289
8290   /* send it... */
8291   S (mp);
8292   /* Wait for a reply... */
8293   W (ret);
8294   return ret;
8295 }
8296
8297 static int
8298 api_mpls_table_add_del (vat_main_t * vam)
8299 {
8300   unformat_input_t *i = vam->input;
8301   vl_api_mpls_table_add_del_t *mp;
8302   u32 table_id = ~0;
8303   u8 is_add = 1;
8304   int ret = 0;
8305
8306   /* Parse args required to build the message */
8307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8308     {
8309       if (unformat (i, "table %d", &table_id))
8310         ;
8311       else if (unformat (i, "del"))
8312         is_add = 0;
8313       else if (unformat (i, "add"))
8314         is_add = 1;
8315       else
8316         {
8317           clib_warning ("parse error '%U'", format_unformat_error, i);
8318           return -99;
8319         }
8320     }
8321
8322   if (~0 == table_id)
8323     {
8324       errmsg ("missing table-ID");
8325       return -99;
8326     }
8327
8328   /* Construct the API message */
8329   M (MPLS_TABLE_ADD_DEL, mp);
8330
8331   mp->mt_table.mt_table_id = ntohl (table_id);
8332   mp->mt_is_add = is_add;
8333
8334   /* send it... */
8335   S (mp);
8336
8337   /* Wait for a reply... */
8338   W (ret);
8339
8340   return ret;
8341 }
8342
8343 static int
8344 api_mpls_route_add_del (vat_main_t * vam)
8345 {
8346   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8347   mpls_label_t local_label = MPLS_LABEL_INVALID;
8348   unformat_input_t *i = vam->input;
8349   vl_api_mpls_route_add_del_t *mp;
8350   vl_api_fib_path_t paths[8];
8351   int count = 1, j;
8352   f64 before = 0;
8353
8354   /* Parse args required to build the message */
8355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8356     {
8357       if (unformat (i, "%d", &local_label))
8358         ;
8359       else if (unformat (i, "eos"))
8360         is_eos = 1;
8361       else if (unformat (i, "non-eos"))
8362         is_eos = 0;
8363       else if (unformat (i, "del"))
8364         is_add = 0;
8365       else if (unformat (i, "add"))
8366         is_add = 1;
8367       else if (unformat (i, "multipath"))
8368         is_multipath = 1;
8369       else if (unformat (i, "count %d", &count))
8370         ;
8371       else
8372         if (unformat
8373             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8374         {
8375           path_count++;
8376           if (8 == path_count)
8377             {
8378               errmsg ("max 8 paths");
8379               return -99;
8380             }
8381         }
8382       else
8383         {
8384           clib_warning ("parse error '%U'", format_unformat_error, i);
8385           return -99;
8386         }
8387     }
8388
8389   if (!path_count)
8390     {
8391       errmsg ("specify a path; via ...");
8392       return -99;
8393     }
8394
8395   if (MPLS_LABEL_INVALID == local_label)
8396     {
8397       errmsg ("missing label");
8398       return -99;
8399     }
8400
8401   if (count > 1)
8402     {
8403       /* Turn on async mode */
8404       vam->async_mode = 1;
8405       vam->async_errors = 0;
8406       before = vat_time_now (vam);
8407     }
8408
8409   for (j = 0; j < count; j++)
8410     {
8411       /* Construct the API message */
8412       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8413
8414       mp->mr_is_add = is_add;
8415       mp->mr_is_multipath = is_multipath;
8416
8417       mp->mr_route.mr_label = local_label;
8418       mp->mr_route.mr_eos = is_eos;
8419       mp->mr_route.mr_table_id = 0;
8420       mp->mr_route.mr_n_paths = path_count;
8421
8422       clib_memcpy (&mp->mr_route.mr_paths, paths,
8423                    sizeof (paths[0]) * path_count);
8424
8425       local_label++;
8426
8427       /* send it... */
8428       S (mp);
8429       /* If we receive SIGTERM, stop now... */
8430       if (vam->do_exit)
8431         break;
8432     }
8433
8434   /* When testing multiple add/del ops, use a control-ping to sync */
8435   if (count > 1)
8436     {
8437       vl_api_control_ping_t *mp_ping;
8438       f64 after;
8439       f64 timeout;
8440
8441       /* Shut off async mode */
8442       vam->async_mode = 0;
8443
8444       MPING (CONTROL_PING, mp_ping);
8445       S (mp_ping);
8446
8447       timeout = vat_time_now (vam) + 1.0;
8448       while (vat_time_now (vam) < timeout)
8449         if (vam->result_ready == 1)
8450           goto out;
8451       vam->retval = -99;
8452
8453     out:
8454       if (vam->retval == -99)
8455         errmsg ("timeout");
8456
8457       if (vam->async_errors > 0)
8458         {
8459           errmsg ("%d asynchronous errors", vam->async_errors);
8460           vam->retval = -98;
8461         }
8462       vam->async_errors = 0;
8463       after = vat_time_now (vam);
8464
8465       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8466       if (j > 0)
8467         count = j;
8468
8469       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8470              count, after - before, count / (after - before));
8471     }
8472   else
8473     {
8474       int ret;
8475
8476       /* Wait for a reply... */
8477       W (ret);
8478       return ret;
8479     }
8480
8481   /* Return the good/bad news */
8482   return (vam->retval);
8483   return (0);
8484 }
8485
8486 static int
8487 api_mpls_ip_bind_unbind (vat_main_t * vam)
8488 {
8489   unformat_input_t *i = vam->input;
8490   vl_api_mpls_ip_bind_unbind_t *mp;
8491   u32 ip_table_id = 0;
8492   u8 is_bind = 1;
8493   vl_api_prefix_t pfx;
8494   u8 prefix_set = 0;
8495   mpls_label_t local_label = MPLS_LABEL_INVALID;
8496   int ret;
8497
8498   /* Parse args required to build the message */
8499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8500     {
8501       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8502         prefix_set = 1;
8503       else if (unformat (i, "%d", &local_label))
8504         ;
8505       else if (unformat (i, "table-id %d", &ip_table_id))
8506         ;
8507       else if (unformat (i, "unbind"))
8508         is_bind = 0;
8509       else if (unformat (i, "bind"))
8510         is_bind = 1;
8511       else
8512         {
8513           clib_warning ("parse error '%U'", format_unformat_error, i);
8514           return -99;
8515         }
8516     }
8517
8518   if (!prefix_set)
8519     {
8520       errmsg ("IP prefix not set");
8521       return -99;
8522     }
8523
8524   if (MPLS_LABEL_INVALID == local_label)
8525     {
8526       errmsg ("missing label");
8527       return -99;
8528     }
8529
8530   /* Construct the API message */
8531   M (MPLS_IP_BIND_UNBIND, mp);
8532
8533   mp->mb_is_bind = is_bind;
8534   mp->mb_ip_table_id = ntohl (ip_table_id);
8535   mp->mb_mpls_table_id = 0;
8536   mp->mb_label = ntohl (local_label);
8537   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8538
8539   /* send it... */
8540   S (mp);
8541
8542   /* Wait for a reply... */
8543   W (ret);
8544   return ret;
8545   return (0);
8546 }
8547
8548 static int
8549 api_sr_mpls_policy_add (vat_main_t * vam)
8550 {
8551   unformat_input_t *i = vam->input;
8552   vl_api_sr_mpls_policy_add_t *mp;
8553   u32 bsid = 0;
8554   u32 weight = 1;
8555   u8 type = 0;
8556   u8 n_segments = 0;
8557   u32 sid;
8558   u32 *segments = NULL;
8559   int ret;
8560
8561   /* Parse args required to build the message */
8562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8563     {
8564       if (unformat (i, "bsid %d", &bsid))
8565         ;
8566       else if (unformat (i, "weight %d", &weight))
8567         ;
8568       else if (unformat (i, "spray"))
8569         type = 1;
8570       else if (unformat (i, "next %d", &sid))
8571         {
8572           n_segments += 1;
8573           vec_add1 (segments, htonl (sid));
8574         }
8575       else
8576         {
8577           clib_warning ("parse error '%U'", format_unformat_error, i);
8578           return -99;
8579         }
8580     }
8581
8582   if (bsid == 0)
8583     {
8584       errmsg ("bsid not set");
8585       return -99;
8586     }
8587
8588   if (n_segments == 0)
8589     {
8590       errmsg ("no sid in segment stack");
8591       return -99;
8592     }
8593
8594   /* Construct the API message */
8595   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8596
8597   mp->bsid = htonl (bsid);
8598   mp->weight = htonl (weight);
8599   mp->type = type;
8600   mp->n_segments = n_segments;
8601   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8602   vec_free (segments);
8603
8604   /* send it... */
8605   S (mp);
8606
8607   /* Wait for a reply... */
8608   W (ret);
8609   return ret;
8610 }
8611
8612 static int
8613 api_sr_mpls_policy_del (vat_main_t * vam)
8614 {
8615   unformat_input_t *i = vam->input;
8616   vl_api_sr_mpls_policy_del_t *mp;
8617   u32 bsid = 0;
8618   int ret;
8619
8620   /* Parse args required to build the message */
8621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8622     {
8623       if (unformat (i, "bsid %d", &bsid))
8624         ;
8625       else
8626         {
8627           clib_warning ("parse error '%U'", format_unformat_error, i);
8628           return -99;
8629         }
8630     }
8631
8632   if (bsid == 0)
8633     {
8634       errmsg ("bsid not set");
8635       return -99;
8636     }
8637
8638   /* Construct the API message */
8639   M (SR_MPLS_POLICY_DEL, mp);
8640
8641   mp->bsid = htonl (bsid);
8642
8643   /* send it... */
8644   S (mp);
8645
8646   /* Wait for a reply... */
8647   W (ret);
8648   return ret;
8649 }
8650
8651 static int
8652 api_bier_table_add_del (vat_main_t * vam)
8653 {
8654   unformat_input_t *i = vam->input;
8655   vl_api_bier_table_add_del_t *mp;
8656   u8 is_add = 1;
8657   u32 set = 0, sub_domain = 0, hdr_len = 3;
8658   mpls_label_t local_label = MPLS_LABEL_INVALID;
8659   int ret;
8660
8661   /* Parse args required to build the message */
8662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8663     {
8664       if (unformat (i, "sub-domain %d", &sub_domain))
8665         ;
8666       else if (unformat (i, "set %d", &set))
8667         ;
8668       else if (unformat (i, "label %d", &local_label))
8669         ;
8670       else if (unformat (i, "hdr-len %d", &hdr_len))
8671         ;
8672       else if (unformat (i, "add"))
8673         is_add = 1;
8674       else if (unformat (i, "del"))
8675         is_add = 0;
8676       else
8677         {
8678           clib_warning ("parse error '%U'", format_unformat_error, i);
8679           return -99;
8680         }
8681     }
8682
8683   if (MPLS_LABEL_INVALID == local_label)
8684     {
8685       errmsg ("missing label\n");
8686       return -99;
8687     }
8688
8689   /* Construct the API message */
8690   M (BIER_TABLE_ADD_DEL, mp);
8691
8692   mp->bt_is_add = is_add;
8693   mp->bt_label = ntohl (local_label);
8694   mp->bt_tbl_id.bt_set = set;
8695   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8696   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8697
8698   /* send it... */
8699   S (mp);
8700
8701   /* Wait for a reply... */
8702   W (ret);
8703
8704   return (ret);
8705 }
8706
8707 static int
8708 api_bier_route_add_del (vat_main_t * vam)
8709 {
8710   unformat_input_t *i = vam->input;
8711   vl_api_bier_route_add_del_t *mp;
8712   u8 is_add = 1;
8713   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8714   ip4_address_t v4_next_hop_address;
8715   ip6_address_t v6_next_hop_address;
8716   u8 next_hop_set = 0;
8717   u8 next_hop_proto_is_ip4 = 1;
8718   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8719   int ret;
8720
8721   /* Parse args required to build the message */
8722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8723     {
8724       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8725         {
8726           next_hop_proto_is_ip4 = 1;
8727           next_hop_set = 1;
8728         }
8729       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8730         {
8731           next_hop_proto_is_ip4 = 0;
8732           next_hop_set = 1;
8733         }
8734       if (unformat (i, "sub-domain %d", &sub_domain))
8735         ;
8736       else if (unformat (i, "set %d", &set))
8737         ;
8738       else if (unformat (i, "hdr-len %d", &hdr_len))
8739         ;
8740       else if (unformat (i, "bp %d", &bp))
8741         ;
8742       else if (unformat (i, "add"))
8743         is_add = 1;
8744       else if (unformat (i, "del"))
8745         is_add = 0;
8746       else if (unformat (i, "out-label %d", &next_hop_out_label))
8747         ;
8748       else
8749         {
8750           clib_warning ("parse error '%U'", format_unformat_error, i);
8751           return -99;
8752         }
8753     }
8754
8755   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8756     {
8757       errmsg ("next hop / label set\n");
8758       return -99;
8759     }
8760   if (0 == bp)
8761     {
8762       errmsg ("bit=position not set\n");
8763       return -99;
8764     }
8765
8766   /* Construct the API message */
8767   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8768
8769   mp->br_is_add = is_add;
8770   mp->br_route.br_tbl_id.bt_set = set;
8771   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8772   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8773   mp->br_route.br_bp = ntohs (bp);
8774   mp->br_route.br_n_paths = 1;
8775   mp->br_route.br_paths[0].n_labels = 1;
8776   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8777   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8778                                     FIB_API_PATH_NH_PROTO_IP4 :
8779                                     FIB_API_PATH_NH_PROTO_IP6);
8780
8781   if (next_hop_proto_is_ip4)
8782     {
8783       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8784                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8785     }
8786   else
8787     {
8788       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8789                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8790     }
8791
8792   /* send it... */
8793   S (mp);
8794
8795   /* Wait for a reply... */
8796   W (ret);
8797
8798   return (ret);
8799 }
8800
8801 static int
8802 api_proxy_arp_add_del (vat_main_t * vam)
8803 {
8804   unformat_input_t *i = vam->input;
8805   vl_api_proxy_arp_add_del_t *mp;
8806   u32 vrf_id = 0;
8807   u8 is_add = 1;
8808   vl_api_ip4_address_t lo, hi;
8809   u8 range_set = 0;
8810   int ret;
8811
8812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8813     {
8814       if (unformat (i, "vrf %d", &vrf_id))
8815         ;
8816       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8817                          unformat_vl_api_ip4_address, &hi))
8818         range_set = 1;
8819       else if (unformat (i, "del"))
8820         is_add = 0;
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   if (range_set == 0)
8829     {
8830       errmsg ("address range not set");
8831       return -99;
8832     }
8833
8834   M (PROXY_ARP_ADD_DEL, mp);
8835
8836   mp->proxy.table_id = ntohl (vrf_id);
8837   mp->is_add = is_add;
8838   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8839   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8840
8841   S (mp);
8842   W (ret);
8843   return ret;
8844 }
8845
8846 static int
8847 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8851   u32 sw_if_index;
8852   u8 enable = 1;
8853   u8 sw_if_index_set = 0;
8854   int ret;
8855
8856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8857     {
8858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8859         sw_if_index_set = 1;
8860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8861         sw_if_index_set = 1;
8862       else if (unformat (i, "enable"))
8863         enable = 1;
8864       else if (unformat (i, "disable"))
8865         enable = 0;
8866       else
8867         {
8868           clib_warning ("parse error '%U'", format_unformat_error, i);
8869           return -99;
8870         }
8871     }
8872
8873   if (sw_if_index_set == 0)
8874     {
8875       errmsg ("missing interface name or sw_if_index");
8876       return -99;
8877     }
8878
8879   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8880
8881   mp->sw_if_index = ntohl (sw_if_index);
8882   mp->enable_disable = enable;
8883
8884   S (mp);
8885   W (ret);
8886   return ret;
8887 }
8888
8889 static int
8890 api_mpls_tunnel_add_del (vat_main_t * vam)
8891 {
8892   unformat_input_t *i = vam->input;
8893   vl_api_mpls_tunnel_add_del_t *mp;
8894
8895   vl_api_fib_path_t paths[8];
8896   u32 sw_if_index = ~0;
8897   u8 path_count = 0;
8898   u8 l2_only = 0;
8899   u8 is_add = 1;
8900   int ret;
8901
8902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8903     {
8904       if (unformat (i, "add"))
8905         is_add = 1;
8906       else
8907         if (unformat
8908             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8909         is_add = 0;
8910       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8911         is_add = 0;
8912       else if (unformat (i, "l2-only"))
8913         l2_only = 1;
8914       else
8915         if (unformat
8916             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8917         {
8918           path_count++;
8919           if (8 == path_count)
8920             {
8921               errmsg ("max 8 paths");
8922               return -99;
8923             }
8924         }
8925       else
8926         {
8927           clib_warning ("parse error '%U'", format_unformat_error, i);
8928           return -99;
8929         }
8930     }
8931
8932   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8933
8934   mp->mt_is_add = is_add;
8935   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8936   mp->mt_tunnel.mt_l2_only = l2_only;
8937   mp->mt_tunnel.mt_is_multicast = 0;
8938   mp->mt_tunnel.mt_n_paths = path_count;
8939
8940   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8941                sizeof (paths[0]) * path_count);
8942
8943   S (mp);
8944   W (ret);
8945   return ret;
8946 }
8947
8948 static int
8949 api_sw_interface_set_unnumbered (vat_main_t * vam)
8950 {
8951   unformat_input_t *i = vam->input;
8952   vl_api_sw_interface_set_unnumbered_t *mp;
8953   u32 sw_if_index;
8954   u32 unnum_sw_index = ~0;
8955   u8 is_add = 1;
8956   u8 sw_if_index_set = 0;
8957   int ret;
8958
8959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8960     {
8961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8962         sw_if_index_set = 1;
8963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8964         sw_if_index_set = 1;
8965       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8966         ;
8967       else if (unformat (i, "del"))
8968         is_add = 0;
8969       else
8970         {
8971           clib_warning ("parse error '%U'", format_unformat_error, i);
8972           return -99;
8973         }
8974     }
8975
8976   if (sw_if_index_set == 0)
8977     {
8978       errmsg ("missing interface name or sw_if_index");
8979       return -99;
8980     }
8981
8982   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8983
8984   mp->sw_if_index = ntohl (sw_if_index);
8985   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8986   mp->is_add = is_add;
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_ip_neighbor_add_del (vat_main_t * vam)
8995 {
8996   vl_api_mac_address_t mac_address;
8997   unformat_input_t *i = vam->input;
8998   vl_api_ip_neighbor_add_del_t *mp;
8999   vl_api_address_t ip_address;
9000   u32 sw_if_index;
9001   u8 sw_if_index_set = 0;
9002   u8 is_add = 1;
9003   u8 mac_set = 0;
9004   u8 address_set = 0;
9005   int ret;
9006   ip_neighbor_flags_t flags;
9007
9008   flags = IP_NEIGHBOR_FLAG_NONE;
9009   clib_memset (&ip_address, 0, sizeof (ip_address));
9010   clib_memset (&mac_address, 0, sizeof (mac_address));
9011
9012   /* Parse args required to build the message */
9013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9014     {
9015       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9016         {
9017           mac_set = 1;
9018         }
9019       else if (unformat (i, "del"))
9020         is_add = 0;
9021       else
9022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9023         sw_if_index_set = 1;
9024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9025         sw_if_index_set = 1;
9026       else if (unformat (i, "static"))
9027         flags |= IP_NEIGHBOR_FLAG_STATIC;
9028       else if (unformat (i, "no-fib-entry"))
9029         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9030       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9031         address_set = 1;
9032       else
9033         {
9034           clib_warning ("parse error '%U'", format_unformat_error, i);
9035           return -99;
9036         }
9037     }
9038
9039   if (sw_if_index_set == 0)
9040     {
9041       errmsg ("missing interface name or sw_if_index");
9042       return -99;
9043     }
9044   if (!address_set)
9045     {
9046       errmsg ("no address set");
9047       return -99;
9048     }
9049
9050   /* Construct the API message */
9051   M (IP_NEIGHBOR_ADD_DEL, mp);
9052
9053   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9054   mp->is_add = is_add;
9055   mp->neighbor.flags = htonl (flags);
9056   if (mac_set)
9057     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9058                  sizeof (mac_address));
9059   if (address_set)
9060     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9061
9062   /* send it... */
9063   S (mp);
9064
9065   /* Wait for a reply, return good/bad news  */
9066   W (ret);
9067   return ret;
9068 }
9069
9070 static int
9071 api_create_vlan_subif (vat_main_t * vam)
9072 {
9073   unformat_input_t *i = vam->input;
9074   vl_api_create_vlan_subif_t *mp;
9075   u32 sw_if_index;
9076   u8 sw_if_index_set = 0;
9077   u32 vlan_id;
9078   u8 vlan_id_set = 0;
9079   int ret;
9080
9081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9082     {
9083       if (unformat (i, "sw_if_index %d", &sw_if_index))
9084         sw_if_index_set = 1;
9085       else
9086         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9087         sw_if_index_set = 1;
9088       else if (unformat (i, "vlan %d", &vlan_id))
9089         vlan_id_set = 1;
9090       else
9091         {
9092           clib_warning ("parse error '%U'", format_unformat_error, i);
9093           return -99;
9094         }
9095     }
9096
9097   if (sw_if_index_set == 0)
9098     {
9099       errmsg ("missing interface name or sw_if_index");
9100       return -99;
9101     }
9102
9103   if (vlan_id_set == 0)
9104     {
9105       errmsg ("missing vlan_id");
9106       return -99;
9107     }
9108   M (CREATE_VLAN_SUBIF, mp);
9109
9110   mp->sw_if_index = ntohl (sw_if_index);
9111   mp->vlan_id = ntohl (vlan_id);
9112
9113   S (mp);
9114   W (ret);
9115   return ret;
9116 }
9117
9118 #define foreach_create_subif_bit                \
9119 _(no_tags)                                      \
9120 _(one_tag)                                      \
9121 _(two_tags)                                     \
9122 _(dot1ad)                                       \
9123 _(exact_match)                                  \
9124 _(default_sub)                                  \
9125 _(outer_vlan_id_any)                            \
9126 _(inner_vlan_id_any)
9127
9128 #define foreach_create_subif_flag               \
9129 _(0, "no_tags")                                 \
9130 _(1, "one_tag")                                 \
9131 _(2, "two_tags")                                \
9132 _(3, "dot1ad")                                  \
9133 _(4, "exact_match")                             \
9134 _(5, "default_sub")                             \
9135 _(6, "outer_vlan_id_any")                       \
9136 _(7, "inner_vlan_id_any")
9137
9138 static int
9139 api_create_subif (vat_main_t * vam)
9140 {
9141   unformat_input_t *i = vam->input;
9142   vl_api_create_subif_t *mp;
9143   u32 sw_if_index;
9144   u8 sw_if_index_set = 0;
9145   u32 sub_id;
9146   u8 sub_id_set = 0;
9147   u32 __attribute__ ((unused)) no_tags = 0;
9148   u32 __attribute__ ((unused)) one_tag = 0;
9149   u32 __attribute__ ((unused)) two_tags = 0;
9150   u32 __attribute__ ((unused)) dot1ad = 0;
9151   u32 __attribute__ ((unused)) exact_match = 0;
9152   u32 __attribute__ ((unused)) default_sub = 0;
9153   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9154   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9155   u32 tmp;
9156   u16 outer_vlan_id = 0;
9157   u16 inner_vlan_id = 0;
9158   int ret;
9159
9160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9161     {
9162       if (unformat (i, "sw_if_index %d", &sw_if_index))
9163         sw_if_index_set = 1;
9164       else
9165         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9166         sw_if_index_set = 1;
9167       else if (unformat (i, "sub_id %d", &sub_id))
9168         sub_id_set = 1;
9169       else if (unformat (i, "outer_vlan_id %d", &tmp))
9170         outer_vlan_id = tmp;
9171       else if (unformat (i, "inner_vlan_id %d", &tmp))
9172         inner_vlan_id = tmp;
9173
9174 #define _(a) else if (unformat (i, #a)) a = 1 ;
9175       foreach_create_subif_bit
9176 #undef _
9177         else
9178         {
9179           clib_warning ("parse error '%U'", format_unformat_error, i);
9180           return -99;
9181         }
9182     }
9183
9184   if (sw_if_index_set == 0)
9185     {
9186       errmsg ("missing interface name or sw_if_index");
9187       return -99;
9188     }
9189
9190   if (sub_id_set == 0)
9191     {
9192       errmsg ("missing sub_id");
9193       return -99;
9194     }
9195   M (CREATE_SUBIF, mp);
9196
9197   mp->sw_if_index = ntohl (sw_if_index);
9198   mp->sub_id = ntohl (sub_id);
9199
9200 #define _(a,b) mp->sub_if_flags |= (1 << a);
9201   foreach_create_subif_flag;
9202 #undef _
9203
9204   mp->outer_vlan_id = ntohs (outer_vlan_id);
9205   mp->inner_vlan_id = ntohs (inner_vlan_id);
9206
9207   S (mp);
9208   W (ret);
9209   return ret;
9210 }
9211
9212 static int
9213 api_reset_fib (vat_main_t * vam)
9214 {
9215   unformat_input_t *i = vam->input;
9216   vl_api_reset_fib_t *mp;
9217   u32 vrf_id = 0;
9218   u8 is_ipv6 = 0;
9219   u8 vrf_id_set = 0;
9220
9221   int ret;
9222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9223     {
9224       if (unformat (i, "vrf %d", &vrf_id))
9225         vrf_id_set = 1;
9226       else if (unformat (i, "ipv6"))
9227         is_ipv6 = 1;
9228       else
9229         {
9230           clib_warning ("parse error '%U'", format_unformat_error, i);
9231           return -99;
9232         }
9233     }
9234
9235   if (vrf_id_set == 0)
9236     {
9237       errmsg ("missing vrf id");
9238       return -99;
9239     }
9240
9241   M (RESET_FIB, mp);
9242
9243   mp->vrf_id = ntohl (vrf_id);
9244   mp->is_ipv6 = is_ipv6;
9245
9246   S (mp);
9247   W (ret);
9248   return ret;
9249 }
9250
9251 static int
9252 api_set_ip_flow_hash (vat_main_t * vam)
9253 {
9254   unformat_input_t *i = vam->input;
9255   vl_api_set_ip_flow_hash_t *mp;
9256   u32 vrf_id = 0;
9257   u8 is_ipv6 = 0;
9258   u8 vrf_id_set = 0;
9259   u8 src = 0;
9260   u8 dst = 0;
9261   u8 sport = 0;
9262   u8 dport = 0;
9263   u8 proto = 0;
9264   u8 reverse = 0;
9265   int ret;
9266
9267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9268     {
9269       if (unformat (i, "vrf %d", &vrf_id))
9270         vrf_id_set = 1;
9271       else if (unformat (i, "ipv6"))
9272         is_ipv6 = 1;
9273       else if (unformat (i, "src"))
9274         src = 1;
9275       else if (unformat (i, "dst"))
9276         dst = 1;
9277       else if (unformat (i, "sport"))
9278         sport = 1;
9279       else if (unformat (i, "dport"))
9280         dport = 1;
9281       else if (unformat (i, "proto"))
9282         proto = 1;
9283       else if (unformat (i, "reverse"))
9284         reverse = 1;
9285
9286       else
9287         {
9288           clib_warning ("parse error '%U'", format_unformat_error, i);
9289           return -99;
9290         }
9291     }
9292
9293   if (vrf_id_set == 0)
9294     {
9295       errmsg ("missing vrf id");
9296       return -99;
9297     }
9298
9299   M (SET_IP_FLOW_HASH, mp);
9300   mp->src = src;
9301   mp->dst = dst;
9302   mp->sport = sport;
9303   mp->dport = dport;
9304   mp->proto = proto;
9305   mp->reverse = reverse;
9306   mp->vrf_id = ntohl (vrf_id);
9307   mp->is_ipv6 = is_ipv6;
9308
9309   S (mp);
9310   W (ret);
9311   return ret;
9312 }
9313
9314 static int
9315 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9316 {
9317   unformat_input_t *i = vam->input;
9318   vl_api_sw_interface_ip6_enable_disable_t *mp;
9319   u32 sw_if_index;
9320   u8 sw_if_index_set = 0;
9321   u8 enable = 0;
9322   int ret;
9323
9324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9325     {
9326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9329         sw_if_index_set = 1;
9330       else if (unformat (i, "enable"))
9331         enable = 1;
9332       else if (unformat (i, "disable"))
9333         enable = 0;
9334       else
9335         {
9336           clib_warning ("parse error '%U'", format_unformat_error, i);
9337           return -99;
9338         }
9339     }
9340
9341   if (sw_if_index_set == 0)
9342     {
9343       errmsg ("missing interface name or sw_if_index");
9344       return -99;
9345     }
9346
9347   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9348
9349   mp->sw_if_index = ntohl (sw_if_index);
9350   mp->enable = enable;
9351
9352   S (mp);
9353   W (ret);
9354   return ret;
9355 }
9356
9357 static int
9358 api_ip6nd_proxy_add_del (vat_main_t * vam)
9359 {
9360   unformat_input_t *i = vam->input;
9361   vl_api_ip6nd_proxy_add_del_t *mp;
9362   u32 sw_if_index = ~0;
9363   u8 v6_address_set = 0;
9364   vl_api_ip6_address_t v6address;
9365   u8 is_del = 0;
9366   int ret;
9367
9368   /* Parse args required to build the message */
9369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9370     {
9371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9372         ;
9373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9374         ;
9375       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9376         v6_address_set = 1;
9377       if (unformat (i, "del"))
9378         is_del = 1;
9379       else
9380         {
9381           clib_warning ("parse error '%U'", format_unformat_error, i);
9382           return -99;
9383         }
9384     }
9385
9386   if (sw_if_index == ~0)
9387     {
9388       errmsg ("missing interface name or sw_if_index");
9389       return -99;
9390     }
9391   if (!v6_address_set)
9392     {
9393       errmsg ("no address set");
9394       return -99;
9395     }
9396
9397   /* Construct the API message */
9398   M (IP6ND_PROXY_ADD_DEL, mp);
9399
9400   mp->is_del = is_del;
9401   mp->sw_if_index = ntohl (sw_if_index);
9402   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9403
9404   /* send it... */
9405   S (mp);
9406
9407   /* Wait for a reply, return good/bad news  */
9408   W (ret);
9409   return ret;
9410 }
9411
9412 static int
9413 api_ip6nd_proxy_dump (vat_main_t * vam)
9414 {
9415   vl_api_ip6nd_proxy_dump_t *mp;
9416   vl_api_control_ping_t *mp_ping;
9417   int ret;
9418
9419   M (IP6ND_PROXY_DUMP, mp);
9420
9421   S (mp);
9422
9423   /* Use a control ping for synchronization */
9424   MPING (CONTROL_PING, mp_ping);
9425   S (mp_ping);
9426
9427   W (ret);
9428   return ret;
9429 }
9430
9431 static void vl_api_ip6nd_proxy_details_t_handler
9432   (vl_api_ip6nd_proxy_details_t * mp)
9433 {
9434   vat_main_t *vam = &vat_main;
9435
9436   print (vam->ofp, "host %U sw_if_index %d",
9437          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9438 }
9439
9440 static void vl_api_ip6nd_proxy_details_t_handler_json
9441   (vl_api_ip6nd_proxy_details_t * mp)
9442 {
9443   vat_main_t *vam = &vat_main;
9444   struct in6_addr ip6;
9445   vat_json_node_t *node = NULL;
9446
9447   if (VAT_JSON_ARRAY != vam->json_tree.type)
9448     {
9449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9450       vat_json_init_array (&vam->json_tree);
9451     }
9452   node = vat_json_array_add (&vam->json_tree);
9453
9454   vat_json_init_object (node);
9455   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9456
9457   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9458   vat_json_object_add_ip6 (node, "host", ip6);
9459 }
9460
9461 static int
9462 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9463 {
9464   unformat_input_t *i = vam->input;
9465   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9466   u32 sw_if_index;
9467   u8 sw_if_index_set = 0;
9468   u8 v6_address_set = 0;
9469   vl_api_prefix_t pfx;
9470   u8 use_default = 0;
9471   u8 no_advertise = 0;
9472   u8 off_link = 0;
9473   u8 no_autoconfig = 0;
9474   u8 no_onlink = 0;
9475   u8 is_no = 0;
9476   u32 val_lifetime = 0;
9477   u32 pref_lifetime = 0;
9478   int ret;
9479
9480   /* Parse args required to build the message */
9481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9482     {
9483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9484         sw_if_index_set = 1;
9485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9486         sw_if_index_set = 1;
9487       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9488         v6_address_set = 1;
9489       else if (unformat (i, "val_life %d", &val_lifetime))
9490         ;
9491       else if (unformat (i, "pref_life %d", &pref_lifetime))
9492         ;
9493       else if (unformat (i, "def"))
9494         use_default = 1;
9495       else if (unformat (i, "noadv"))
9496         no_advertise = 1;
9497       else if (unformat (i, "offl"))
9498         off_link = 1;
9499       else if (unformat (i, "noauto"))
9500         no_autoconfig = 1;
9501       else if (unformat (i, "nolink"))
9502         no_onlink = 1;
9503       else if (unformat (i, "isno"))
9504         is_no = 1;
9505       else
9506         {
9507           clib_warning ("parse error '%U'", format_unformat_error, i);
9508           return -99;
9509         }
9510     }
9511
9512   if (sw_if_index_set == 0)
9513     {
9514       errmsg ("missing interface name or sw_if_index");
9515       return -99;
9516     }
9517   if (!v6_address_set)
9518     {
9519       errmsg ("no address set");
9520       return -99;
9521     }
9522
9523   /* Construct the API message */
9524   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9525
9526   mp->sw_if_index = ntohl (sw_if_index);
9527   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9528   mp->use_default = use_default;
9529   mp->no_advertise = no_advertise;
9530   mp->off_link = off_link;
9531   mp->no_autoconfig = no_autoconfig;
9532   mp->no_onlink = no_onlink;
9533   mp->is_no = is_no;
9534   mp->val_lifetime = ntohl (val_lifetime);
9535   mp->pref_lifetime = ntohl (pref_lifetime);
9536
9537   /* send it... */
9538   S (mp);
9539
9540   /* Wait for a reply, return good/bad news  */
9541   W (ret);
9542   return ret;
9543 }
9544
9545 static int
9546 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9547 {
9548   unformat_input_t *i = vam->input;
9549   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9550   u32 sw_if_index;
9551   u8 sw_if_index_set = 0;
9552   u8 suppress = 0;
9553   u8 managed = 0;
9554   u8 other = 0;
9555   u8 ll_option = 0;
9556   u8 send_unicast = 0;
9557   u8 cease = 0;
9558   u8 is_no = 0;
9559   u8 default_router = 0;
9560   u32 max_interval = 0;
9561   u32 min_interval = 0;
9562   u32 lifetime = 0;
9563   u32 initial_count = 0;
9564   u32 initial_interval = 0;
9565   int ret;
9566
9567
9568   /* Parse args required to build the message */
9569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9572         sw_if_index_set = 1;
9573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9574         sw_if_index_set = 1;
9575       else if (unformat (i, "maxint %d", &max_interval))
9576         ;
9577       else if (unformat (i, "minint %d", &min_interval))
9578         ;
9579       else if (unformat (i, "life %d", &lifetime))
9580         ;
9581       else if (unformat (i, "count %d", &initial_count))
9582         ;
9583       else if (unformat (i, "interval %d", &initial_interval))
9584         ;
9585       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9586         suppress = 1;
9587       else if (unformat (i, "managed"))
9588         managed = 1;
9589       else if (unformat (i, "other"))
9590         other = 1;
9591       else if (unformat (i, "ll"))
9592         ll_option = 1;
9593       else if (unformat (i, "send"))
9594         send_unicast = 1;
9595       else if (unformat (i, "cease"))
9596         cease = 1;
9597       else if (unformat (i, "isno"))
9598         is_no = 1;
9599       else if (unformat (i, "def"))
9600         default_router = 1;
9601       else
9602         {
9603           clib_warning ("parse error '%U'", format_unformat_error, i);
9604           return -99;
9605         }
9606     }
9607
9608   if (sw_if_index_set == 0)
9609     {
9610       errmsg ("missing interface name or sw_if_index");
9611       return -99;
9612     }
9613
9614   /* Construct the API message */
9615   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9616
9617   mp->sw_if_index = ntohl (sw_if_index);
9618   mp->max_interval = ntohl (max_interval);
9619   mp->min_interval = ntohl (min_interval);
9620   mp->lifetime = ntohl (lifetime);
9621   mp->initial_count = ntohl (initial_count);
9622   mp->initial_interval = ntohl (initial_interval);
9623   mp->suppress = suppress;
9624   mp->managed = managed;
9625   mp->other = other;
9626   mp->ll_option = ll_option;
9627   mp->send_unicast = send_unicast;
9628   mp->cease = cease;
9629   mp->is_no = is_no;
9630   mp->default_router = default_router;
9631
9632   /* send it... */
9633   S (mp);
9634
9635   /* Wait for a reply, return good/bad news  */
9636   W (ret);
9637   return ret;
9638 }
9639
9640 static int
9641 api_set_arp_neighbor_limit (vat_main_t * vam)
9642 {
9643   unformat_input_t *i = vam->input;
9644   vl_api_set_arp_neighbor_limit_t *mp;
9645   u32 arp_nbr_limit;
9646   u8 limit_set = 0;
9647   u8 is_ipv6 = 0;
9648   int ret;
9649
9650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9651     {
9652       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9653         limit_set = 1;
9654       else if (unformat (i, "ipv6"))
9655         is_ipv6 = 1;
9656       else
9657         {
9658           clib_warning ("parse error '%U'", format_unformat_error, i);
9659           return -99;
9660         }
9661     }
9662
9663   if (limit_set == 0)
9664     {
9665       errmsg ("missing limit value");
9666       return -99;
9667     }
9668
9669   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9670
9671   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9672   mp->is_ipv6 = is_ipv6;
9673
9674   S (mp);
9675   W (ret);
9676   return ret;
9677 }
9678
9679 static int
9680 api_l2_patch_add_del (vat_main_t * vam)
9681 {
9682   unformat_input_t *i = vam->input;
9683   vl_api_l2_patch_add_del_t *mp;
9684   u32 rx_sw_if_index;
9685   u8 rx_sw_if_index_set = 0;
9686   u32 tx_sw_if_index;
9687   u8 tx_sw_if_index_set = 0;
9688   u8 is_add = 1;
9689   int ret;
9690
9691   /* Parse args required to build the message */
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9695         rx_sw_if_index_set = 1;
9696       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9697         tx_sw_if_index_set = 1;
9698       else if (unformat (i, "rx"))
9699         {
9700           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9701             {
9702               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9703                             &rx_sw_if_index))
9704                 rx_sw_if_index_set = 1;
9705             }
9706           else
9707             break;
9708         }
9709       else if (unformat (i, "tx"))
9710         {
9711           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9712             {
9713               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9714                             &tx_sw_if_index))
9715                 tx_sw_if_index_set = 1;
9716             }
9717           else
9718             break;
9719         }
9720       else if (unformat (i, "del"))
9721         is_add = 0;
9722       else
9723         break;
9724     }
9725
9726   if (rx_sw_if_index_set == 0)
9727     {
9728       errmsg ("missing rx interface name or rx_sw_if_index");
9729       return -99;
9730     }
9731
9732   if (tx_sw_if_index_set == 0)
9733     {
9734       errmsg ("missing tx interface name or tx_sw_if_index");
9735       return -99;
9736     }
9737
9738   M (L2_PATCH_ADD_DEL, mp);
9739
9740   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9741   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9742   mp->is_add = is_add;
9743
9744   S (mp);
9745   W (ret);
9746   return ret;
9747 }
9748
9749 u8 is_del;
9750 u8 localsid_addr[16];
9751 u8 end_psp;
9752 u8 behavior;
9753 u32 sw_if_index;
9754 u32 vlan_index;
9755 u32 fib_table;
9756 u8 nh_addr[16];
9757
9758 static int
9759 api_sr_localsid_add_del (vat_main_t * vam)
9760 {
9761   unformat_input_t *i = vam->input;
9762   vl_api_sr_localsid_add_del_t *mp;
9763
9764   u8 is_del;
9765   ip6_address_t localsid;
9766   u8 end_psp = 0;
9767   u8 behavior = ~0;
9768   u32 sw_if_index;
9769   u32 fib_table = ~(u32) 0;
9770   ip6_address_t nh_addr6;
9771   ip4_address_t nh_addr4;
9772   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9773   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9774
9775   bool nexthop_set = 0;
9776
9777   int ret;
9778
9779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9780     {
9781       if (unformat (i, "del"))
9782         is_del = 1;
9783       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9784       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9785         nexthop_set = 1;
9786       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9787         nexthop_set = 1;
9788       else if (unformat (i, "behavior %u", &behavior));
9789       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9790       else if (unformat (i, "fib-table %u", &fib_table));
9791       else if (unformat (i, "end.psp %u", &behavior));
9792       else
9793         break;
9794     }
9795
9796   M (SR_LOCALSID_ADD_DEL, mp);
9797
9798   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9799   if (nexthop_set)
9800     {
9801       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9802       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9803     }
9804   mp->behavior = behavior;
9805   mp->sw_if_index = ntohl (sw_if_index);
9806   mp->fib_table = ntohl (fib_table);
9807   mp->end_psp = end_psp;
9808   mp->is_del = is_del;
9809
9810   S (mp);
9811   W (ret);
9812   return ret;
9813 }
9814
9815 static int
9816 api_ioam_enable (vat_main_t * vam)
9817 {
9818   unformat_input_t *input = vam->input;
9819   vl_api_ioam_enable_t *mp;
9820   u32 id = 0;
9821   int has_trace_option = 0;
9822   int has_pot_option = 0;
9823   int has_seqno_option = 0;
9824   int has_analyse_option = 0;
9825   int ret;
9826
9827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9828     {
9829       if (unformat (input, "trace"))
9830         has_trace_option = 1;
9831       else if (unformat (input, "pot"))
9832         has_pot_option = 1;
9833       else if (unformat (input, "seqno"))
9834         has_seqno_option = 1;
9835       else if (unformat (input, "analyse"))
9836         has_analyse_option = 1;
9837       else
9838         break;
9839     }
9840   M (IOAM_ENABLE, mp);
9841   mp->id = htons (id);
9842   mp->seqno = has_seqno_option;
9843   mp->analyse = has_analyse_option;
9844   mp->pot_enable = has_pot_option;
9845   mp->trace_enable = has_trace_option;
9846
9847   S (mp);
9848   W (ret);
9849   return ret;
9850 }
9851
9852
9853 static int
9854 api_ioam_disable (vat_main_t * vam)
9855 {
9856   vl_api_ioam_disable_t *mp;
9857   int ret;
9858
9859   M (IOAM_DISABLE, mp);
9860   S (mp);
9861   W (ret);
9862   return ret;
9863 }
9864
9865 #define foreach_tcp_proto_field                 \
9866 _(src_port)                                     \
9867 _(dst_port)
9868
9869 #define foreach_udp_proto_field                 \
9870 _(src_port)                                     \
9871 _(dst_port)
9872
9873 #define foreach_ip4_proto_field                 \
9874 _(src_address)                                  \
9875 _(dst_address)                                  \
9876 _(tos)                                          \
9877 _(length)                                       \
9878 _(fragment_id)                                  \
9879 _(ttl)                                          \
9880 _(protocol)                                     \
9881 _(checksum)
9882
9883 typedef struct
9884 {
9885   u16 src_port, dst_port;
9886 } tcpudp_header_t;
9887
9888 #if VPP_API_TEST_BUILTIN == 0
9889 uword
9890 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9891 {
9892   u8 **maskp = va_arg (*args, u8 **);
9893   u8 *mask = 0;
9894   u8 found_something = 0;
9895   tcp_header_t *tcp;
9896
9897 #define _(a) u8 a=0;
9898   foreach_tcp_proto_field;
9899 #undef _
9900
9901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9902     {
9903       if (0);
9904 #define _(a) else if (unformat (input, #a)) a=1;
9905       foreach_tcp_proto_field
9906 #undef _
9907         else
9908         break;
9909     }
9910
9911 #define _(a) found_something += a;
9912   foreach_tcp_proto_field;
9913 #undef _
9914
9915   if (found_something == 0)
9916     return 0;
9917
9918   vec_validate (mask, sizeof (*tcp) - 1);
9919
9920   tcp = (tcp_header_t *) mask;
9921
9922 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9923   foreach_tcp_proto_field;
9924 #undef _
9925
9926   *maskp = mask;
9927   return 1;
9928 }
9929
9930 uword
9931 unformat_udp_mask (unformat_input_t * input, va_list * args)
9932 {
9933   u8 **maskp = va_arg (*args, u8 **);
9934   u8 *mask = 0;
9935   u8 found_something = 0;
9936   udp_header_t *udp;
9937
9938 #define _(a) u8 a=0;
9939   foreach_udp_proto_field;
9940 #undef _
9941
9942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9943     {
9944       if (0);
9945 #define _(a) else if (unformat (input, #a)) a=1;
9946       foreach_udp_proto_field
9947 #undef _
9948         else
9949         break;
9950     }
9951
9952 #define _(a) found_something += a;
9953   foreach_udp_proto_field;
9954 #undef _
9955
9956   if (found_something == 0)
9957     return 0;
9958
9959   vec_validate (mask, sizeof (*udp) - 1);
9960
9961   udp = (udp_header_t *) mask;
9962
9963 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9964   foreach_udp_proto_field;
9965 #undef _
9966
9967   *maskp = mask;
9968   return 1;
9969 }
9970
9971 uword
9972 unformat_l4_mask (unformat_input_t * input, va_list * args)
9973 {
9974   u8 **maskp = va_arg (*args, u8 **);
9975   u16 src_port = 0, dst_port = 0;
9976   tcpudp_header_t *tcpudp;
9977
9978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9979     {
9980       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9981         return 1;
9982       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9983         return 1;
9984       else if (unformat (input, "src_port"))
9985         src_port = 0xFFFF;
9986       else if (unformat (input, "dst_port"))
9987         dst_port = 0xFFFF;
9988       else
9989         return 0;
9990     }
9991
9992   if (!src_port && !dst_port)
9993     return 0;
9994
9995   u8 *mask = 0;
9996   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9997
9998   tcpudp = (tcpudp_header_t *) mask;
9999   tcpudp->src_port = src_port;
10000   tcpudp->dst_port = dst_port;
10001
10002   *maskp = mask;
10003
10004   return 1;
10005 }
10006
10007 uword
10008 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10009 {
10010   u8 **maskp = va_arg (*args, u8 **);
10011   u8 *mask = 0;
10012   u8 found_something = 0;
10013   ip4_header_t *ip;
10014
10015 #define _(a) u8 a=0;
10016   foreach_ip4_proto_field;
10017 #undef _
10018   u8 version = 0;
10019   u8 hdr_length = 0;
10020
10021
10022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10023     {
10024       if (unformat (input, "version"))
10025         version = 1;
10026       else if (unformat (input, "hdr_length"))
10027         hdr_length = 1;
10028       else if (unformat (input, "src"))
10029         src_address = 1;
10030       else if (unformat (input, "dst"))
10031         dst_address = 1;
10032       else if (unformat (input, "proto"))
10033         protocol = 1;
10034
10035 #define _(a) else if (unformat (input, #a)) a=1;
10036       foreach_ip4_proto_field
10037 #undef _
10038         else
10039         break;
10040     }
10041
10042 #define _(a) found_something += a;
10043   foreach_ip4_proto_field;
10044 #undef _
10045
10046   if (found_something == 0)
10047     return 0;
10048
10049   vec_validate (mask, sizeof (*ip) - 1);
10050
10051   ip = (ip4_header_t *) mask;
10052
10053 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10054   foreach_ip4_proto_field;
10055 #undef _
10056
10057   ip->ip_version_and_header_length = 0;
10058
10059   if (version)
10060     ip->ip_version_and_header_length |= 0xF0;
10061
10062   if (hdr_length)
10063     ip->ip_version_and_header_length |= 0x0F;
10064
10065   *maskp = mask;
10066   return 1;
10067 }
10068
10069 #define foreach_ip6_proto_field                 \
10070 _(src_address)                                  \
10071 _(dst_address)                                  \
10072 _(payload_length)                               \
10073 _(hop_limit)                                    \
10074 _(protocol)
10075
10076 uword
10077 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10078 {
10079   u8 **maskp = va_arg (*args, u8 **);
10080   u8 *mask = 0;
10081   u8 found_something = 0;
10082   ip6_header_t *ip;
10083   u32 ip_version_traffic_class_and_flow_label;
10084
10085 #define _(a) u8 a=0;
10086   foreach_ip6_proto_field;
10087 #undef _
10088   u8 version = 0;
10089   u8 traffic_class = 0;
10090   u8 flow_label = 0;
10091
10092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10093     {
10094       if (unformat (input, "version"))
10095         version = 1;
10096       else if (unformat (input, "traffic-class"))
10097         traffic_class = 1;
10098       else if (unformat (input, "flow-label"))
10099         flow_label = 1;
10100       else if (unformat (input, "src"))
10101         src_address = 1;
10102       else if (unformat (input, "dst"))
10103         dst_address = 1;
10104       else if (unformat (input, "proto"))
10105         protocol = 1;
10106
10107 #define _(a) else if (unformat (input, #a)) a=1;
10108       foreach_ip6_proto_field
10109 #undef _
10110         else
10111         break;
10112     }
10113
10114 #define _(a) found_something += a;
10115   foreach_ip6_proto_field;
10116 #undef _
10117
10118   if (found_something == 0)
10119     return 0;
10120
10121   vec_validate (mask, sizeof (*ip) - 1);
10122
10123   ip = (ip6_header_t *) mask;
10124
10125 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10126   foreach_ip6_proto_field;
10127 #undef _
10128
10129   ip_version_traffic_class_and_flow_label = 0;
10130
10131   if (version)
10132     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10133
10134   if (traffic_class)
10135     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10136
10137   if (flow_label)
10138     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10139
10140   ip->ip_version_traffic_class_and_flow_label =
10141     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10142
10143   *maskp = mask;
10144   return 1;
10145 }
10146
10147 uword
10148 unformat_l3_mask (unformat_input_t * input, va_list * args)
10149 {
10150   u8 **maskp = va_arg (*args, u8 **);
10151
10152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10153     {
10154       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10155         return 1;
10156       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10157         return 1;
10158       else
10159         break;
10160     }
10161   return 0;
10162 }
10163
10164 uword
10165 unformat_l2_mask (unformat_input_t * input, va_list * args)
10166 {
10167   u8 **maskp = va_arg (*args, u8 **);
10168   u8 *mask = 0;
10169   u8 src = 0;
10170   u8 dst = 0;
10171   u8 proto = 0;
10172   u8 tag1 = 0;
10173   u8 tag2 = 0;
10174   u8 ignore_tag1 = 0;
10175   u8 ignore_tag2 = 0;
10176   u8 cos1 = 0;
10177   u8 cos2 = 0;
10178   u8 dot1q = 0;
10179   u8 dot1ad = 0;
10180   int len = 14;
10181
10182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10183     {
10184       if (unformat (input, "src"))
10185         src = 1;
10186       else if (unformat (input, "dst"))
10187         dst = 1;
10188       else if (unformat (input, "proto"))
10189         proto = 1;
10190       else if (unformat (input, "tag1"))
10191         tag1 = 1;
10192       else if (unformat (input, "tag2"))
10193         tag2 = 1;
10194       else if (unformat (input, "ignore-tag1"))
10195         ignore_tag1 = 1;
10196       else if (unformat (input, "ignore-tag2"))
10197         ignore_tag2 = 1;
10198       else if (unformat (input, "cos1"))
10199         cos1 = 1;
10200       else if (unformat (input, "cos2"))
10201         cos2 = 1;
10202       else if (unformat (input, "dot1q"))
10203         dot1q = 1;
10204       else if (unformat (input, "dot1ad"))
10205         dot1ad = 1;
10206       else
10207         break;
10208     }
10209   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10210        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10211     return 0;
10212
10213   if (tag1 || ignore_tag1 || cos1 || dot1q)
10214     len = 18;
10215   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10216     len = 22;
10217
10218   vec_validate (mask, len - 1);
10219
10220   if (dst)
10221     clib_memset (mask, 0xff, 6);
10222
10223   if (src)
10224     clib_memset (mask + 6, 0xff, 6);
10225
10226   if (tag2 || dot1ad)
10227     {
10228       /* inner vlan tag */
10229       if (tag2)
10230         {
10231           mask[19] = 0xff;
10232           mask[18] = 0x0f;
10233         }
10234       if (cos2)
10235         mask[18] |= 0xe0;
10236       if (proto)
10237         mask[21] = mask[20] = 0xff;
10238       if (tag1)
10239         {
10240           mask[15] = 0xff;
10241           mask[14] = 0x0f;
10242         }
10243       if (cos1)
10244         mask[14] |= 0xe0;
10245       *maskp = mask;
10246       return 1;
10247     }
10248   if (tag1 | dot1q)
10249     {
10250       if (tag1)
10251         {
10252           mask[15] = 0xff;
10253           mask[14] = 0x0f;
10254         }
10255       if (cos1)
10256         mask[14] |= 0xe0;
10257       if (proto)
10258         mask[16] = mask[17] = 0xff;
10259
10260       *maskp = mask;
10261       return 1;
10262     }
10263   if (cos2)
10264     mask[18] |= 0xe0;
10265   if (cos1)
10266     mask[14] |= 0xe0;
10267   if (proto)
10268     mask[12] = mask[13] = 0xff;
10269
10270   *maskp = mask;
10271   return 1;
10272 }
10273
10274 uword
10275 unformat_classify_mask (unformat_input_t * input, va_list * args)
10276 {
10277   u8 **maskp = va_arg (*args, u8 **);
10278   u32 *skipp = va_arg (*args, u32 *);
10279   u32 *matchp = va_arg (*args, u32 *);
10280   u32 match;
10281   u8 *mask = 0;
10282   u8 *l2 = 0;
10283   u8 *l3 = 0;
10284   u8 *l4 = 0;
10285   int i;
10286
10287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10290         ;
10291       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10292         ;
10293       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10294         ;
10295       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10296         ;
10297       else
10298         break;
10299     }
10300
10301   if (l4 && !l3)
10302     {
10303       vec_free (mask);
10304       vec_free (l2);
10305       vec_free (l4);
10306       return 0;
10307     }
10308
10309   if (mask || l2 || l3 || l4)
10310     {
10311       if (l2 || l3 || l4)
10312         {
10313           /* "With a free Ethernet header in every package" */
10314           if (l2 == 0)
10315             vec_validate (l2, 13);
10316           mask = l2;
10317           if (vec_len (l3))
10318             {
10319               vec_append (mask, l3);
10320               vec_free (l3);
10321             }
10322           if (vec_len (l4))
10323             {
10324               vec_append (mask, l4);
10325               vec_free (l4);
10326             }
10327         }
10328
10329       /* Scan forward looking for the first significant mask octet */
10330       for (i = 0; i < vec_len (mask); i++)
10331         if (mask[i])
10332           break;
10333
10334       /* compute (skip, match) params */
10335       *skipp = i / sizeof (u32x4);
10336       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10337
10338       /* Pad mask to an even multiple of the vector size */
10339       while (vec_len (mask) % sizeof (u32x4))
10340         vec_add1 (mask, 0);
10341
10342       match = vec_len (mask) / sizeof (u32x4);
10343
10344       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10345         {
10346           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10347           if (*tmp || *(tmp + 1))
10348             break;
10349           match--;
10350         }
10351       if (match == 0)
10352         clib_warning ("BUG: match 0");
10353
10354       _vec_len (mask) = match * sizeof (u32x4);
10355
10356       *matchp = match;
10357       *maskp = mask;
10358
10359       return 1;
10360     }
10361
10362   return 0;
10363 }
10364 #endif /* VPP_API_TEST_BUILTIN */
10365
10366 #define foreach_l2_next                         \
10367 _(drop, DROP)                                   \
10368 _(ethernet, ETHERNET_INPUT)                     \
10369 _(ip4, IP4_INPUT)                               \
10370 _(ip6, IP6_INPUT)
10371
10372 uword
10373 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10374 {
10375   u32 *miss_next_indexp = va_arg (*args, u32 *);
10376   u32 next_index = 0;
10377   u32 tmp;
10378
10379 #define _(n,N) \
10380   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10381   foreach_l2_next;
10382 #undef _
10383
10384   if (unformat (input, "%d", &tmp))
10385     {
10386       next_index = tmp;
10387       goto out;
10388     }
10389
10390   return 0;
10391
10392 out:
10393   *miss_next_indexp = next_index;
10394   return 1;
10395 }
10396
10397 #define foreach_ip_next                         \
10398 _(drop, DROP)                                   \
10399 _(local, LOCAL)                                 \
10400 _(rewrite, REWRITE)
10401
10402 uword
10403 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10404 {
10405   u32 *miss_next_indexp = va_arg (*args, u32 *);
10406   u32 next_index = 0;
10407   u32 tmp;
10408
10409 #define _(n,N) \
10410   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10411   foreach_ip_next;
10412 #undef _
10413
10414   if (unformat (input, "%d", &tmp))
10415     {
10416       next_index = tmp;
10417       goto out;
10418     }
10419
10420   return 0;
10421
10422 out:
10423   *miss_next_indexp = next_index;
10424   return 1;
10425 }
10426
10427 #define foreach_acl_next                        \
10428 _(deny, DENY)
10429
10430 uword
10431 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10432 {
10433   u32 *miss_next_indexp = va_arg (*args, u32 *);
10434   u32 next_index = 0;
10435   u32 tmp;
10436
10437 #define _(n,N) \
10438   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10439   foreach_acl_next;
10440 #undef _
10441
10442   if (unformat (input, "permit"))
10443     {
10444       next_index = ~0;
10445       goto out;
10446     }
10447   else if (unformat (input, "%d", &tmp))
10448     {
10449       next_index = tmp;
10450       goto out;
10451     }
10452
10453   return 0;
10454
10455 out:
10456   *miss_next_indexp = next_index;
10457   return 1;
10458 }
10459
10460 uword
10461 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10462 {
10463   u32 *r = va_arg (*args, u32 *);
10464
10465   if (unformat (input, "conform-color"))
10466     *r = POLICE_CONFORM;
10467   else if (unformat (input, "exceed-color"))
10468     *r = POLICE_EXCEED;
10469   else
10470     return 0;
10471
10472   return 1;
10473 }
10474
10475 static int
10476 api_classify_add_del_table (vat_main_t * vam)
10477 {
10478   unformat_input_t *i = vam->input;
10479   vl_api_classify_add_del_table_t *mp;
10480
10481   u32 nbuckets = 2;
10482   u32 skip = ~0;
10483   u32 match = ~0;
10484   int is_add = 1;
10485   int del_chain = 0;
10486   u32 table_index = ~0;
10487   u32 next_table_index = ~0;
10488   u32 miss_next_index = ~0;
10489   u32 memory_size = 32 << 20;
10490   u8 *mask = 0;
10491   u32 current_data_flag = 0;
10492   int current_data_offset = 0;
10493   int ret;
10494
10495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10496     {
10497       if (unformat (i, "del"))
10498         is_add = 0;
10499       else if (unformat (i, "del-chain"))
10500         {
10501           is_add = 0;
10502           del_chain = 1;
10503         }
10504       else if (unformat (i, "buckets %d", &nbuckets))
10505         ;
10506       else if (unformat (i, "memory_size %d", &memory_size))
10507         ;
10508       else if (unformat (i, "skip %d", &skip))
10509         ;
10510       else if (unformat (i, "match %d", &match))
10511         ;
10512       else if (unformat (i, "table %d", &table_index))
10513         ;
10514       else if (unformat (i, "mask %U", unformat_classify_mask,
10515                          &mask, &skip, &match))
10516         ;
10517       else if (unformat (i, "next-table %d", &next_table_index))
10518         ;
10519       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10520                          &miss_next_index))
10521         ;
10522       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10523                          &miss_next_index))
10524         ;
10525       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10526                          &miss_next_index))
10527         ;
10528       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10529         ;
10530       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10531         ;
10532       else
10533         break;
10534     }
10535
10536   if (is_add && mask == 0)
10537     {
10538       errmsg ("Mask required");
10539       return -99;
10540     }
10541
10542   if (is_add && skip == ~0)
10543     {
10544       errmsg ("skip count required");
10545       return -99;
10546     }
10547
10548   if (is_add && match == ~0)
10549     {
10550       errmsg ("match count required");
10551       return -99;
10552     }
10553
10554   if (!is_add && table_index == ~0)
10555     {
10556       errmsg ("table index required for delete");
10557       return -99;
10558     }
10559
10560   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10561
10562   mp->is_add = is_add;
10563   mp->del_chain = del_chain;
10564   mp->table_index = ntohl (table_index);
10565   mp->nbuckets = ntohl (nbuckets);
10566   mp->memory_size = ntohl (memory_size);
10567   mp->skip_n_vectors = ntohl (skip);
10568   mp->match_n_vectors = ntohl (match);
10569   mp->next_table_index = ntohl (next_table_index);
10570   mp->miss_next_index = ntohl (miss_next_index);
10571   mp->current_data_flag = ntohl (current_data_flag);
10572   mp->current_data_offset = ntohl (current_data_offset);
10573   mp->mask_len = ntohl (vec_len (mask));
10574   clib_memcpy (mp->mask, mask, vec_len (mask));
10575
10576   vec_free (mask);
10577
10578   S (mp);
10579   W (ret);
10580   return ret;
10581 }
10582
10583 #if VPP_API_TEST_BUILTIN == 0
10584 uword
10585 unformat_l4_match (unformat_input_t * input, va_list * args)
10586 {
10587   u8 **matchp = va_arg (*args, u8 **);
10588
10589   u8 *proto_header = 0;
10590   int src_port = 0;
10591   int dst_port = 0;
10592
10593   tcpudp_header_t h;
10594
10595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (input, "src_port %d", &src_port))
10598         ;
10599       else if (unformat (input, "dst_port %d", &dst_port))
10600         ;
10601       else
10602         return 0;
10603     }
10604
10605   h.src_port = clib_host_to_net_u16 (src_port);
10606   h.dst_port = clib_host_to_net_u16 (dst_port);
10607   vec_validate (proto_header, sizeof (h) - 1);
10608   memcpy (proto_header, &h, sizeof (h));
10609
10610   *matchp = proto_header;
10611
10612   return 1;
10613 }
10614
10615 uword
10616 unformat_ip4_match (unformat_input_t * input, va_list * args)
10617 {
10618   u8 **matchp = va_arg (*args, u8 **);
10619   u8 *match = 0;
10620   ip4_header_t *ip;
10621   int version = 0;
10622   u32 version_val;
10623   int hdr_length = 0;
10624   u32 hdr_length_val;
10625   int src = 0, dst = 0;
10626   ip4_address_t src_val, dst_val;
10627   int proto = 0;
10628   u32 proto_val;
10629   int tos = 0;
10630   u32 tos_val;
10631   int length = 0;
10632   u32 length_val;
10633   int fragment_id = 0;
10634   u32 fragment_id_val;
10635   int ttl = 0;
10636   int ttl_val;
10637   int checksum = 0;
10638   u32 checksum_val;
10639
10640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10641     {
10642       if (unformat (input, "version %d", &version_val))
10643         version = 1;
10644       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10645         hdr_length = 1;
10646       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10647         src = 1;
10648       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10649         dst = 1;
10650       else if (unformat (input, "proto %d", &proto_val))
10651         proto = 1;
10652       else if (unformat (input, "tos %d", &tos_val))
10653         tos = 1;
10654       else if (unformat (input, "length %d", &length_val))
10655         length = 1;
10656       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10657         fragment_id = 1;
10658       else if (unformat (input, "ttl %d", &ttl_val))
10659         ttl = 1;
10660       else if (unformat (input, "checksum %d", &checksum_val))
10661         checksum = 1;
10662       else
10663         break;
10664     }
10665
10666   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10667       + ttl + checksum == 0)
10668     return 0;
10669
10670   /*
10671    * Aligned because we use the real comparison functions
10672    */
10673   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10674
10675   ip = (ip4_header_t *) match;
10676
10677   /* These are realistically matched in practice */
10678   if (src)
10679     ip->src_address.as_u32 = src_val.as_u32;
10680
10681   if (dst)
10682     ip->dst_address.as_u32 = dst_val.as_u32;
10683
10684   if (proto)
10685     ip->protocol = proto_val;
10686
10687
10688   /* These are not, but they're included for completeness */
10689   if (version)
10690     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10691
10692   if (hdr_length)
10693     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10694
10695   if (tos)
10696     ip->tos = tos_val;
10697
10698   if (length)
10699     ip->length = clib_host_to_net_u16 (length_val);
10700
10701   if (ttl)
10702     ip->ttl = ttl_val;
10703
10704   if (checksum)
10705     ip->checksum = clib_host_to_net_u16 (checksum_val);
10706
10707   *matchp = match;
10708   return 1;
10709 }
10710
10711 uword
10712 unformat_ip6_match (unformat_input_t * input, va_list * args)
10713 {
10714   u8 **matchp = va_arg (*args, u8 **);
10715   u8 *match = 0;
10716   ip6_header_t *ip;
10717   int version = 0;
10718   u32 version_val;
10719   u8 traffic_class = 0;
10720   u32 traffic_class_val = 0;
10721   u8 flow_label = 0;
10722   u8 flow_label_val;
10723   int src = 0, dst = 0;
10724   ip6_address_t src_val, dst_val;
10725   int proto = 0;
10726   u32 proto_val;
10727   int payload_length = 0;
10728   u32 payload_length_val;
10729   int hop_limit = 0;
10730   int hop_limit_val;
10731   u32 ip_version_traffic_class_and_flow_label;
10732
10733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10734     {
10735       if (unformat (input, "version %d", &version_val))
10736         version = 1;
10737       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10738         traffic_class = 1;
10739       else if (unformat (input, "flow_label %d", &flow_label_val))
10740         flow_label = 1;
10741       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10742         src = 1;
10743       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10744         dst = 1;
10745       else if (unformat (input, "proto %d", &proto_val))
10746         proto = 1;
10747       else if (unformat (input, "payload_length %d", &payload_length_val))
10748         payload_length = 1;
10749       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10750         hop_limit = 1;
10751       else
10752         break;
10753     }
10754
10755   if (version + traffic_class + flow_label + src + dst + proto +
10756       payload_length + hop_limit == 0)
10757     return 0;
10758
10759   /*
10760    * Aligned because we use the real comparison functions
10761    */
10762   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10763
10764   ip = (ip6_header_t *) match;
10765
10766   if (src)
10767     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10768
10769   if (dst)
10770     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10771
10772   if (proto)
10773     ip->protocol = proto_val;
10774
10775   ip_version_traffic_class_and_flow_label = 0;
10776
10777   if (version)
10778     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10779
10780   if (traffic_class)
10781     ip_version_traffic_class_and_flow_label |=
10782       (traffic_class_val & 0xFF) << 20;
10783
10784   if (flow_label)
10785     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10786
10787   ip->ip_version_traffic_class_and_flow_label =
10788     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10789
10790   if (payload_length)
10791     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10792
10793   if (hop_limit)
10794     ip->hop_limit = hop_limit_val;
10795
10796   *matchp = match;
10797   return 1;
10798 }
10799
10800 uword
10801 unformat_l3_match (unformat_input_t * input, va_list * args)
10802 {
10803   u8 **matchp = va_arg (*args, u8 **);
10804
10805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10806     {
10807       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10808         return 1;
10809       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10810         return 1;
10811       else
10812         break;
10813     }
10814   return 0;
10815 }
10816
10817 uword
10818 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10819 {
10820   u8 *tagp = va_arg (*args, u8 *);
10821   u32 tag;
10822
10823   if (unformat (input, "%d", &tag))
10824     {
10825       tagp[0] = (tag >> 8) & 0x0F;
10826       tagp[1] = tag & 0xFF;
10827       return 1;
10828     }
10829
10830   return 0;
10831 }
10832
10833 uword
10834 unformat_l2_match (unformat_input_t * input, va_list * args)
10835 {
10836   u8 **matchp = va_arg (*args, u8 **);
10837   u8 *match = 0;
10838   u8 src = 0;
10839   u8 src_val[6];
10840   u8 dst = 0;
10841   u8 dst_val[6];
10842   u8 proto = 0;
10843   u16 proto_val;
10844   u8 tag1 = 0;
10845   u8 tag1_val[2];
10846   u8 tag2 = 0;
10847   u8 tag2_val[2];
10848   int len = 14;
10849   u8 ignore_tag1 = 0;
10850   u8 ignore_tag2 = 0;
10851   u8 cos1 = 0;
10852   u8 cos2 = 0;
10853   u32 cos1_val = 0;
10854   u32 cos2_val = 0;
10855
10856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10857     {
10858       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10859         src = 1;
10860       else
10861         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10862         dst = 1;
10863       else if (unformat (input, "proto %U",
10864                          unformat_ethernet_type_host_byte_order, &proto_val))
10865         proto = 1;
10866       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10867         tag1 = 1;
10868       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10869         tag2 = 1;
10870       else if (unformat (input, "ignore-tag1"))
10871         ignore_tag1 = 1;
10872       else if (unformat (input, "ignore-tag2"))
10873         ignore_tag2 = 1;
10874       else if (unformat (input, "cos1 %d", &cos1_val))
10875         cos1 = 1;
10876       else if (unformat (input, "cos2 %d", &cos2_val))
10877         cos2 = 1;
10878       else
10879         break;
10880     }
10881   if ((src + dst + proto + tag1 + tag2 +
10882        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10883     return 0;
10884
10885   if (tag1 || ignore_tag1 || cos1)
10886     len = 18;
10887   if (tag2 || ignore_tag2 || cos2)
10888     len = 22;
10889
10890   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10891
10892   if (dst)
10893     clib_memcpy (match, dst_val, 6);
10894
10895   if (src)
10896     clib_memcpy (match + 6, src_val, 6);
10897
10898   if (tag2)
10899     {
10900       /* inner vlan tag */
10901       match[19] = tag2_val[1];
10902       match[18] = tag2_val[0];
10903       if (cos2)
10904         match[18] |= (cos2_val & 0x7) << 5;
10905       if (proto)
10906         {
10907           match[21] = proto_val & 0xff;
10908           match[20] = proto_val >> 8;
10909         }
10910       if (tag1)
10911         {
10912           match[15] = tag1_val[1];
10913           match[14] = tag1_val[0];
10914         }
10915       if (cos1)
10916         match[14] |= (cos1_val & 0x7) << 5;
10917       *matchp = match;
10918       return 1;
10919     }
10920   if (tag1)
10921     {
10922       match[15] = tag1_val[1];
10923       match[14] = tag1_val[0];
10924       if (proto)
10925         {
10926           match[17] = proto_val & 0xff;
10927           match[16] = proto_val >> 8;
10928         }
10929       if (cos1)
10930         match[14] |= (cos1_val & 0x7) << 5;
10931
10932       *matchp = match;
10933       return 1;
10934     }
10935   if (cos2)
10936     match[18] |= (cos2_val & 0x7) << 5;
10937   if (cos1)
10938     match[14] |= (cos1_val & 0x7) << 5;
10939   if (proto)
10940     {
10941       match[13] = proto_val & 0xff;
10942       match[12] = proto_val >> 8;
10943     }
10944
10945   *matchp = match;
10946   return 1;
10947 }
10948
10949 uword
10950 unformat_qos_source (unformat_input_t * input, va_list * args)
10951 {
10952   int *qs = va_arg (*args, int *);
10953
10954   if (unformat (input, "ip"))
10955     *qs = QOS_SOURCE_IP;
10956   else if (unformat (input, "mpls"))
10957     *qs = QOS_SOURCE_MPLS;
10958   else if (unformat (input, "ext"))
10959     *qs = QOS_SOURCE_EXT;
10960   else if (unformat (input, "vlan"))
10961     *qs = QOS_SOURCE_VLAN;
10962   else
10963     return 0;
10964
10965   return 1;
10966 }
10967 #endif
10968
10969 uword
10970 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10971 {
10972   u8 **matchp = va_arg (*args, u8 **);
10973   u32 skip_n_vectors = va_arg (*args, u32);
10974   u32 match_n_vectors = va_arg (*args, u32);
10975
10976   u8 *match = 0;
10977   u8 *l2 = 0;
10978   u8 *l3 = 0;
10979   u8 *l4 = 0;
10980
10981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10982     {
10983       if (unformat (input, "hex %U", unformat_hex_string, &match))
10984         ;
10985       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10986         ;
10987       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10988         ;
10989       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10990         ;
10991       else
10992         break;
10993     }
10994
10995   if (l4 && !l3)
10996     {
10997       vec_free (match);
10998       vec_free (l2);
10999       vec_free (l4);
11000       return 0;
11001     }
11002
11003   if (match || l2 || l3 || l4)
11004     {
11005       if (l2 || l3 || l4)
11006         {
11007           /* "Win a free Ethernet header in every packet" */
11008           if (l2 == 0)
11009             vec_validate_aligned (l2, 13, sizeof (u32x4));
11010           match = l2;
11011           if (vec_len (l3))
11012             {
11013               vec_append_aligned (match, l3, sizeof (u32x4));
11014               vec_free (l3);
11015             }
11016           if (vec_len (l4))
11017             {
11018               vec_append_aligned (match, l4, sizeof (u32x4));
11019               vec_free (l4);
11020             }
11021         }
11022
11023       /* Make sure the vector is big enough even if key is all 0's */
11024       vec_validate_aligned
11025         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11026          sizeof (u32x4));
11027
11028       /* Set size, include skipped vectors */
11029       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11030
11031       *matchp = match;
11032
11033       return 1;
11034     }
11035
11036   return 0;
11037 }
11038
11039 static int
11040 api_classify_add_del_session (vat_main_t * vam)
11041 {
11042   unformat_input_t *i = vam->input;
11043   vl_api_classify_add_del_session_t *mp;
11044   int is_add = 1;
11045   u32 table_index = ~0;
11046   u32 hit_next_index = ~0;
11047   u32 opaque_index = ~0;
11048   u8 *match = 0;
11049   i32 advance = 0;
11050   u32 skip_n_vectors = 0;
11051   u32 match_n_vectors = 0;
11052   u32 action = 0;
11053   u32 metadata = 0;
11054   int ret;
11055
11056   /*
11057    * Warning: you have to supply skip_n and match_n
11058    * because the API client cant simply look at the classify
11059    * table object.
11060    */
11061
11062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11063     {
11064       if (unformat (i, "del"))
11065         is_add = 0;
11066       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11067                          &hit_next_index))
11068         ;
11069       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11070                          &hit_next_index))
11071         ;
11072       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11073                          &hit_next_index))
11074         ;
11075       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11076         ;
11077       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11078         ;
11079       else if (unformat (i, "opaque-index %d", &opaque_index))
11080         ;
11081       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11082         ;
11083       else if (unformat (i, "match_n %d", &match_n_vectors))
11084         ;
11085       else if (unformat (i, "match %U", api_unformat_classify_match,
11086                          &match, skip_n_vectors, match_n_vectors))
11087         ;
11088       else if (unformat (i, "advance %d", &advance))
11089         ;
11090       else if (unformat (i, "table-index %d", &table_index))
11091         ;
11092       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11093         action = 1;
11094       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11095         action = 2;
11096       else if (unformat (i, "action %d", &action))
11097         ;
11098       else if (unformat (i, "metadata %d", &metadata))
11099         ;
11100       else
11101         break;
11102     }
11103
11104   if (table_index == ~0)
11105     {
11106       errmsg ("Table index required");
11107       return -99;
11108     }
11109
11110   if (is_add && match == 0)
11111     {
11112       errmsg ("Match value required");
11113       return -99;
11114     }
11115
11116   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11117
11118   mp->is_add = is_add;
11119   mp->table_index = ntohl (table_index);
11120   mp->hit_next_index = ntohl (hit_next_index);
11121   mp->opaque_index = ntohl (opaque_index);
11122   mp->advance = ntohl (advance);
11123   mp->action = action;
11124   mp->metadata = ntohl (metadata);
11125   mp->match_len = ntohl (vec_len (match));
11126   clib_memcpy (mp->match, match, vec_len (match));
11127   vec_free (match);
11128
11129   S (mp);
11130   W (ret);
11131   return ret;
11132 }
11133
11134 static int
11135 api_classify_set_interface_ip_table (vat_main_t * vam)
11136 {
11137   unformat_input_t *i = vam->input;
11138   vl_api_classify_set_interface_ip_table_t *mp;
11139   u32 sw_if_index;
11140   int sw_if_index_set;
11141   u32 table_index = ~0;
11142   u8 is_ipv6 = 0;
11143   int ret;
11144
11145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11146     {
11147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11148         sw_if_index_set = 1;
11149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11150         sw_if_index_set = 1;
11151       else if (unformat (i, "table %d", &table_index))
11152         ;
11153       else
11154         {
11155           clib_warning ("parse error '%U'", format_unformat_error, i);
11156           return -99;
11157         }
11158     }
11159
11160   if (sw_if_index_set == 0)
11161     {
11162       errmsg ("missing interface name or sw_if_index");
11163       return -99;
11164     }
11165
11166
11167   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11168
11169   mp->sw_if_index = ntohl (sw_if_index);
11170   mp->table_index = ntohl (table_index);
11171   mp->is_ipv6 = is_ipv6;
11172
11173   S (mp);
11174   W (ret);
11175   return ret;
11176 }
11177
11178 static int
11179 api_classify_set_interface_l2_tables (vat_main_t * vam)
11180 {
11181   unformat_input_t *i = vam->input;
11182   vl_api_classify_set_interface_l2_tables_t *mp;
11183   u32 sw_if_index;
11184   int sw_if_index_set;
11185   u32 ip4_table_index = ~0;
11186   u32 ip6_table_index = ~0;
11187   u32 other_table_index = ~0;
11188   u32 is_input = 1;
11189   int ret;
11190
11191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11192     {
11193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11196         sw_if_index_set = 1;
11197       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11198         ;
11199       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11200         ;
11201       else if (unformat (i, "other-table %d", &other_table_index))
11202         ;
11203       else if (unformat (i, "is-input %d", &is_input))
11204         ;
11205       else
11206         {
11207           clib_warning ("parse error '%U'", format_unformat_error, i);
11208           return -99;
11209         }
11210     }
11211
11212   if (sw_if_index_set == 0)
11213     {
11214       errmsg ("missing interface name or sw_if_index");
11215       return -99;
11216     }
11217
11218
11219   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11220
11221   mp->sw_if_index = ntohl (sw_if_index);
11222   mp->ip4_table_index = ntohl (ip4_table_index);
11223   mp->ip6_table_index = ntohl (ip6_table_index);
11224   mp->other_table_index = ntohl (other_table_index);
11225   mp->is_input = (u8) is_input;
11226
11227   S (mp);
11228   W (ret);
11229   return ret;
11230 }
11231
11232 static int
11233 api_set_ipfix_exporter (vat_main_t * vam)
11234 {
11235   unformat_input_t *i = vam->input;
11236   vl_api_set_ipfix_exporter_t *mp;
11237   ip4_address_t collector_address;
11238   u8 collector_address_set = 0;
11239   u32 collector_port = ~0;
11240   ip4_address_t src_address;
11241   u8 src_address_set = 0;
11242   u32 vrf_id = ~0;
11243   u32 path_mtu = ~0;
11244   u32 template_interval = ~0;
11245   u8 udp_checksum = 0;
11246   int ret;
11247
11248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11249     {
11250       if (unformat (i, "collector_address %U", unformat_ip4_address,
11251                     &collector_address))
11252         collector_address_set = 1;
11253       else if (unformat (i, "collector_port %d", &collector_port))
11254         ;
11255       else if (unformat (i, "src_address %U", unformat_ip4_address,
11256                          &src_address))
11257         src_address_set = 1;
11258       else if (unformat (i, "vrf_id %d", &vrf_id))
11259         ;
11260       else if (unformat (i, "path_mtu %d", &path_mtu))
11261         ;
11262       else if (unformat (i, "template_interval %d", &template_interval))
11263         ;
11264       else if (unformat (i, "udp_checksum"))
11265         udp_checksum = 1;
11266       else
11267         break;
11268     }
11269
11270   if (collector_address_set == 0)
11271     {
11272       errmsg ("collector_address required");
11273       return -99;
11274     }
11275
11276   if (src_address_set == 0)
11277     {
11278       errmsg ("src_address required");
11279       return -99;
11280     }
11281
11282   M (SET_IPFIX_EXPORTER, mp);
11283
11284   memcpy (mp->collector_address, collector_address.data,
11285           sizeof (collector_address.data));
11286   mp->collector_port = htons ((u16) collector_port);
11287   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11288   mp->vrf_id = htonl (vrf_id);
11289   mp->path_mtu = htonl (path_mtu);
11290   mp->template_interval = htonl (template_interval);
11291   mp->udp_checksum = udp_checksum;
11292
11293   S (mp);
11294   W (ret);
11295   return ret;
11296 }
11297
11298 static int
11299 api_set_ipfix_classify_stream (vat_main_t * vam)
11300 {
11301   unformat_input_t *i = vam->input;
11302   vl_api_set_ipfix_classify_stream_t *mp;
11303   u32 domain_id = 0;
11304   u32 src_port = UDP_DST_PORT_ipfix;
11305   int ret;
11306
11307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11308     {
11309       if (unformat (i, "domain %d", &domain_id))
11310         ;
11311       else if (unformat (i, "src_port %d", &src_port))
11312         ;
11313       else
11314         {
11315           errmsg ("unknown input `%U'", format_unformat_error, i);
11316           return -99;
11317         }
11318     }
11319
11320   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11321
11322   mp->domain_id = htonl (domain_id);
11323   mp->src_port = htons ((u16) src_port);
11324
11325   S (mp);
11326   W (ret);
11327   return ret;
11328 }
11329
11330 static int
11331 api_ipfix_classify_table_add_del (vat_main_t * vam)
11332 {
11333   unformat_input_t *i = vam->input;
11334   vl_api_ipfix_classify_table_add_del_t *mp;
11335   int is_add = -1;
11336   u32 classify_table_index = ~0;
11337   u8 ip_version = 0;
11338   u8 transport_protocol = 255;
11339   int ret;
11340
11341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11342     {
11343       if (unformat (i, "add"))
11344         is_add = 1;
11345       else if (unformat (i, "del"))
11346         is_add = 0;
11347       else if (unformat (i, "table %d", &classify_table_index))
11348         ;
11349       else if (unformat (i, "ip4"))
11350         ip_version = 4;
11351       else if (unformat (i, "ip6"))
11352         ip_version = 6;
11353       else if (unformat (i, "tcp"))
11354         transport_protocol = 6;
11355       else if (unformat (i, "udp"))
11356         transport_protocol = 17;
11357       else
11358         {
11359           errmsg ("unknown input `%U'", format_unformat_error, i);
11360           return -99;
11361         }
11362     }
11363
11364   if (is_add == -1)
11365     {
11366       errmsg ("expecting: add|del");
11367       return -99;
11368     }
11369   if (classify_table_index == ~0)
11370     {
11371       errmsg ("classifier table not specified");
11372       return -99;
11373     }
11374   if (ip_version == 0)
11375     {
11376       errmsg ("IP version not specified");
11377       return -99;
11378     }
11379
11380   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11381
11382   mp->is_add = is_add;
11383   mp->table_id = htonl (classify_table_index);
11384   mp->ip_version = ip_version;
11385   mp->transport_protocol = transport_protocol;
11386
11387   S (mp);
11388   W (ret);
11389   return ret;
11390 }
11391
11392 static int
11393 api_get_node_index (vat_main_t * vam)
11394 {
11395   unformat_input_t *i = vam->input;
11396   vl_api_get_node_index_t *mp;
11397   u8 *name = 0;
11398   int ret;
11399
11400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11401     {
11402       if (unformat (i, "node %s", &name))
11403         ;
11404       else
11405         break;
11406     }
11407   if (name == 0)
11408     {
11409       errmsg ("node name required");
11410       return -99;
11411     }
11412   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11413     {
11414       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11415       return -99;
11416     }
11417
11418   M (GET_NODE_INDEX, mp);
11419   clib_memcpy (mp->node_name, name, vec_len (name));
11420   vec_free (name);
11421
11422   S (mp);
11423   W (ret);
11424   return ret;
11425 }
11426
11427 static int
11428 api_get_next_index (vat_main_t * vam)
11429 {
11430   unformat_input_t *i = vam->input;
11431   vl_api_get_next_index_t *mp;
11432   u8 *node_name = 0, *next_node_name = 0;
11433   int ret;
11434
11435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11436     {
11437       if (unformat (i, "node-name %s", &node_name))
11438         ;
11439       else if (unformat (i, "next-node-name %s", &next_node_name))
11440         break;
11441     }
11442
11443   if (node_name == 0)
11444     {
11445       errmsg ("node name required");
11446       return -99;
11447     }
11448   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11449     {
11450       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11451       return -99;
11452     }
11453
11454   if (next_node_name == 0)
11455     {
11456       errmsg ("next node name required");
11457       return -99;
11458     }
11459   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11460     {
11461       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11462       return -99;
11463     }
11464
11465   M (GET_NEXT_INDEX, mp);
11466   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11467   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11468   vec_free (node_name);
11469   vec_free (next_node_name);
11470
11471   S (mp);
11472   W (ret);
11473   return ret;
11474 }
11475
11476 static int
11477 api_add_node_next (vat_main_t * vam)
11478 {
11479   unformat_input_t *i = vam->input;
11480   vl_api_add_node_next_t *mp;
11481   u8 *name = 0;
11482   u8 *next = 0;
11483   int ret;
11484
11485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (i, "node %s", &name))
11488         ;
11489       else if (unformat (i, "next %s", &next))
11490         ;
11491       else
11492         break;
11493     }
11494   if (name == 0)
11495     {
11496       errmsg ("node name required");
11497       return -99;
11498     }
11499   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11500     {
11501       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11502       return -99;
11503     }
11504   if (next == 0)
11505     {
11506       errmsg ("next node required");
11507       return -99;
11508     }
11509   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11510     {
11511       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11512       return -99;
11513     }
11514
11515   M (ADD_NODE_NEXT, mp);
11516   clib_memcpy (mp->node_name, name, vec_len (name));
11517   clib_memcpy (mp->next_name, next, vec_len (next));
11518   vec_free (name);
11519   vec_free (next);
11520
11521   S (mp);
11522   W (ret);
11523   return ret;
11524 }
11525
11526 static int
11527 api_l2tpv3_create_tunnel (vat_main_t * vam)
11528 {
11529   unformat_input_t *i = vam->input;
11530   ip6_address_t client_address, our_address;
11531   int client_address_set = 0;
11532   int our_address_set = 0;
11533   u32 local_session_id = 0;
11534   u32 remote_session_id = 0;
11535   u64 local_cookie = 0;
11536   u64 remote_cookie = 0;
11537   u8 l2_sublayer_present = 0;
11538   vl_api_l2tpv3_create_tunnel_t *mp;
11539   int ret;
11540
11541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (i, "client_address %U", unformat_ip6_address,
11544                     &client_address))
11545         client_address_set = 1;
11546       else if (unformat (i, "our_address %U", unformat_ip6_address,
11547                          &our_address))
11548         our_address_set = 1;
11549       else if (unformat (i, "local_session_id %d", &local_session_id))
11550         ;
11551       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11552         ;
11553       else if (unformat (i, "local_cookie %lld", &local_cookie))
11554         ;
11555       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11556         ;
11557       else if (unformat (i, "l2-sublayer-present"))
11558         l2_sublayer_present = 1;
11559       else
11560         break;
11561     }
11562
11563   if (client_address_set == 0)
11564     {
11565       errmsg ("client_address required");
11566       return -99;
11567     }
11568
11569   if (our_address_set == 0)
11570     {
11571       errmsg ("our_address required");
11572       return -99;
11573     }
11574
11575   M (L2TPV3_CREATE_TUNNEL, mp);
11576
11577   clib_memcpy (mp->client_address, client_address.as_u8,
11578                sizeof (mp->client_address));
11579
11580   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11581
11582   mp->local_session_id = ntohl (local_session_id);
11583   mp->remote_session_id = ntohl (remote_session_id);
11584   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11585   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11586   mp->l2_sublayer_present = l2_sublayer_present;
11587   mp->is_ipv6 = 1;
11588
11589   S (mp);
11590   W (ret);
11591   return ret;
11592 }
11593
11594 static int
11595 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11596 {
11597   unformat_input_t *i = vam->input;
11598   u32 sw_if_index;
11599   u8 sw_if_index_set = 0;
11600   u64 new_local_cookie = 0;
11601   u64 new_remote_cookie = 0;
11602   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11603   int ret;
11604
11605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11606     {
11607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11608         sw_if_index_set = 1;
11609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11610         sw_if_index_set = 1;
11611       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11612         ;
11613       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11614         ;
11615       else
11616         break;
11617     }
11618
11619   if (sw_if_index_set == 0)
11620     {
11621       errmsg ("missing interface name or sw_if_index");
11622       return -99;
11623     }
11624
11625   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11626
11627   mp->sw_if_index = ntohl (sw_if_index);
11628   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11629   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11630
11631   S (mp);
11632   W (ret);
11633   return ret;
11634 }
11635
11636 static int
11637 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11638 {
11639   unformat_input_t *i = vam->input;
11640   vl_api_l2tpv3_interface_enable_disable_t *mp;
11641   u32 sw_if_index;
11642   u8 sw_if_index_set = 0;
11643   u8 enable_disable = 1;
11644   int ret;
11645
11646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11649         sw_if_index_set = 1;
11650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11651         sw_if_index_set = 1;
11652       else if (unformat (i, "enable"))
11653         enable_disable = 1;
11654       else if (unformat (i, "disable"))
11655         enable_disable = 0;
11656       else
11657         break;
11658     }
11659
11660   if (sw_if_index_set == 0)
11661     {
11662       errmsg ("missing interface name or sw_if_index");
11663       return -99;
11664     }
11665
11666   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11667
11668   mp->sw_if_index = ntohl (sw_if_index);
11669   mp->enable_disable = enable_disable;
11670
11671   S (mp);
11672   W (ret);
11673   return ret;
11674 }
11675
11676 static int
11677 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11678 {
11679   unformat_input_t *i = vam->input;
11680   vl_api_l2tpv3_set_lookup_key_t *mp;
11681   u8 key = ~0;
11682   int ret;
11683
11684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11685     {
11686       if (unformat (i, "lookup_v6_src"))
11687         key = L2T_LOOKUP_SRC_ADDRESS;
11688       else if (unformat (i, "lookup_v6_dst"))
11689         key = L2T_LOOKUP_DST_ADDRESS;
11690       else if (unformat (i, "lookup_session_id"))
11691         key = L2T_LOOKUP_SESSION_ID;
11692       else
11693         break;
11694     }
11695
11696   if (key == (u8) ~ 0)
11697     {
11698       errmsg ("l2tp session lookup key unset");
11699       return -99;
11700     }
11701
11702   M (L2TPV3_SET_LOOKUP_KEY, mp);
11703
11704   mp->key = key;
11705
11706   S (mp);
11707   W (ret);
11708   return ret;
11709 }
11710
11711 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11712   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11713 {
11714   vat_main_t *vam = &vat_main;
11715
11716   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11717          format_ip6_address, mp->our_address,
11718          format_ip6_address, mp->client_address,
11719          clib_net_to_host_u32 (mp->sw_if_index));
11720
11721   print (vam->ofp,
11722          "   local cookies %016llx %016llx remote cookie %016llx",
11723          clib_net_to_host_u64 (mp->local_cookie[0]),
11724          clib_net_to_host_u64 (mp->local_cookie[1]),
11725          clib_net_to_host_u64 (mp->remote_cookie));
11726
11727   print (vam->ofp, "   local session-id %d remote session-id %d",
11728          clib_net_to_host_u32 (mp->local_session_id),
11729          clib_net_to_host_u32 (mp->remote_session_id));
11730
11731   print (vam->ofp, "   l2 specific sublayer %s\n",
11732          mp->l2_sublayer_present ? "preset" : "absent");
11733
11734 }
11735
11736 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11737   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11738 {
11739   vat_main_t *vam = &vat_main;
11740   vat_json_node_t *node = NULL;
11741   struct in6_addr addr;
11742
11743   if (VAT_JSON_ARRAY != vam->json_tree.type)
11744     {
11745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11746       vat_json_init_array (&vam->json_tree);
11747     }
11748   node = vat_json_array_add (&vam->json_tree);
11749
11750   vat_json_init_object (node);
11751
11752   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11753   vat_json_object_add_ip6 (node, "our_address", addr);
11754   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11755   vat_json_object_add_ip6 (node, "client_address", addr);
11756
11757   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11758   vat_json_init_array (lc);
11759   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11760   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11761   vat_json_object_add_uint (node, "remote_cookie",
11762                             clib_net_to_host_u64 (mp->remote_cookie));
11763
11764   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11765   vat_json_object_add_uint (node, "local_session_id",
11766                             clib_net_to_host_u32 (mp->local_session_id));
11767   vat_json_object_add_uint (node, "remote_session_id",
11768                             clib_net_to_host_u32 (mp->remote_session_id));
11769   vat_json_object_add_string_copy (node, "l2_sublayer",
11770                                    mp->l2_sublayer_present ? (u8 *) "present"
11771                                    : (u8 *) "absent");
11772 }
11773
11774 static int
11775 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11776 {
11777   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11778   vl_api_control_ping_t *mp_ping;
11779   int ret;
11780
11781   /* Get list of l2tpv3-tunnel interfaces */
11782   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11783   S (mp);
11784
11785   /* Use a control ping for synchronization */
11786   MPING (CONTROL_PING, mp_ping);
11787   S (mp_ping);
11788
11789   W (ret);
11790   return ret;
11791 }
11792
11793
11794 static void vl_api_sw_interface_tap_v2_details_t_handler
11795   (vl_api_sw_interface_tap_v2_details_t * mp)
11796 {
11797   vat_main_t *vam = &vat_main;
11798
11799   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11800                     mp->host_ip4_prefix_len);
11801   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11802                     mp->host_ip6_prefix_len);
11803
11804   print (vam->ofp,
11805          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11806          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11807          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11808          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11809          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11810
11811   vec_free (ip4);
11812   vec_free (ip6);
11813 }
11814
11815 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11816   (vl_api_sw_interface_tap_v2_details_t * mp)
11817 {
11818   vat_main_t *vam = &vat_main;
11819   vat_json_node_t *node = NULL;
11820
11821   if (VAT_JSON_ARRAY != vam->json_tree.type)
11822     {
11823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11824       vat_json_init_array (&vam->json_tree);
11825     }
11826   node = vat_json_array_add (&vam->json_tree);
11827
11828   vat_json_init_object (node);
11829   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11830   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11831   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11832   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11833   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11834   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11835   vat_json_object_add_string_copy (node, "host_mac_addr",
11836                                    format (0, "%U", format_ethernet_address,
11837                                            &mp->host_mac_addr));
11838   vat_json_object_add_string_copy (node, "host_namespace",
11839                                    mp->host_namespace);
11840   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11841   vat_json_object_add_string_copy (node, "host_ip4_addr",
11842                                    format (0, "%U/%d", format_ip4_address,
11843                                            mp->host_ip4_addr,
11844                                            mp->host_ip4_prefix_len));
11845   vat_json_object_add_string_copy (node, "host_ip6_addr",
11846                                    format (0, "%U/%d", format_ip6_address,
11847                                            mp->host_ip6_addr,
11848                                            mp->host_ip6_prefix_len));
11849
11850 }
11851
11852 static int
11853 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11854 {
11855   vl_api_sw_interface_tap_v2_dump_t *mp;
11856   vl_api_control_ping_t *mp_ping;
11857   int ret;
11858
11859   print (vam->ofp,
11860          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11861          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11862          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11863          "host_ip6_addr");
11864
11865   /* Get list of tap interfaces */
11866   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11867   S (mp);
11868
11869   /* Use a control ping for synchronization */
11870   MPING (CONTROL_PING, mp_ping);
11871   S (mp_ping);
11872
11873   W (ret);
11874   return ret;
11875 }
11876
11877 static void vl_api_sw_interface_virtio_pci_details_t_handler
11878   (vl_api_sw_interface_virtio_pci_details_t * mp)
11879 {
11880   vat_main_t *vam = &vat_main;
11881
11882   typedef union
11883   {
11884     struct
11885     {
11886       u16 domain;
11887       u8 bus;
11888       u8 slot:5;
11889       u8 function:3;
11890     };
11891     u32 as_u32;
11892   } pci_addr_t;
11893   pci_addr_t addr;
11894   addr.as_u32 = ntohl (mp->pci_addr);
11895   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11896                          addr.slot, addr.function);
11897
11898   print (vam->ofp,
11899          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11900          pci_addr, ntohl (mp->sw_if_index),
11901          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11902          format_ethernet_address, mp->mac_addr,
11903          clib_net_to_host_u64 (mp->features));
11904   vec_free (pci_addr);
11905 }
11906
11907 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11908   (vl_api_sw_interface_virtio_pci_details_t * mp)
11909 {
11910   vat_main_t *vam = &vat_main;
11911   vat_json_node_t *node = NULL;
11912
11913   if (VAT_JSON_ARRAY != vam->json_tree.type)
11914     {
11915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11916       vat_json_init_array (&vam->json_tree);
11917     }
11918   node = vat_json_array_add (&vam->json_tree);
11919
11920   vat_json_init_object (node);
11921   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11922   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11923   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11924   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11925   vat_json_object_add_uint (node, "features",
11926                             clib_net_to_host_u64 (mp->features));
11927   vat_json_object_add_string_copy (node, "mac_addr",
11928                                    format (0, "%U", format_ethernet_address,
11929                                            &mp->mac_addr));
11930 }
11931
11932 static int
11933 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11934 {
11935   vl_api_sw_interface_virtio_pci_dump_t *mp;
11936   vl_api_control_ping_t *mp_ping;
11937   int ret;
11938
11939   print (vam->ofp,
11940          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11941          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11942          "mac_addr", "features");
11943
11944   /* Get list of tap interfaces */
11945   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11946   S (mp);
11947
11948   /* Use a control ping for synchronization */
11949   MPING (CONTROL_PING, mp_ping);
11950   S (mp_ping);
11951
11952   W (ret);
11953   return ret;
11954 }
11955
11956 static int
11957 api_vxlan_offload_rx (vat_main_t * vam)
11958 {
11959   unformat_input_t *line_input = vam->input;
11960   vl_api_vxlan_offload_rx_t *mp;
11961   u32 hw_if_index = ~0, rx_if_index = ~0;
11962   u8 is_add = 1;
11963   int ret;
11964
11965   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11966     {
11967       if (unformat (line_input, "del"))
11968         is_add = 0;
11969       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11970                          &hw_if_index))
11971         ;
11972       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11973         ;
11974       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11975                          &rx_if_index))
11976         ;
11977       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11978         ;
11979       else
11980         {
11981           errmsg ("parse error '%U'", format_unformat_error, line_input);
11982           return -99;
11983         }
11984     }
11985
11986   if (hw_if_index == ~0)
11987     {
11988       errmsg ("no hw interface");
11989       return -99;
11990     }
11991
11992   if (rx_if_index == ~0)
11993     {
11994       errmsg ("no rx tunnel");
11995       return -99;
11996     }
11997
11998   M (VXLAN_OFFLOAD_RX, mp);
11999
12000   mp->hw_if_index = ntohl (hw_if_index);
12001   mp->sw_if_index = ntohl (rx_if_index);
12002   mp->enable = is_add;
12003
12004   S (mp);
12005   W (ret);
12006   return ret;
12007 }
12008
12009 static uword unformat_vxlan_decap_next
12010   (unformat_input_t * input, va_list * args)
12011 {
12012   u32 *result = va_arg (*args, u32 *);
12013   u32 tmp;
12014
12015   if (unformat (input, "l2"))
12016     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12017   else if (unformat (input, "%d", &tmp))
12018     *result = tmp;
12019   else
12020     return 0;
12021   return 1;
12022 }
12023
12024 static int
12025 api_vxlan_add_del_tunnel (vat_main_t * vam)
12026 {
12027   unformat_input_t *line_input = vam->input;
12028   vl_api_vxlan_add_del_tunnel_t *mp;
12029   ip46_address_t src, dst;
12030   u8 is_add = 1;
12031   u8 ipv4_set = 0, ipv6_set = 0;
12032   u8 src_set = 0;
12033   u8 dst_set = 0;
12034   u8 grp_set = 0;
12035   u32 instance = ~0;
12036   u32 mcast_sw_if_index = ~0;
12037   u32 encap_vrf_id = 0;
12038   u32 decap_next_index = ~0;
12039   u32 vni = 0;
12040   int ret;
12041
12042   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12043   clib_memset (&src, 0, sizeof src);
12044   clib_memset (&dst, 0, sizeof dst);
12045
12046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12047     {
12048       if (unformat (line_input, "del"))
12049         is_add = 0;
12050       else if (unformat (line_input, "instance %d", &instance))
12051         ;
12052       else
12053         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12054         {
12055           ipv4_set = 1;
12056           src_set = 1;
12057         }
12058       else
12059         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12060         {
12061           ipv4_set = 1;
12062           dst_set = 1;
12063         }
12064       else
12065         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12066         {
12067           ipv6_set = 1;
12068           src_set = 1;
12069         }
12070       else
12071         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12072         {
12073           ipv6_set = 1;
12074           dst_set = 1;
12075         }
12076       else if (unformat (line_input, "group %U %U",
12077                          unformat_ip4_address, &dst.ip4,
12078                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12079         {
12080           grp_set = dst_set = 1;
12081           ipv4_set = 1;
12082         }
12083       else if (unformat (line_input, "group %U",
12084                          unformat_ip4_address, &dst.ip4))
12085         {
12086           grp_set = dst_set = 1;
12087           ipv4_set = 1;
12088         }
12089       else if (unformat (line_input, "group %U %U",
12090                          unformat_ip6_address, &dst.ip6,
12091                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12092         {
12093           grp_set = dst_set = 1;
12094           ipv6_set = 1;
12095         }
12096       else if (unformat (line_input, "group %U",
12097                          unformat_ip6_address, &dst.ip6))
12098         {
12099           grp_set = dst_set = 1;
12100           ipv6_set = 1;
12101         }
12102       else
12103         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12104         ;
12105       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12106         ;
12107       else if (unformat (line_input, "decap-next %U",
12108                          unformat_vxlan_decap_next, &decap_next_index))
12109         ;
12110       else if (unformat (line_input, "vni %d", &vni))
12111         ;
12112       else
12113         {
12114           errmsg ("parse error '%U'", format_unformat_error, line_input);
12115           return -99;
12116         }
12117     }
12118
12119   if (src_set == 0)
12120     {
12121       errmsg ("tunnel src address not specified");
12122       return -99;
12123     }
12124   if (dst_set == 0)
12125     {
12126       errmsg ("tunnel dst address not specified");
12127       return -99;
12128     }
12129
12130   if (grp_set && !ip46_address_is_multicast (&dst))
12131     {
12132       errmsg ("tunnel group address not multicast");
12133       return -99;
12134     }
12135   if (grp_set && mcast_sw_if_index == ~0)
12136     {
12137       errmsg ("tunnel nonexistent multicast device");
12138       return -99;
12139     }
12140   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12141     {
12142       errmsg ("tunnel dst address must be unicast");
12143       return -99;
12144     }
12145
12146
12147   if (ipv4_set && ipv6_set)
12148     {
12149       errmsg ("both IPv4 and IPv6 addresses specified");
12150       return -99;
12151     }
12152
12153   if ((vni == 0) || (vni >> 24))
12154     {
12155       errmsg ("vni not specified or out of range");
12156       return -99;
12157     }
12158
12159   M (VXLAN_ADD_DEL_TUNNEL, mp);
12160
12161   if (ipv6_set)
12162     {
12163       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12164       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12165     }
12166   else
12167     {
12168       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12169       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12170     }
12171
12172   mp->instance = htonl (instance);
12173   mp->encap_vrf_id = ntohl (encap_vrf_id);
12174   mp->decap_next_index = ntohl (decap_next_index);
12175   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12176   mp->vni = ntohl (vni);
12177   mp->is_add = is_add;
12178   mp->is_ipv6 = ipv6_set;
12179
12180   S (mp);
12181   W (ret);
12182   return ret;
12183 }
12184
12185 static void vl_api_vxlan_tunnel_details_t_handler
12186   (vl_api_vxlan_tunnel_details_t * mp)
12187 {
12188   vat_main_t *vam = &vat_main;
12189   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12190   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12191
12192   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12193          ntohl (mp->sw_if_index),
12194          ntohl (mp->instance),
12195          format_ip46_address, &src, IP46_TYPE_ANY,
12196          format_ip46_address, &dst, IP46_TYPE_ANY,
12197          ntohl (mp->encap_vrf_id),
12198          ntohl (mp->decap_next_index), ntohl (mp->vni),
12199          ntohl (mp->mcast_sw_if_index));
12200 }
12201
12202 static void vl_api_vxlan_tunnel_details_t_handler_json
12203   (vl_api_vxlan_tunnel_details_t * mp)
12204 {
12205   vat_main_t *vam = &vat_main;
12206   vat_json_node_t *node = NULL;
12207
12208   if (VAT_JSON_ARRAY != vam->json_tree.type)
12209     {
12210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12211       vat_json_init_array (&vam->json_tree);
12212     }
12213   node = vat_json_array_add (&vam->json_tree);
12214
12215   vat_json_init_object (node);
12216   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12217
12218   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12219
12220   if (mp->is_ipv6)
12221     {
12222       struct in6_addr ip6;
12223
12224       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12225       vat_json_object_add_ip6 (node, "src_address", ip6);
12226       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12227       vat_json_object_add_ip6 (node, "dst_address", ip6);
12228     }
12229   else
12230     {
12231       struct in_addr ip4;
12232
12233       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12234       vat_json_object_add_ip4 (node, "src_address", ip4);
12235       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12236       vat_json_object_add_ip4 (node, "dst_address", ip4);
12237     }
12238   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12239   vat_json_object_add_uint (node, "decap_next_index",
12240                             ntohl (mp->decap_next_index));
12241   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12242   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12243   vat_json_object_add_uint (node, "mcast_sw_if_index",
12244                             ntohl (mp->mcast_sw_if_index));
12245 }
12246
12247 static int
12248 api_vxlan_tunnel_dump (vat_main_t * vam)
12249 {
12250   unformat_input_t *i = vam->input;
12251   vl_api_vxlan_tunnel_dump_t *mp;
12252   vl_api_control_ping_t *mp_ping;
12253   u32 sw_if_index;
12254   u8 sw_if_index_set = 0;
12255   int ret;
12256
12257   /* Parse args required to build the message */
12258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (i, "sw_if_index %d", &sw_if_index))
12261         sw_if_index_set = 1;
12262       else
12263         break;
12264     }
12265
12266   if (sw_if_index_set == 0)
12267     {
12268       sw_if_index = ~0;
12269     }
12270
12271   if (!vam->json_output)
12272     {
12273       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12274              "sw_if_index", "instance", "src_address", "dst_address",
12275              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12276     }
12277
12278   /* Get list of vxlan-tunnel interfaces */
12279   M (VXLAN_TUNNEL_DUMP, mp);
12280
12281   mp->sw_if_index = htonl (sw_if_index);
12282
12283   S (mp);
12284
12285   /* Use a control ping for synchronization */
12286   MPING (CONTROL_PING, mp_ping);
12287   S (mp_ping);
12288
12289   W (ret);
12290   return ret;
12291 }
12292
12293 static uword unformat_geneve_decap_next
12294   (unformat_input_t * input, va_list * args)
12295 {
12296   u32 *result = va_arg (*args, u32 *);
12297   u32 tmp;
12298
12299   if (unformat (input, "l2"))
12300     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12301   else if (unformat (input, "%d", &tmp))
12302     *result = tmp;
12303   else
12304     return 0;
12305   return 1;
12306 }
12307
12308 static int
12309 api_geneve_add_del_tunnel (vat_main_t * vam)
12310 {
12311   unformat_input_t *line_input = vam->input;
12312   vl_api_geneve_add_del_tunnel_t *mp;
12313   ip46_address_t src, dst;
12314   u8 is_add = 1;
12315   u8 ipv4_set = 0, ipv6_set = 0;
12316   u8 src_set = 0;
12317   u8 dst_set = 0;
12318   u8 grp_set = 0;
12319   u32 mcast_sw_if_index = ~0;
12320   u32 encap_vrf_id = 0;
12321   u32 decap_next_index = ~0;
12322   u32 vni = 0;
12323   int ret;
12324
12325   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12326   clib_memset (&src, 0, sizeof src);
12327   clib_memset (&dst, 0, sizeof dst);
12328
12329   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (line_input, "del"))
12332         is_add = 0;
12333       else
12334         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12335         {
12336           ipv4_set = 1;
12337           src_set = 1;
12338         }
12339       else
12340         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12341         {
12342           ipv4_set = 1;
12343           dst_set = 1;
12344         }
12345       else
12346         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12347         {
12348           ipv6_set = 1;
12349           src_set = 1;
12350         }
12351       else
12352         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12353         {
12354           ipv6_set = 1;
12355           dst_set = 1;
12356         }
12357       else if (unformat (line_input, "group %U %U",
12358                          unformat_ip4_address, &dst.ip4,
12359                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12360         {
12361           grp_set = dst_set = 1;
12362           ipv4_set = 1;
12363         }
12364       else if (unformat (line_input, "group %U",
12365                          unformat_ip4_address, &dst.ip4))
12366         {
12367           grp_set = dst_set = 1;
12368           ipv4_set = 1;
12369         }
12370       else if (unformat (line_input, "group %U %U",
12371                          unformat_ip6_address, &dst.ip6,
12372                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12373         {
12374           grp_set = dst_set = 1;
12375           ipv6_set = 1;
12376         }
12377       else if (unformat (line_input, "group %U",
12378                          unformat_ip6_address, &dst.ip6))
12379         {
12380           grp_set = dst_set = 1;
12381           ipv6_set = 1;
12382         }
12383       else
12384         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12385         ;
12386       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12387         ;
12388       else if (unformat (line_input, "decap-next %U",
12389                          unformat_geneve_decap_next, &decap_next_index))
12390         ;
12391       else if (unformat (line_input, "vni %d", &vni))
12392         ;
12393       else
12394         {
12395           errmsg ("parse error '%U'", format_unformat_error, line_input);
12396           return -99;
12397         }
12398     }
12399
12400   if (src_set == 0)
12401     {
12402       errmsg ("tunnel src address not specified");
12403       return -99;
12404     }
12405   if (dst_set == 0)
12406     {
12407       errmsg ("tunnel dst address not specified");
12408       return -99;
12409     }
12410
12411   if (grp_set && !ip46_address_is_multicast (&dst))
12412     {
12413       errmsg ("tunnel group address not multicast");
12414       return -99;
12415     }
12416   if (grp_set && mcast_sw_if_index == ~0)
12417     {
12418       errmsg ("tunnel nonexistent multicast device");
12419       return -99;
12420     }
12421   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12422     {
12423       errmsg ("tunnel dst address must be unicast");
12424       return -99;
12425     }
12426
12427
12428   if (ipv4_set && ipv6_set)
12429     {
12430       errmsg ("both IPv4 and IPv6 addresses specified");
12431       return -99;
12432     }
12433
12434   if ((vni == 0) || (vni >> 24))
12435     {
12436       errmsg ("vni not specified or out of range");
12437       return -99;
12438     }
12439
12440   M (GENEVE_ADD_DEL_TUNNEL, mp);
12441
12442   if (ipv6_set)
12443     {
12444       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12445       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12446     }
12447   else
12448     {
12449       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12450       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12451     }
12452   mp->encap_vrf_id = ntohl (encap_vrf_id);
12453   mp->decap_next_index = ntohl (decap_next_index);
12454   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12455   mp->vni = ntohl (vni);
12456   mp->is_add = is_add;
12457
12458   S (mp);
12459   W (ret);
12460   return ret;
12461 }
12462
12463 static void vl_api_geneve_tunnel_details_t_handler
12464   (vl_api_geneve_tunnel_details_t * mp)
12465 {
12466   vat_main_t *vam = &vat_main;
12467   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12468   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12469
12470   if (mp->src_address.af == ADDRESS_IP6)
12471     {
12472       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12473       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12474     }
12475   else
12476     {
12477       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12478       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12479     }
12480
12481   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12482          ntohl (mp->sw_if_index),
12483          format_ip46_address, &src, IP46_TYPE_ANY,
12484          format_ip46_address, &dst, IP46_TYPE_ANY,
12485          ntohl (mp->encap_vrf_id),
12486          ntohl (mp->decap_next_index), ntohl (mp->vni),
12487          ntohl (mp->mcast_sw_if_index));
12488 }
12489
12490 static void vl_api_geneve_tunnel_details_t_handler_json
12491   (vl_api_geneve_tunnel_details_t * mp)
12492 {
12493   vat_main_t *vam = &vat_main;
12494   vat_json_node_t *node = NULL;
12495   bool is_ipv6;
12496
12497   if (VAT_JSON_ARRAY != vam->json_tree.type)
12498     {
12499       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12500       vat_json_init_array (&vam->json_tree);
12501     }
12502   node = vat_json_array_add (&vam->json_tree);
12503
12504   vat_json_init_object (node);
12505   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12506   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12507   if (is_ipv6)
12508     {
12509       struct in6_addr ip6;
12510
12511       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12512       vat_json_object_add_ip6 (node, "src_address", ip6);
12513       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12514       vat_json_object_add_ip6 (node, "dst_address", ip6);
12515     }
12516   else
12517     {
12518       struct in_addr ip4;
12519
12520       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12521       vat_json_object_add_ip4 (node, "src_address", ip4);
12522       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12523       vat_json_object_add_ip4 (node, "dst_address", ip4);
12524     }
12525   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12526   vat_json_object_add_uint (node, "decap_next_index",
12527                             ntohl (mp->decap_next_index));
12528   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12529   vat_json_object_add_uint (node, "mcast_sw_if_index",
12530                             ntohl (mp->mcast_sw_if_index));
12531 }
12532
12533 static int
12534 api_geneve_tunnel_dump (vat_main_t * vam)
12535 {
12536   unformat_input_t *i = vam->input;
12537   vl_api_geneve_tunnel_dump_t *mp;
12538   vl_api_control_ping_t *mp_ping;
12539   u32 sw_if_index;
12540   u8 sw_if_index_set = 0;
12541   int ret;
12542
12543   /* Parse args required to build the message */
12544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12545     {
12546       if (unformat (i, "sw_if_index %d", &sw_if_index))
12547         sw_if_index_set = 1;
12548       else
12549         break;
12550     }
12551
12552   if (sw_if_index_set == 0)
12553     {
12554       sw_if_index = ~0;
12555     }
12556
12557   if (!vam->json_output)
12558     {
12559       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12560              "sw_if_index", "local_address", "remote_address",
12561              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12562     }
12563
12564   /* Get list of geneve-tunnel interfaces */
12565   M (GENEVE_TUNNEL_DUMP, mp);
12566
12567   mp->sw_if_index = htonl (sw_if_index);
12568
12569   S (mp);
12570
12571   /* Use a control ping for synchronization */
12572   M (CONTROL_PING, mp_ping);
12573   S (mp_ping);
12574
12575   W (ret);
12576   return ret;
12577 }
12578
12579 static int
12580 api_gre_tunnel_add_del (vat_main_t * vam)
12581 {
12582   unformat_input_t *line_input = vam->input;
12583   vl_api_address_t src = { }, dst =
12584   {
12585   };
12586   vl_api_gre_tunnel_add_del_t *mp;
12587   vl_api_gre_tunnel_type_t t_type;
12588   u8 is_add = 1;
12589   u8 src_set = 0;
12590   u8 dst_set = 0;
12591   u32 outer_fib_id = 0;
12592   u32 session_id = 0;
12593   u32 instance = ~0;
12594   int ret;
12595
12596   t_type = GRE_API_TUNNEL_TYPE_L3;
12597
12598   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12599     {
12600       if (unformat (line_input, "del"))
12601         is_add = 0;
12602       else if (unformat (line_input, "instance %d", &instance))
12603         ;
12604       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12605         {
12606           src_set = 1;
12607         }
12608       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12609         {
12610           dst_set = 1;
12611         }
12612       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12613         ;
12614       else if (unformat (line_input, "teb"))
12615         t_type = GRE_API_TUNNEL_TYPE_TEB;
12616       else if (unformat (line_input, "erspan %d", &session_id))
12617         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12618       else
12619         {
12620           errmsg ("parse error '%U'", format_unformat_error, line_input);
12621           return -99;
12622         }
12623     }
12624
12625   if (src_set == 0)
12626     {
12627       errmsg ("tunnel src address not specified");
12628       return -99;
12629     }
12630   if (dst_set == 0)
12631     {
12632       errmsg ("tunnel dst address not specified");
12633       return -99;
12634     }
12635
12636   M (GRE_TUNNEL_ADD_DEL, mp);
12637
12638   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12639   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12640
12641   mp->tunnel.instance = htonl (instance);
12642   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12643   mp->is_add = is_add;
12644   mp->tunnel.session_id = htons ((u16) session_id);
12645   mp->tunnel.type = htonl (t_type);
12646
12647   S (mp);
12648   W (ret);
12649   return ret;
12650 }
12651
12652 static void vl_api_gre_tunnel_details_t_handler
12653   (vl_api_gre_tunnel_details_t * mp)
12654 {
12655   vat_main_t *vam = &vat_main;
12656
12657   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12658          ntohl (mp->tunnel.sw_if_index),
12659          ntohl (mp->tunnel.instance),
12660          format_vl_api_address, &mp->tunnel.src,
12661          format_vl_api_address, &mp->tunnel.dst,
12662          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12663          ntohl (mp->tunnel.session_id));
12664 }
12665
12666 static void vl_api_gre_tunnel_details_t_handler_json
12667   (vl_api_gre_tunnel_details_t * mp)
12668 {
12669   vat_main_t *vam = &vat_main;
12670   vat_json_node_t *node = NULL;
12671
12672   if (VAT_JSON_ARRAY != vam->json_tree.type)
12673     {
12674       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12675       vat_json_init_array (&vam->json_tree);
12676     }
12677   node = vat_json_array_add (&vam->json_tree);
12678
12679   vat_json_init_object (node);
12680   vat_json_object_add_uint (node, "sw_if_index",
12681                             ntohl (mp->tunnel.sw_if_index));
12682   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12683
12684   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12685   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12686   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12687   vat_json_object_add_uint (node, "outer_fib_id",
12688                             ntohl (mp->tunnel.outer_fib_id));
12689   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12690 }
12691
12692 static int
12693 api_gre_tunnel_dump (vat_main_t * vam)
12694 {
12695   unformat_input_t *i = vam->input;
12696   vl_api_gre_tunnel_dump_t *mp;
12697   vl_api_control_ping_t *mp_ping;
12698   u32 sw_if_index;
12699   u8 sw_if_index_set = 0;
12700   int ret;
12701
12702   /* Parse args required to build the message */
12703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12704     {
12705       if (unformat (i, "sw_if_index %d", &sw_if_index))
12706         sw_if_index_set = 1;
12707       else
12708         break;
12709     }
12710
12711   if (sw_if_index_set == 0)
12712     {
12713       sw_if_index = ~0;
12714     }
12715
12716   if (!vam->json_output)
12717     {
12718       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12719              "sw_if_index", "instance", "src_address", "dst_address",
12720              "tunnel_type", "outer_fib_id", "session_id");
12721     }
12722
12723   /* Get list of gre-tunnel interfaces */
12724   M (GRE_TUNNEL_DUMP, mp);
12725
12726   mp->sw_if_index = htonl (sw_if_index);
12727
12728   S (mp);
12729
12730   /* Use a control ping for synchronization */
12731   MPING (CONTROL_PING, mp_ping);
12732   S (mp_ping);
12733
12734   W (ret);
12735   return ret;
12736 }
12737
12738 static int
12739 api_l2_fib_clear_table (vat_main_t * vam)
12740 {
12741 //  unformat_input_t * i = vam->input;
12742   vl_api_l2_fib_clear_table_t *mp;
12743   int ret;
12744
12745   M (L2_FIB_CLEAR_TABLE, mp);
12746
12747   S (mp);
12748   W (ret);
12749   return ret;
12750 }
12751
12752 static int
12753 api_l2_interface_efp_filter (vat_main_t * vam)
12754 {
12755   unformat_input_t *i = vam->input;
12756   vl_api_l2_interface_efp_filter_t *mp;
12757   u32 sw_if_index;
12758   u8 enable = 1;
12759   u8 sw_if_index_set = 0;
12760   int ret;
12761
12762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12763     {
12764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12765         sw_if_index_set = 1;
12766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12767         sw_if_index_set = 1;
12768       else if (unformat (i, "enable"))
12769         enable = 1;
12770       else if (unformat (i, "disable"))
12771         enable = 0;
12772       else
12773         {
12774           clib_warning ("parse error '%U'", format_unformat_error, i);
12775           return -99;
12776         }
12777     }
12778
12779   if (sw_if_index_set == 0)
12780     {
12781       errmsg ("missing sw_if_index");
12782       return -99;
12783     }
12784
12785   M (L2_INTERFACE_EFP_FILTER, mp);
12786
12787   mp->sw_if_index = ntohl (sw_if_index);
12788   mp->enable_disable = enable;
12789
12790   S (mp);
12791   W (ret);
12792   return ret;
12793 }
12794
12795 #define foreach_vtr_op                          \
12796 _("disable",  L2_VTR_DISABLED)                  \
12797 _("push-1",  L2_VTR_PUSH_1)                     \
12798 _("push-2",  L2_VTR_PUSH_2)                     \
12799 _("pop-1",  L2_VTR_POP_1)                       \
12800 _("pop-2",  L2_VTR_POP_2)                       \
12801 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12802 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12803 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12804 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12805
12806 static int
12807 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12808 {
12809   unformat_input_t *i = vam->input;
12810   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12811   u32 sw_if_index;
12812   u8 sw_if_index_set = 0;
12813   u8 vtr_op_set = 0;
12814   u32 vtr_op = 0;
12815   u32 push_dot1q = 1;
12816   u32 tag1 = ~0;
12817   u32 tag2 = ~0;
12818   int ret;
12819
12820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12821     {
12822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12823         sw_if_index_set = 1;
12824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12825         sw_if_index_set = 1;
12826       else if (unformat (i, "vtr_op %d", &vtr_op))
12827         vtr_op_set = 1;
12828 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12829       foreach_vtr_op
12830 #undef _
12831         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12832         ;
12833       else if (unformat (i, "tag1 %d", &tag1))
12834         ;
12835       else if (unformat (i, "tag2 %d", &tag2))
12836         ;
12837       else
12838         {
12839           clib_warning ("parse error '%U'", format_unformat_error, i);
12840           return -99;
12841         }
12842     }
12843
12844   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12845     {
12846       errmsg ("missing vtr operation or sw_if_index");
12847       return -99;
12848     }
12849
12850   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12851   mp->sw_if_index = ntohl (sw_if_index);
12852   mp->vtr_op = ntohl (vtr_op);
12853   mp->push_dot1q = ntohl (push_dot1q);
12854   mp->tag1 = ntohl (tag1);
12855   mp->tag2 = ntohl (tag2);
12856
12857   S (mp);
12858   W (ret);
12859   return ret;
12860 }
12861
12862 static int
12863 api_create_vhost_user_if (vat_main_t * vam)
12864 {
12865   unformat_input_t *i = vam->input;
12866   vl_api_create_vhost_user_if_t *mp;
12867   u8 *file_name;
12868   u8 is_server = 0;
12869   u8 file_name_set = 0;
12870   u32 custom_dev_instance = ~0;
12871   u8 hwaddr[6];
12872   u8 use_custom_mac = 0;
12873   u8 disable_mrg_rxbuf = 0;
12874   u8 disable_indirect_desc = 0;
12875   u8 *tag = 0;
12876   u8 enable_gso = 0;
12877   int ret;
12878
12879   /* Shut up coverity */
12880   clib_memset (hwaddr, 0, sizeof (hwaddr));
12881
12882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12883     {
12884       if (unformat (i, "socket %s", &file_name))
12885         {
12886           file_name_set = 1;
12887         }
12888       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12889         ;
12890       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12891         use_custom_mac = 1;
12892       else if (unformat (i, "server"))
12893         is_server = 1;
12894       else if (unformat (i, "disable_mrg_rxbuf"))
12895         disable_mrg_rxbuf = 1;
12896       else if (unformat (i, "disable_indirect_desc"))
12897         disable_indirect_desc = 1;
12898       else if (unformat (i, "gso"))
12899         enable_gso = 1;
12900       else if (unformat (i, "tag %s", &tag))
12901         ;
12902       else
12903         break;
12904     }
12905
12906   if (file_name_set == 0)
12907     {
12908       errmsg ("missing socket file name");
12909       return -99;
12910     }
12911
12912   if (vec_len (file_name) > 255)
12913     {
12914       errmsg ("socket file name too long");
12915       return -99;
12916     }
12917   vec_add1 (file_name, 0);
12918
12919   M (CREATE_VHOST_USER_IF, mp);
12920
12921   mp->is_server = is_server;
12922   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12923   mp->disable_indirect_desc = disable_indirect_desc;
12924   mp->enable_gso = enable_gso;
12925   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12926   vec_free (file_name);
12927   if (custom_dev_instance != ~0)
12928     {
12929       mp->renumber = 1;
12930       mp->custom_dev_instance = ntohl (custom_dev_instance);
12931     }
12932
12933   mp->use_custom_mac = use_custom_mac;
12934   clib_memcpy (mp->mac_address, hwaddr, 6);
12935   if (tag)
12936     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12937   vec_free (tag);
12938
12939   S (mp);
12940   W (ret);
12941   return ret;
12942 }
12943
12944 static int
12945 api_modify_vhost_user_if (vat_main_t * vam)
12946 {
12947   unformat_input_t *i = vam->input;
12948   vl_api_modify_vhost_user_if_t *mp;
12949   u8 *file_name;
12950   u8 is_server = 0;
12951   u8 file_name_set = 0;
12952   u32 custom_dev_instance = ~0;
12953   u8 sw_if_index_set = 0;
12954   u32 sw_if_index = (u32) ~ 0;
12955   u8 enable_gso = 0;
12956   int ret;
12957
12958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12961         sw_if_index_set = 1;
12962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12963         sw_if_index_set = 1;
12964       else if (unformat (i, "socket %s", &file_name))
12965         {
12966           file_name_set = 1;
12967         }
12968       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12969         ;
12970       else if (unformat (i, "server"))
12971         is_server = 1;
12972       else if (unformat (i, "gso"))
12973         enable_gso = 1;
12974       else
12975         break;
12976     }
12977
12978   if (sw_if_index_set == 0)
12979     {
12980       errmsg ("missing sw_if_index or interface name");
12981       return -99;
12982     }
12983
12984   if (file_name_set == 0)
12985     {
12986       errmsg ("missing socket file name");
12987       return -99;
12988     }
12989
12990   if (vec_len (file_name) > 255)
12991     {
12992       errmsg ("socket file name too long");
12993       return -99;
12994     }
12995   vec_add1 (file_name, 0);
12996
12997   M (MODIFY_VHOST_USER_IF, mp);
12998
12999   mp->sw_if_index = ntohl (sw_if_index);
13000   mp->is_server = is_server;
13001   mp->enable_gso = enable_gso;
13002   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13003   vec_free (file_name);
13004   if (custom_dev_instance != ~0)
13005     {
13006       mp->renumber = 1;
13007       mp->custom_dev_instance = ntohl (custom_dev_instance);
13008     }
13009
13010   S (mp);
13011   W (ret);
13012   return ret;
13013 }
13014
13015 static int
13016 api_delete_vhost_user_if (vat_main_t * vam)
13017 {
13018   unformat_input_t *i = vam->input;
13019   vl_api_delete_vhost_user_if_t *mp;
13020   u32 sw_if_index = ~0;
13021   u8 sw_if_index_set = 0;
13022   int ret;
13023
13024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13025     {
13026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13027         sw_if_index_set = 1;
13028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13029         sw_if_index_set = 1;
13030       else
13031         break;
13032     }
13033
13034   if (sw_if_index_set == 0)
13035     {
13036       errmsg ("missing sw_if_index or interface name");
13037       return -99;
13038     }
13039
13040
13041   M (DELETE_VHOST_USER_IF, mp);
13042
13043   mp->sw_if_index = ntohl (sw_if_index);
13044
13045   S (mp);
13046   W (ret);
13047   return ret;
13048 }
13049
13050 static void vl_api_sw_interface_vhost_user_details_t_handler
13051   (vl_api_sw_interface_vhost_user_details_t * mp)
13052 {
13053   vat_main_t *vam = &vat_main;
13054
13055   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13056          (char *) mp->interface_name,
13057          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13058          clib_net_to_host_u64 (mp->features), mp->is_server,
13059          ntohl (mp->num_regions), (char *) mp->sock_filename);
13060   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13061 }
13062
13063 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13064   (vl_api_sw_interface_vhost_user_details_t * mp)
13065 {
13066   vat_main_t *vam = &vat_main;
13067   vat_json_node_t *node = NULL;
13068
13069   if (VAT_JSON_ARRAY != vam->json_tree.type)
13070     {
13071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13072       vat_json_init_array (&vam->json_tree);
13073     }
13074   node = vat_json_array_add (&vam->json_tree);
13075
13076   vat_json_init_object (node);
13077   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13078   vat_json_object_add_string_copy (node, "interface_name",
13079                                    mp->interface_name);
13080   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13081                             ntohl (mp->virtio_net_hdr_sz));
13082   vat_json_object_add_uint (node, "features",
13083                             clib_net_to_host_u64 (mp->features));
13084   vat_json_object_add_uint (node, "is_server", mp->is_server);
13085   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13086   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13087   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13088 }
13089
13090 static int
13091 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13092 {
13093   vl_api_sw_interface_vhost_user_dump_t *mp;
13094   vl_api_control_ping_t *mp_ping;
13095   int ret;
13096   print (vam->ofp,
13097          "Interface name            idx hdr_sz features server regions filename");
13098
13099   /* Get list of vhost-user interfaces */
13100   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13101   S (mp);
13102
13103   /* Use a control ping for synchronization */
13104   MPING (CONTROL_PING, mp_ping);
13105   S (mp_ping);
13106
13107   W (ret);
13108   return ret;
13109 }
13110
13111 static int
13112 api_show_version (vat_main_t * vam)
13113 {
13114   vl_api_show_version_t *mp;
13115   int ret;
13116
13117   M (SHOW_VERSION, mp);
13118
13119   S (mp);
13120   W (ret);
13121   return ret;
13122 }
13123
13124
13125 static int
13126 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13127 {
13128   unformat_input_t *line_input = vam->input;
13129   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13130   ip4_address_t local4, remote4;
13131   ip6_address_t local6, remote6;
13132   u8 is_add = 1;
13133   u8 ipv4_set = 0, ipv6_set = 0;
13134   u8 local_set = 0;
13135   u8 remote_set = 0;
13136   u8 grp_set = 0;
13137   u32 mcast_sw_if_index = ~0;
13138   u32 encap_vrf_id = 0;
13139   u32 decap_vrf_id = 0;
13140   u8 protocol = ~0;
13141   u32 vni;
13142   u8 vni_set = 0;
13143   int ret;
13144
13145   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13146   clib_memset (&local4, 0, sizeof local4);
13147   clib_memset (&remote4, 0, sizeof remote4);
13148   clib_memset (&local6, 0, sizeof local6);
13149   clib_memset (&remote6, 0, sizeof remote6);
13150
13151   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13152     {
13153       if (unformat (line_input, "del"))
13154         is_add = 0;
13155       else if (unformat (line_input, "local %U",
13156                          unformat_ip4_address, &local4))
13157         {
13158           local_set = 1;
13159           ipv4_set = 1;
13160         }
13161       else if (unformat (line_input, "remote %U",
13162                          unformat_ip4_address, &remote4))
13163         {
13164           remote_set = 1;
13165           ipv4_set = 1;
13166         }
13167       else if (unformat (line_input, "local %U",
13168                          unformat_ip6_address, &local6))
13169         {
13170           local_set = 1;
13171           ipv6_set = 1;
13172         }
13173       else if (unformat (line_input, "remote %U",
13174                          unformat_ip6_address, &remote6))
13175         {
13176           remote_set = 1;
13177           ipv6_set = 1;
13178         }
13179       else if (unformat (line_input, "group %U %U",
13180                          unformat_ip4_address, &remote4,
13181                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13182         {
13183           grp_set = remote_set = 1;
13184           ipv4_set = 1;
13185         }
13186       else if (unformat (line_input, "group %U",
13187                          unformat_ip4_address, &remote4))
13188         {
13189           grp_set = remote_set = 1;
13190           ipv4_set = 1;
13191         }
13192       else if (unformat (line_input, "group %U %U",
13193                          unformat_ip6_address, &remote6,
13194                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13195         {
13196           grp_set = remote_set = 1;
13197           ipv6_set = 1;
13198         }
13199       else if (unformat (line_input, "group %U",
13200                          unformat_ip6_address, &remote6))
13201         {
13202           grp_set = remote_set = 1;
13203           ipv6_set = 1;
13204         }
13205       else
13206         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13207         ;
13208       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13209         ;
13210       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13211         ;
13212       else if (unformat (line_input, "vni %d", &vni))
13213         vni_set = 1;
13214       else if (unformat (line_input, "next-ip4"))
13215         protocol = 1;
13216       else if (unformat (line_input, "next-ip6"))
13217         protocol = 2;
13218       else if (unformat (line_input, "next-ethernet"))
13219         protocol = 3;
13220       else if (unformat (line_input, "next-nsh"))
13221         protocol = 4;
13222       else
13223         {
13224           errmsg ("parse error '%U'", format_unformat_error, line_input);
13225           return -99;
13226         }
13227     }
13228
13229   if (local_set == 0)
13230     {
13231       errmsg ("tunnel local address not specified");
13232       return -99;
13233     }
13234   if (remote_set == 0)
13235     {
13236       errmsg ("tunnel remote address not specified");
13237       return -99;
13238     }
13239   if (grp_set && mcast_sw_if_index == ~0)
13240     {
13241       errmsg ("tunnel nonexistent multicast device");
13242       return -99;
13243     }
13244   if (ipv4_set && ipv6_set)
13245     {
13246       errmsg ("both IPv4 and IPv6 addresses specified");
13247       return -99;
13248     }
13249
13250   if (vni_set == 0)
13251     {
13252       errmsg ("vni not specified");
13253       return -99;
13254     }
13255
13256   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13257
13258
13259   if (ipv6_set)
13260     {
13261       clib_memcpy (&mp->local, &local6, sizeof (local6));
13262       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13263     }
13264   else
13265     {
13266       clib_memcpy (&mp->local, &local4, sizeof (local4));
13267       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13268     }
13269
13270   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13271   mp->encap_vrf_id = ntohl (encap_vrf_id);
13272   mp->decap_vrf_id = ntohl (decap_vrf_id);
13273   mp->protocol = protocol;
13274   mp->vni = ntohl (vni);
13275   mp->is_add = is_add;
13276   mp->is_ipv6 = ipv6_set;
13277
13278   S (mp);
13279   W (ret);
13280   return ret;
13281 }
13282
13283 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13284   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13285 {
13286   vat_main_t *vam = &vat_main;
13287   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13288   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13289
13290   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13291          ntohl (mp->sw_if_index),
13292          format_ip46_address, &local, IP46_TYPE_ANY,
13293          format_ip46_address, &remote, IP46_TYPE_ANY,
13294          ntohl (mp->vni), mp->protocol,
13295          ntohl (mp->mcast_sw_if_index),
13296          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13297 }
13298
13299
13300 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13301   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13302 {
13303   vat_main_t *vam = &vat_main;
13304   vat_json_node_t *node = NULL;
13305   struct in_addr ip4;
13306   struct in6_addr ip6;
13307
13308   if (VAT_JSON_ARRAY != vam->json_tree.type)
13309     {
13310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13311       vat_json_init_array (&vam->json_tree);
13312     }
13313   node = vat_json_array_add (&vam->json_tree);
13314
13315   vat_json_init_object (node);
13316   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13317   if (mp->is_ipv6)
13318     {
13319       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13320       vat_json_object_add_ip6 (node, "local", ip6);
13321       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13322       vat_json_object_add_ip6 (node, "remote", ip6);
13323     }
13324   else
13325     {
13326       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13327       vat_json_object_add_ip4 (node, "local", ip4);
13328       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13329       vat_json_object_add_ip4 (node, "remote", ip4);
13330     }
13331   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13332   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13333   vat_json_object_add_uint (node, "mcast_sw_if_index",
13334                             ntohl (mp->mcast_sw_if_index));
13335   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13336   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13337   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13338 }
13339
13340 static int
13341 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13342 {
13343   unformat_input_t *i = vam->input;
13344   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13345   vl_api_control_ping_t *mp_ping;
13346   u32 sw_if_index;
13347   u8 sw_if_index_set = 0;
13348   int ret;
13349
13350   /* Parse args required to build the message */
13351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13352     {
13353       if (unformat (i, "sw_if_index %d", &sw_if_index))
13354         sw_if_index_set = 1;
13355       else
13356         break;
13357     }
13358
13359   if (sw_if_index_set == 0)
13360     {
13361       sw_if_index = ~0;
13362     }
13363
13364   if (!vam->json_output)
13365     {
13366       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13367              "sw_if_index", "local", "remote", "vni",
13368              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13369     }
13370
13371   /* Get list of vxlan-tunnel interfaces */
13372   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13373
13374   mp->sw_if_index = htonl (sw_if_index);
13375
13376   S (mp);
13377
13378   /* Use a control ping for synchronization */
13379   MPING (CONTROL_PING, mp_ping);
13380   S (mp_ping);
13381
13382   W (ret);
13383   return ret;
13384 }
13385
13386 static void vl_api_l2_fib_table_details_t_handler
13387   (vl_api_l2_fib_table_details_t * mp)
13388 {
13389   vat_main_t *vam = &vat_main;
13390
13391   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13392          "       %d       %d     %d",
13393          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13394          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13395          mp->bvi_mac);
13396 }
13397
13398 static void vl_api_l2_fib_table_details_t_handler_json
13399   (vl_api_l2_fib_table_details_t * mp)
13400 {
13401   vat_main_t *vam = &vat_main;
13402   vat_json_node_t *node = NULL;
13403
13404   if (VAT_JSON_ARRAY != vam->json_tree.type)
13405     {
13406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13407       vat_json_init_array (&vam->json_tree);
13408     }
13409   node = vat_json_array_add (&vam->json_tree);
13410
13411   vat_json_init_object (node);
13412   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13413   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13414   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13415   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13416   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13417   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13418 }
13419
13420 static int
13421 api_l2_fib_table_dump (vat_main_t * vam)
13422 {
13423   unformat_input_t *i = vam->input;
13424   vl_api_l2_fib_table_dump_t *mp;
13425   vl_api_control_ping_t *mp_ping;
13426   u32 bd_id;
13427   u8 bd_id_set = 0;
13428   int ret;
13429
13430   /* Parse args required to build the message */
13431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13432     {
13433       if (unformat (i, "bd_id %d", &bd_id))
13434         bd_id_set = 1;
13435       else
13436         break;
13437     }
13438
13439   if (bd_id_set == 0)
13440     {
13441       errmsg ("missing bridge domain");
13442       return -99;
13443     }
13444
13445   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13446
13447   /* Get list of l2 fib entries */
13448   M (L2_FIB_TABLE_DUMP, mp);
13449
13450   mp->bd_id = ntohl (bd_id);
13451   S (mp);
13452
13453   /* Use a control ping for synchronization */
13454   MPING (CONTROL_PING, mp_ping);
13455   S (mp_ping);
13456
13457   W (ret);
13458   return ret;
13459 }
13460
13461
13462 static int
13463 api_interface_name_renumber (vat_main_t * vam)
13464 {
13465   unformat_input_t *line_input = vam->input;
13466   vl_api_interface_name_renumber_t *mp;
13467   u32 sw_if_index = ~0;
13468   u32 new_show_dev_instance = ~0;
13469   int ret;
13470
13471   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13472     {
13473       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13474                     &sw_if_index))
13475         ;
13476       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13477         ;
13478       else if (unformat (line_input, "new_show_dev_instance %d",
13479                          &new_show_dev_instance))
13480         ;
13481       else
13482         break;
13483     }
13484
13485   if (sw_if_index == ~0)
13486     {
13487       errmsg ("missing interface name or sw_if_index");
13488       return -99;
13489     }
13490
13491   if (new_show_dev_instance == ~0)
13492     {
13493       errmsg ("missing new_show_dev_instance");
13494       return -99;
13495     }
13496
13497   M (INTERFACE_NAME_RENUMBER, mp);
13498
13499   mp->sw_if_index = ntohl (sw_if_index);
13500   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13501
13502   S (mp);
13503   W (ret);
13504   return ret;
13505 }
13506
13507 static int
13508 api_ip_probe_neighbor (vat_main_t * vam)
13509 {
13510   unformat_input_t *i = vam->input;
13511   vl_api_ip_probe_neighbor_t *mp;
13512   vl_api_address_t dst_adr = { };
13513   u8 int_set = 0;
13514   u8 adr_set = 0;
13515   u32 sw_if_index;
13516   int ret;
13517
13518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13519     {
13520       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13521         int_set = 1;
13522       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13523         int_set = 1;
13524       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13525         adr_set = 1;
13526       else
13527         break;
13528     }
13529
13530   if (int_set == 0)
13531     {
13532       errmsg ("missing interface");
13533       return -99;
13534     }
13535
13536   if (adr_set == 0)
13537     {
13538       errmsg ("missing addresses");
13539       return -99;
13540     }
13541
13542   M (IP_PROBE_NEIGHBOR, mp);
13543
13544   mp->sw_if_index = ntohl (sw_if_index);
13545   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13546
13547   S (mp);
13548   W (ret);
13549   return ret;
13550 }
13551
13552 static int
13553 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13554 {
13555   unformat_input_t *i = vam->input;
13556   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13557   u8 mode = IP_SCAN_V46_NEIGHBORS;
13558   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13559   int ret;
13560
13561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13562     {
13563       if (unformat (i, "ip4"))
13564         mode = IP_SCAN_V4_NEIGHBORS;
13565       else if (unformat (i, "ip6"))
13566         mode = IP_SCAN_V6_NEIGHBORS;
13567       if (unformat (i, "both"))
13568         mode = IP_SCAN_V46_NEIGHBORS;
13569       else if (unformat (i, "disable"))
13570         mode = IP_SCAN_DISABLED;
13571       else if (unformat (i, "interval %d", &interval))
13572         ;
13573       else if (unformat (i, "max-time %d", &time))
13574         ;
13575       else if (unformat (i, "max-update %d", &update))
13576         ;
13577       else if (unformat (i, "delay %d", &delay))
13578         ;
13579       else if (unformat (i, "stale %d", &stale))
13580         ;
13581       else
13582         break;
13583     }
13584
13585   if (interval > 255)
13586     {
13587       errmsg ("interval cannot exceed 255 minutes.");
13588       return -99;
13589     }
13590   if (time > 255)
13591     {
13592       errmsg ("max-time cannot exceed 255 usec.");
13593       return -99;
13594     }
13595   if (update > 255)
13596     {
13597       errmsg ("max-update cannot exceed 255.");
13598       return -99;
13599     }
13600   if (delay > 255)
13601     {
13602       errmsg ("delay cannot exceed 255 msec.");
13603       return -99;
13604     }
13605   if (stale > 255)
13606     {
13607       errmsg ("stale cannot exceed 255 minutes.");
13608       return -99;
13609     }
13610
13611   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13612   mp->mode = mode;
13613   mp->scan_interval = interval;
13614   mp->max_proc_time = time;
13615   mp->max_update = update;
13616   mp->scan_int_delay = delay;
13617   mp->stale_threshold = stale;
13618
13619   S (mp);
13620   W (ret);
13621   return ret;
13622 }
13623
13624 static int
13625 api_want_ip4_arp_events (vat_main_t * vam)
13626 {
13627   unformat_input_t *line_input = vam->input;
13628   vl_api_want_ip4_arp_events_t *mp;
13629   ip4_address_t address;
13630   int address_set = 0;
13631   u32 enable_disable = 1;
13632   int ret;
13633
13634   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13635     {
13636       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13637         address_set = 1;
13638       else if (unformat (line_input, "del"))
13639         enable_disable = 0;
13640       else
13641         break;
13642     }
13643
13644   if (address_set == 0)
13645     {
13646       errmsg ("missing addresses");
13647       return -99;
13648     }
13649
13650   M (WANT_IP4_ARP_EVENTS, mp);
13651   mp->enable_disable = enable_disable;
13652   mp->pid = htonl (getpid ());
13653   clib_memcpy (mp->ip, &address, sizeof (address));
13654
13655   S (mp);
13656   W (ret);
13657   return ret;
13658 }
13659
13660 static int
13661 api_want_ip6_nd_events (vat_main_t * vam)
13662 {
13663   unformat_input_t *line_input = vam->input;
13664   vl_api_want_ip6_nd_events_t *mp;
13665   vl_api_ip6_address_t address;
13666   int address_set = 0;
13667   u32 enable_disable = 1;
13668   int ret;
13669
13670   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13671     {
13672       if (unformat
13673           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13674         address_set = 1;
13675       else if (unformat (line_input, "del"))
13676         enable_disable = 0;
13677       else
13678         break;
13679     }
13680
13681   if (address_set == 0)
13682     {
13683       errmsg ("missing addresses");
13684       return -99;
13685     }
13686
13687   M (WANT_IP6_ND_EVENTS, mp);
13688   mp->enable_disable = enable_disable;
13689   mp->pid = htonl (getpid ());
13690   clib_memcpy (&mp->ip, &address, sizeof (address));
13691
13692   S (mp);
13693   W (ret);
13694   return ret;
13695 }
13696
13697 static int
13698 api_want_l2_macs_events (vat_main_t * vam)
13699 {
13700   unformat_input_t *line_input = vam->input;
13701   vl_api_want_l2_macs_events_t *mp;
13702   u8 enable_disable = 1;
13703   u32 scan_delay = 0;
13704   u32 max_macs_in_event = 0;
13705   u32 learn_limit = 0;
13706   int ret;
13707
13708   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13709     {
13710       if (unformat (line_input, "learn-limit %d", &learn_limit))
13711         ;
13712       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13713         ;
13714       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13715         ;
13716       else if (unformat (line_input, "disable"))
13717         enable_disable = 0;
13718       else
13719         break;
13720     }
13721
13722   M (WANT_L2_MACS_EVENTS, mp);
13723   mp->enable_disable = enable_disable;
13724   mp->pid = htonl (getpid ());
13725   mp->learn_limit = htonl (learn_limit);
13726   mp->scan_delay = (u8) scan_delay;
13727   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13728   S (mp);
13729   W (ret);
13730   return ret;
13731 }
13732
13733 static int
13734 api_input_acl_set_interface (vat_main_t * vam)
13735 {
13736   unformat_input_t *i = vam->input;
13737   vl_api_input_acl_set_interface_t *mp;
13738   u32 sw_if_index;
13739   int sw_if_index_set;
13740   u32 ip4_table_index = ~0;
13741   u32 ip6_table_index = ~0;
13742   u32 l2_table_index = ~0;
13743   u8 is_add = 1;
13744   int ret;
13745
13746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13749         sw_if_index_set = 1;
13750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13751         sw_if_index_set = 1;
13752       else if (unformat (i, "del"))
13753         is_add = 0;
13754       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13755         ;
13756       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13757         ;
13758       else if (unformat (i, "l2-table %d", &l2_table_index))
13759         ;
13760       else
13761         {
13762           clib_warning ("parse error '%U'", format_unformat_error, i);
13763           return -99;
13764         }
13765     }
13766
13767   if (sw_if_index_set == 0)
13768     {
13769       errmsg ("missing interface name or sw_if_index");
13770       return -99;
13771     }
13772
13773   M (INPUT_ACL_SET_INTERFACE, mp);
13774
13775   mp->sw_if_index = ntohl (sw_if_index);
13776   mp->ip4_table_index = ntohl (ip4_table_index);
13777   mp->ip6_table_index = ntohl (ip6_table_index);
13778   mp->l2_table_index = ntohl (l2_table_index);
13779   mp->is_add = is_add;
13780
13781   S (mp);
13782   W (ret);
13783   return ret;
13784 }
13785
13786 static int
13787 api_output_acl_set_interface (vat_main_t * vam)
13788 {
13789   unformat_input_t *i = vam->input;
13790   vl_api_output_acl_set_interface_t *mp;
13791   u32 sw_if_index;
13792   int sw_if_index_set;
13793   u32 ip4_table_index = ~0;
13794   u32 ip6_table_index = ~0;
13795   u32 l2_table_index = ~0;
13796   u8 is_add = 1;
13797   int ret;
13798
13799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13800     {
13801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13802         sw_if_index_set = 1;
13803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13804         sw_if_index_set = 1;
13805       else if (unformat (i, "del"))
13806         is_add = 0;
13807       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13808         ;
13809       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13810         ;
13811       else if (unformat (i, "l2-table %d", &l2_table_index))
13812         ;
13813       else
13814         {
13815           clib_warning ("parse error '%U'", format_unformat_error, i);
13816           return -99;
13817         }
13818     }
13819
13820   if (sw_if_index_set == 0)
13821     {
13822       errmsg ("missing interface name or sw_if_index");
13823       return -99;
13824     }
13825
13826   M (OUTPUT_ACL_SET_INTERFACE, mp);
13827
13828   mp->sw_if_index = ntohl (sw_if_index);
13829   mp->ip4_table_index = ntohl (ip4_table_index);
13830   mp->ip6_table_index = ntohl (ip6_table_index);
13831   mp->l2_table_index = ntohl (l2_table_index);
13832   mp->is_add = is_add;
13833
13834   S (mp);
13835   W (ret);
13836   return ret;
13837 }
13838
13839 static int
13840 api_ip_address_dump (vat_main_t * vam)
13841 {
13842   unformat_input_t *i = vam->input;
13843   vl_api_ip_address_dump_t *mp;
13844   vl_api_control_ping_t *mp_ping;
13845   u32 sw_if_index = ~0;
13846   u8 sw_if_index_set = 0;
13847   u8 ipv4_set = 0;
13848   u8 ipv6_set = 0;
13849   int ret;
13850
13851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13852     {
13853       if (unformat (i, "sw_if_index %d", &sw_if_index))
13854         sw_if_index_set = 1;
13855       else
13856         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13857         sw_if_index_set = 1;
13858       else if (unformat (i, "ipv4"))
13859         ipv4_set = 1;
13860       else if (unformat (i, "ipv6"))
13861         ipv6_set = 1;
13862       else
13863         break;
13864     }
13865
13866   if (ipv4_set && ipv6_set)
13867     {
13868       errmsg ("ipv4 and ipv6 flags cannot be both set");
13869       return -99;
13870     }
13871
13872   if ((!ipv4_set) && (!ipv6_set))
13873     {
13874       errmsg ("no ipv4 nor ipv6 flag set");
13875       return -99;
13876     }
13877
13878   if (sw_if_index_set == 0)
13879     {
13880       errmsg ("missing interface name or sw_if_index");
13881       return -99;
13882     }
13883
13884   vam->current_sw_if_index = sw_if_index;
13885   vam->is_ipv6 = ipv6_set;
13886
13887   M (IP_ADDRESS_DUMP, mp);
13888   mp->sw_if_index = ntohl (sw_if_index);
13889   mp->is_ipv6 = ipv6_set;
13890   S (mp);
13891
13892   /* Use a control ping for synchronization */
13893   MPING (CONTROL_PING, mp_ping);
13894   S (mp_ping);
13895
13896   W (ret);
13897   return ret;
13898 }
13899
13900 static int
13901 api_ip_dump (vat_main_t * vam)
13902 {
13903   vl_api_ip_dump_t *mp;
13904   vl_api_control_ping_t *mp_ping;
13905   unformat_input_t *in = vam->input;
13906   int ipv4_set = 0;
13907   int ipv6_set = 0;
13908   int is_ipv6;
13909   int i;
13910   int ret;
13911
13912   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13913     {
13914       if (unformat (in, "ipv4"))
13915         ipv4_set = 1;
13916       else if (unformat (in, "ipv6"))
13917         ipv6_set = 1;
13918       else
13919         break;
13920     }
13921
13922   if (ipv4_set && ipv6_set)
13923     {
13924       errmsg ("ipv4 and ipv6 flags cannot be both set");
13925       return -99;
13926     }
13927
13928   if ((!ipv4_set) && (!ipv6_set))
13929     {
13930       errmsg ("no ipv4 nor ipv6 flag set");
13931       return -99;
13932     }
13933
13934   is_ipv6 = ipv6_set;
13935   vam->is_ipv6 = is_ipv6;
13936
13937   /* free old data */
13938   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13939     {
13940       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13941     }
13942   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13943
13944   M (IP_DUMP, mp);
13945   mp->is_ipv6 = ipv6_set;
13946   S (mp);
13947
13948   /* Use a control ping for synchronization */
13949   MPING (CONTROL_PING, mp_ping);
13950   S (mp_ping);
13951
13952   W (ret);
13953   return ret;
13954 }
13955
13956 static int
13957 api_ipsec_spd_add_del (vat_main_t * vam)
13958 {
13959   unformat_input_t *i = vam->input;
13960   vl_api_ipsec_spd_add_del_t *mp;
13961   u32 spd_id = ~0;
13962   u8 is_add = 1;
13963   int ret;
13964
13965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13966     {
13967       if (unformat (i, "spd_id %d", &spd_id))
13968         ;
13969       else if (unformat (i, "del"))
13970         is_add = 0;
13971       else
13972         {
13973           clib_warning ("parse error '%U'", format_unformat_error, i);
13974           return -99;
13975         }
13976     }
13977   if (spd_id == ~0)
13978     {
13979       errmsg ("spd_id must be set");
13980       return -99;
13981     }
13982
13983   M (IPSEC_SPD_ADD_DEL, mp);
13984
13985   mp->spd_id = ntohl (spd_id);
13986   mp->is_add = is_add;
13987
13988   S (mp);
13989   W (ret);
13990   return ret;
13991 }
13992
13993 static int
13994 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13995 {
13996   unformat_input_t *i = vam->input;
13997   vl_api_ipsec_interface_add_del_spd_t *mp;
13998   u32 sw_if_index;
13999   u8 sw_if_index_set = 0;
14000   u32 spd_id = (u32) ~ 0;
14001   u8 is_add = 1;
14002   int ret;
14003
14004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14005     {
14006       if (unformat (i, "del"))
14007         is_add = 0;
14008       else if (unformat (i, "spd_id %d", &spd_id))
14009         ;
14010       else
14011         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14012         sw_if_index_set = 1;
14013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14014         sw_if_index_set = 1;
14015       else
14016         {
14017           clib_warning ("parse error '%U'", format_unformat_error, i);
14018           return -99;
14019         }
14020
14021     }
14022
14023   if (spd_id == (u32) ~ 0)
14024     {
14025       errmsg ("spd_id must be set");
14026       return -99;
14027     }
14028
14029   if (sw_if_index_set == 0)
14030     {
14031       errmsg ("missing interface name or sw_if_index");
14032       return -99;
14033     }
14034
14035   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14036
14037   mp->spd_id = ntohl (spd_id);
14038   mp->sw_if_index = ntohl (sw_if_index);
14039   mp->is_add = is_add;
14040
14041   S (mp);
14042   W (ret);
14043   return ret;
14044 }
14045
14046 static int
14047 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14048 {
14049   unformat_input_t *i = vam->input;
14050   vl_api_ipsec_spd_entry_add_del_t *mp;
14051   u8 is_add = 1, is_outbound = 0;
14052   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14053   i32 priority = 0;
14054   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14055   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14056   vl_api_address_t laddr_start = { }, laddr_stop =
14057   {
14058   }, raddr_start =
14059   {
14060   }, raddr_stop =
14061   {
14062   };
14063   int ret;
14064
14065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14066     {
14067       if (unformat (i, "del"))
14068         is_add = 0;
14069       if (unformat (i, "outbound"))
14070         is_outbound = 1;
14071       if (unformat (i, "inbound"))
14072         is_outbound = 0;
14073       else if (unformat (i, "spd_id %d", &spd_id))
14074         ;
14075       else if (unformat (i, "sa_id %d", &sa_id))
14076         ;
14077       else if (unformat (i, "priority %d", &priority))
14078         ;
14079       else if (unformat (i, "protocol %d", &protocol))
14080         ;
14081       else if (unformat (i, "lport_start %d", &lport_start))
14082         ;
14083       else if (unformat (i, "lport_stop %d", &lport_stop))
14084         ;
14085       else if (unformat (i, "rport_start %d", &rport_start))
14086         ;
14087       else if (unformat (i, "rport_stop %d", &rport_stop))
14088         ;
14089       else if (unformat (i, "laddr_start %U",
14090                          unformat_vl_api_address, &laddr_start))
14091         ;
14092       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14093                          &laddr_stop))
14094         ;
14095       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14096                          &raddr_start))
14097         ;
14098       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14099                          &raddr_stop))
14100         ;
14101       else
14102         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14103         {
14104           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14105             {
14106               clib_warning ("unsupported action: 'resolve'");
14107               return -99;
14108             }
14109         }
14110       else
14111         {
14112           clib_warning ("parse error '%U'", format_unformat_error, i);
14113           return -99;
14114         }
14115
14116     }
14117
14118   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14119
14120   mp->is_add = is_add;
14121
14122   mp->entry.spd_id = ntohl (spd_id);
14123   mp->entry.priority = ntohl (priority);
14124   mp->entry.is_outbound = is_outbound;
14125
14126   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14127                sizeof (vl_api_address_t));
14128   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14129                sizeof (vl_api_address_t));
14130   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14131                sizeof (vl_api_address_t));
14132   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14133                sizeof (vl_api_address_t));
14134
14135   mp->entry.protocol = (u8) protocol;
14136   mp->entry.local_port_start = ntohs ((u16) lport_start);
14137   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14138   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14139   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14140   mp->entry.policy = (u8) policy;
14141   mp->entry.sa_id = ntohl (sa_id);
14142
14143   S (mp);
14144   W (ret);
14145   return ret;
14146 }
14147
14148 static int
14149 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14150 {
14151   unformat_input_t *i = vam->input;
14152   vl_api_ipsec_sad_entry_add_del_t *mp;
14153   u32 sad_id = 0, spi = 0;
14154   u8 *ck = 0, *ik = 0;
14155   u8 is_add = 1;
14156
14157   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14158   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14159   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14160   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14161   vl_api_address_t tun_src, tun_dst;
14162   int ret;
14163
14164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14165     {
14166       if (unformat (i, "del"))
14167         is_add = 0;
14168       else if (unformat (i, "sad_id %d", &sad_id))
14169         ;
14170       else if (unformat (i, "spi %d", &spi))
14171         ;
14172       else if (unformat (i, "esp"))
14173         protocol = IPSEC_API_PROTO_ESP;
14174       else
14175         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14176         {
14177           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14178           if (ADDRESS_IP6 == tun_src.af)
14179             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14180         }
14181       else
14182         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14183         {
14184           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14185           if (ADDRESS_IP6 == tun_src.af)
14186             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14187         }
14188       else
14189         if (unformat (i, "crypto_alg %U",
14190                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14191         ;
14192       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14193         ;
14194       else if (unformat (i, "integ_alg %U",
14195                          unformat_ipsec_api_integ_alg, &integ_alg))
14196         ;
14197       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14198         ;
14199       else
14200         {
14201           clib_warning ("parse error '%U'", format_unformat_error, i);
14202           return -99;
14203         }
14204
14205     }
14206
14207   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14208
14209   mp->is_add = is_add;
14210   mp->entry.sad_id = ntohl (sad_id);
14211   mp->entry.protocol = protocol;
14212   mp->entry.spi = ntohl (spi);
14213   mp->entry.flags = flags;
14214
14215   mp->entry.crypto_algorithm = crypto_alg;
14216   mp->entry.integrity_algorithm = integ_alg;
14217   mp->entry.crypto_key.length = vec_len (ck);
14218   mp->entry.integrity_key.length = vec_len (ik);
14219
14220   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14221     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14222
14223   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14224     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14225
14226   if (ck)
14227     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14228   if (ik)
14229     clib_memcpy (mp->entry.integrity_key.data, ik,
14230                  mp->entry.integrity_key.length);
14231
14232   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14233     {
14234       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14235                    sizeof (mp->entry.tunnel_src));
14236       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14237                    sizeof (mp->entry.tunnel_dst));
14238     }
14239
14240   S (mp);
14241   W (ret);
14242   return ret;
14243 }
14244
14245 static int
14246 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14247 {
14248   unformat_input_t *i = vam->input;
14249   vl_api_ipsec_tunnel_if_add_del_t *mp;
14250   u32 local_spi = 0, remote_spi = 0;
14251   u32 crypto_alg = 0, integ_alg = 0;
14252   u8 *lck = NULL, *rck = NULL;
14253   u8 *lik = NULL, *rik = NULL;
14254   vl_api_address_t local_ip = { 0 };
14255   vl_api_address_t remote_ip = { 0 };
14256   f64 before = 0;
14257   u8 is_add = 1;
14258   u8 esn = 0;
14259   u8 anti_replay = 0;
14260   u8 renumber = 0;
14261   u32 instance = ~0;
14262   u32 count = 1, jj;
14263   int ret = -1;
14264
14265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14266     {
14267       if (unformat (i, "del"))
14268         is_add = 0;
14269       else if (unformat (i, "esn"))
14270         esn = 1;
14271       else if (unformat (i, "anti-replay"))
14272         anti_replay = 1;
14273       else if (unformat (i, "count %d", &count))
14274         ;
14275       else if (unformat (i, "local_spi %d", &local_spi))
14276         ;
14277       else if (unformat (i, "remote_spi %d", &remote_spi))
14278         ;
14279       else
14280         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14281         ;
14282       else
14283         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14284         ;
14285       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14286         ;
14287       else
14288         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14289         ;
14290       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14291         ;
14292       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14293         ;
14294       else
14295         if (unformat
14296             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14297         {
14298           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14299             {
14300               errmsg ("unsupported crypto-alg: '%U'\n",
14301                       format_ipsec_crypto_alg, crypto_alg);
14302               return -99;
14303             }
14304         }
14305       else
14306         if (unformat
14307             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14308         {
14309           if (integ_alg >= IPSEC_INTEG_N_ALG)
14310             {
14311               errmsg ("unsupported integ-alg: '%U'\n",
14312                       format_ipsec_integ_alg, integ_alg);
14313               return -99;
14314             }
14315         }
14316       else if (unformat (i, "instance %u", &instance))
14317         renumber = 1;
14318       else
14319         {
14320           errmsg ("parse error '%U'\n", format_unformat_error, i);
14321           return -99;
14322         }
14323     }
14324
14325   if (count > 1)
14326     {
14327       /* Turn on async mode */
14328       vam->async_mode = 1;
14329       vam->async_errors = 0;
14330       before = vat_time_now (vam);
14331     }
14332
14333   for (jj = 0; jj < count; jj++)
14334     {
14335       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14336
14337       mp->is_add = is_add;
14338       mp->esn = esn;
14339       mp->anti_replay = anti_replay;
14340
14341       if (jj > 0)
14342         increment_address (&remote_ip);
14343
14344       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14345       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14346
14347       mp->local_spi = htonl (local_spi + jj);
14348       mp->remote_spi = htonl (remote_spi + jj);
14349       mp->crypto_alg = (u8) crypto_alg;
14350
14351       mp->local_crypto_key_len = 0;
14352       if (lck)
14353         {
14354           mp->local_crypto_key_len = vec_len (lck);
14355           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14356             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14357           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14358         }
14359
14360       mp->remote_crypto_key_len = 0;
14361       if (rck)
14362         {
14363           mp->remote_crypto_key_len = vec_len (rck);
14364           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14365             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14366           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14367         }
14368
14369       mp->integ_alg = (u8) integ_alg;
14370
14371       mp->local_integ_key_len = 0;
14372       if (lik)
14373         {
14374           mp->local_integ_key_len = vec_len (lik);
14375           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14376             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14377           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14378         }
14379
14380       mp->remote_integ_key_len = 0;
14381       if (rik)
14382         {
14383           mp->remote_integ_key_len = vec_len (rik);
14384           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14385             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14386           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14387         }
14388
14389       if (renumber)
14390         {
14391           mp->renumber = renumber;
14392           mp->show_instance = ntohl (instance);
14393         }
14394       S (mp);
14395     }
14396
14397   /* When testing multiple add/del ops, use a control-ping to sync */
14398   if (count > 1)
14399     {
14400       vl_api_control_ping_t *mp_ping;
14401       f64 after;
14402       f64 timeout;
14403
14404       /* Shut off async mode */
14405       vam->async_mode = 0;
14406
14407       MPING (CONTROL_PING, mp_ping);
14408       S (mp_ping);
14409
14410       timeout = vat_time_now (vam) + 1.0;
14411       while (vat_time_now (vam) < timeout)
14412         if (vam->result_ready == 1)
14413           goto out;
14414       vam->retval = -99;
14415
14416     out:
14417       if (vam->retval == -99)
14418         errmsg ("timeout");
14419
14420       if (vam->async_errors > 0)
14421         {
14422           errmsg ("%d asynchronous errors", vam->async_errors);
14423           vam->retval = -98;
14424         }
14425       vam->async_errors = 0;
14426       after = vat_time_now (vam);
14427
14428       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14429       if (jj > 0)
14430         count = jj;
14431
14432       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14433              count, after - before, count / (after - before));
14434     }
14435   else
14436     {
14437       /* Wait for a reply... */
14438       W (ret);
14439       return ret;
14440     }
14441
14442   return ret;
14443 }
14444
14445 static void
14446 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14447 {
14448   vat_main_t *vam = &vat_main;
14449
14450   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14451          "crypto_key %U integ_alg %u integ_key %U flags %x "
14452          "tunnel_src_addr %U tunnel_dst_addr %U "
14453          "salt %u seq_outbound %lu last_seq_inbound %lu "
14454          "replay_window %lu\n",
14455          ntohl (mp->entry.sad_id),
14456          ntohl (mp->sw_if_index),
14457          ntohl (mp->entry.spi),
14458          ntohl (mp->entry.protocol),
14459          ntohl (mp->entry.crypto_algorithm),
14460          format_hex_bytes, mp->entry.crypto_key.data,
14461          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14462          format_hex_bytes, mp->entry.integrity_key.data,
14463          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14464          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14465          &mp->entry.tunnel_dst, ntohl (mp->salt),
14466          clib_net_to_host_u64 (mp->seq_outbound),
14467          clib_net_to_host_u64 (mp->last_seq_inbound),
14468          clib_net_to_host_u64 (mp->replay_window));
14469 }
14470
14471 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14472 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14473
14474 static void vl_api_ipsec_sa_details_t_handler_json
14475   (vl_api_ipsec_sa_details_t * mp)
14476 {
14477   vat_main_t *vam = &vat_main;
14478   vat_json_node_t *node = NULL;
14479   vl_api_ipsec_sad_flags_t flags;
14480
14481   if (VAT_JSON_ARRAY != vam->json_tree.type)
14482     {
14483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14484       vat_json_init_array (&vam->json_tree);
14485     }
14486   node = vat_json_array_add (&vam->json_tree);
14487
14488   vat_json_init_object (node);
14489   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14491   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14492   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14493   vat_json_object_add_uint (node, "crypto_alg",
14494                             ntohl (mp->entry.crypto_algorithm));
14495   vat_json_object_add_uint (node, "integ_alg",
14496                             ntohl (mp->entry.integrity_algorithm));
14497   flags = ntohl (mp->entry.flags);
14498   vat_json_object_add_uint (node, "use_esn",
14499                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14500   vat_json_object_add_uint (node, "use_anti_replay",
14501                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14502   vat_json_object_add_uint (node, "is_tunnel",
14503                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14504   vat_json_object_add_uint (node, "is_tunnel_ip6",
14505                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14506   vat_json_object_add_uint (node, "udp_encap",
14507                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14508   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14509                              mp->entry.crypto_key.length);
14510   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14511                              mp->entry.integrity_key.length);
14512   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14513   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14514   vat_json_object_add_uint (node, "replay_window",
14515                             clib_net_to_host_u64 (mp->replay_window));
14516 }
14517
14518 static int
14519 api_ipsec_sa_dump (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_ipsec_sa_dump_t *mp;
14523   vl_api_control_ping_t *mp_ping;
14524   u32 sa_id = ~0;
14525   int ret;
14526
14527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (i, "sa_id %d", &sa_id))
14530         ;
14531       else
14532         {
14533           clib_warning ("parse error '%U'", format_unformat_error, i);
14534           return -99;
14535         }
14536     }
14537
14538   M (IPSEC_SA_DUMP, mp);
14539
14540   mp->sa_id = ntohl (sa_id);
14541
14542   S (mp);
14543
14544   /* Use a control ping for synchronization */
14545   M (CONTROL_PING, mp_ping);
14546   S (mp_ping);
14547
14548   W (ret);
14549   return ret;
14550 }
14551
14552 static int
14553 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14554 {
14555   unformat_input_t *i = vam->input;
14556   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14557   u32 sw_if_index = ~0;
14558   u32 sa_id = ~0;
14559   u8 is_outbound = (u8) ~ 0;
14560   int ret;
14561
14562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14563     {
14564       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14565         ;
14566       else if (unformat (i, "sa_id %d", &sa_id))
14567         ;
14568       else if (unformat (i, "outbound"))
14569         is_outbound = 1;
14570       else if (unformat (i, "inbound"))
14571         is_outbound = 0;
14572       else
14573         {
14574           clib_warning ("parse error '%U'", format_unformat_error, i);
14575           return -99;
14576         }
14577     }
14578
14579   if (sw_if_index == ~0)
14580     {
14581       errmsg ("interface must be specified");
14582       return -99;
14583     }
14584
14585   if (sa_id == ~0)
14586     {
14587       errmsg ("SA ID must be specified");
14588       return -99;
14589     }
14590
14591   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14592
14593   mp->sw_if_index = htonl (sw_if_index);
14594   mp->sa_id = htonl (sa_id);
14595   mp->is_outbound = is_outbound;
14596
14597   S (mp);
14598   W (ret);
14599
14600   return ret;
14601 }
14602
14603 static int
14604 api_get_first_msg_id (vat_main_t * vam)
14605 {
14606   vl_api_get_first_msg_id_t *mp;
14607   unformat_input_t *i = vam->input;
14608   u8 *name;
14609   u8 name_set = 0;
14610   int ret;
14611
14612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (i, "client %s", &name))
14615         name_set = 1;
14616       else
14617         break;
14618     }
14619
14620   if (name_set == 0)
14621     {
14622       errmsg ("missing client name");
14623       return -99;
14624     }
14625   vec_add1 (name, 0);
14626
14627   if (vec_len (name) > 63)
14628     {
14629       errmsg ("client name too long");
14630       return -99;
14631     }
14632
14633   M (GET_FIRST_MSG_ID, mp);
14634   clib_memcpy (mp->name, name, vec_len (name));
14635   S (mp);
14636   W (ret);
14637   return ret;
14638 }
14639
14640 static int
14641 api_cop_interface_enable_disable (vat_main_t * vam)
14642 {
14643   unformat_input_t *line_input = vam->input;
14644   vl_api_cop_interface_enable_disable_t *mp;
14645   u32 sw_if_index = ~0;
14646   u8 enable_disable = 1;
14647   int ret;
14648
14649   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14650     {
14651       if (unformat (line_input, "disable"))
14652         enable_disable = 0;
14653       if (unformat (line_input, "enable"))
14654         enable_disable = 1;
14655       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14656                          vam, &sw_if_index))
14657         ;
14658       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14659         ;
14660       else
14661         break;
14662     }
14663
14664   if (sw_if_index == ~0)
14665     {
14666       errmsg ("missing interface name or sw_if_index");
14667       return -99;
14668     }
14669
14670   /* Construct the API message */
14671   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14672   mp->sw_if_index = ntohl (sw_if_index);
14673   mp->enable_disable = enable_disable;
14674
14675   /* send it... */
14676   S (mp);
14677   /* Wait for the reply */
14678   W (ret);
14679   return ret;
14680 }
14681
14682 static int
14683 api_cop_whitelist_enable_disable (vat_main_t * vam)
14684 {
14685   unformat_input_t *line_input = vam->input;
14686   vl_api_cop_whitelist_enable_disable_t *mp;
14687   u32 sw_if_index = ~0;
14688   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14689   u32 fib_id = 0;
14690   int ret;
14691
14692   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14693     {
14694       if (unformat (line_input, "ip4"))
14695         ip4 = 1;
14696       else if (unformat (line_input, "ip6"))
14697         ip6 = 1;
14698       else if (unformat (line_input, "default"))
14699         default_cop = 1;
14700       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14701                          vam, &sw_if_index))
14702         ;
14703       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14704         ;
14705       else if (unformat (line_input, "fib-id %d", &fib_id))
14706         ;
14707       else
14708         break;
14709     }
14710
14711   if (sw_if_index == ~0)
14712     {
14713       errmsg ("missing interface name or sw_if_index");
14714       return -99;
14715     }
14716
14717   /* Construct the API message */
14718   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14719   mp->sw_if_index = ntohl (sw_if_index);
14720   mp->fib_id = ntohl (fib_id);
14721   mp->ip4 = ip4;
14722   mp->ip6 = ip6;
14723   mp->default_cop = default_cop;
14724
14725   /* send it... */
14726   S (mp);
14727   /* Wait for the reply */
14728   W (ret);
14729   return ret;
14730 }
14731
14732 static int
14733 api_get_node_graph (vat_main_t * vam)
14734 {
14735   vl_api_get_node_graph_t *mp;
14736   int ret;
14737
14738   M (GET_NODE_GRAPH, mp);
14739
14740   /* send it... */
14741   S (mp);
14742   /* Wait for the reply */
14743   W (ret);
14744   return ret;
14745 }
14746
14747 /* *INDENT-OFF* */
14748 /** Used for parsing LISP eids */
14749 typedef CLIB_PACKED(struct{
14750   u8 addr[16];   /**< eid address */
14751   u32 len;       /**< prefix length if IP */
14752   u8 type;      /**< type of eid */
14753 }) lisp_eid_vat_t;
14754 /* *INDENT-ON* */
14755
14756 static uword
14757 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14758 {
14759   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14760
14761   clib_memset (a, 0, sizeof (a[0]));
14762
14763   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14764     {
14765       a->type = 0;              /* ipv4 type */
14766     }
14767   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14768     {
14769       a->type = 1;              /* ipv6 type */
14770     }
14771   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14772     {
14773       a->type = 2;              /* mac type */
14774     }
14775   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14776     {
14777       a->type = 3;              /* NSH type */
14778       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14779       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14780     }
14781   else
14782     {
14783       return 0;
14784     }
14785
14786   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14787     {
14788       return 0;
14789     }
14790
14791   return 1;
14792 }
14793
14794 static int
14795 lisp_eid_size_vat (u8 type)
14796 {
14797   switch (type)
14798     {
14799     case 0:
14800       return 4;
14801     case 1:
14802       return 16;
14803     case 2:
14804       return 6;
14805     case 3:
14806       return 5;
14807     }
14808   return 0;
14809 }
14810
14811 static void
14812 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14813 {
14814   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14815 }
14816
14817 static int
14818 api_one_add_del_locator_set (vat_main_t * vam)
14819 {
14820   unformat_input_t *input = vam->input;
14821   vl_api_one_add_del_locator_set_t *mp;
14822   u8 is_add = 1;
14823   u8 *locator_set_name = NULL;
14824   u8 locator_set_name_set = 0;
14825   vl_api_local_locator_t locator, *locators = 0;
14826   u32 sw_if_index, priority, weight;
14827   u32 data_len = 0;
14828
14829   int ret;
14830   /* Parse args required to build the message */
14831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14832     {
14833       if (unformat (input, "del"))
14834         {
14835           is_add = 0;
14836         }
14837       else if (unformat (input, "locator-set %s", &locator_set_name))
14838         {
14839           locator_set_name_set = 1;
14840         }
14841       else if (unformat (input, "sw_if_index %u p %u w %u",
14842                          &sw_if_index, &priority, &weight))
14843         {
14844           locator.sw_if_index = htonl (sw_if_index);
14845           locator.priority = priority;
14846           locator.weight = weight;
14847           vec_add1 (locators, locator);
14848         }
14849       else
14850         if (unformat
14851             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14852              &sw_if_index, &priority, &weight))
14853         {
14854           locator.sw_if_index = htonl (sw_if_index);
14855           locator.priority = priority;
14856           locator.weight = weight;
14857           vec_add1 (locators, locator);
14858         }
14859       else
14860         break;
14861     }
14862
14863   if (locator_set_name_set == 0)
14864     {
14865       errmsg ("missing locator-set name");
14866       vec_free (locators);
14867       return -99;
14868     }
14869
14870   if (vec_len (locator_set_name) > 64)
14871     {
14872       errmsg ("locator-set name too long");
14873       vec_free (locator_set_name);
14874       vec_free (locators);
14875       return -99;
14876     }
14877   vec_add1 (locator_set_name, 0);
14878
14879   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14880
14881   /* Construct the API message */
14882   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14883
14884   mp->is_add = is_add;
14885   clib_memcpy (mp->locator_set_name, locator_set_name,
14886                vec_len (locator_set_name));
14887   vec_free (locator_set_name);
14888
14889   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14890   if (locators)
14891     clib_memcpy (mp->locators, locators, data_len);
14892   vec_free (locators);
14893
14894   /* send it... */
14895   S (mp);
14896
14897   /* Wait for a reply... */
14898   W (ret);
14899   return ret;
14900 }
14901
14902 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14903
14904 static int
14905 api_one_add_del_locator (vat_main_t * vam)
14906 {
14907   unformat_input_t *input = vam->input;
14908   vl_api_one_add_del_locator_t *mp;
14909   u32 tmp_if_index = ~0;
14910   u32 sw_if_index = ~0;
14911   u8 sw_if_index_set = 0;
14912   u8 sw_if_index_if_name_set = 0;
14913   u32 priority = ~0;
14914   u8 priority_set = 0;
14915   u32 weight = ~0;
14916   u8 weight_set = 0;
14917   u8 is_add = 1;
14918   u8 *locator_set_name = NULL;
14919   u8 locator_set_name_set = 0;
14920   int ret;
14921
14922   /* Parse args required to build the message */
14923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (input, "del"))
14926         {
14927           is_add = 0;
14928         }
14929       else if (unformat (input, "locator-set %s", &locator_set_name))
14930         {
14931           locator_set_name_set = 1;
14932         }
14933       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14934                          &tmp_if_index))
14935         {
14936           sw_if_index_if_name_set = 1;
14937           sw_if_index = tmp_if_index;
14938         }
14939       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14940         {
14941           sw_if_index_set = 1;
14942           sw_if_index = tmp_if_index;
14943         }
14944       else if (unformat (input, "p %d", &priority))
14945         {
14946           priority_set = 1;
14947         }
14948       else if (unformat (input, "w %d", &weight))
14949         {
14950           weight_set = 1;
14951         }
14952       else
14953         break;
14954     }
14955
14956   if (locator_set_name_set == 0)
14957     {
14958       errmsg ("missing locator-set name");
14959       return -99;
14960     }
14961
14962   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14963     {
14964       errmsg ("missing sw_if_index");
14965       vec_free (locator_set_name);
14966       return -99;
14967     }
14968
14969   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14970     {
14971       errmsg ("cannot use both params interface name and sw_if_index");
14972       vec_free (locator_set_name);
14973       return -99;
14974     }
14975
14976   if (priority_set == 0)
14977     {
14978       errmsg ("missing locator-set priority");
14979       vec_free (locator_set_name);
14980       return -99;
14981     }
14982
14983   if (weight_set == 0)
14984     {
14985       errmsg ("missing locator-set weight");
14986       vec_free (locator_set_name);
14987       return -99;
14988     }
14989
14990   if (vec_len (locator_set_name) > 64)
14991     {
14992       errmsg ("locator-set name too long");
14993       vec_free (locator_set_name);
14994       return -99;
14995     }
14996   vec_add1 (locator_set_name, 0);
14997
14998   /* Construct the API message */
14999   M (ONE_ADD_DEL_LOCATOR, mp);
15000
15001   mp->is_add = is_add;
15002   mp->sw_if_index = ntohl (sw_if_index);
15003   mp->priority = priority;
15004   mp->weight = weight;
15005   clib_memcpy (mp->locator_set_name, locator_set_name,
15006                vec_len (locator_set_name));
15007   vec_free (locator_set_name);
15008
15009   /* send it... */
15010   S (mp);
15011
15012   /* Wait for a reply... */
15013   W (ret);
15014   return ret;
15015 }
15016
15017 #define api_lisp_add_del_locator api_one_add_del_locator
15018
15019 uword
15020 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15021 {
15022   u32 *key_id = va_arg (*args, u32 *);
15023   u8 *s = 0;
15024
15025   if (unformat (input, "%s", &s))
15026     {
15027       if (!strcmp ((char *) s, "sha1"))
15028         key_id[0] = HMAC_SHA_1_96;
15029       else if (!strcmp ((char *) s, "sha256"))
15030         key_id[0] = HMAC_SHA_256_128;
15031       else
15032         {
15033           clib_warning ("invalid key_id: '%s'", s);
15034           key_id[0] = HMAC_NO_KEY;
15035         }
15036     }
15037   else
15038     return 0;
15039
15040   vec_free (s);
15041   return 1;
15042 }
15043
15044 static int
15045 api_one_add_del_local_eid (vat_main_t * vam)
15046 {
15047   unformat_input_t *input = vam->input;
15048   vl_api_one_add_del_local_eid_t *mp;
15049   u8 is_add = 1;
15050   u8 eid_set = 0;
15051   lisp_eid_vat_t _eid, *eid = &_eid;
15052   u8 *locator_set_name = 0;
15053   u8 locator_set_name_set = 0;
15054   u32 vni = 0;
15055   u16 key_id = 0;
15056   u8 *key = 0;
15057   int ret;
15058
15059   /* Parse args required to build the message */
15060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15061     {
15062       if (unformat (input, "del"))
15063         {
15064           is_add = 0;
15065         }
15066       else if (unformat (input, "vni %d", &vni))
15067         {
15068           ;
15069         }
15070       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15071         {
15072           eid_set = 1;
15073         }
15074       else if (unformat (input, "locator-set %s", &locator_set_name))
15075         {
15076           locator_set_name_set = 1;
15077         }
15078       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15079         ;
15080       else if (unformat (input, "secret-key %_%v%_", &key))
15081         ;
15082       else
15083         break;
15084     }
15085
15086   if (locator_set_name_set == 0)
15087     {
15088       errmsg ("missing locator-set name");
15089       return -99;
15090     }
15091
15092   if (0 == eid_set)
15093     {
15094       errmsg ("EID address not set!");
15095       vec_free (locator_set_name);
15096       return -99;
15097     }
15098
15099   if (key && (0 == key_id))
15100     {
15101       errmsg ("invalid key_id!");
15102       return -99;
15103     }
15104
15105   if (vec_len (key) > 64)
15106     {
15107       errmsg ("key too long");
15108       vec_free (key);
15109       return -99;
15110     }
15111
15112   if (vec_len (locator_set_name) > 64)
15113     {
15114       errmsg ("locator-set name too long");
15115       vec_free (locator_set_name);
15116       return -99;
15117     }
15118   vec_add1 (locator_set_name, 0);
15119
15120   /* Construct the API message */
15121   M (ONE_ADD_DEL_LOCAL_EID, mp);
15122
15123   mp->is_add = is_add;
15124   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15125   mp->eid_type = eid->type;
15126   mp->prefix_len = eid->len;
15127   mp->vni = clib_host_to_net_u32 (vni);
15128   mp->key_id = clib_host_to_net_u16 (key_id);
15129   clib_memcpy (mp->locator_set_name, locator_set_name,
15130                vec_len (locator_set_name));
15131   clib_memcpy (mp->key, key, vec_len (key));
15132
15133   vec_free (locator_set_name);
15134   vec_free (key);
15135
15136   /* send it... */
15137   S (mp);
15138
15139   /* Wait for a reply... */
15140   W (ret);
15141   return ret;
15142 }
15143
15144 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15145
15146 static int
15147 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15148 {
15149   u32 dp_table = 0, vni = 0;;
15150   unformat_input_t *input = vam->input;
15151   vl_api_gpe_add_del_fwd_entry_t *mp;
15152   u8 is_add = 1;
15153   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15154   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15155   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15156   u32 action = ~0, w;
15157   ip4_address_t rmt_rloc4, lcl_rloc4;
15158   ip6_address_t rmt_rloc6, lcl_rloc6;
15159   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15160   int ret;
15161
15162   clib_memset (&rloc, 0, sizeof (rloc));
15163
15164   /* Parse args required to build the message */
15165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15166     {
15167       if (unformat (input, "del"))
15168         is_add = 0;
15169       else if (unformat (input, "add"))
15170         is_add = 1;
15171       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15172         {
15173           rmt_eid_set = 1;
15174         }
15175       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15176         {
15177           lcl_eid_set = 1;
15178         }
15179       else if (unformat (input, "vrf %d", &dp_table))
15180         ;
15181       else if (unformat (input, "bd %d", &dp_table))
15182         ;
15183       else if (unformat (input, "vni %d", &vni))
15184         ;
15185       else if (unformat (input, "w %d", &w))
15186         {
15187           if (!curr_rloc)
15188             {
15189               errmsg ("No RLOC configured for setting priority/weight!");
15190               return -99;
15191             }
15192           curr_rloc->weight = w;
15193         }
15194       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15195                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15196         {
15197           rloc.is_ip4 = 1;
15198
15199           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15200           rloc.weight = 0;
15201           vec_add1 (lcl_locs, rloc);
15202
15203           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
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, "loc-pair %U %U", unformat_ip6_address,
15209                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15210         {
15211           rloc.is_ip4 = 0;
15212           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15213           rloc.weight = 0;
15214           vec_add1 (lcl_locs, rloc);
15215
15216           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15217           vec_add1 (rmt_locs, rloc);
15218           /* weight saved in rmt loc */
15219           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15220         }
15221       else if (unformat (input, "action %d", &action))
15222         {
15223           ;
15224         }
15225       else
15226         {
15227           clib_warning ("parse error '%U'", format_unformat_error, input);
15228           return -99;
15229         }
15230     }
15231
15232   if (!rmt_eid_set)
15233     {
15234       errmsg ("remote eid addresses not set");
15235       return -99;
15236     }
15237
15238   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15239     {
15240       errmsg ("eid types don't match");
15241       return -99;
15242     }
15243
15244   if (0 == rmt_locs && (u32) ~ 0 == action)
15245     {
15246       errmsg ("action not set for negative mapping");
15247       return -99;
15248     }
15249
15250   /* Construct the API message */
15251   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15252       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15253
15254   mp->is_add = is_add;
15255   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15256   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15257   mp->eid_type = rmt_eid->type;
15258   mp->dp_table = clib_host_to_net_u32 (dp_table);
15259   mp->vni = clib_host_to_net_u32 (vni);
15260   mp->rmt_len = rmt_eid->len;
15261   mp->lcl_len = lcl_eid->len;
15262   mp->action = action;
15263
15264   if (0 != rmt_locs && 0 != lcl_locs)
15265     {
15266       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15267       clib_memcpy (mp->locs, lcl_locs,
15268                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15269
15270       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15271       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15272                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15273     }
15274   vec_free (lcl_locs);
15275   vec_free (rmt_locs);
15276
15277   /* send it... */
15278   S (mp);
15279
15280   /* Wait for a reply... */
15281   W (ret);
15282   return ret;
15283 }
15284
15285 static int
15286 api_one_add_del_map_server (vat_main_t * vam)
15287 {
15288   unformat_input_t *input = vam->input;
15289   vl_api_one_add_del_map_server_t *mp;
15290   u8 is_add = 1;
15291   u8 ipv4_set = 0;
15292   u8 ipv6_set = 0;
15293   ip4_address_t ipv4;
15294   ip6_address_t ipv6;
15295   int ret;
15296
15297   /* Parse args required to build the message */
15298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (input, "del"))
15301         {
15302           is_add = 0;
15303         }
15304       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15305         {
15306           ipv4_set = 1;
15307         }
15308       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15309         {
15310           ipv6_set = 1;
15311         }
15312       else
15313         break;
15314     }
15315
15316   if (ipv4_set && ipv6_set)
15317     {
15318       errmsg ("both eid v4 and v6 addresses set");
15319       return -99;
15320     }
15321
15322   if (!ipv4_set && !ipv6_set)
15323     {
15324       errmsg ("eid addresses not set");
15325       return -99;
15326     }
15327
15328   /* Construct the API message */
15329   M (ONE_ADD_DEL_MAP_SERVER, mp);
15330
15331   mp->is_add = is_add;
15332   if (ipv6_set)
15333     {
15334       mp->is_ipv6 = 1;
15335       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15336     }
15337   else
15338     {
15339       mp->is_ipv6 = 0;
15340       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15341     }
15342
15343   /* send it... */
15344   S (mp);
15345
15346   /* Wait for a reply... */
15347   W (ret);
15348   return ret;
15349 }
15350
15351 #define api_lisp_add_del_map_server api_one_add_del_map_server
15352
15353 static int
15354 api_one_add_del_map_resolver (vat_main_t * vam)
15355 {
15356   unformat_input_t *input = vam->input;
15357   vl_api_one_add_del_map_resolver_t *mp;
15358   u8 is_add = 1;
15359   u8 ipv4_set = 0;
15360   u8 ipv6_set = 0;
15361   ip4_address_t ipv4;
15362   ip6_address_t ipv6;
15363   int ret;
15364
15365   /* Parse args required to build the message */
15366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15367     {
15368       if (unformat (input, "del"))
15369         {
15370           is_add = 0;
15371         }
15372       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15373         {
15374           ipv4_set = 1;
15375         }
15376       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15377         {
15378           ipv6_set = 1;
15379         }
15380       else
15381         break;
15382     }
15383
15384   if (ipv4_set && ipv6_set)
15385     {
15386       errmsg ("both eid v4 and v6 addresses set");
15387       return -99;
15388     }
15389
15390   if (!ipv4_set && !ipv6_set)
15391     {
15392       errmsg ("eid addresses not set");
15393       return -99;
15394     }
15395
15396   /* Construct the API message */
15397   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15398
15399   mp->is_add = is_add;
15400   if (ipv6_set)
15401     {
15402       mp->is_ipv6 = 1;
15403       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15404     }
15405   else
15406     {
15407       mp->is_ipv6 = 0;
15408       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15409     }
15410
15411   /* send it... */
15412   S (mp);
15413
15414   /* Wait for a reply... */
15415   W (ret);
15416   return ret;
15417 }
15418
15419 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15420
15421 static int
15422 api_lisp_gpe_enable_disable (vat_main_t * vam)
15423 {
15424   unformat_input_t *input = vam->input;
15425   vl_api_gpe_enable_disable_t *mp;
15426   u8 is_set = 0;
15427   u8 is_en = 1;
15428   int ret;
15429
15430   /* Parse args required to build the message */
15431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15432     {
15433       if (unformat (input, "enable"))
15434         {
15435           is_set = 1;
15436           is_en = 1;
15437         }
15438       else if (unformat (input, "disable"))
15439         {
15440           is_set = 1;
15441           is_en = 0;
15442         }
15443       else
15444         break;
15445     }
15446
15447   if (is_set == 0)
15448     {
15449       errmsg ("Value not set");
15450       return -99;
15451     }
15452
15453   /* Construct the API message */
15454   M (GPE_ENABLE_DISABLE, mp);
15455
15456   mp->is_en = is_en;
15457
15458   /* send it... */
15459   S (mp);
15460
15461   /* Wait for a reply... */
15462   W (ret);
15463   return ret;
15464 }
15465
15466 static int
15467 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15468 {
15469   unformat_input_t *input = vam->input;
15470   vl_api_one_rloc_probe_enable_disable_t *mp;
15471   u8 is_set = 0;
15472   u8 is_en = 0;
15473   int ret;
15474
15475   /* Parse args required to build the message */
15476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15477     {
15478       if (unformat (input, "enable"))
15479         {
15480           is_set = 1;
15481           is_en = 1;
15482         }
15483       else if (unformat (input, "disable"))
15484         is_set = 1;
15485       else
15486         break;
15487     }
15488
15489   if (!is_set)
15490     {
15491       errmsg ("Value not set");
15492       return -99;
15493     }
15494
15495   /* Construct the API message */
15496   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15497
15498   mp->is_enabled = is_en;
15499
15500   /* send it... */
15501   S (mp);
15502
15503   /* Wait for a reply... */
15504   W (ret);
15505   return ret;
15506 }
15507
15508 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15509
15510 static int
15511 api_one_map_register_enable_disable (vat_main_t * vam)
15512 {
15513   unformat_input_t *input = vam->input;
15514   vl_api_one_map_register_enable_disable_t *mp;
15515   u8 is_set = 0;
15516   u8 is_en = 0;
15517   int ret;
15518
15519   /* Parse args required to build the message */
15520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15521     {
15522       if (unformat (input, "enable"))
15523         {
15524           is_set = 1;
15525           is_en = 1;
15526         }
15527       else if (unformat (input, "disable"))
15528         is_set = 1;
15529       else
15530         break;
15531     }
15532
15533   if (!is_set)
15534     {
15535       errmsg ("Value not set");
15536       return -99;
15537     }
15538
15539   /* Construct the API message */
15540   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15541
15542   mp->is_enabled = is_en;
15543
15544   /* send it... */
15545   S (mp);
15546
15547   /* Wait for a reply... */
15548   W (ret);
15549   return ret;
15550 }
15551
15552 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15553
15554 static int
15555 api_one_enable_disable (vat_main_t * vam)
15556 {
15557   unformat_input_t *input = vam->input;
15558   vl_api_one_enable_disable_t *mp;
15559   u8 is_set = 0;
15560   u8 is_en = 0;
15561   int ret;
15562
15563   /* Parse args required to build the message */
15564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15565     {
15566       if (unformat (input, "enable"))
15567         {
15568           is_set = 1;
15569           is_en = 1;
15570         }
15571       else if (unformat (input, "disable"))
15572         {
15573           is_set = 1;
15574         }
15575       else
15576         break;
15577     }
15578
15579   if (!is_set)
15580     {
15581       errmsg ("Value not set");
15582       return -99;
15583     }
15584
15585   /* Construct the API message */
15586   M (ONE_ENABLE_DISABLE, mp);
15587
15588   mp->is_en = is_en;
15589
15590   /* send it... */
15591   S (mp);
15592
15593   /* Wait for a reply... */
15594   W (ret);
15595   return ret;
15596 }
15597
15598 #define api_lisp_enable_disable api_one_enable_disable
15599
15600 static int
15601 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15602 {
15603   unformat_input_t *input = vam->input;
15604   vl_api_one_enable_disable_xtr_mode_t *mp;
15605   u8 is_set = 0;
15606   u8 is_en = 0;
15607   int ret;
15608
15609   /* Parse args required to build the message */
15610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (input, "enable"))
15613         {
15614           is_set = 1;
15615           is_en = 1;
15616         }
15617       else if (unformat (input, "disable"))
15618         {
15619           is_set = 1;
15620         }
15621       else
15622         break;
15623     }
15624
15625   if (!is_set)
15626     {
15627       errmsg ("Value not set");
15628       return -99;
15629     }
15630
15631   /* Construct the API message */
15632   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15633
15634   mp->is_en = is_en;
15635
15636   /* send it... */
15637   S (mp);
15638
15639   /* Wait for a reply... */
15640   W (ret);
15641   return ret;
15642 }
15643
15644 static int
15645 api_one_show_xtr_mode (vat_main_t * vam)
15646 {
15647   vl_api_one_show_xtr_mode_t *mp;
15648   int ret;
15649
15650   /* Construct the API message */
15651   M (ONE_SHOW_XTR_MODE, mp);
15652
15653   /* send it... */
15654   S (mp);
15655
15656   /* Wait for a reply... */
15657   W (ret);
15658   return ret;
15659 }
15660
15661 static int
15662 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15663 {
15664   unformat_input_t *input = vam->input;
15665   vl_api_one_enable_disable_pitr_mode_t *mp;
15666   u8 is_set = 0;
15667   u8 is_en = 0;
15668   int ret;
15669
15670   /* Parse args required to build the message */
15671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15672     {
15673       if (unformat (input, "enable"))
15674         {
15675           is_set = 1;
15676           is_en = 1;
15677         }
15678       else if (unformat (input, "disable"))
15679         {
15680           is_set = 1;
15681         }
15682       else
15683         break;
15684     }
15685
15686   if (!is_set)
15687     {
15688       errmsg ("Value not set");
15689       return -99;
15690     }
15691
15692   /* Construct the API message */
15693   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15694
15695   mp->is_en = is_en;
15696
15697   /* send it... */
15698   S (mp);
15699
15700   /* Wait for a reply... */
15701   W (ret);
15702   return ret;
15703 }
15704
15705 static int
15706 api_one_show_pitr_mode (vat_main_t * vam)
15707 {
15708   vl_api_one_show_pitr_mode_t *mp;
15709   int ret;
15710
15711   /* Construct the API message */
15712   M (ONE_SHOW_PITR_MODE, mp);
15713
15714   /* send it... */
15715   S (mp);
15716
15717   /* Wait for a reply... */
15718   W (ret);
15719   return ret;
15720 }
15721
15722 static int
15723 api_one_enable_disable_petr_mode (vat_main_t * vam)
15724 {
15725   unformat_input_t *input = vam->input;
15726   vl_api_one_enable_disable_petr_mode_t *mp;
15727   u8 is_set = 0;
15728   u8 is_en = 0;
15729   int ret;
15730
15731   /* Parse args required to build the message */
15732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15733     {
15734       if (unformat (input, "enable"))
15735         {
15736           is_set = 1;
15737           is_en = 1;
15738         }
15739       else if (unformat (input, "disable"))
15740         {
15741           is_set = 1;
15742         }
15743       else
15744         break;
15745     }
15746
15747   if (!is_set)
15748     {
15749       errmsg ("Value not set");
15750       return -99;
15751     }
15752
15753   /* Construct the API message */
15754   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15755
15756   mp->is_en = is_en;
15757
15758   /* send it... */
15759   S (mp);
15760
15761   /* Wait for a reply... */
15762   W (ret);
15763   return ret;
15764 }
15765
15766 static int
15767 api_one_show_petr_mode (vat_main_t * vam)
15768 {
15769   vl_api_one_show_petr_mode_t *mp;
15770   int ret;
15771
15772   /* Construct the API message */
15773   M (ONE_SHOW_PETR_MODE, mp);
15774
15775   /* send it... */
15776   S (mp);
15777
15778   /* Wait for a reply... */
15779   W (ret);
15780   return ret;
15781 }
15782
15783 static int
15784 api_show_one_map_register_state (vat_main_t * vam)
15785 {
15786   vl_api_show_one_map_register_state_t *mp;
15787   int ret;
15788
15789   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15790
15791   /* send */
15792   S (mp);
15793
15794   /* wait for reply */
15795   W (ret);
15796   return ret;
15797 }
15798
15799 #define api_show_lisp_map_register_state api_show_one_map_register_state
15800
15801 static int
15802 api_show_one_rloc_probe_state (vat_main_t * vam)
15803 {
15804   vl_api_show_one_rloc_probe_state_t *mp;
15805   int ret;
15806
15807   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15808
15809   /* send */
15810   S (mp);
15811
15812   /* wait for reply */
15813   W (ret);
15814   return ret;
15815 }
15816
15817 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15818
15819 static int
15820 api_one_add_del_ndp_entry (vat_main_t * vam)
15821 {
15822   vl_api_one_add_del_ndp_entry_t *mp;
15823   unformat_input_t *input = vam->input;
15824   u8 is_add = 1;
15825   u8 mac_set = 0;
15826   u8 bd_set = 0;
15827   u8 ip_set = 0;
15828   u8 mac[6] = { 0, };
15829   u8 ip6[16] = { 0, };
15830   u32 bd = ~0;
15831   int ret;
15832
15833   /* Parse args required to build the message */
15834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15835     {
15836       if (unformat (input, "del"))
15837         is_add = 0;
15838       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15839         mac_set = 1;
15840       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15841         ip_set = 1;
15842       else if (unformat (input, "bd %d", &bd))
15843         bd_set = 1;
15844       else
15845         {
15846           errmsg ("parse error '%U'", format_unformat_error, input);
15847           return -99;
15848         }
15849     }
15850
15851   if (!bd_set || !ip_set || (!mac_set && is_add))
15852     {
15853       errmsg ("Missing BD, IP or MAC!");
15854       return -99;
15855     }
15856
15857   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15858   mp->is_add = is_add;
15859   clib_memcpy (mp->mac, mac, 6);
15860   mp->bd = clib_host_to_net_u32 (bd);
15861   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15862
15863   /* send */
15864   S (mp);
15865
15866   /* wait for reply */
15867   W (ret);
15868   return ret;
15869 }
15870
15871 static int
15872 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15873 {
15874   vl_api_one_add_del_l2_arp_entry_t *mp;
15875   unformat_input_t *input = vam->input;
15876   u8 is_add = 1;
15877   u8 mac_set = 0;
15878   u8 bd_set = 0;
15879   u8 ip_set = 0;
15880   u8 mac[6] = { 0, };
15881   u32 ip4 = 0, bd = ~0;
15882   int ret;
15883
15884   /* Parse args required to build the message */
15885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15886     {
15887       if (unformat (input, "del"))
15888         is_add = 0;
15889       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15890         mac_set = 1;
15891       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15892         ip_set = 1;
15893       else if (unformat (input, "bd %d", &bd))
15894         bd_set = 1;
15895       else
15896         {
15897           errmsg ("parse error '%U'", format_unformat_error, input);
15898           return -99;
15899         }
15900     }
15901
15902   if (!bd_set || !ip_set || (!mac_set && is_add))
15903     {
15904       errmsg ("Missing BD, IP or MAC!");
15905       return -99;
15906     }
15907
15908   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15909   mp->is_add = is_add;
15910   clib_memcpy (mp->mac, mac, 6);
15911   mp->bd = clib_host_to_net_u32 (bd);
15912   mp->ip4 = ip4;
15913
15914   /* send */
15915   S (mp);
15916
15917   /* wait for reply */
15918   W (ret);
15919   return ret;
15920 }
15921
15922 static int
15923 api_one_ndp_bd_get (vat_main_t * vam)
15924 {
15925   vl_api_one_ndp_bd_get_t *mp;
15926   int ret;
15927
15928   M (ONE_NDP_BD_GET, mp);
15929
15930   /* send */
15931   S (mp);
15932
15933   /* wait for reply */
15934   W (ret);
15935   return ret;
15936 }
15937
15938 static int
15939 api_one_ndp_entries_get (vat_main_t * vam)
15940 {
15941   vl_api_one_ndp_entries_get_t *mp;
15942   unformat_input_t *input = vam->input;
15943   u8 bd_set = 0;
15944   u32 bd = ~0;
15945   int ret;
15946
15947   /* Parse args required to build the message */
15948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15949     {
15950       if (unformat (input, "bd %d", &bd))
15951         bd_set = 1;
15952       else
15953         {
15954           errmsg ("parse error '%U'", format_unformat_error, input);
15955           return -99;
15956         }
15957     }
15958
15959   if (!bd_set)
15960     {
15961       errmsg ("Expected bridge domain!");
15962       return -99;
15963     }
15964
15965   M (ONE_NDP_ENTRIES_GET, mp);
15966   mp->bd = clib_host_to_net_u32 (bd);
15967
15968   /* send */
15969   S (mp);
15970
15971   /* wait for reply */
15972   W (ret);
15973   return ret;
15974 }
15975
15976 static int
15977 api_one_l2_arp_bd_get (vat_main_t * vam)
15978 {
15979   vl_api_one_l2_arp_bd_get_t *mp;
15980   int ret;
15981
15982   M (ONE_L2_ARP_BD_GET, mp);
15983
15984   /* send */
15985   S (mp);
15986
15987   /* wait for reply */
15988   W (ret);
15989   return ret;
15990 }
15991
15992 static int
15993 api_one_l2_arp_entries_get (vat_main_t * vam)
15994 {
15995   vl_api_one_l2_arp_entries_get_t *mp;
15996   unformat_input_t *input = vam->input;
15997   u8 bd_set = 0;
15998   u32 bd = ~0;
15999   int ret;
16000
16001   /* Parse args required to build the message */
16002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16003     {
16004       if (unformat (input, "bd %d", &bd))
16005         bd_set = 1;
16006       else
16007         {
16008           errmsg ("parse error '%U'", format_unformat_error, input);
16009           return -99;
16010         }
16011     }
16012
16013   if (!bd_set)
16014     {
16015       errmsg ("Expected bridge domain!");
16016       return -99;
16017     }
16018
16019   M (ONE_L2_ARP_ENTRIES_GET, mp);
16020   mp->bd = clib_host_to_net_u32 (bd);
16021
16022   /* send */
16023   S (mp);
16024
16025   /* wait for reply */
16026   W (ret);
16027   return ret;
16028 }
16029
16030 static int
16031 api_one_stats_enable_disable (vat_main_t * vam)
16032 {
16033   vl_api_one_stats_enable_disable_t *mp;
16034   unformat_input_t *input = vam->input;
16035   u8 is_set = 0;
16036   u8 is_en = 0;
16037   int ret;
16038
16039   /* Parse args required to build the message */
16040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16041     {
16042       if (unformat (input, "enable"))
16043         {
16044           is_set = 1;
16045           is_en = 1;
16046         }
16047       else if (unformat (input, "disable"))
16048         {
16049           is_set = 1;
16050         }
16051       else
16052         break;
16053     }
16054
16055   if (!is_set)
16056     {
16057       errmsg ("Value not set");
16058       return -99;
16059     }
16060
16061   M (ONE_STATS_ENABLE_DISABLE, mp);
16062   mp->is_en = is_en;
16063
16064   /* send */
16065   S (mp);
16066
16067   /* wait for reply */
16068   W (ret);
16069   return ret;
16070 }
16071
16072 static int
16073 api_show_one_stats_enable_disable (vat_main_t * vam)
16074 {
16075   vl_api_show_one_stats_enable_disable_t *mp;
16076   int ret;
16077
16078   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16079
16080   /* send */
16081   S (mp);
16082
16083   /* wait for reply */
16084   W (ret);
16085   return ret;
16086 }
16087
16088 static int
16089 api_show_one_map_request_mode (vat_main_t * vam)
16090 {
16091   vl_api_show_one_map_request_mode_t *mp;
16092   int ret;
16093
16094   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16095
16096   /* send */
16097   S (mp);
16098
16099   /* wait for reply */
16100   W (ret);
16101   return ret;
16102 }
16103
16104 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16105
16106 static int
16107 api_one_map_request_mode (vat_main_t * vam)
16108 {
16109   unformat_input_t *input = vam->input;
16110   vl_api_one_map_request_mode_t *mp;
16111   u8 mode = 0;
16112   int ret;
16113
16114   /* Parse args required to build the message */
16115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16116     {
16117       if (unformat (input, "dst-only"))
16118         mode = 0;
16119       else if (unformat (input, "src-dst"))
16120         mode = 1;
16121       else
16122         {
16123           errmsg ("parse error '%U'", format_unformat_error, input);
16124           return -99;
16125         }
16126     }
16127
16128   M (ONE_MAP_REQUEST_MODE, mp);
16129
16130   mp->mode = mode;
16131
16132   /* send */
16133   S (mp);
16134
16135   /* wait for reply */
16136   W (ret);
16137   return ret;
16138 }
16139
16140 #define api_lisp_map_request_mode api_one_map_request_mode
16141
16142 /**
16143  * Enable/disable ONE proxy ITR.
16144  *
16145  * @param vam vpp API test context
16146  * @return return code
16147  */
16148 static int
16149 api_one_pitr_set_locator_set (vat_main_t * vam)
16150 {
16151   u8 ls_name_set = 0;
16152   unformat_input_t *input = vam->input;
16153   vl_api_one_pitr_set_locator_set_t *mp;
16154   u8 is_add = 1;
16155   u8 *ls_name = 0;
16156   int ret;
16157
16158   /* Parse args required to build the message */
16159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16160     {
16161       if (unformat (input, "del"))
16162         is_add = 0;
16163       else if (unformat (input, "locator-set %s", &ls_name))
16164         ls_name_set = 1;
16165       else
16166         {
16167           errmsg ("parse error '%U'", format_unformat_error, input);
16168           return -99;
16169         }
16170     }
16171
16172   if (!ls_name_set)
16173     {
16174       errmsg ("locator-set name not set!");
16175       return -99;
16176     }
16177
16178   M (ONE_PITR_SET_LOCATOR_SET, mp);
16179
16180   mp->is_add = is_add;
16181   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16182   vec_free (ls_name);
16183
16184   /* send */
16185   S (mp);
16186
16187   /* wait for reply */
16188   W (ret);
16189   return ret;
16190 }
16191
16192 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16193
16194 static int
16195 api_one_nsh_set_locator_set (vat_main_t * vam)
16196 {
16197   u8 ls_name_set = 0;
16198   unformat_input_t *input = vam->input;
16199   vl_api_one_nsh_set_locator_set_t *mp;
16200   u8 is_add = 1;
16201   u8 *ls_name = 0;
16202   int ret;
16203
16204   /* Parse args required to build the message */
16205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16206     {
16207       if (unformat (input, "del"))
16208         is_add = 0;
16209       else if (unformat (input, "ls %s", &ls_name))
16210         ls_name_set = 1;
16211       else
16212         {
16213           errmsg ("parse error '%U'", format_unformat_error, input);
16214           return -99;
16215         }
16216     }
16217
16218   if (!ls_name_set && is_add)
16219     {
16220       errmsg ("locator-set name not set!");
16221       return -99;
16222     }
16223
16224   M (ONE_NSH_SET_LOCATOR_SET, mp);
16225
16226   mp->is_add = is_add;
16227   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16228   vec_free (ls_name);
16229
16230   /* send */
16231   S (mp);
16232
16233   /* wait for reply */
16234   W (ret);
16235   return ret;
16236 }
16237
16238 static int
16239 api_show_one_pitr (vat_main_t * vam)
16240 {
16241   vl_api_show_one_pitr_t *mp;
16242   int ret;
16243
16244   if (!vam->json_output)
16245     {
16246       print (vam->ofp, "%=20s", "lisp status:");
16247     }
16248
16249   M (SHOW_ONE_PITR, mp);
16250   /* send it... */
16251   S (mp);
16252
16253   /* Wait for a reply... */
16254   W (ret);
16255   return ret;
16256 }
16257
16258 #define api_show_lisp_pitr api_show_one_pitr
16259
16260 static int
16261 api_one_use_petr (vat_main_t * vam)
16262 {
16263   unformat_input_t *input = vam->input;
16264   vl_api_one_use_petr_t *mp;
16265   u8 is_add = 0;
16266   ip_address_t ip;
16267   int ret;
16268
16269   clib_memset (&ip, 0, sizeof (ip));
16270
16271   /* Parse args required to build the message */
16272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16273     {
16274       if (unformat (input, "disable"))
16275         is_add = 0;
16276       else
16277         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16278         {
16279           is_add = 1;
16280           ip_addr_version (&ip) = IP4;
16281         }
16282       else
16283         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16284         {
16285           is_add = 1;
16286           ip_addr_version (&ip) = IP6;
16287         }
16288       else
16289         {
16290           errmsg ("parse error '%U'", format_unformat_error, input);
16291           return -99;
16292         }
16293     }
16294
16295   M (ONE_USE_PETR, mp);
16296
16297   mp->is_add = is_add;
16298   if (is_add)
16299     {
16300       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16301       if (mp->is_ip4)
16302         clib_memcpy (mp->address, &ip, 4);
16303       else
16304         clib_memcpy (mp->address, &ip, 16);
16305     }
16306
16307   /* send */
16308   S (mp);
16309
16310   /* wait for reply */
16311   W (ret);
16312   return ret;
16313 }
16314
16315 #define api_lisp_use_petr api_one_use_petr
16316
16317 static int
16318 api_show_one_nsh_mapping (vat_main_t * vam)
16319 {
16320   vl_api_show_one_use_petr_t *mp;
16321   int ret;
16322
16323   if (!vam->json_output)
16324     {
16325       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16326     }
16327
16328   M (SHOW_ONE_NSH_MAPPING, mp);
16329   /* send it... */
16330   S (mp);
16331
16332   /* Wait for a reply... */
16333   W (ret);
16334   return ret;
16335 }
16336
16337 static int
16338 api_show_one_use_petr (vat_main_t * vam)
16339 {
16340   vl_api_show_one_use_petr_t *mp;
16341   int ret;
16342
16343   if (!vam->json_output)
16344     {
16345       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16346     }
16347
16348   M (SHOW_ONE_USE_PETR, mp);
16349   /* send it... */
16350   S (mp);
16351
16352   /* Wait for a reply... */
16353   W (ret);
16354   return ret;
16355 }
16356
16357 #define api_show_lisp_use_petr api_show_one_use_petr
16358
16359 /**
16360  * Add/delete mapping between vni and vrf
16361  */
16362 static int
16363 api_one_eid_table_add_del_map (vat_main_t * vam)
16364 {
16365   unformat_input_t *input = vam->input;
16366   vl_api_one_eid_table_add_del_map_t *mp;
16367   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16368   u32 vni, vrf, bd_index;
16369   int ret;
16370
16371   /* Parse args required to build the message */
16372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (input, "del"))
16375         is_add = 0;
16376       else if (unformat (input, "vrf %d", &vrf))
16377         vrf_set = 1;
16378       else if (unformat (input, "bd_index %d", &bd_index))
16379         bd_index_set = 1;
16380       else if (unformat (input, "vni %d", &vni))
16381         vni_set = 1;
16382       else
16383         break;
16384     }
16385
16386   if (!vni_set || (!vrf_set && !bd_index_set))
16387     {
16388       errmsg ("missing arguments!");
16389       return -99;
16390     }
16391
16392   if (vrf_set && bd_index_set)
16393     {
16394       errmsg ("error: both vrf and bd entered!");
16395       return -99;
16396     }
16397
16398   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16399
16400   mp->is_add = is_add;
16401   mp->vni = htonl (vni);
16402   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16403   mp->is_l2 = bd_index_set;
16404
16405   /* send */
16406   S (mp);
16407
16408   /* wait for reply */
16409   W (ret);
16410   return ret;
16411 }
16412
16413 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16414
16415 uword
16416 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16417 {
16418   u32 *action = va_arg (*args, u32 *);
16419   u8 *s = 0;
16420
16421   if (unformat (input, "%s", &s))
16422     {
16423       if (!strcmp ((char *) s, "no-action"))
16424         action[0] = 0;
16425       else if (!strcmp ((char *) s, "natively-forward"))
16426         action[0] = 1;
16427       else if (!strcmp ((char *) s, "send-map-request"))
16428         action[0] = 2;
16429       else if (!strcmp ((char *) s, "drop"))
16430         action[0] = 3;
16431       else
16432         {
16433           clib_warning ("invalid action: '%s'", s);
16434           action[0] = 3;
16435         }
16436     }
16437   else
16438     return 0;
16439
16440   vec_free (s);
16441   return 1;
16442 }
16443
16444 /**
16445  * Add/del remote mapping to/from ONE control plane
16446  *
16447  * @param vam vpp API test context
16448  * @return return code
16449  */
16450 static int
16451 api_one_add_del_remote_mapping (vat_main_t * vam)
16452 {
16453   unformat_input_t *input = vam->input;
16454   vl_api_one_add_del_remote_mapping_t *mp;
16455   u32 vni = 0;
16456   lisp_eid_vat_t _eid, *eid = &_eid;
16457   lisp_eid_vat_t _seid, *seid = &_seid;
16458   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16459   u32 action = ~0, p, w, data_len;
16460   ip4_address_t rloc4;
16461   ip6_address_t rloc6;
16462   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16463   int ret;
16464
16465   clib_memset (&rloc, 0, sizeof (rloc));
16466
16467   /* Parse args required to build the message */
16468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16469     {
16470       if (unformat (input, "del-all"))
16471         {
16472           del_all = 1;
16473         }
16474       else if (unformat (input, "del"))
16475         {
16476           is_add = 0;
16477         }
16478       else if (unformat (input, "add"))
16479         {
16480           is_add = 1;
16481         }
16482       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16483         {
16484           eid_set = 1;
16485         }
16486       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16487         {
16488           seid_set = 1;
16489         }
16490       else if (unformat (input, "vni %d", &vni))
16491         {
16492           ;
16493         }
16494       else if (unformat (input, "p %d w %d", &p, &w))
16495         {
16496           if (!curr_rloc)
16497             {
16498               errmsg ("No RLOC configured for setting priority/weight!");
16499               return -99;
16500             }
16501           curr_rloc->priority = p;
16502           curr_rloc->weight = w;
16503         }
16504       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16505         {
16506           rloc.is_ip4 = 1;
16507           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16508           vec_add1 (rlocs, rloc);
16509           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16510         }
16511       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16512         {
16513           rloc.is_ip4 = 0;
16514           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16515           vec_add1 (rlocs, rloc);
16516           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16517         }
16518       else if (unformat (input, "action %U",
16519                          unformat_negative_mapping_action, &action))
16520         {
16521           ;
16522         }
16523       else
16524         {
16525           clib_warning ("parse error '%U'", format_unformat_error, input);
16526           return -99;
16527         }
16528     }
16529
16530   if (0 == eid_set)
16531     {
16532       errmsg ("missing params!");
16533       return -99;
16534     }
16535
16536   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16537     {
16538       errmsg ("no action set for negative map-reply!");
16539       return -99;
16540     }
16541
16542   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16543
16544   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16545   mp->is_add = is_add;
16546   mp->vni = htonl (vni);
16547   mp->action = (u8) action;
16548   mp->is_src_dst = seid_set;
16549   mp->eid_len = eid->len;
16550   mp->seid_len = seid->len;
16551   mp->del_all = del_all;
16552   mp->eid_type = eid->type;
16553   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16554   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16555
16556   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16557   clib_memcpy (mp->rlocs, rlocs, data_len);
16558   vec_free (rlocs);
16559
16560   /* send it... */
16561   S (mp);
16562
16563   /* Wait for a reply... */
16564   W (ret);
16565   return ret;
16566 }
16567
16568 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16569
16570 /**
16571  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16572  * forwarding entries in data-plane accordingly.
16573  *
16574  * @param vam vpp API test context
16575  * @return return code
16576  */
16577 static int
16578 api_one_add_del_adjacency (vat_main_t * vam)
16579 {
16580   unformat_input_t *input = vam->input;
16581   vl_api_one_add_del_adjacency_t *mp;
16582   u32 vni = 0;
16583   ip4_address_t leid4, reid4;
16584   ip6_address_t leid6, reid6;
16585   u8 reid_mac[6] = { 0 };
16586   u8 leid_mac[6] = { 0 };
16587   u8 reid_type, leid_type;
16588   u32 leid_len = 0, reid_len = 0, len;
16589   u8 is_add = 1;
16590   int ret;
16591
16592   leid_type = reid_type = (u8) ~ 0;
16593
16594   /* Parse args required to build the message */
16595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16596     {
16597       if (unformat (input, "del"))
16598         {
16599           is_add = 0;
16600         }
16601       else if (unformat (input, "add"))
16602         {
16603           is_add = 1;
16604         }
16605       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16606                          &reid4, &len))
16607         {
16608           reid_type = 0;        /* ipv4 */
16609           reid_len = len;
16610         }
16611       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16612                          &reid6, &len))
16613         {
16614           reid_type = 1;        /* ipv6 */
16615           reid_len = len;
16616         }
16617       else if (unformat (input, "reid %U", unformat_ethernet_address,
16618                          reid_mac))
16619         {
16620           reid_type = 2;        /* mac */
16621         }
16622       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16623                          &leid4, &len))
16624         {
16625           leid_type = 0;        /* ipv4 */
16626           leid_len = len;
16627         }
16628       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16629                          &leid6, &len))
16630         {
16631           leid_type = 1;        /* ipv6 */
16632           leid_len = len;
16633         }
16634       else if (unformat (input, "leid %U", unformat_ethernet_address,
16635                          leid_mac))
16636         {
16637           leid_type = 2;        /* mac */
16638         }
16639       else if (unformat (input, "vni %d", &vni))
16640         {
16641           ;
16642         }
16643       else
16644         {
16645           errmsg ("parse error '%U'", format_unformat_error, input);
16646           return -99;
16647         }
16648     }
16649
16650   if ((u8) ~ 0 == reid_type)
16651     {
16652       errmsg ("missing params!");
16653       return -99;
16654     }
16655
16656   if (leid_type != reid_type)
16657     {
16658       errmsg ("remote and local EIDs are of different types!");
16659       return -99;
16660     }
16661
16662   M (ONE_ADD_DEL_ADJACENCY, mp);
16663   mp->is_add = is_add;
16664   mp->vni = htonl (vni);
16665   mp->leid_len = leid_len;
16666   mp->reid_len = reid_len;
16667   mp->eid_type = reid_type;
16668
16669   switch (mp->eid_type)
16670     {
16671     case 0:
16672       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16673       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16674       break;
16675     case 1:
16676       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16677       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16678       break;
16679     case 2:
16680       clib_memcpy (mp->leid, leid_mac, 6);
16681       clib_memcpy (mp->reid, reid_mac, 6);
16682       break;
16683     default:
16684       errmsg ("unknown EID type %d!", mp->eid_type);
16685       return 0;
16686     }
16687
16688   /* send it... */
16689   S (mp);
16690
16691   /* Wait for a reply... */
16692   W (ret);
16693   return ret;
16694 }
16695
16696 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16697
16698 uword
16699 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16700 {
16701   u32 *mode = va_arg (*args, u32 *);
16702
16703   if (unformat (input, "lisp"))
16704     *mode = 0;
16705   else if (unformat (input, "vxlan"))
16706     *mode = 1;
16707   else
16708     return 0;
16709
16710   return 1;
16711 }
16712
16713 static int
16714 api_gpe_get_encap_mode (vat_main_t * vam)
16715 {
16716   vl_api_gpe_get_encap_mode_t *mp;
16717   int ret;
16718
16719   /* Construct the API message */
16720   M (GPE_GET_ENCAP_MODE, mp);
16721
16722   /* send it... */
16723   S (mp);
16724
16725   /* Wait for a reply... */
16726   W (ret);
16727   return ret;
16728 }
16729
16730 static int
16731 api_gpe_set_encap_mode (vat_main_t * vam)
16732 {
16733   unformat_input_t *input = vam->input;
16734   vl_api_gpe_set_encap_mode_t *mp;
16735   int ret;
16736   u32 mode = 0;
16737
16738   /* Parse args required to build the message */
16739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16740     {
16741       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16742         ;
16743       else
16744         break;
16745     }
16746
16747   /* Construct the API message */
16748   M (GPE_SET_ENCAP_MODE, mp);
16749
16750   mp->mode = mode;
16751
16752   /* send it... */
16753   S (mp);
16754
16755   /* Wait for a reply... */
16756   W (ret);
16757   return ret;
16758 }
16759
16760 static int
16761 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16762 {
16763   unformat_input_t *input = vam->input;
16764   vl_api_gpe_add_del_iface_t *mp;
16765   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16766   u32 dp_table = 0, vni = 0;
16767   int ret;
16768
16769   /* Parse args required to build the message */
16770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16771     {
16772       if (unformat (input, "up"))
16773         {
16774           action_set = 1;
16775           is_add = 1;
16776         }
16777       else if (unformat (input, "down"))
16778         {
16779           action_set = 1;
16780           is_add = 0;
16781         }
16782       else if (unformat (input, "table_id %d", &dp_table))
16783         {
16784           dp_table_set = 1;
16785         }
16786       else if (unformat (input, "bd_id %d", &dp_table))
16787         {
16788           dp_table_set = 1;
16789           is_l2 = 1;
16790         }
16791       else if (unformat (input, "vni %d", &vni))
16792         {
16793           vni_set = 1;
16794         }
16795       else
16796         break;
16797     }
16798
16799   if (action_set == 0)
16800     {
16801       errmsg ("Action not set");
16802       return -99;
16803     }
16804   if (dp_table_set == 0 || vni_set == 0)
16805     {
16806       errmsg ("vni and dp_table must be set");
16807       return -99;
16808     }
16809
16810   /* Construct the API message */
16811   M (GPE_ADD_DEL_IFACE, mp);
16812
16813   mp->is_add = is_add;
16814   mp->dp_table = clib_host_to_net_u32 (dp_table);
16815   mp->is_l2 = is_l2;
16816   mp->vni = clib_host_to_net_u32 (vni);
16817
16818   /* send it... */
16819   S (mp);
16820
16821   /* Wait for a reply... */
16822   W (ret);
16823   return ret;
16824 }
16825
16826 static int
16827 api_one_map_register_fallback_threshold (vat_main_t * vam)
16828 {
16829   unformat_input_t *input = vam->input;
16830   vl_api_one_map_register_fallback_threshold_t *mp;
16831   u32 value = 0;
16832   u8 is_set = 0;
16833   int ret;
16834
16835   /* Parse args required to build the message */
16836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16837     {
16838       if (unformat (input, "%u", &value))
16839         is_set = 1;
16840       else
16841         {
16842           clib_warning ("parse error '%U'", format_unformat_error, input);
16843           return -99;
16844         }
16845     }
16846
16847   if (!is_set)
16848     {
16849       errmsg ("fallback threshold value is missing!");
16850       return -99;
16851     }
16852
16853   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16854   mp->value = clib_host_to_net_u32 (value);
16855
16856   /* send it... */
16857   S (mp);
16858
16859   /* Wait for a reply... */
16860   W (ret);
16861   return ret;
16862 }
16863
16864 static int
16865 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16866 {
16867   vl_api_show_one_map_register_fallback_threshold_t *mp;
16868   int ret;
16869
16870   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16871
16872   /* send it... */
16873   S (mp);
16874
16875   /* Wait for a reply... */
16876   W (ret);
16877   return ret;
16878 }
16879
16880 uword
16881 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16882 {
16883   u32 *proto = va_arg (*args, u32 *);
16884
16885   if (unformat (input, "udp"))
16886     *proto = 1;
16887   else if (unformat (input, "api"))
16888     *proto = 2;
16889   else
16890     return 0;
16891
16892   return 1;
16893 }
16894
16895 static int
16896 api_one_set_transport_protocol (vat_main_t * vam)
16897 {
16898   unformat_input_t *input = vam->input;
16899   vl_api_one_set_transport_protocol_t *mp;
16900   u8 is_set = 0;
16901   u32 protocol = 0;
16902   int ret;
16903
16904   /* Parse args required to build the message */
16905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16906     {
16907       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16908         is_set = 1;
16909       else
16910         {
16911           clib_warning ("parse error '%U'", format_unformat_error, input);
16912           return -99;
16913         }
16914     }
16915
16916   if (!is_set)
16917     {
16918       errmsg ("Transport protocol missing!");
16919       return -99;
16920     }
16921
16922   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16923   mp->protocol = (u8) protocol;
16924
16925   /* send it... */
16926   S (mp);
16927
16928   /* Wait for a reply... */
16929   W (ret);
16930   return ret;
16931 }
16932
16933 static int
16934 api_one_get_transport_protocol (vat_main_t * vam)
16935 {
16936   vl_api_one_get_transport_protocol_t *mp;
16937   int ret;
16938
16939   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16940
16941   /* send it... */
16942   S (mp);
16943
16944   /* Wait for a reply... */
16945   W (ret);
16946   return ret;
16947 }
16948
16949 static int
16950 api_one_map_register_set_ttl (vat_main_t * vam)
16951 {
16952   unformat_input_t *input = vam->input;
16953   vl_api_one_map_register_set_ttl_t *mp;
16954   u32 ttl = 0;
16955   u8 is_set = 0;
16956   int ret;
16957
16958   /* Parse args required to build the message */
16959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16960     {
16961       if (unformat (input, "%u", &ttl))
16962         is_set = 1;
16963       else
16964         {
16965           clib_warning ("parse error '%U'", format_unformat_error, input);
16966           return -99;
16967         }
16968     }
16969
16970   if (!is_set)
16971     {
16972       errmsg ("TTL value missing!");
16973       return -99;
16974     }
16975
16976   M (ONE_MAP_REGISTER_SET_TTL, mp);
16977   mp->ttl = clib_host_to_net_u32 (ttl);
16978
16979   /* send it... */
16980   S (mp);
16981
16982   /* Wait for a reply... */
16983   W (ret);
16984   return ret;
16985 }
16986
16987 static int
16988 api_show_one_map_register_ttl (vat_main_t * vam)
16989 {
16990   vl_api_show_one_map_register_ttl_t *mp;
16991   int ret;
16992
16993   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16994
16995   /* send it... */
16996   S (mp);
16997
16998   /* Wait for a reply... */
16999   W (ret);
17000   return ret;
17001 }
17002
17003 /**
17004  * Add/del map request itr rlocs from ONE control plane and updates
17005  *
17006  * @param vam vpp API test context
17007  * @return return code
17008  */
17009 static int
17010 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17011 {
17012   unformat_input_t *input = vam->input;
17013   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17014   u8 *locator_set_name = 0;
17015   u8 locator_set_name_set = 0;
17016   u8 is_add = 1;
17017   int ret;
17018
17019   /* Parse args required to build the message */
17020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17021     {
17022       if (unformat (input, "del"))
17023         {
17024           is_add = 0;
17025         }
17026       else if (unformat (input, "%_%v%_", &locator_set_name))
17027         {
17028           locator_set_name_set = 1;
17029         }
17030       else
17031         {
17032           clib_warning ("parse error '%U'", format_unformat_error, input);
17033           return -99;
17034         }
17035     }
17036
17037   if (is_add && !locator_set_name_set)
17038     {
17039       errmsg ("itr-rloc is not set!");
17040       return -99;
17041     }
17042
17043   if (is_add && vec_len (locator_set_name) > 64)
17044     {
17045       errmsg ("itr-rloc locator-set name too long");
17046       vec_free (locator_set_name);
17047       return -99;
17048     }
17049
17050   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17051   mp->is_add = is_add;
17052   if (is_add)
17053     {
17054       clib_memcpy (mp->locator_set_name, locator_set_name,
17055                    vec_len (locator_set_name));
17056     }
17057   else
17058     {
17059       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17060     }
17061   vec_free (locator_set_name);
17062
17063   /* send it... */
17064   S (mp);
17065
17066   /* Wait for a reply... */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17072
17073 static int
17074 api_one_locator_dump (vat_main_t * vam)
17075 {
17076   unformat_input_t *input = vam->input;
17077   vl_api_one_locator_dump_t *mp;
17078   vl_api_control_ping_t *mp_ping;
17079   u8 is_index_set = 0, is_name_set = 0;
17080   u8 *ls_name = 0;
17081   u32 ls_index = ~0;
17082   int ret;
17083
17084   /* Parse args required to build the message */
17085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17086     {
17087       if (unformat (input, "ls_name %_%v%_", &ls_name))
17088         {
17089           is_name_set = 1;
17090         }
17091       else if (unformat (input, "ls_index %d", &ls_index))
17092         {
17093           is_index_set = 1;
17094         }
17095       else
17096         {
17097           errmsg ("parse error '%U'", format_unformat_error, input);
17098           return -99;
17099         }
17100     }
17101
17102   if (!is_index_set && !is_name_set)
17103     {
17104       errmsg ("error: expected one of index or name!");
17105       return -99;
17106     }
17107
17108   if (is_index_set && is_name_set)
17109     {
17110       errmsg ("error: only one param expected!");
17111       return -99;
17112     }
17113
17114   if (vec_len (ls_name) > 62)
17115     {
17116       errmsg ("error: locator set name too long!");
17117       return -99;
17118     }
17119
17120   if (!vam->json_output)
17121     {
17122       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17123     }
17124
17125   M (ONE_LOCATOR_DUMP, mp);
17126   mp->is_index_set = is_index_set;
17127
17128   if (is_index_set)
17129     mp->ls_index = clib_host_to_net_u32 (ls_index);
17130   else
17131     {
17132       vec_add1 (ls_name, 0);
17133       strncpy ((char *) mp->ls_name, (char *) ls_name,
17134                sizeof (mp->ls_name) - 1);
17135     }
17136
17137   /* send it... */
17138   S (mp);
17139
17140   /* Use a control ping for synchronization */
17141   MPING (CONTROL_PING, mp_ping);
17142   S (mp_ping);
17143
17144   /* Wait for a reply... */
17145   W (ret);
17146   return ret;
17147 }
17148
17149 #define api_lisp_locator_dump api_one_locator_dump
17150
17151 static int
17152 api_one_locator_set_dump (vat_main_t * vam)
17153 {
17154   vl_api_one_locator_set_dump_t *mp;
17155   vl_api_control_ping_t *mp_ping;
17156   unformat_input_t *input = vam->input;
17157   u8 filter = 0;
17158   int ret;
17159
17160   /* Parse args required to build the message */
17161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17162     {
17163       if (unformat (input, "local"))
17164         {
17165           filter = 1;
17166         }
17167       else if (unformat (input, "remote"))
17168         {
17169           filter = 2;
17170         }
17171       else
17172         {
17173           errmsg ("parse error '%U'", format_unformat_error, input);
17174           return -99;
17175         }
17176     }
17177
17178   if (!vam->json_output)
17179     {
17180       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17181     }
17182
17183   M (ONE_LOCATOR_SET_DUMP, mp);
17184
17185   mp->filter = filter;
17186
17187   /* send it... */
17188   S (mp);
17189
17190   /* Use a control ping for synchronization */
17191   MPING (CONTROL_PING, mp_ping);
17192   S (mp_ping);
17193
17194   /* Wait for a reply... */
17195   W (ret);
17196   return ret;
17197 }
17198
17199 #define api_lisp_locator_set_dump api_one_locator_set_dump
17200
17201 static int
17202 api_one_eid_table_map_dump (vat_main_t * vam)
17203 {
17204   u8 is_l2 = 0;
17205   u8 mode_set = 0;
17206   unformat_input_t *input = vam->input;
17207   vl_api_one_eid_table_map_dump_t *mp;
17208   vl_api_control_ping_t *mp_ping;
17209   int ret;
17210
17211   /* Parse args required to build the message */
17212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17213     {
17214       if (unformat (input, "l2"))
17215         {
17216           is_l2 = 1;
17217           mode_set = 1;
17218         }
17219       else if (unformat (input, "l3"))
17220         {
17221           is_l2 = 0;
17222           mode_set = 1;
17223         }
17224       else
17225         {
17226           errmsg ("parse error '%U'", format_unformat_error, input);
17227           return -99;
17228         }
17229     }
17230
17231   if (!mode_set)
17232     {
17233       errmsg ("expected one of 'l2' or 'l3' parameter!");
17234       return -99;
17235     }
17236
17237   if (!vam->json_output)
17238     {
17239       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17240     }
17241
17242   M (ONE_EID_TABLE_MAP_DUMP, mp);
17243   mp->is_l2 = is_l2;
17244
17245   /* send it... */
17246   S (mp);
17247
17248   /* Use a control ping for synchronization */
17249   MPING (CONTROL_PING, mp_ping);
17250   S (mp_ping);
17251
17252   /* Wait for a reply... */
17253   W (ret);
17254   return ret;
17255 }
17256
17257 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17258
17259 static int
17260 api_one_eid_table_vni_dump (vat_main_t * vam)
17261 {
17262   vl_api_one_eid_table_vni_dump_t *mp;
17263   vl_api_control_ping_t *mp_ping;
17264   int ret;
17265
17266   if (!vam->json_output)
17267     {
17268       print (vam->ofp, "VNI");
17269     }
17270
17271   M (ONE_EID_TABLE_VNI_DUMP, mp);
17272
17273   /* send it... */
17274   S (mp);
17275
17276   /* Use a control ping for synchronization */
17277   MPING (CONTROL_PING, mp_ping);
17278   S (mp_ping);
17279
17280   /* Wait for a reply... */
17281   W (ret);
17282   return ret;
17283 }
17284
17285 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17286
17287 static int
17288 api_one_eid_table_dump (vat_main_t * vam)
17289 {
17290   unformat_input_t *i = vam->input;
17291   vl_api_one_eid_table_dump_t *mp;
17292   vl_api_control_ping_t *mp_ping;
17293   struct in_addr ip4;
17294   struct in6_addr ip6;
17295   u8 mac[6];
17296   u8 eid_type = ~0, eid_set = 0;
17297   u32 prefix_length = ~0, t, vni = 0;
17298   u8 filter = 0;
17299   int ret;
17300   lisp_nsh_api_t nsh;
17301
17302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17303     {
17304       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17305         {
17306           eid_set = 1;
17307           eid_type = 0;
17308           prefix_length = t;
17309         }
17310       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17311         {
17312           eid_set = 1;
17313           eid_type = 1;
17314           prefix_length = t;
17315         }
17316       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17317         {
17318           eid_set = 1;
17319           eid_type = 2;
17320         }
17321       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17322         {
17323           eid_set = 1;
17324           eid_type = 3;
17325         }
17326       else if (unformat (i, "vni %d", &t))
17327         {
17328           vni = t;
17329         }
17330       else if (unformat (i, "local"))
17331         {
17332           filter = 1;
17333         }
17334       else if (unformat (i, "remote"))
17335         {
17336           filter = 2;
17337         }
17338       else
17339         {
17340           errmsg ("parse error '%U'", format_unformat_error, i);
17341           return -99;
17342         }
17343     }
17344
17345   if (!vam->json_output)
17346     {
17347       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17348              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17349     }
17350
17351   M (ONE_EID_TABLE_DUMP, mp);
17352
17353   mp->filter = filter;
17354   if (eid_set)
17355     {
17356       mp->eid_set = 1;
17357       mp->vni = htonl (vni);
17358       mp->eid_type = eid_type;
17359       switch (eid_type)
17360         {
17361         case 0:
17362           mp->prefix_length = prefix_length;
17363           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17364           break;
17365         case 1:
17366           mp->prefix_length = prefix_length;
17367           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17368           break;
17369         case 2:
17370           clib_memcpy (mp->eid, mac, sizeof (mac));
17371           break;
17372         case 3:
17373           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17374           break;
17375         default:
17376           errmsg ("unknown EID type %d!", eid_type);
17377           return -99;
17378         }
17379     }
17380
17381   /* send it... */
17382   S (mp);
17383
17384   /* Use a control ping for synchronization */
17385   MPING (CONTROL_PING, mp_ping);
17386   S (mp_ping);
17387
17388   /* Wait for a reply... */
17389   W (ret);
17390   return ret;
17391 }
17392
17393 #define api_lisp_eid_table_dump api_one_eid_table_dump
17394
17395 static int
17396 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17397 {
17398   unformat_input_t *i = vam->input;
17399   vl_api_gpe_fwd_entries_get_t *mp;
17400   u8 vni_set = 0;
17401   u32 vni = ~0;
17402   int ret;
17403
17404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17405     {
17406       if (unformat (i, "vni %d", &vni))
17407         {
17408           vni_set = 1;
17409         }
17410       else
17411         {
17412           errmsg ("parse error '%U'", format_unformat_error, i);
17413           return -99;
17414         }
17415     }
17416
17417   if (!vni_set)
17418     {
17419       errmsg ("vni not set!");
17420       return -99;
17421     }
17422
17423   if (!vam->json_output)
17424     {
17425       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17426              "leid", "reid");
17427     }
17428
17429   M (GPE_FWD_ENTRIES_GET, mp);
17430   mp->vni = clib_host_to_net_u32 (vni);
17431
17432   /* send it... */
17433   S (mp);
17434
17435   /* Wait for a reply... */
17436   W (ret);
17437   return ret;
17438 }
17439
17440 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17441 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17442 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17443 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17444 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17445 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17446 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17447 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17448
17449 static int
17450 api_one_adjacencies_get (vat_main_t * vam)
17451 {
17452   unformat_input_t *i = vam->input;
17453   vl_api_one_adjacencies_get_t *mp;
17454   u8 vni_set = 0;
17455   u32 vni = ~0;
17456   int ret;
17457
17458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17459     {
17460       if (unformat (i, "vni %d", &vni))
17461         {
17462           vni_set = 1;
17463         }
17464       else
17465         {
17466           errmsg ("parse error '%U'", format_unformat_error, i);
17467           return -99;
17468         }
17469     }
17470
17471   if (!vni_set)
17472     {
17473       errmsg ("vni not set!");
17474       return -99;
17475     }
17476
17477   if (!vam->json_output)
17478     {
17479       print (vam->ofp, "%s %40s", "leid", "reid");
17480     }
17481
17482   M (ONE_ADJACENCIES_GET, mp);
17483   mp->vni = clib_host_to_net_u32 (vni);
17484
17485   /* send it... */
17486   S (mp);
17487
17488   /* Wait for a reply... */
17489   W (ret);
17490   return ret;
17491 }
17492
17493 #define api_lisp_adjacencies_get api_one_adjacencies_get
17494
17495 static int
17496 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17497 {
17498   unformat_input_t *i = vam->input;
17499   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17500   int ret;
17501   u8 ip_family_set = 0, is_ip4 = 1;
17502
17503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17504     {
17505       if (unformat (i, "ip4"))
17506         {
17507           ip_family_set = 1;
17508           is_ip4 = 1;
17509         }
17510       else if (unformat (i, "ip6"))
17511         {
17512           ip_family_set = 1;
17513           is_ip4 = 0;
17514         }
17515       else
17516         {
17517           errmsg ("parse error '%U'", format_unformat_error, i);
17518           return -99;
17519         }
17520     }
17521
17522   if (!ip_family_set)
17523     {
17524       errmsg ("ip family not set!");
17525       return -99;
17526     }
17527
17528   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17529   mp->is_ip4 = is_ip4;
17530
17531   /* send it... */
17532   S (mp);
17533
17534   /* Wait for a reply... */
17535   W (ret);
17536   return ret;
17537 }
17538
17539 static int
17540 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17541 {
17542   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17543   int ret;
17544
17545   if (!vam->json_output)
17546     {
17547       print (vam->ofp, "VNIs");
17548     }
17549
17550   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17551
17552   /* send it... */
17553   S (mp);
17554
17555   /* Wait for a reply... */
17556   W (ret);
17557   return ret;
17558 }
17559
17560 static int
17561 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17562 {
17563   unformat_input_t *i = vam->input;
17564   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17565   int ret = 0;
17566   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17567   struct in_addr ip4;
17568   struct in6_addr ip6;
17569   u32 table_id = 0, nh_sw_if_index = ~0;
17570
17571   clib_memset (&ip4, 0, sizeof (ip4));
17572   clib_memset (&ip6, 0, sizeof (ip6));
17573
17574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17575     {
17576       if (unformat (i, "del"))
17577         is_add = 0;
17578       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17579                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17580         {
17581           ip_set = 1;
17582           is_ip4 = 1;
17583         }
17584       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17585                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17586         {
17587           ip_set = 1;
17588           is_ip4 = 0;
17589         }
17590       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17591         {
17592           ip_set = 1;
17593           is_ip4 = 1;
17594           nh_sw_if_index = ~0;
17595         }
17596       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17597         {
17598           ip_set = 1;
17599           is_ip4 = 0;
17600           nh_sw_if_index = ~0;
17601         }
17602       else if (unformat (i, "table %d", &table_id))
17603         ;
17604       else
17605         {
17606           errmsg ("parse error '%U'", format_unformat_error, i);
17607           return -99;
17608         }
17609     }
17610
17611   if (!ip_set)
17612     {
17613       errmsg ("nh addr not set!");
17614       return -99;
17615     }
17616
17617   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17618   mp->is_add = is_add;
17619   mp->table_id = clib_host_to_net_u32 (table_id);
17620   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17621   mp->is_ip4 = is_ip4;
17622   if (is_ip4)
17623     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17624   else
17625     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17626
17627   /* send it... */
17628   S (mp);
17629
17630   /* Wait for a reply... */
17631   W (ret);
17632   return ret;
17633 }
17634
17635 static int
17636 api_one_map_server_dump (vat_main_t * vam)
17637 {
17638   vl_api_one_map_server_dump_t *mp;
17639   vl_api_control_ping_t *mp_ping;
17640   int ret;
17641
17642   if (!vam->json_output)
17643     {
17644       print (vam->ofp, "%=20s", "Map server");
17645     }
17646
17647   M (ONE_MAP_SERVER_DUMP, mp);
17648   /* send it... */
17649   S (mp);
17650
17651   /* Use a control ping for synchronization */
17652   MPING (CONTROL_PING, mp_ping);
17653   S (mp_ping);
17654
17655   /* Wait for a reply... */
17656   W (ret);
17657   return ret;
17658 }
17659
17660 #define api_lisp_map_server_dump api_one_map_server_dump
17661
17662 static int
17663 api_one_map_resolver_dump (vat_main_t * vam)
17664 {
17665   vl_api_one_map_resolver_dump_t *mp;
17666   vl_api_control_ping_t *mp_ping;
17667   int ret;
17668
17669   if (!vam->json_output)
17670     {
17671       print (vam->ofp, "%=20s", "Map resolver");
17672     }
17673
17674   M (ONE_MAP_RESOLVER_DUMP, mp);
17675   /* send it... */
17676   S (mp);
17677
17678   /* Use a control ping for synchronization */
17679   MPING (CONTROL_PING, mp_ping);
17680   S (mp_ping);
17681
17682   /* Wait for a reply... */
17683   W (ret);
17684   return ret;
17685 }
17686
17687 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17688
17689 static int
17690 api_one_stats_flush (vat_main_t * vam)
17691 {
17692   vl_api_one_stats_flush_t *mp;
17693   int ret = 0;
17694
17695   M (ONE_STATS_FLUSH, mp);
17696   S (mp);
17697   W (ret);
17698   return ret;
17699 }
17700
17701 static int
17702 api_one_stats_dump (vat_main_t * vam)
17703 {
17704   vl_api_one_stats_dump_t *mp;
17705   vl_api_control_ping_t *mp_ping;
17706   int ret;
17707
17708   M (ONE_STATS_DUMP, mp);
17709   /* send it... */
17710   S (mp);
17711
17712   /* Use a control ping for synchronization */
17713   MPING (CONTROL_PING, mp_ping);
17714   S (mp_ping);
17715
17716   /* Wait for a reply... */
17717   W (ret);
17718   return ret;
17719 }
17720
17721 static int
17722 api_show_one_status (vat_main_t * vam)
17723 {
17724   vl_api_show_one_status_t *mp;
17725   int ret;
17726
17727   if (!vam->json_output)
17728     {
17729       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17730     }
17731
17732   M (SHOW_ONE_STATUS, mp);
17733   /* send it... */
17734   S (mp);
17735   /* Wait for a reply... */
17736   W (ret);
17737   return ret;
17738 }
17739
17740 #define api_show_lisp_status api_show_one_status
17741
17742 static int
17743 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17744 {
17745   vl_api_gpe_fwd_entry_path_dump_t *mp;
17746   vl_api_control_ping_t *mp_ping;
17747   unformat_input_t *i = vam->input;
17748   u32 fwd_entry_index = ~0;
17749   int ret;
17750
17751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17752     {
17753       if (unformat (i, "index %d", &fwd_entry_index))
17754         ;
17755       else
17756         break;
17757     }
17758
17759   if (~0 == fwd_entry_index)
17760     {
17761       errmsg ("no index specified!");
17762       return -99;
17763     }
17764
17765   if (!vam->json_output)
17766     {
17767       print (vam->ofp, "first line");
17768     }
17769
17770   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17771
17772   /* send it... */
17773   S (mp);
17774   /* Use a control ping for synchronization */
17775   MPING (CONTROL_PING, mp_ping);
17776   S (mp_ping);
17777
17778   /* Wait for a reply... */
17779   W (ret);
17780   return ret;
17781 }
17782
17783 static int
17784 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17785 {
17786   vl_api_one_get_map_request_itr_rlocs_t *mp;
17787   int ret;
17788
17789   if (!vam->json_output)
17790     {
17791       print (vam->ofp, "%=20s", "itr-rlocs:");
17792     }
17793
17794   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17795   /* send it... */
17796   S (mp);
17797   /* Wait for a reply... */
17798   W (ret);
17799   return ret;
17800 }
17801
17802 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17803
17804 static int
17805 api_af_packet_create (vat_main_t * vam)
17806 {
17807   unformat_input_t *i = vam->input;
17808   vl_api_af_packet_create_t *mp;
17809   u8 *host_if_name = 0;
17810   u8 hw_addr[6];
17811   u8 random_hw_addr = 1;
17812   int ret;
17813
17814   clib_memset (hw_addr, 0, sizeof (hw_addr));
17815
17816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17817     {
17818       if (unformat (i, "name %s", &host_if_name))
17819         vec_add1 (host_if_name, 0);
17820       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17821         random_hw_addr = 0;
17822       else
17823         break;
17824     }
17825
17826   if (!vec_len (host_if_name))
17827     {
17828       errmsg ("host-interface name must be specified");
17829       return -99;
17830     }
17831
17832   if (vec_len (host_if_name) > 64)
17833     {
17834       errmsg ("host-interface name too long");
17835       return -99;
17836     }
17837
17838   M (AF_PACKET_CREATE, mp);
17839
17840   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17841   clib_memcpy (mp->hw_addr, hw_addr, 6);
17842   mp->use_random_hw_addr = random_hw_addr;
17843   vec_free (host_if_name);
17844
17845   S (mp);
17846
17847   /* *INDENT-OFF* */
17848   W2 (ret,
17849       ({
17850         if (ret == 0)
17851           fprintf (vam->ofp ? vam->ofp : stderr,
17852                    " new sw_if_index = %d\n", vam->sw_if_index);
17853       }));
17854   /* *INDENT-ON* */
17855   return ret;
17856 }
17857
17858 static int
17859 api_af_packet_delete (vat_main_t * vam)
17860 {
17861   unformat_input_t *i = vam->input;
17862   vl_api_af_packet_delete_t *mp;
17863   u8 *host_if_name = 0;
17864   int ret;
17865
17866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17867     {
17868       if (unformat (i, "name %s", &host_if_name))
17869         vec_add1 (host_if_name, 0);
17870       else
17871         break;
17872     }
17873
17874   if (!vec_len (host_if_name))
17875     {
17876       errmsg ("host-interface name must be specified");
17877       return -99;
17878     }
17879
17880   if (vec_len (host_if_name) > 64)
17881     {
17882       errmsg ("host-interface name too long");
17883       return -99;
17884     }
17885
17886   M (AF_PACKET_DELETE, mp);
17887
17888   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17889   vec_free (host_if_name);
17890
17891   S (mp);
17892   W (ret);
17893   return ret;
17894 }
17895
17896 static void vl_api_af_packet_details_t_handler
17897   (vl_api_af_packet_details_t * mp)
17898 {
17899   vat_main_t *vam = &vat_main;
17900
17901   print (vam->ofp, "%-16s %d",
17902          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17903 }
17904
17905 static void vl_api_af_packet_details_t_handler_json
17906   (vl_api_af_packet_details_t * mp)
17907 {
17908   vat_main_t *vam = &vat_main;
17909   vat_json_node_t *node = NULL;
17910
17911   if (VAT_JSON_ARRAY != vam->json_tree.type)
17912     {
17913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17914       vat_json_init_array (&vam->json_tree);
17915     }
17916   node = vat_json_array_add (&vam->json_tree);
17917
17918   vat_json_init_object (node);
17919   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17920   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17921 }
17922
17923 static int
17924 api_af_packet_dump (vat_main_t * vam)
17925 {
17926   vl_api_af_packet_dump_t *mp;
17927   vl_api_control_ping_t *mp_ping;
17928   int ret;
17929
17930   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17931   /* Get list of tap interfaces */
17932   M (AF_PACKET_DUMP, mp);
17933   S (mp);
17934
17935   /* Use a control ping for synchronization */
17936   MPING (CONTROL_PING, mp_ping);
17937   S (mp_ping);
17938
17939   W (ret);
17940   return ret;
17941 }
17942
17943 static int
17944 api_policer_add_del (vat_main_t * vam)
17945 {
17946   unformat_input_t *i = vam->input;
17947   vl_api_policer_add_del_t *mp;
17948   u8 is_add = 1;
17949   u8 *name = 0;
17950   u32 cir = 0;
17951   u32 eir = 0;
17952   u64 cb = 0;
17953   u64 eb = 0;
17954   u8 rate_type = 0;
17955   u8 round_type = 0;
17956   u8 type = 0;
17957   u8 color_aware = 0;
17958   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17959   int ret;
17960
17961   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17962   conform_action.dscp = 0;
17963   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17964   exceed_action.dscp = 0;
17965   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17966   violate_action.dscp = 0;
17967
17968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17969     {
17970       if (unformat (i, "del"))
17971         is_add = 0;
17972       else if (unformat (i, "name %s", &name))
17973         vec_add1 (name, 0);
17974       else if (unformat (i, "cir %u", &cir))
17975         ;
17976       else if (unformat (i, "eir %u", &eir))
17977         ;
17978       else if (unformat (i, "cb %u", &cb))
17979         ;
17980       else if (unformat (i, "eb %u", &eb))
17981         ;
17982       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17983                          &rate_type))
17984         ;
17985       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17986                          &round_type))
17987         ;
17988       else if (unformat (i, "type %U", unformat_policer_type, &type))
17989         ;
17990       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17991                          &conform_action))
17992         ;
17993       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17994                          &exceed_action))
17995         ;
17996       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17997                          &violate_action))
17998         ;
17999       else if (unformat (i, "color-aware"))
18000         color_aware = 1;
18001       else
18002         break;
18003     }
18004
18005   if (!vec_len (name))
18006     {
18007       errmsg ("policer name must be specified");
18008       return -99;
18009     }
18010
18011   if (vec_len (name) > 64)
18012     {
18013       errmsg ("policer name too long");
18014       return -99;
18015     }
18016
18017   M (POLICER_ADD_DEL, mp);
18018
18019   clib_memcpy (mp->name, name, vec_len (name));
18020   vec_free (name);
18021   mp->is_add = is_add;
18022   mp->cir = ntohl (cir);
18023   mp->eir = ntohl (eir);
18024   mp->cb = clib_net_to_host_u64 (cb);
18025   mp->eb = clib_net_to_host_u64 (eb);
18026   mp->rate_type = rate_type;
18027   mp->round_type = round_type;
18028   mp->type = type;
18029   mp->conform_action_type = conform_action.action_type;
18030   mp->conform_dscp = conform_action.dscp;
18031   mp->exceed_action_type = exceed_action.action_type;
18032   mp->exceed_dscp = exceed_action.dscp;
18033   mp->violate_action_type = violate_action.action_type;
18034   mp->violate_dscp = violate_action.dscp;
18035   mp->color_aware = color_aware;
18036
18037   S (mp);
18038   W (ret);
18039   return ret;
18040 }
18041
18042 static int
18043 api_policer_dump (vat_main_t * vam)
18044 {
18045   unformat_input_t *i = vam->input;
18046   vl_api_policer_dump_t *mp;
18047   vl_api_control_ping_t *mp_ping;
18048   u8 *match_name = 0;
18049   u8 match_name_valid = 0;
18050   int ret;
18051
18052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18053     {
18054       if (unformat (i, "name %s", &match_name))
18055         {
18056           vec_add1 (match_name, 0);
18057           match_name_valid = 1;
18058         }
18059       else
18060         break;
18061     }
18062
18063   M (POLICER_DUMP, mp);
18064   mp->match_name_valid = match_name_valid;
18065   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18066   vec_free (match_name);
18067   /* send it... */
18068   S (mp);
18069
18070   /* Use a control ping for synchronization */
18071   MPING (CONTROL_PING, mp_ping);
18072   S (mp_ping);
18073
18074   /* Wait for a reply... */
18075   W (ret);
18076   return ret;
18077 }
18078
18079 static int
18080 api_policer_classify_set_interface (vat_main_t * vam)
18081 {
18082   unformat_input_t *i = vam->input;
18083   vl_api_policer_classify_set_interface_t *mp;
18084   u32 sw_if_index;
18085   int sw_if_index_set;
18086   u32 ip4_table_index = ~0;
18087   u32 ip6_table_index = ~0;
18088   u32 l2_table_index = ~0;
18089   u8 is_add = 1;
18090   int ret;
18091
18092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18093     {
18094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18095         sw_if_index_set = 1;
18096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18097         sw_if_index_set = 1;
18098       else if (unformat (i, "del"))
18099         is_add = 0;
18100       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18101         ;
18102       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18103         ;
18104       else if (unformat (i, "l2-table %d", &l2_table_index))
18105         ;
18106       else
18107         {
18108           clib_warning ("parse error '%U'", format_unformat_error, i);
18109           return -99;
18110         }
18111     }
18112
18113   if (sw_if_index_set == 0)
18114     {
18115       errmsg ("missing interface name or sw_if_index");
18116       return -99;
18117     }
18118
18119   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18120
18121   mp->sw_if_index = ntohl (sw_if_index);
18122   mp->ip4_table_index = ntohl (ip4_table_index);
18123   mp->ip6_table_index = ntohl (ip6_table_index);
18124   mp->l2_table_index = ntohl (l2_table_index);
18125   mp->is_add = is_add;
18126
18127   S (mp);
18128   W (ret);
18129   return ret;
18130 }
18131
18132 static int
18133 api_policer_classify_dump (vat_main_t * vam)
18134 {
18135   unformat_input_t *i = vam->input;
18136   vl_api_policer_classify_dump_t *mp;
18137   vl_api_control_ping_t *mp_ping;
18138   u8 type = POLICER_CLASSIFY_N_TABLES;
18139   int ret;
18140
18141   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18142     ;
18143   else
18144     {
18145       errmsg ("classify table type must be specified");
18146       return -99;
18147     }
18148
18149   if (!vam->json_output)
18150     {
18151       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18152     }
18153
18154   M (POLICER_CLASSIFY_DUMP, mp);
18155   mp->type = type;
18156   /* send it... */
18157   S (mp);
18158
18159   /* Use a control ping for synchronization */
18160   MPING (CONTROL_PING, mp_ping);
18161   S (mp_ping);
18162
18163   /* Wait for a reply... */
18164   W (ret);
18165   return ret;
18166 }
18167
18168 static int
18169 api_netmap_create (vat_main_t * vam)
18170 {
18171   unformat_input_t *i = vam->input;
18172   vl_api_netmap_create_t *mp;
18173   u8 *if_name = 0;
18174   u8 hw_addr[6];
18175   u8 random_hw_addr = 1;
18176   u8 is_pipe = 0;
18177   u8 is_master = 0;
18178   int ret;
18179
18180   clib_memset (hw_addr, 0, sizeof (hw_addr));
18181
18182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18183     {
18184       if (unformat (i, "name %s", &if_name))
18185         vec_add1 (if_name, 0);
18186       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18187         random_hw_addr = 0;
18188       else if (unformat (i, "pipe"))
18189         is_pipe = 1;
18190       else if (unformat (i, "master"))
18191         is_master = 1;
18192       else if (unformat (i, "slave"))
18193         is_master = 0;
18194       else
18195         break;
18196     }
18197
18198   if (!vec_len (if_name))
18199     {
18200       errmsg ("interface name must be specified");
18201       return -99;
18202     }
18203
18204   if (vec_len (if_name) > 64)
18205     {
18206       errmsg ("interface name too long");
18207       return -99;
18208     }
18209
18210   M (NETMAP_CREATE, mp);
18211
18212   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18213   clib_memcpy (mp->hw_addr, hw_addr, 6);
18214   mp->use_random_hw_addr = random_hw_addr;
18215   mp->is_pipe = is_pipe;
18216   mp->is_master = is_master;
18217   vec_free (if_name);
18218
18219   S (mp);
18220   W (ret);
18221   return ret;
18222 }
18223
18224 static int
18225 api_netmap_delete (vat_main_t * vam)
18226 {
18227   unformat_input_t *i = vam->input;
18228   vl_api_netmap_delete_t *mp;
18229   u8 *if_name = 0;
18230   int ret;
18231
18232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18233     {
18234       if (unformat (i, "name %s", &if_name))
18235         vec_add1 (if_name, 0);
18236       else
18237         break;
18238     }
18239
18240   if (!vec_len (if_name))
18241     {
18242       errmsg ("interface name must be specified");
18243       return -99;
18244     }
18245
18246   if (vec_len (if_name) > 64)
18247     {
18248       errmsg ("interface name too long");
18249       return -99;
18250     }
18251
18252   M (NETMAP_DELETE, mp);
18253
18254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18255   vec_free (if_name);
18256
18257   S (mp);
18258   W (ret);
18259   return ret;
18260 }
18261
18262 static u8 *
18263 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18264 {
18265   vl_api_fib_path_nh_proto_t proto =
18266     va_arg (*args, vl_api_fib_path_nh_proto_t);
18267
18268   switch (proto)
18269     {
18270     case FIB_API_PATH_NH_PROTO_IP4:
18271       s = format (s, "ip4");
18272       break;
18273     case FIB_API_PATH_NH_PROTO_IP6:
18274       s = format (s, "ip6");
18275       break;
18276     case FIB_API_PATH_NH_PROTO_MPLS:
18277       s = format (s, "mpls");
18278       break;
18279     case FIB_API_PATH_NH_PROTO_BIER:
18280       s = format (s, "bier");
18281       break;
18282     case FIB_API_PATH_NH_PROTO_ETHERNET:
18283       s = format (s, "ethernet");
18284       break;
18285     }
18286
18287   return (s);
18288 }
18289
18290 static u8 *
18291 format_vl_api_ip_address_union (u8 * s, va_list * args)
18292 {
18293   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18294   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18295
18296   switch (af)
18297     {
18298     case ADDRESS_IP4:
18299       s = format (s, "%U", format_ip4_address, u->ip4);
18300       break;
18301     case ADDRESS_IP6:
18302       s = format (s, "%U", format_ip6_address, u->ip6);
18303       break;
18304     }
18305   return (s);
18306 }
18307
18308 static u8 *
18309 format_vl_api_fib_path_type (u8 * s, va_list * args)
18310 {
18311   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18312
18313   switch (t)
18314     {
18315     case FIB_API_PATH_TYPE_NORMAL:
18316       s = format (s, "normal");
18317       break;
18318     case FIB_API_PATH_TYPE_LOCAL:
18319       s = format (s, "local");
18320       break;
18321     case FIB_API_PATH_TYPE_DROP:
18322       s = format (s, "drop");
18323       break;
18324     case FIB_API_PATH_TYPE_UDP_ENCAP:
18325       s = format (s, "udp-encap");
18326       break;
18327     case FIB_API_PATH_TYPE_BIER_IMP:
18328       s = format (s, "bier-imp");
18329       break;
18330     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18331       s = format (s, "unreach");
18332       break;
18333     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18334       s = format (s, "prohibit");
18335       break;
18336     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18337       s = format (s, "src-lookup");
18338       break;
18339     case FIB_API_PATH_TYPE_DVR:
18340       s = format (s, "dvr");
18341       break;
18342     case FIB_API_PATH_TYPE_INTERFACE_RX:
18343       s = format (s, "interface-rx");
18344       break;
18345     case FIB_API_PATH_TYPE_CLASSIFY:
18346       s = format (s, "classify");
18347       break;
18348     }
18349
18350   return (s);
18351 }
18352
18353 static void
18354 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18355 {
18356   print (vam->ofp,
18357          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18358          ntohl (fp->weight), ntohl (fp->sw_if_index),
18359          format_vl_api_fib_path_type, fp->type,
18360          format_fib_api_path_nh_proto, fp->proto,
18361          format_vl_api_ip_address_union, &fp->nh.address);
18362 }
18363
18364 static void
18365 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18366                                  vl_api_fib_path_t * fp)
18367 {
18368   struct in_addr ip4;
18369   struct in6_addr ip6;
18370
18371   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18372   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18373   vat_json_object_add_uint (node, "type", fp->type);
18374   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18375   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18376     {
18377       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18378       vat_json_object_add_ip4 (node, "next_hop", ip4);
18379     }
18380   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18381     {
18382       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18383       vat_json_object_add_ip6 (node, "next_hop", ip6);
18384     }
18385 }
18386
18387 static void
18388 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18389 {
18390   vat_main_t *vam = &vat_main;
18391   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18392   vl_api_fib_path_t *fp;
18393   i32 i;
18394
18395   print (vam->ofp, "sw_if_index %d via:",
18396          ntohl (mp->mt_tunnel.mt_sw_if_index));
18397   fp = mp->mt_tunnel.mt_paths;
18398   for (i = 0; i < count; i++)
18399     {
18400       vl_api_fib_path_print (vam, fp);
18401       fp++;
18402     }
18403
18404   print (vam->ofp, "");
18405 }
18406
18407 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18408 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18409
18410 static void
18411 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18412 {
18413   vat_main_t *vam = &vat_main;
18414   vat_json_node_t *node = NULL;
18415   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18416   vl_api_fib_path_t *fp;
18417   i32 i;
18418
18419   if (VAT_JSON_ARRAY != vam->json_tree.type)
18420     {
18421       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18422       vat_json_init_array (&vam->json_tree);
18423     }
18424   node = vat_json_array_add (&vam->json_tree);
18425
18426   vat_json_init_object (node);
18427   vat_json_object_add_uint (node, "sw_if_index",
18428                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18429
18430   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18431
18432   fp = mp->mt_tunnel.mt_paths;
18433   for (i = 0; i < count; i++)
18434     {
18435       vl_api_mpls_fib_path_json_print (node, fp);
18436       fp++;
18437     }
18438 }
18439
18440 static int
18441 api_mpls_tunnel_dump (vat_main_t * vam)
18442 {
18443   vl_api_mpls_tunnel_dump_t *mp;
18444   vl_api_control_ping_t *mp_ping;
18445   int ret;
18446
18447   M (MPLS_TUNNEL_DUMP, mp);
18448
18449   S (mp);
18450
18451   /* Use a control ping for synchronization */
18452   MPING (CONTROL_PING, mp_ping);
18453   S (mp_ping);
18454
18455   W (ret);
18456   return ret;
18457 }
18458
18459 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18460 #define vl_api_mpls_table_details_t_print vl_noop_handler
18461
18462
18463 static void
18464 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18465 {
18466   vat_main_t *vam = &vat_main;
18467
18468   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18469 }
18470
18471 static void vl_api_mpls_table_details_t_handler_json
18472   (vl_api_mpls_table_details_t * mp)
18473 {
18474   vat_main_t *vam = &vat_main;
18475   vat_json_node_t *node = NULL;
18476
18477   if (VAT_JSON_ARRAY != vam->json_tree.type)
18478     {
18479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18480       vat_json_init_array (&vam->json_tree);
18481     }
18482   node = vat_json_array_add (&vam->json_tree);
18483
18484   vat_json_init_object (node);
18485   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18486 }
18487
18488 static int
18489 api_mpls_table_dump (vat_main_t * vam)
18490 {
18491   vl_api_mpls_table_dump_t *mp;
18492   vl_api_control_ping_t *mp_ping;
18493   int ret;
18494
18495   M (MPLS_TABLE_DUMP, mp);
18496   S (mp);
18497
18498   /* Use a control ping for synchronization */
18499   MPING (CONTROL_PING, mp_ping);
18500   S (mp_ping);
18501
18502   W (ret);
18503   return ret;
18504 }
18505
18506 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18507 #define vl_api_mpls_route_details_t_print vl_noop_handler
18508
18509 static void
18510 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18511 {
18512   vat_main_t *vam = &vat_main;
18513   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18514   vl_api_fib_path_t *fp;
18515   int i;
18516
18517   print (vam->ofp,
18518          "table-id %d, label %u, ess_bit %u",
18519          ntohl (mp->mr_route.mr_table_id),
18520          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18521   fp = mp->mr_route.mr_paths;
18522   for (i = 0; i < count; i++)
18523     {
18524       vl_api_fib_path_print (vam, fp);
18525       fp++;
18526     }
18527 }
18528
18529 static void vl_api_mpls_route_details_t_handler_json
18530   (vl_api_mpls_route_details_t * mp)
18531 {
18532   vat_main_t *vam = &vat_main;
18533   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18534   vat_json_node_t *node = NULL;
18535   vl_api_fib_path_t *fp;
18536   int i;
18537
18538   if (VAT_JSON_ARRAY != vam->json_tree.type)
18539     {
18540       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18541       vat_json_init_array (&vam->json_tree);
18542     }
18543   node = vat_json_array_add (&vam->json_tree);
18544
18545   vat_json_init_object (node);
18546   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18547   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18548   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18549   vat_json_object_add_uint (node, "path_count", count);
18550   fp = mp->mr_route.mr_paths;
18551   for (i = 0; i < count; i++)
18552     {
18553       vl_api_mpls_fib_path_json_print (node, fp);
18554       fp++;
18555     }
18556 }
18557
18558 static int
18559 api_mpls_route_dump (vat_main_t * vam)
18560 {
18561   unformat_input_t *input = vam->input;
18562   vl_api_mpls_route_dump_t *mp;
18563   vl_api_control_ping_t *mp_ping;
18564   u32 table_id;
18565   int ret;
18566
18567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18568     {
18569       if (unformat (input, "table_id %d", &table_id))
18570         ;
18571       else
18572         break;
18573     }
18574   if (table_id == ~0)
18575     {
18576       errmsg ("missing table id");
18577       return -99;
18578     }
18579
18580   M (MPLS_ROUTE_DUMP, mp);
18581
18582   mp->table.mt_table_id = ntohl (table_id);
18583   S (mp);
18584
18585   /* Use a control ping for synchronization */
18586   MPING (CONTROL_PING, mp_ping);
18587   S (mp_ping);
18588
18589   W (ret);
18590   return ret;
18591 }
18592
18593 #define vl_api_ip_table_details_t_endian vl_noop_handler
18594 #define vl_api_ip_table_details_t_print vl_noop_handler
18595
18596 static void
18597 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18598 {
18599   vat_main_t *vam = &vat_main;
18600
18601   print (vam->ofp,
18602          "%s; table-id %d, prefix %U/%d",
18603          mp->table.name, ntohl (mp->table.table_id));
18604 }
18605
18606
18607 static void vl_api_ip_table_details_t_handler_json
18608   (vl_api_ip_table_details_t * mp)
18609 {
18610   vat_main_t *vam = &vat_main;
18611   vat_json_node_t *node = NULL;
18612
18613   if (VAT_JSON_ARRAY != vam->json_tree.type)
18614     {
18615       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18616       vat_json_init_array (&vam->json_tree);
18617     }
18618   node = vat_json_array_add (&vam->json_tree);
18619
18620   vat_json_init_object (node);
18621   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18622 }
18623
18624 static int
18625 api_ip_table_dump (vat_main_t * vam)
18626 {
18627   vl_api_ip_table_dump_t *mp;
18628   vl_api_control_ping_t *mp_ping;
18629   int ret;
18630
18631   M (IP_TABLE_DUMP, mp);
18632   S (mp);
18633
18634   /* Use a control ping for synchronization */
18635   MPING (CONTROL_PING, mp_ping);
18636   S (mp_ping);
18637
18638   W (ret);
18639   return ret;
18640 }
18641
18642 static int
18643 api_ip_mtable_dump (vat_main_t * vam)
18644 {
18645   vl_api_ip_mtable_dump_t *mp;
18646   vl_api_control_ping_t *mp_ping;
18647   int ret;
18648
18649   M (IP_MTABLE_DUMP, mp);
18650   S (mp);
18651
18652   /* Use a control ping for synchronization */
18653   MPING (CONTROL_PING, mp_ping);
18654   S (mp_ping);
18655
18656   W (ret);
18657   return ret;
18658 }
18659
18660 static int
18661 api_ip_mroute_dump (vat_main_t * vam)
18662 {
18663   unformat_input_t *input = vam->input;
18664   vl_api_control_ping_t *mp_ping;
18665   vl_api_ip_mroute_dump_t *mp;
18666   int ret, is_ip6;
18667   u32 table_id;
18668
18669   is_ip6 = 0;
18670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18671     {
18672       if (unformat (input, "table_id %d", &table_id))
18673         ;
18674       else if (unformat (input, "ip6"))
18675         is_ip6 = 1;
18676       else if (unformat (input, "ip4"))
18677         is_ip6 = 0;
18678       else
18679         break;
18680     }
18681   if (table_id == ~0)
18682     {
18683       errmsg ("missing table id");
18684       return -99;
18685     }
18686
18687   M (IP_MROUTE_DUMP, mp);
18688   mp->table.table_id = table_id;
18689   mp->table.is_ip6 = is_ip6;
18690   S (mp);
18691
18692   /* Use a control ping for synchronization */
18693   MPING (CONTROL_PING, mp_ping);
18694   S (mp_ping);
18695
18696   W (ret);
18697   return ret;
18698 }
18699
18700 static void vl_api_ip_neighbor_details_t_handler
18701   (vl_api_ip_neighbor_details_t * mp)
18702 {
18703   vat_main_t *vam = &vat_main;
18704
18705   print (vam->ofp, "%c %U %U",
18706          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18707          format_vl_api_mac_address, &mp->neighbor.mac_address,
18708          format_vl_api_address, &mp->neighbor.ip_address);
18709 }
18710
18711 static void vl_api_ip_neighbor_details_t_handler_json
18712   (vl_api_ip_neighbor_details_t * mp)
18713 {
18714
18715   vat_main_t *vam = &vat_main;
18716   vat_json_node_t *node;
18717
18718   if (VAT_JSON_ARRAY != vam->json_tree.type)
18719     {
18720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18721       vat_json_init_array (&vam->json_tree);
18722     }
18723   node = vat_json_array_add (&vam->json_tree);
18724
18725   vat_json_init_object (node);
18726   vat_json_object_add_string_copy
18727     (node, "flag",
18728      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18729       (u8 *) "static" : (u8 *) "dynamic"));
18730
18731   vat_json_object_add_string_copy (node, "link_layer",
18732                                    format (0, "%U", format_vl_api_mac_address,
18733                                            &mp->neighbor.mac_address));
18734   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18735 }
18736
18737 static int
18738 api_ip_neighbor_dump (vat_main_t * vam)
18739 {
18740   unformat_input_t *i = vam->input;
18741   vl_api_ip_neighbor_dump_t *mp;
18742   vl_api_control_ping_t *mp_ping;
18743   u8 is_ipv6 = 0;
18744   u32 sw_if_index = ~0;
18745   int ret;
18746
18747   /* Parse args required to build the message */
18748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18749     {
18750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18751         ;
18752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18753         ;
18754       else if (unformat (i, "ip6"))
18755         is_ipv6 = 1;
18756       else
18757         break;
18758     }
18759
18760   if (sw_if_index == ~0)
18761     {
18762       errmsg ("missing interface name or sw_if_index");
18763       return -99;
18764     }
18765
18766   M (IP_NEIGHBOR_DUMP, mp);
18767   mp->is_ipv6 = (u8) is_ipv6;
18768   mp->sw_if_index = ntohl (sw_if_index);
18769   S (mp);
18770
18771   /* Use a control ping for synchronization */
18772   MPING (CONTROL_PING, mp_ping);
18773   S (mp_ping);
18774
18775   W (ret);
18776   return ret;
18777 }
18778
18779 #define vl_api_ip_route_details_t_endian vl_noop_handler
18780 #define vl_api_ip_route_details_t_print vl_noop_handler
18781
18782 static void
18783 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18784 {
18785   vat_main_t *vam = &vat_main;
18786   u8 count = mp->route.n_paths;
18787   vl_api_fib_path_t *fp;
18788   int i;
18789
18790   print (vam->ofp,
18791          "table-id %d, prefix %U/%d",
18792          ntohl (mp->route.table_id),
18793          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18794   for (i = 0; i < count; i++)
18795     {
18796       fp = &mp->route.paths[i];
18797
18798       vl_api_fib_path_print (vam, fp);
18799       fp++;
18800     }
18801 }
18802
18803 static void vl_api_ip_route_details_t_handler_json
18804   (vl_api_ip_route_details_t * mp)
18805 {
18806   vat_main_t *vam = &vat_main;
18807   u8 count = mp->route.n_paths;
18808   vat_json_node_t *node = NULL;
18809   struct in_addr ip4;
18810   struct in6_addr ip6;
18811   vl_api_fib_path_t *fp;
18812   int i;
18813
18814   if (VAT_JSON_ARRAY != vam->json_tree.type)
18815     {
18816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18817       vat_json_init_array (&vam->json_tree);
18818     }
18819   node = vat_json_array_add (&vam->json_tree);
18820
18821   vat_json_init_object (node);
18822   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18823   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18824     {
18825       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18826       vat_json_object_add_ip6 (node, "prefix", ip6);
18827     }
18828   else
18829     {
18830       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18831       vat_json_object_add_ip4 (node, "prefix", ip4);
18832     }
18833   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18834   vat_json_object_add_uint (node, "path_count", count);
18835   for (i = 0; i < count; i++)
18836     {
18837       fp = &mp->route.paths[i];
18838       vl_api_mpls_fib_path_json_print (node, fp);
18839     }
18840 }
18841
18842 static int
18843 api_ip_route_dump (vat_main_t * vam)
18844 {
18845   unformat_input_t *input = vam->input;
18846   vl_api_ip_route_dump_t *mp;
18847   vl_api_control_ping_t *mp_ping;
18848   u32 table_id;
18849   u8 is_ip6;
18850   int ret;
18851
18852   is_ip6 = 0;
18853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18854     {
18855       if (unformat (input, "table_id %d", &table_id))
18856         ;
18857       else if (unformat (input, "ip6"))
18858         is_ip6 = 1;
18859       else if (unformat (input, "ip4"))
18860         is_ip6 = 0;
18861       else
18862         break;
18863     }
18864   if (table_id == ~0)
18865     {
18866       errmsg ("missing table id");
18867       return -99;
18868     }
18869
18870   M (IP_ROUTE_DUMP, mp);
18871
18872   mp->table.table_id = table_id;
18873   mp->table.is_ip6 = is_ip6;
18874
18875   S (mp);
18876
18877   /* Use a control ping for synchronization */
18878   MPING (CONTROL_PING, mp_ping);
18879   S (mp_ping);
18880
18881   W (ret);
18882   return ret;
18883 }
18884
18885 int
18886 api_classify_table_ids (vat_main_t * vam)
18887 {
18888   vl_api_classify_table_ids_t *mp;
18889   int ret;
18890
18891   /* Construct the API message */
18892   M (CLASSIFY_TABLE_IDS, mp);
18893   mp->context = 0;
18894
18895   S (mp);
18896   W (ret);
18897   return ret;
18898 }
18899
18900 int
18901 api_classify_table_by_interface (vat_main_t * vam)
18902 {
18903   unformat_input_t *input = vam->input;
18904   vl_api_classify_table_by_interface_t *mp;
18905
18906   u32 sw_if_index = ~0;
18907   int ret;
18908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18909     {
18910       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18911         ;
18912       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18913         ;
18914       else
18915         break;
18916     }
18917   if (sw_if_index == ~0)
18918     {
18919       errmsg ("missing interface name or sw_if_index");
18920       return -99;
18921     }
18922
18923   /* Construct the API message */
18924   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18925   mp->context = 0;
18926   mp->sw_if_index = ntohl (sw_if_index);
18927
18928   S (mp);
18929   W (ret);
18930   return ret;
18931 }
18932
18933 int
18934 api_classify_table_info (vat_main_t * vam)
18935 {
18936   unformat_input_t *input = vam->input;
18937   vl_api_classify_table_info_t *mp;
18938
18939   u32 table_id = ~0;
18940   int ret;
18941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18942     {
18943       if (unformat (input, "table_id %d", &table_id))
18944         ;
18945       else
18946         break;
18947     }
18948   if (table_id == ~0)
18949     {
18950       errmsg ("missing table id");
18951       return -99;
18952     }
18953
18954   /* Construct the API message */
18955   M (CLASSIFY_TABLE_INFO, mp);
18956   mp->context = 0;
18957   mp->table_id = ntohl (table_id);
18958
18959   S (mp);
18960   W (ret);
18961   return ret;
18962 }
18963
18964 int
18965 api_classify_session_dump (vat_main_t * vam)
18966 {
18967   unformat_input_t *input = vam->input;
18968   vl_api_classify_session_dump_t *mp;
18969   vl_api_control_ping_t *mp_ping;
18970
18971   u32 table_id = ~0;
18972   int ret;
18973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18974     {
18975       if (unformat (input, "table_id %d", &table_id))
18976         ;
18977       else
18978         break;
18979     }
18980   if (table_id == ~0)
18981     {
18982       errmsg ("missing table id");
18983       return -99;
18984     }
18985
18986   /* Construct the API message */
18987   M (CLASSIFY_SESSION_DUMP, mp);
18988   mp->context = 0;
18989   mp->table_id = ntohl (table_id);
18990   S (mp);
18991
18992   /* Use a control ping for synchronization */
18993   MPING (CONTROL_PING, mp_ping);
18994   S (mp_ping);
18995
18996   W (ret);
18997   return ret;
18998 }
18999
19000 static void
19001 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19002 {
19003   vat_main_t *vam = &vat_main;
19004
19005   print (vam->ofp, "collector_address %U, collector_port %d, "
19006          "src_address %U, vrf_id %d, path_mtu %u, "
19007          "template_interval %u, udp_checksum %d",
19008          format_ip4_address, mp->collector_address,
19009          ntohs (mp->collector_port),
19010          format_ip4_address, mp->src_address,
19011          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19012          ntohl (mp->template_interval), mp->udp_checksum);
19013
19014   vam->retval = 0;
19015   vam->result_ready = 1;
19016 }
19017
19018 static void
19019   vl_api_ipfix_exporter_details_t_handler_json
19020   (vl_api_ipfix_exporter_details_t * mp)
19021 {
19022   vat_main_t *vam = &vat_main;
19023   vat_json_node_t node;
19024   struct in_addr collector_address;
19025   struct in_addr src_address;
19026
19027   vat_json_init_object (&node);
19028   clib_memcpy (&collector_address, &mp->collector_address,
19029                sizeof (collector_address));
19030   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19031   vat_json_object_add_uint (&node, "collector_port",
19032                             ntohs (mp->collector_port));
19033   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19034   vat_json_object_add_ip4 (&node, "src_address", src_address);
19035   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19036   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19037   vat_json_object_add_uint (&node, "template_interval",
19038                             ntohl (mp->template_interval));
19039   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19040
19041   vat_json_print (vam->ofp, &node);
19042   vat_json_free (&node);
19043   vam->retval = 0;
19044   vam->result_ready = 1;
19045 }
19046
19047 int
19048 api_ipfix_exporter_dump (vat_main_t * vam)
19049 {
19050   vl_api_ipfix_exporter_dump_t *mp;
19051   int ret;
19052
19053   /* Construct the API message */
19054   M (IPFIX_EXPORTER_DUMP, mp);
19055   mp->context = 0;
19056
19057   S (mp);
19058   W (ret);
19059   return ret;
19060 }
19061
19062 static int
19063 api_ipfix_classify_stream_dump (vat_main_t * vam)
19064 {
19065   vl_api_ipfix_classify_stream_dump_t *mp;
19066   int ret;
19067
19068   /* Construct the API message */
19069   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19070   mp->context = 0;
19071
19072   S (mp);
19073   W (ret);
19074   return ret;
19075   /* NOTREACHED */
19076   return 0;
19077 }
19078
19079 static void
19080   vl_api_ipfix_classify_stream_details_t_handler
19081   (vl_api_ipfix_classify_stream_details_t * mp)
19082 {
19083   vat_main_t *vam = &vat_main;
19084   print (vam->ofp, "domain_id %d, src_port %d",
19085          ntohl (mp->domain_id), ntohs (mp->src_port));
19086   vam->retval = 0;
19087   vam->result_ready = 1;
19088 }
19089
19090 static void
19091   vl_api_ipfix_classify_stream_details_t_handler_json
19092   (vl_api_ipfix_classify_stream_details_t * mp)
19093 {
19094   vat_main_t *vam = &vat_main;
19095   vat_json_node_t node;
19096
19097   vat_json_init_object (&node);
19098   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19099   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19100
19101   vat_json_print (vam->ofp, &node);
19102   vat_json_free (&node);
19103   vam->retval = 0;
19104   vam->result_ready = 1;
19105 }
19106
19107 static int
19108 api_ipfix_classify_table_dump (vat_main_t * vam)
19109 {
19110   vl_api_ipfix_classify_table_dump_t *mp;
19111   vl_api_control_ping_t *mp_ping;
19112   int ret;
19113
19114   if (!vam->json_output)
19115     {
19116       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19117              "transport_protocol");
19118     }
19119
19120   /* Construct the API message */
19121   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19122
19123   /* send it... */
19124   S (mp);
19125
19126   /* Use a control ping for synchronization */
19127   MPING (CONTROL_PING, mp_ping);
19128   S (mp_ping);
19129
19130   W (ret);
19131   return ret;
19132 }
19133
19134 static void
19135   vl_api_ipfix_classify_table_details_t_handler
19136   (vl_api_ipfix_classify_table_details_t * mp)
19137 {
19138   vat_main_t *vam = &vat_main;
19139   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19140          mp->transport_protocol);
19141 }
19142
19143 static void
19144   vl_api_ipfix_classify_table_details_t_handler_json
19145   (vl_api_ipfix_classify_table_details_t * mp)
19146 {
19147   vat_json_node_t *node = NULL;
19148   vat_main_t *vam = &vat_main;
19149
19150   if (VAT_JSON_ARRAY != vam->json_tree.type)
19151     {
19152       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19153       vat_json_init_array (&vam->json_tree);
19154     }
19155
19156   node = vat_json_array_add (&vam->json_tree);
19157   vat_json_init_object (node);
19158
19159   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19160   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19161   vat_json_object_add_uint (node, "transport_protocol",
19162                             mp->transport_protocol);
19163 }
19164
19165 static int
19166 api_sw_interface_span_enable_disable (vat_main_t * vam)
19167 {
19168   unformat_input_t *i = vam->input;
19169   vl_api_sw_interface_span_enable_disable_t *mp;
19170   u32 src_sw_if_index = ~0;
19171   u32 dst_sw_if_index = ~0;
19172   u8 state = 3;
19173   int ret;
19174   u8 is_l2 = 0;
19175
19176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19177     {
19178       if (unformat
19179           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19180         ;
19181       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19182         ;
19183       else
19184         if (unformat
19185             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19186         ;
19187       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19188         ;
19189       else if (unformat (i, "disable"))
19190         state = 0;
19191       else if (unformat (i, "rx"))
19192         state = 1;
19193       else if (unformat (i, "tx"))
19194         state = 2;
19195       else if (unformat (i, "both"))
19196         state = 3;
19197       else if (unformat (i, "l2"))
19198         is_l2 = 1;
19199       else
19200         break;
19201     }
19202
19203   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19204
19205   mp->sw_if_index_from = htonl (src_sw_if_index);
19206   mp->sw_if_index_to = htonl (dst_sw_if_index);
19207   mp->state = state;
19208   mp->is_l2 = is_l2;
19209
19210   S (mp);
19211   W (ret);
19212   return ret;
19213 }
19214
19215 static void
19216 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19217                                             * mp)
19218 {
19219   vat_main_t *vam = &vat_main;
19220   u8 *sw_if_from_name = 0;
19221   u8 *sw_if_to_name = 0;
19222   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19223   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19224   char *states[] = { "none", "rx", "tx", "both" };
19225   hash_pair_t *p;
19226
19227   /* *INDENT-OFF* */
19228   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19229   ({
19230     if ((u32) p->value[0] == sw_if_index_from)
19231       {
19232         sw_if_from_name = (u8 *)(p->key);
19233         if (sw_if_to_name)
19234           break;
19235       }
19236     if ((u32) p->value[0] == sw_if_index_to)
19237       {
19238         sw_if_to_name = (u8 *)(p->key);
19239         if (sw_if_from_name)
19240           break;
19241       }
19242   }));
19243   /* *INDENT-ON* */
19244   print (vam->ofp, "%20s => %20s (%s) %s",
19245          sw_if_from_name, sw_if_to_name, states[mp->state],
19246          mp->is_l2 ? "l2" : "device");
19247 }
19248
19249 static void
19250   vl_api_sw_interface_span_details_t_handler_json
19251   (vl_api_sw_interface_span_details_t * mp)
19252 {
19253   vat_main_t *vam = &vat_main;
19254   vat_json_node_t *node = NULL;
19255   u8 *sw_if_from_name = 0;
19256   u8 *sw_if_to_name = 0;
19257   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19258   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19259   hash_pair_t *p;
19260
19261   /* *INDENT-OFF* */
19262   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19263   ({
19264     if ((u32) p->value[0] == sw_if_index_from)
19265       {
19266         sw_if_from_name = (u8 *)(p->key);
19267         if (sw_if_to_name)
19268           break;
19269       }
19270     if ((u32) p->value[0] == sw_if_index_to)
19271       {
19272         sw_if_to_name = (u8 *)(p->key);
19273         if (sw_if_from_name)
19274           break;
19275       }
19276   }));
19277   /* *INDENT-ON* */
19278
19279   if (VAT_JSON_ARRAY != vam->json_tree.type)
19280     {
19281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19282       vat_json_init_array (&vam->json_tree);
19283     }
19284   node = vat_json_array_add (&vam->json_tree);
19285
19286   vat_json_init_object (node);
19287   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19288   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19289   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19290   if (0 != sw_if_to_name)
19291     {
19292       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19293     }
19294   vat_json_object_add_uint (node, "state", mp->state);
19295   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19296 }
19297
19298 static int
19299 api_sw_interface_span_dump (vat_main_t * vam)
19300 {
19301   unformat_input_t *input = vam->input;
19302   vl_api_sw_interface_span_dump_t *mp;
19303   vl_api_control_ping_t *mp_ping;
19304   u8 is_l2 = 0;
19305   int ret;
19306
19307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19308     {
19309       if (unformat (input, "l2"))
19310         is_l2 = 1;
19311       else
19312         break;
19313     }
19314
19315   M (SW_INTERFACE_SPAN_DUMP, mp);
19316   mp->is_l2 = is_l2;
19317   S (mp);
19318
19319   /* Use a control ping for synchronization */
19320   MPING (CONTROL_PING, mp_ping);
19321   S (mp_ping);
19322
19323   W (ret);
19324   return ret;
19325 }
19326
19327 int
19328 api_pg_create_interface (vat_main_t * vam)
19329 {
19330   unformat_input_t *input = vam->input;
19331   vl_api_pg_create_interface_t *mp;
19332
19333   u32 if_id = ~0, gso_size = 0;
19334   u8 gso_enabled = 0;
19335   int ret;
19336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19337     {
19338       if (unformat (input, "if_id %d", &if_id))
19339         ;
19340       else if (unformat (input, "gso-enabled"))
19341         {
19342           gso_enabled = 1;
19343           if (unformat (input, "gso-size %u", &gso_size))
19344             ;
19345           else
19346             {
19347               errmsg ("missing gso-size");
19348               return -99;
19349             }
19350         }
19351       else
19352         break;
19353     }
19354   if (if_id == ~0)
19355     {
19356       errmsg ("missing pg interface index");
19357       return -99;
19358     }
19359
19360   /* Construct the API message */
19361   M (PG_CREATE_INTERFACE, mp);
19362   mp->context = 0;
19363   mp->interface_id = ntohl (if_id);
19364   mp->gso_enabled = gso_enabled;
19365
19366   S (mp);
19367   W (ret);
19368   return ret;
19369 }
19370
19371 int
19372 api_pg_capture (vat_main_t * vam)
19373 {
19374   unformat_input_t *input = vam->input;
19375   vl_api_pg_capture_t *mp;
19376
19377   u32 if_id = ~0;
19378   u8 enable = 1;
19379   u32 count = 1;
19380   u8 pcap_file_set = 0;
19381   u8 *pcap_file = 0;
19382   int ret;
19383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19384     {
19385       if (unformat (input, "if_id %d", &if_id))
19386         ;
19387       else if (unformat (input, "pcap %s", &pcap_file))
19388         pcap_file_set = 1;
19389       else if (unformat (input, "count %d", &count))
19390         ;
19391       else if (unformat (input, "disable"))
19392         enable = 0;
19393       else
19394         break;
19395     }
19396   if (if_id == ~0)
19397     {
19398       errmsg ("missing pg interface index");
19399       return -99;
19400     }
19401   if (pcap_file_set > 0)
19402     {
19403       if (vec_len (pcap_file) > 255)
19404         {
19405           errmsg ("pcap file name is too long");
19406           return -99;
19407         }
19408     }
19409
19410   u32 name_len = vec_len (pcap_file);
19411   /* Construct the API message */
19412   M (PG_CAPTURE, mp);
19413   mp->context = 0;
19414   mp->interface_id = ntohl (if_id);
19415   mp->is_enabled = enable;
19416   mp->count = ntohl (count);
19417   mp->pcap_name_length = ntohl (name_len);
19418   if (pcap_file_set != 0)
19419     {
19420       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19421     }
19422   vec_free (pcap_file);
19423
19424   S (mp);
19425   W (ret);
19426   return ret;
19427 }
19428
19429 int
19430 api_pg_enable_disable (vat_main_t * vam)
19431 {
19432   unformat_input_t *input = vam->input;
19433   vl_api_pg_enable_disable_t *mp;
19434
19435   u8 enable = 1;
19436   u8 stream_name_set = 0;
19437   u8 *stream_name = 0;
19438   int ret;
19439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19440     {
19441       if (unformat (input, "stream %s", &stream_name))
19442         stream_name_set = 1;
19443       else if (unformat (input, "disable"))
19444         enable = 0;
19445       else
19446         break;
19447     }
19448
19449   if (stream_name_set > 0)
19450     {
19451       if (vec_len (stream_name) > 255)
19452         {
19453           errmsg ("stream name too long");
19454           return -99;
19455         }
19456     }
19457
19458   u32 name_len = vec_len (stream_name);
19459   /* Construct the API message */
19460   M (PG_ENABLE_DISABLE, mp);
19461   mp->context = 0;
19462   mp->is_enabled = enable;
19463   if (stream_name_set != 0)
19464     {
19465       mp->stream_name_length = ntohl (name_len);
19466       clib_memcpy (mp->stream_name, stream_name, name_len);
19467     }
19468   vec_free (stream_name);
19469
19470   S (mp);
19471   W (ret);
19472   return ret;
19473 }
19474
19475 int
19476 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19477 {
19478   unformat_input_t *input = vam->input;
19479   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19480
19481   u16 *low_ports = 0;
19482   u16 *high_ports = 0;
19483   u16 this_low;
19484   u16 this_hi;
19485   vl_api_prefix_t prefix;
19486   u32 tmp, tmp2;
19487   u8 prefix_set = 0;
19488   u32 vrf_id = ~0;
19489   u8 is_add = 1;
19490   int ret;
19491
19492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19493     {
19494       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19495         prefix_set = 1;
19496       else if (unformat (input, "vrf %d", &vrf_id))
19497         ;
19498       else if (unformat (input, "del"))
19499         is_add = 0;
19500       else if (unformat (input, "port %d", &tmp))
19501         {
19502           if (tmp == 0 || tmp > 65535)
19503             {
19504               errmsg ("port %d out of range", tmp);
19505               return -99;
19506             }
19507           this_low = tmp;
19508           this_hi = this_low + 1;
19509           vec_add1 (low_ports, this_low);
19510           vec_add1 (high_ports, this_hi);
19511         }
19512       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19513         {
19514           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19515             {
19516               errmsg ("incorrect range parameters");
19517               return -99;
19518             }
19519           this_low = tmp;
19520           /* Note: in debug CLI +1 is added to high before
19521              passing to real fn that does "the work"
19522              (ip_source_and_port_range_check_add_del).
19523              This fn is a wrapper around the binary API fn a
19524              control plane will call, which expects this increment
19525              to have occurred. Hence letting the binary API control
19526              plane fn do the increment for consistency between VAT
19527              and other control planes.
19528            */
19529           this_hi = tmp2;
19530           vec_add1 (low_ports, this_low);
19531           vec_add1 (high_ports, this_hi);
19532         }
19533       else
19534         break;
19535     }
19536
19537   if (prefix_set == 0)
19538     {
19539       errmsg ("<address>/<mask> not specified");
19540       return -99;
19541     }
19542
19543   if (vrf_id == ~0)
19544     {
19545       errmsg ("VRF ID required, not specified");
19546       return -99;
19547     }
19548
19549   if (vrf_id == 0)
19550     {
19551       errmsg
19552         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19553       return -99;
19554     }
19555
19556   if (vec_len (low_ports) == 0)
19557     {
19558       errmsg ("At least one port or port range required");
19559       return -99;
19560     }
19561
19562   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19563
19564   mp->is_add = is_add;
19565
19566   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19567
19568   mp->number_of_ranges = vec_len (low_ports);
19569
19570   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19571   vec_free (low_ports);
19572
19573   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19574   vec_free (high_ports);
19575
19576   mp->vrf_id = ntohl (vrf_id);
19577
19578   S (mp);
19579   W (ret);
19580   return ret;
19581 }
19582
19583 int
19584 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19585 {
19586   unformat_input_t *input = vam->input;
19587   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19588   u32 sw_if_index = ~0;
19589   int vrf_set = 0;
19590   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19591   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19592   u8 is_add = 1;
19593   int ret;
19594
19595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19596     {
19597       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19598         ;
19599       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19600         ;
19601       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19602         vrf_set = 1;
19603       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19604         vrf_set = 1;
19605       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19606         vrf_set = 1;
19607       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19608         vrf_set = 1;
19609       else if (unformat (input, "del"))
19610         is_add = 0;
19611       else
19612         break;
19613     }
19614
19615   if (sw_if_index == ~0)
19616     {
19617       errmsg ("Interface required but not specified");
19618       return -99;
19619     }
19620
19621   if (vrf_set == 0)
19622     {
19623       errmsg ("VRF ID required but not specified");
19624       return -99;
19625     }
19626
19627   if (tcp_out_vrf_id == 0
19628       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19629     {
19630       errmsg
19631         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19632       return -99;
19633     }
19634
19635   /* Construct the API message */
19636   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19637
19638   mp->sw_if_index = ntohl (sw_if_index);
19639   mp->is_add = is_add;
19640   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19641   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19642   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19643   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19644
19645   /* send it... */
19646   S (mp);
19647
19648   /* Wait for a reply... */
19649   W (ret);
19650   return ret;
19651 }
19652
19653 static int
19654 api_set_punt (vat_main_t * vam)
19655 {
19656   unformat_input_t *i = vam->input;
19657   vl_api_address_family_t af;
19658   vl_api_set_punt_t *mp;
19659   u32 protocol = ~0;
19660   u32 port = ~0;
19661   int is_add = 1;
19662   int ret;
19663
19664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19665     {
19666       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19667         ;
19668       else if (unformat (i, "protocol %d", &protocol))
19669         ;
19670       else if (unformat (i, "port %d", &port))
19671         ;
19672       else if (unformat (i, "del"))
19673         is_add = 0;
19674       else
19675         {
19676           clib_warning ("parse error '%U'", format_unformat_error, i);
19677           return -99;
19678         }
19679     }
19680
19681   M (SET_PUNT, mp);
19682
19683   mp->is_add = (u8) is_add;
19684   mp->punt.type = PUNT_API_TYPE_L4;
19685   mp->punt.punt.l4.af = af;
19686   mp->punt.punt.l4.protocol = (u8) protocol;
19687   mp->punt.punt.l4.port = htons ((u16) port);
19688
19689   S (mp);
19690   W (ret);
19691   return ret;
19692 }
19693
19694 static int
19695 api_delete_subif (vat_main_t * vam)
19696 {
19697   unformat_input_t *i = vam->input;
19698   vl_api_delete_subif_t *mp;
19699   u32 sw_if_index = ~0;
19700   int ret;
19701
19702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19703     {
19704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19705         ;
19706       if (unformat (i, "sw_if_index %d", &sw_if_index))
19707         ;
19708       else
19709         break;
19710     }
19711
19712   if (sw_if_index == ~0)
19713     {
19714       errmsg ("missing sw_if_index");
19715       return -99;
19716     }
19717
19718   /* Construct the API message */
19719   M (DELETE_SUBIF, mp);
19720   mp->sw_if_index = ntohl (sw_if_index);
19721
19722   S (mp);
19723   W (ret);
19724   return ret;
19725 }
19726
19727 #define foreach_pbb_vtr_op      \
19728 _("disable",  L2_VTR_DISABLED)  \
19729 _("pop",  L2_VTR_POP_2)         \
19730 _("push",  L2_VTR_PUSH_2)
19731
19732 static int
19733 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19734 {
19735   unformat_input_t *i = vam->input;
19736   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19737   u32 sw_if_index = ~0, vtr_op = ~0;
19738   u16 outer_tag = ~0;
19739   u8 dmac[6], smac[6];
19740   u8 dmac_set = 0, smac_set = 0;
19741   u16 vlanid = 0;
19742   u32 sid = ~0;
19743   u32 tmp;
19744   int ret;
19745
19746   /* Shut up coverity */
19747   clib_memset (dmac, 0, sizeof (dmac));
19748   clib_memset (smac, 0, sizeof (smac));
19749
19750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19751     {
19752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19753         ;
19754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19755         ;
19756       else if (unformat (i, "vtr_op %d", &vtr_op))
19757         ;
19758 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19759       foreach_pbb_vtr_op
19760 #undef _
19761         else if (unformat (i, "translate_pbb_stag"))
19762         {
19763           if (unformat (i, "%d", &tmp))
19764             {
19765               vtr_op = L2_VTR_TRANSLATE_2_1;
19766               outer_tag = tmp;
19767             }
19768           else
19769             {
19770               errmsg
19771                 ("translate_pbb_stag operation requires outer tag definition");
19772               return -99;
19773             }
19774         }
19775       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19776         dmac_set++;
19777       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19778         smac_set++;
19779       else if (unformat (i, "sid %d", &sid))
19780         ;
19781       else if (unformat (i, "vlanid %d", &tmp))
19782         vlanid = tmp;
19783       else
19784         {
19785           clib_warning ("parse error '%U'", format_unformat_error, i);
19786           return -99;
19787         }
19788     }
19789
19790   if ((sw_if_index == ~0) || (vtr_op == ~0))
19791     {
19792       errmsg ("missing sw_if_index or vtr operation");
19793       return -99;
19794     }
19795   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19796       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19797     {
19798       errmsg
19799         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19800       return -99;
19801     }
19802
19803   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19804   mp->sw_if_index = ntohl (sw_if_index);
19805   mp->vtr_op = ntohl (vtr_op);
19806   mp->outer_tag = ntohs (outer_tag);
19807   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19808   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19809   mp->b_vlanid = ntohs (vlanid);
19810   mp->i_sid = ntohl (sid);
19811
19812   S (mp);
19813   W (ret);
19814   return ret;
19815 }
19816
19817 static int
19818 api_flow_classify_set_interface (vat_main_t * vam)
19819 {
19820   unformat_input_t *i = vam->input;
19821   vl_api_flow_classify_set_interface_t *mp;
19822   u32 sw_if_index;
19823   int sw_if_index_set;
19824   u32 ip4_table_index = ~0;
19825   u32 ip6_table_index = ~0;
19826   u8 is_add = 1;
19827   int ret;
19828
19829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19830     {
19831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19832         sw_if_index_set = 1;
19833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19834         sw_if_index_set = 1;
19835       else if (unformat (i, "del"))
19836         is_add = 0;
19837       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19838         ;
19839       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19840         ;
19841       else
19842         {
19843           clib_warning ("parse error '%U'", format_unformat_error, i);
19844           return -99;
19845         }
19846     }
19847
19848   if (sw_if_index_set == 0)
19849     {
19850       errmsg ("missing interface name or sw_if_index");
19851       return -99;
19852     }
19853
19854   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19855
19856   mp->sw_if_index = ntohl (sw_if_index);
19857   mp->ip4_table_index = ntohl (ip4_table_index);
19858   mp->ip6_table_index = ntohl (ip6_table_index);
19859   mp->is_add = is_add;
19860
19861   S (mp);
19862   W (ret);
19863   return ret;
19864 }
19865
19866 static int
19867 api_flow_classify_dump (vat_main_t * vam)
19868 {
19869   unformat_input_t *i = vam->input;
19870   vl_api_flow_classify_dump_t *mp;
19871   vl_api_control_ping_t *mp_ping;
19872   u8 type = FLOW_CLASSIFY_N_TABLES;
19873   int ret;
19874
19875   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19876     ;
19877   else
19878     {
19879       errmsg ("classify table type must be specified");
19880       return -99;
19881     }
19882
19883   if (!vam->json_output)
19884     {
19885       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19886     }
19887
19888   M (FLOW_CLASSIFY_DUMP, mp);
19889   mp->type = type;
19890   /* send it... */
19891   S (mp);
19892
19893   /* Use a control ping for synchronization */
19894   MPING (CONTROL_PING, mp_ping);
19895   S (mp_ping);
19896
19897   /* Wait for a reply... */
19898   W (ret);
19899   return ret;
19900 }
19901
19902 static int
19903 api_feature_enable_disable (vat_main_t * vam)
19904 {
19905   unformat_input_t *i = vam->input;
19906   vl_api_feature_enable_disable_t *mp;
19907   u8 *arc_name = 0;
19908   u8 *feature_name = 0;
19909   u32 sw_if_index = ~0;
19910   u8 enable = 1;
19911   int ret;
19912
19913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19914     {
19915       if (unformat (i, "arc_name %s", &arc_name))
19916         ;
19917       else if (unformat (i, "feature_name %s", &feature_name))
19918         ;
19919       else
19920         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19921         ;
19922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19923         ;
19924       else if (unformat (i, "disable"))
19925         enable = 0;
19926       else
19927         break;
19928     }
19929
19930   if (arc_name == 0)
19931     {
19932       errmsg ("missing arc name");
19933       return -99;
19934     }
19935   if (vec_len (arc_name) > 63)
19936     {
19937       errmsg ("arc name too long");
19938     }
19939
19940   if (feature_name == 0)
19941     {
19942       errmsg ("missing feature name");
19943       return -99;
19944     }
19945   if (vec_len (feature_name) > 63)
19946     {
19947       errmsg ("feature name too long");
19948     }
19949
19950   if (sw_if_index == ~0)
19951     {
19952       errmsg ("missing interface name or sw_if_index");
19953       return -99;
19954     }
19955
19956   /* Construct the API message */
19957   M (FEATURE_ENABLE_DISABLE, mp);
19958   mp->sw_if_index = ntohl (sw_if_index);
19959   mp->enable = enable;
19960   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19961   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19962   vec_free (arc_name);
19963   vec_free (feature_name);
19964
19965   S (mp);
19966   W (ret);
19967   return ret;
19968 }
19969
19970 static int
19971 api_feature_gso_enable_disable (vat_main_t * vam)
19972 {
19973   unformat_input_t *i = vam->input;
19974   vl_api_feature_gso_enable_disable_t *mp;
19975   u32 sw_if_index = ~0;
19976   u8 enable = 1;
19977   int ret;
19978
19979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19980     {
19981       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19982         ;
19983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19984         ;
19985       else if (unformat (i, "enable"))
19986         enable = 1;
19987       else if (unformat (i, "disable"))
19988         enable = 0;
19989       else
19990         break;
19991     }
19992
19993   if (sw_if_index == ~0)
19994     {
19995       errmsg ("missing interface name or sw_if_index");
19996       return -99;
19997     }
19998
19999   /* Construct the API message */
20000   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20001   mp->sw_if_index = ntohl (sw_if_index);
20002   mp->enable_disable = enable;
20003
20004   S (mp);
20005   W (ret);
20006   return ret;
20007 }
20008
20009 static int
20010 api_sw_interface_tag_add_del (vat_main_t * vam)
20011 {
20012   unformat_input_t *i = vam->input;
20013   vl_api_sw_interface_tag_add_del_t *mp;
20014   u32 sw_if_index = ~0;
20015   u8 *tag = 0;
20016   u8 enable = 1;
20017   int ret;
20018
20019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20020     {
20021       if (unformat (i, "tag %s", &tag))
20022         ;
20023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20024         ;
20025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20026         ;
20027       else if (unformat (i, "del"))
20028         enable = 0;
20029       else
20030         break;
20031     }
20032
20033   if (sw_if_index == ~0)
20034     {
20035       errmsg ("missing interface name or sw_if_index");
20036       return -99;
20037     }
20038
20039   if (enable && (tag == 0))
20040     {
20041       errmsg ("no tag specified");
20042       return -99;
20043     }
20044
20045   /* Construct the API message */
20046   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20047   mp->sw_if_index = ntohl (sw_if_index);
20048   mp->is_add = enable;
20049   if (enable)
20050     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20051   vec_free (tag);
20052
20053   S (mp);
20054   W (ret);
20055   return ret;
20056 }
20057
20058 static int
20059 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20060 {
20061   unformat_input_t *i = vam->input;
20062   vl_api_mac_address_t mac = { 0 };
20063   vl_api_sw_interface_add_del_mac_address_t *mp;
20064   u32 sw_if_index = ~0;
20065   u8 is_add = 1;
20066   u8 mac_set = 0;
20067   int ret;
20068
20069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20070     {
20071       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20072         ;
20073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20074         ;
20075       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20076         mac_set++;
20077       else if (unformat (i, "del"))
20078         is_add = 0;
20079       else
20080         break;
20081     }
20082
20083   if (sw_if_index == ~0)
20084     {
20085       errmsg ("missing interface name or sw_if_index");
20086       return -99;
20087     }
20088
20089   if (!mac_set)
20090     {
20091       errmsg ("missing MAC address");
20092       return -99;
20093     }
20094
20095   /* Construct the API message */
20096   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20097   mp->sw_if_index = ntohl (sw_if_index);
20098   mp->is_add = is_add;
20099   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20100
20101   S (mp);
20102   W (ret);
20103   return ret;
20104 }
20105
20106 static void vl_api_l2_xconnect_details_t_handler
20107   (vl_api_l2_xconnect_details_t * mp)
20108 {
20109   vat_main_t *vam = &vat_main;
20110
20111   print (vam->ofp, "%15d%15d",
20112          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20113 }
20114
20115 static void vl_api_l2_xconnect_details_t_handler_json
20116   (vl_api_l2_xconnect_details_t * mp)
20117 {
20118   vat_main_t *vam = &vat_main;
20119   vat_json_node_t *node = NULL;
20120
20121   if (VAT_JSON_ARRAY != vam->json_tree.type)
20122     {
20123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20124       vat_json_init_array (&vam->json_tree);
20125     }
20126   node = vat_json_array_add (&vam->json_tree);
20127
20128   vat_json_init_object (node);
20129   vat_json_object_add_uint (node, "rx_sw_if_index",
20130                             ntohl (mp->rx_sw_if_index));
20131   vat_json_object_add_uint (node, "tx_sw_if_index",
20132                             ntohl (mp->tx_sw_if_index));
20133 }
20134
20135 static int
20136 api_l2_xconnect_dump (vat_main_t * vam)
20137 {
20138   vl_api_l2_xconnect_dump_t *mp;
20139   vl_api_control_ping_t *mp_ping;
20140   int ret;
20141
20142   if (!vam->json_output)
20143     {
20144       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20145     }
20146
20147   M (L2_XCONNECT_DUMP, mp);
20148
20149   S (mp);
20150
20151   /* Use a control ping for synchronization */
20152   MPING (CONTROL_PING, mp_ping);
20153   S (mp_ping);
20154
20155   W (ret);
20156   return ret;
20157 }
20158
20159 static int
20160 api_hw_interface_set_mtu (vat_main_t * vam)
20161 {
20162   unformat_input_t *i = vam->input;
20163   vl_api_hw_interface_set_mtu_t *mp;
20164   u32 sw_if_index = ~0;
20165   u32 mtu = 0;
20166   int ret;
20167
20168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20169     {
20170       if (unformat (i, "mtu %d", &mtu))
20171         ;
20172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20173         ;
20174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20175         ;
20176       else
20177         break;
20178     }
20179
20180   if (sw_if_index == ~0)
20181     {
20182       errmsg ("missing interface name or sw_if_index");
20183       return -99;
20184     }
20185
20186   if (mtu == 0)
20187     {
20188       errmsg ("no mtu specified");
20189       return -99;
20190     }
20191
20192   /* Construct the API message */
20193   M (HW_INTERFACE_SET_MTU, mp);
20194   mp->sw_if_index = ntohl (sw_if_index);
20195   mp->mtu = ntohs ((u16) mtu);
20196
20197   S (mp);
20198   W (ret);
20199   return ret;
20200 }
20201
20202 static int
20203 api_p2p_ethernet_add (vat_main_t * vam)
20204 {
20205   unformat_input_t *i = vam->input;
20206   vl_api_p2p_ethernet_add_t *mp;
20207   u32 parent_if_index = ~0;
20208   u32 sub_id = ~0;
20209   u8 remote_mac[6];
20210   u8 mac_set = 0;
20211   int ret;
20212
20213   clib_memset (remote_mac, 0, sizeof (remote_mac));
20214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20215     {
20216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20217         ;
20218       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20219         ;
20220       else
20221         if (unformat
20222             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20223         mac_set++;
20224       else if (unformat (i, "sub_id %d", &sub_id))
20225         ;
20226       else
20227         {
20228           clib_warning ("parse error '%U'", format_unformat_error, i);
20229           return -99;
20230         }
20231     }
20232
20233   if (parent_if_index == ~0)
20234     {
20235       errmsg ("missing interface name or sw_if_index");
20236       return -99;
20237     }
20238   if (mac_set == 0)
20239     {
20240       errmsg ("missing remote mac address");
20241       return -99;
20242     }
20243   if (sub_id == ~0)
20244     {
20245       errmsg ("missing sub-interface id");
20246       return -99;
20247     }
20248
20249   M (P2P_ETHERNET_ADD, mp);
20250   mp->parent_if_index = ntohl (parent_if_index);
20251   mp->subif_id = ntohl (sub_id);
20252   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20253
20254   S (mp);
20255   W (ret);
20256   return ret;
20257 }
20258
20259 static int
20260 api_p2p_ethernet_del (vat_main_t * vam)
20261 {
20262   unformat_input_t *i = vam->input;
20263   vl_api_p2p_ethernet_del_t *mp;
20264   u32 parent_if_index = ~0;
20265   u8 remote_mac[6];
20266   u8 mac_set = 0;
20267   int ret;
20268
20269   clib_memset (remote_mac, 0, sizeof (remote_mac));
20270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20271     {
20272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20273         ;
20274       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20275         ;
20276       else
20277         if (unformat
20278             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20279         mac_set++;
20280       else
20281         {
20282           clib_warning ("parse error '%U'", format_unformat_error, i);
20283           return -99;
20284         }
20285     }
20286
20287   if (parent_if_index == ~0)
20288     {
20289       errmsg ("missing interface name or sw_if_index");
20290       return -99;
20291     }
20292   if (mac_set == 0)
20293     {
20294       errmsg ("missing remote mac address");
20295       return -99;
20296     }
20297
20298   M (P2P_ETHERNET_DEL, mp);
20299   mp->parent_if_index = ntohl (parent_if_index);
20300   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20301
20302   S (mp);
20303   W (ret);
20304   return ret;
20305 }
20306
20307 static int
20308 api_lldp_config (vat_main_t * vam)
20309 {
20310   unformat_input_t *i = vam->input;
20311   vl_api_lldp_config_t *mp;
20312   int tx_hold = 0;
20313   int tx_interval = 0;
20314   u8 *sys_name = NULL;
20315   int ret;
20316
20317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20318     {
20319       if (unformat (i, "system-name %s", &sys_name))
20320         ;
20321       else if (unformat (i, "tx-hold %d", &tx_hold))
20322         ;
20323       else if (unformat (i, "tx-interval %d", &tx_interval))
20324         ;
20325       else
20326         {
20327           clib_warning ("parse error '%U'", format_unformat_error, i);
20328           return -99;
20329         }
20330     }
20331
20332   vec_add1 (sys_name, 0);
20333
20334   M (LLDP_CONFIG, mp);
20335   mp->tx_hold = htonl (tx_hold);
20336   mp->tx_interval = htonl (tx_interval);
20337   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20338   vec_free (sys_name);
20339
20340   S (mp);
20341   W (ret);
20342   return ret;
20343 }
20344
20345 static int
20346 api_sw_interface_set_lldp (vat_main_t * vam)
20347 {
20348   unformat_input_t *i = vam->input;
20349   vl_api_sw_interface_set_lldp_t *mp;
20350   u32 sw_if_index = ~0;
20351   u32 enable = 1;
20352   u8 *port_desc = NULL, *mgmt_oid = NULL;
20353   ip4_address_t ip4_addr;
20354   ip6_address_t ip6_addr;
20355   int ret;
20356
20357   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20358   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20359
20360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20361     {
20362       if (unformat (i, "disable"))
20363         enable = 0;
20364       else
20365         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20366         ;
20367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20368         ;
20369       else if (unformat (i, "port-desc %s", &port_desc))
20370         ;
20371       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20372         ;
20373       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20374         ;
20375       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20376         ;
20377       else
20378         break;
20379     }
20380
20381   if (sw_if_index == ~0)
20382     {
20383       errmsg ("missing interface name or sw_if_index");
20384       return -99;
20385     }
20386
20387   /* Construct the API message */
20388   vec_add1 (port_desc, 0);
20389   vec_add1 (mgmt_oid, 0);
20390   M (SW_INTERFACE_SET_LLDP, mp);
20391   mp->sw_if_index = ntohl (sw_if_index);
20392   mp->enable = enable;
20393   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20394   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20395   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20396   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20397   vec_free (port_desc);
20398   vec_free (mgmt_oid);
20399
20400   S (mp);
20401   W (ret);
20402   return ret;
20403 }
20404
20405 static int
20406 api_tcp_configure_src_addresses (vat_main_t * vam)
20407 {
20408   vl_api_tcp_configure_src_addresses_t *mp;
20409   unformat_input_t *i = vam->input;
20410   ip4_address_t v4first, v4last;
20411   ip6_address_t v6first, v6last;
20412   u8 range_set = 0;
20413   u32 vrf_id = 0;
20414   int ret;
20415
20416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20417     {
20418       if (unformat (i, "%U - %U",
20419                     unformat_ip4_address, &v4first,
20420                     unformat_ip4_address, &v4last))
20421         {
20422           if (range_set)
20423             {
20424               errmsg ("one range per message (range already set)");
20425               return -99;
20426             }
20427           range_set = 1;
20428         }
20429       else if (unformat (i, "%U - %U",
20430                          unformat_ip6_address, &v6first,
20431                          unformat_ip6_address, &v6last))
20432         {
20433           if (range_set)
20434             {
20435               errmsg ("one range per message (range already set)");
20436               return -99;
20437             }
20438           range_set = 2;
20439         }
20440       else if (unformat (i, "vrf %d", &vrf_id))
20441         ;
20442       else
20443         break;
20444     }
20445
20446   if (range_set == 0)
20447     {
20448       errmsg ("address range not set");
20449       return -99;
20450     }
20451
20452   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20453   mp->vrf_id = ntohl (vrf_id);
20454   /* ipv6? */
20455   if (range_set == 2)
20456     {
20457       mp->is_ipv6 = 1;
20458       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20459       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20460     }
20461   else
20462     {
20463       mp->is_ipv6 = 0;
20464       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20465       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20466     }
20467   S (mp);
20468   W (ret);
20469   return ret;
20470 }
20471
20472 static void vl_api_app_namespace_add_del_reply_t_handler
20473   (vl_api_app_namespace_add_del_reply_t * mp)
20474 {
20475   vat_main_t *vam = &vat_main;
20476   i32 retval = ntohl (mp->retval);
20477   if (vam->async_mode)
20478     {
20479       vam->async_errors += (retval < 0);
20480     }
20481   else
20482     {
20483       vam->retval = retval;
20484       if (retval == 0)
20485         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20486       vam->result_ready = 1;
20487     }
20488 }
20489
20490 static void vl_api_app_namespace_add_del_reply_t_handler_json
20491   (vl_api_app_namespace_add_del_reply_t * mp)
20492 {
20493   vat_main_t *vam = &vat_main;
20494   vat_json_node_t node;
20495
20496   vat_json_init_object (&node);
20497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20498   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20499
20500   vat_json_print (vam->ofp, &node);
20501   vat_json_free (&node);
20502
20503   vam->retval = ntohl (mp->retval);
20504   vam->result_ready = 1;
20505 }
20506
20507 static int
20508 api_app_namespace_add_del (vat_main_t * vam)
20509 {
20510   vl_api_app_namespace_add_del_t *mp;
20511   unformat_input_t *i = vam->input;
20512   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20513   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20514   u64 secret;
20515   int ret;
20516
20517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (i, "id %_%v%_", &ns_id))
20520         ;
20521       else if (unformat (i, "secret %lu", &secret))
20522         secret_set = 1;
20523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20524         sw_if_index_set = 1;
20525       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20526         ;
20527       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20528         ;
20529       else
20530         break;
20531     }
20532   if (!ns_id || !secret_set || !sw_if_index_set)
20533     {
20534       errmsg ("namespace id, secret and sw_if_index must be set");
20535       return -99;
20536     }
20537   if (vec_len (ns_id) > 64)
20538     {
20539       errmsg ("namespace id too long");
20540       return -99;
20541     }
20542   M (APP_NAMESPACE_ADD_DEL, mp);
20543
20544   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20545   mp->namespace_id_len = vec_len (ns_id);
20546   mp->secret = clib_host_to_net_u64 (secret);
20547   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20548   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20549   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20550   vec_free (ns_id);
20551   S (mp);
20552   W (ret);
20553   return ret;
20554 }
20555
20556 static int
20557 api_sock_init_shm (vat_main_t * vam)
20558 {
20559 #if VPP_API_TEST_BUILTIN == 0
20560   unformat_input_t *i = vam->input;
20561   vl_api_shm_elem_config_t *config = 0;
20562   u64 size = 64 << 20;
20563   int rv;
20564
20565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20566     {
20567       if (unformat (i, "size %U", unformat_memory_size, &size))
20568         ;
20569       else
20570         break;
20571     }
20572
20573   /*
20574    * Canned custom ring allocator config.
20575    * Should probably parse all of this
20576    */
20577   vec_validate (config, 6);
20578   config[0].type = VL_API_VLIB_RING;
20579   config[0].size = 256;
20580   config[0].count = 32;
20581
20582   config[1].type = VL_API_VLIB_RING;
20583   config[1].size = 1024;
20584   config[1].count = 16;
20585
20586   config[2].type = VL_API_VLIB_RING;
20587   config[2].size = 4096;
20588   config[2].count = 2;
20589
20590   config[3].type = VL_API_CLIENT_RING;
20591   config[3].size = 256;
20592   config[3].count = 32;
20593
20594   config[4].type = VL_API_CLIENT_RING;
20595   config[4].size = 1024;
20596   config[4].count = 16;
20597
20598   config[5].type = VL_API_CLIENT_RING;
20599   config[5].size = 4096;
20600   config[5].count = 2;
20601
20602   config[6].type = VL_API_QUEUE;
20603   config[6].count = 128;
20604   config[6].size = sizeof (uword);
20605
20606   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20607   if (!rv)
20608     vam->client_index_invalid = 1;
20609   return rv;
20610 #else
20611   return -99;
20612 #endif
20613 }
20614
20615 static void
20616 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20617 {
20618   vat_main_t *vam = &vat_main;
20619
20620   if (mp->is_ip4)
20621     {
20622       print (vam->ofp,
20623              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20624              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20625              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20626              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20627              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20628              clib_net_to_host_u32 (mp->action_index), mp->tag);
20629     }
20630   else
20631     {
20632       print (vam->ofp,
20633              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20634              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20635              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20636              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20637              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20638              clib_net_to_host_u32 (mp->action_index), mp->tag);
20639     }
20640 }
20641
20642 static void
20643 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20644                                              mp)
20645 {
20646   vat_main_t *vam = &vat_main;
20647   vat_json_node_t *node = NULL;
20648   struct in6_addr ip6;
20649   struct in_addr ip4;
20650
20651   if (VAT_JSON_ARRAY != vam->json_tree.type)
20652     {
20653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20654       vat_json_init_array (&vam->json_tree);
20655     }
20656   node = vat_json_array_add (&vam->json_tree);
20657   vat_json_init_object (node);
20658
20659   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20660   vat_json_object_add_uint (node, "appns_index",
20661                             clib_net_to_host_u32 (mp->appns_index));
20662   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20663   vat_json_object_add_uint (node, "scope", mp->scope);
20664   vat_json_object_add_uint (node, "action_index",
20665                             clib_net_to_host_u32 (mp->action_index));
20666   vat_json_object_add_uint (node, "lcl_port",
20667                             clib_net_to_host_u16 (mp->lcl_port));
20668   vat_json_object_add_uint (node, "rmt_port",
20669                             clib_net_to_host_u16 (mp->rmt_port));
20670   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20671   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20672   vat_json_object_add_string_copy (node, "tag", mp->tag);
20673   if (mp->is_ip4)
20674     {
20675       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20676       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20677       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20678       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20679     }
20680   else
20681     {
20682       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20683       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20684       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20685       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20686     }
20687 }
20688
20689 static int
20690 api_session_rule_add_del (vat_main_t * vam)
20691 {
20692   vl_api_session_rule_add_del_t *mp;
20693   unformat_input_t *i = vam->input;
20694   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20695   u32 appns_index = 0, scope = 0;
20696   ip4_address_t lcl_ip4, rmt_ip4;
20697   ip6_address_t lcl_ip6, rmt_ip6;
20698   u8 is_ip4 = 1, conn_set = 0;
20699   u8 is_add = 1, *tag = 0;
20700   int ret;
20701
20702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20703     {
20704       if (unformat (i, "del"))
20705         is_add = 0;
20706       else if (unformat (i, "add"))
20707         ;
20708       else if (unformat (i, "proto tcp"))
20709         proto = 0;
20710       else if (unformat (i, "proto udp"))
20711         proto = 1;
20712       else if (unformat (i, "appns %d", &appns_index))
20713         ;
20714       else if (unformat (i, "scope %d", &scope))
20715         ;
20716       else if (unformat (i, "tag %_%v%_", &tag))
20717         ;
20718       else
20719         if (unformat
20720             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20721              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20722              &rmt_port))
20723         {
20724           is_ip4 = 1;
20725           conn_set = 1;
20726         }
20727       else
20728         if (unformat
20729             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20730              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20731              &rmt_port))
20732         {
20733           is_ip4 = 0;
20734           conn_set = 1;
20735         }
20736       else if (unformat (i, "action %d", &action))
20737         ;
20738       else
20739         break;
20740     }
20741   if (proto == ~0 || !conn_set || action == ~0)
20742     {
20743       errmsg ("transport proto, connection and action must be set");
20744       return -99;
20745     }
20746
20747   if (scope > 3)
20748     {
20749       errmsg ("scope should be 0-3");
20750       return -99;
20751     }
20752
20753   M (SESSION_RULE_ADD_DEL, mp);
20754
20755   mp->is_ip4 = is_ip4;
20756   mp->transport_proto = proto;
20757   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20758   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20759   mp->lcl_plen = lcl_plen;
20760   mp->rmt_plen = rmt_plen;
20761   mp->action_index = clib_host_to_net_u32 (action);
20762   mp->appns_index = clib_host_to_net_u32 (appns_index);
20763   mp->scope = scope;
20764   mp->is_add = is_add;
20765   if (is_ip4)
20766     {
20767       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20768       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20769     }
20770   else
20771     {
20772       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20773       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20774     }
20775   if (tag)
20776     {
20777       clib_memcpy (mp->tag, tag, vec_len (tag));
20778       vec_free (tag);
20779     }
20780
20781   S (mp);
20782   W (ret);
20783   return ret;
20784 }
20785
20786 static int
20787 api_session_rules_dump (vat_main_t * vam)
20788 {
20789   vl_api_session_rules_dump_t *mp;
20790   vl_api_control_ping_t *mp_ping;
20791   int ret;
20792
20793   if (!vam->json_output)
20794     {
20795       print (vam->ofp, "%=20s", "Session Rules");
20796     }
20797
20798   M (SESSION_RULES_DUMP, mp);
20799   /* send it... */
20800   S (mp);
20801
20802   /* Use a control ping for synchronization */
20803   MPING (CONTROL_PING, mp_ping);
20804   S (mp_ping);
20805
20806   /* Wait for a reply... */
20807   W (ret);
20808   return ret;
20809 }
20810
20811 static int
20812 api_ip_container_proxy_add_del (vat_main_t * vam)
20813 {
20814   vl_api_ip_container_proxy_add_del_t *mp;
20815   unformat_input_t *i = vam->input;
20816   u32 sw_if_index = ~0;
20817   vl_api_prefix_t pfx = { };
20818   u8 is_add = 1;
20819   int ret;
20820
20821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20822     {
20823       if (unformat (i, "del"))
20824         is_add = 0;
20825       else if (unformat (i, "add"))
20826         ;
20827       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20828         ;
20829       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20830         ;
20831       else
20832         break;
20833     }
20834   if (sw_if_index == ~0 || pfx.len == 0)
20835     {
20836       errmsg ("address and sw_if_index must be set");
20837       return -99;
20838     }
20839
20840   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20841
20842   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20843   mp->is_add = is_add;
20844   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20845
20846   S (mp);
20847   W (ret);
20848   return ret;
20849 }
20850
20851 static int
20852 api_qos_record_enable_disable (vat_main_t * vam)
20853 {
20854   unformat_input_t *i = vam->input;
20855   vl_api_qos_record_enable_disable_t *mp;
20856   u32 sw_if_index, qs = 0xff;
20857   u8 sw_if_index_set = 0;
20858   u8 enable = 1;
20859   int ret;
20860
20861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20862     {
20863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20864         sw_if_index_set = 1;
20865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20866         sw_if_index_set = 1;
20867       else if (unformat (i, "%U", unformat_qos_source, &qs))
20868         ;
20869       else if (unformat (i, "disable"))
20870         enable = 0;
20871       else
20872         {
20873           clib_warning ("parse error '%U'", format_unformat_error, i);
20874           return -99;
20875         }
20876     }
20877
20878   if (sw_if_index_set == 0)
20879     {
20880       errmsg ("missing interface name or sw_if_index");
20881       return -99;
20882     }
20883   if (qs == 0xff)
20884     {
20885       errmsg ("input location must be specified");
20886       return -99;
20887     }
20888
20889   M (QOS_RECORD_ENABLE_DISABLE, mp);
20890
20891   mp->record.sw_if_index = ntohl (sw_if_index);
20892   mp->record.input_source = qs;
20893   mp->enable = enable;
20894
20895   S (mp);
20896   W (ret);
20897   return ret;
20898 }
20899
20900
20901 static int
20902 q_or_quit (vat_main_t * vam)
20903 {
20904 #if VPP_API_TEST_BUILTIN == 0
20905   longjmp (vam->jump_buf, 1);
20906 #endif
20907   return 0;                     /* not so much */
20908 }
20909
20910 static int
20911 q (vat_main_t * vam)
20912 {
20913   return q_or_quit (vam);
20914 }
20915
20916 static int
20917 quit (vat_main_t * vam)
20918 {
20919   return q_or_quit (vam);
20920 }
20921
20922 static int
20923 comment (vat_main_t * vam)
20924 {
20925   return 0;
20926 }
20927
20928 static int
20929 elog_save (vat_main_t * vam)
20930 {
20931 #if VPP_API_TEST_BUILTIN == 0
20932   elog_main_t *em = &vam->elog_main;
20933   unformat_input_t *i = vam->input;
20934   char *file, *chroot_file;
20935   clib_error_t *error;
20936
20937   if (!unformat (i, "%s", &file))
20938     {
20939       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20940       return 0;
20941     }
20942
20943   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20944   if (strstr (file, "..") || index (file, '/'))
20945     {
20946       errmsg ("illegal characters in filename '%s'", file);
20947       return 0;
20948     }
20949
20950   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20951
20952   vec_free (file);
20953
20954   errmsg ("Saving %wd of %wd events to %s",
20955           elog_n_events_in_buffer (em),
20956           elog_buffer_capacity (em), chroot_file);
20957
20958   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20959   vec_free (chroot_file);
20960
20961   if (error)
20962     clib_error_report (error);
20963 #else
20964   errmsg ("Use the vpp event loger...");
20965 #endif
20966
20967   return 0;
20968 }
20969
20970 static int
20971 elog_setup (vat_main_t * vam)
20972 {
20973 #if VPP_API_TEST_BUILTIN == 0
20974   elog_main_t *em = &vam->elog_main;
20975   unformat_input_t *i = vam->input;
20976   u32 nevents = 128 << 10;
20977
20978   (void) unformat (i, "nevents %d", &nevents);
20979
20980   elog_init (em, nevents);
20981   vl_api_set_elog_main (em);
20982   vl_api_set_elog_trace_api_messages (1);
20983   errmsg ("Event logger initialized with %u events", nevents);
20984 #else
20985   errmsg ("Use the vpp event loger...");
20986 #endif
20987   return 0;
20988 }
20989
20990 static int
20991 elog_enable (vat_main_t * vam)
20992 {
20993 #if VPP_API_TEST_BUILTIN == 0
20994   elog_main_t *em = &vam->elog_main;
20995
20996   elog_enable_disable (em, 1 /* enable */ );
20997   vl_api_set_elog_trace_api_messages (1);
20998   errmsg ("Event logger enabled...");
20999 #else
21000   errmsg ("Use the vpp event loger...");
21001 #endif
21002   return 0;
21003 }
21004
21005 static int
21006 elog_disable (vat_main_t * vam)
21007 {
21008 #if VPP_API_TEST_BUILTIN == 0
21009   elog_main_t *em = &vam->elog_main;
21010
21011   elog_enable_disable (em, 0 /* enable */ );
21012   vl_api_set_elog_trace_api_messages (1);
21013   errmsg ("Event logger disabled...");
21014 #else
21015   errmsg ("Use the vpp event loger...");
21016 #endif
21017   return 0;
21018 }
21019
21020 static int
21021 statseg (vat_main_t * vam)
21022 {
21023   ssvm_private_t *ssvmp = &vam->stat_segment;
21024   ssvm_shared_header_t *shared_header = ssvmp->sh;
21025   vlib_counter_t **counters;
21026   u64 thread0_index1_packets;
21027   u64 thread0_index1_bytes;
21028   f64 vector_rate, input_rate;
21029   uword *p;
21030
21031   uword *counter_vector_by_name;
21032   if (vam->stat_segment_lockp == 0)
21033     {
21034       errmsg ("Stat segment not mapped...");
21035       return -99;
21036     }
21037
21038   /* look up "/if/rx for sw_if_index 1 as a test */
21039
21040   clib_spinlock_lock (vam->stat_segment_lockp);
21041
21042   counter_vector_by_name = (uword *) shared_header->opaque[1];
21043
21044   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21045   if (p == 0)
21046     {
21047       clib_spinlock_unlock (vam->stat_segment_lockp);
21048       errmsg ("/if/tx not found?");
21049       return -99;
21050     }
21051
21052   /* Fish per-thread vector of combined counters from shared memory */
21053   counters = (vlib_counter_t **) p[0];
21054
21055   if (vec_len (counters[0]) < 2)
21056     {
21057       clib_spinlock_unlock (vam->stat_segment_lockp);
21058       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21059       return -99;
21060     }
21061
21062   /* Read thread 0 sw_if_index 1 counter */
21063   thread0_index1_packets = counters[0][1].packets;
21064   thread0_index1_bytes = counters[0][1].bytes;
21065
21066   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21067   if (p == 0)
21068     {
21069       clib_spinlock_unlock (vam->stat_segment_lockp);
21070       errmsg ("vector_rate not found?");
21071       return -99;
21072     }
21073
21074   vector_rate = *(f64 *) (p[0]);
21075   p = hash_get_mem (counter_vector_by_name, "input_rate");
21076   if (p == 0)
21077     {
21078       clib_spinlock_unlock (vam->stat_segment_lockp);
21079       errmsg ("input_rate not found?");
21080       return -99;
21081     }
21082   input_rate = *(f64 *) (p[0]);
21083
21084   clib_spinlock_unlock (vam->stat_segment_lockp);
21085
21086   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21087          vector_rate, input_rate);
21088   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21089          thread0_index1_packets, thread0_index1_bytes);
21090
21091   return 0;
21092 }
21093
21094 static int
21095 cmd_cmp (void *a1, void *a2)
21096 {
21097   u8 **c1 = a1;
21098   u8 **c2 = a2;
21099
21100   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21101 }
21102
21103 static int
21104 help (vat_main_t * vam)
21105 {
21106   u8 **cmds = 0;
21107   u8 *name = 0;
21108   hash_pair_t *p;
21109   unformat_input_t *i = vam->input;
21110   int j;
21111
21112   if (unformat (i, "%s", &name))
21113     {
21114       uword *hs;
21115
21116       vec_add1 (name, 0);
21117
21118       hs = hash_get_mem (vam->help_by_name, name);
21119       if (hs)
21120         print (vam->ofp, "usage: %s %s", name, hs[0]);
21121       else
21122         print (vam->ofp, "No such msg / command '%s'", name);
21123       vec_free (name);
21124       return 0;
21125     }
21126
21127   print (vam->ofp, "Help is available for the following:");
21128
21129     /* *INDENT-OFF* */
21130     hash_foreach_pair (p, vam->function_by_name,
21131     ({
21132       vec_add1 (cmds, (u8 *)(p->key));
21133     }));
21134     /* *INDENT-ON* */
21135
21136   vec_sort_with_function (cmds, cmd_cmp);
21137
21138   for (j = 0; j < vec_len (cmds); j++)
21139     print (vam->ofp, "%s", cmds[j]);
21140
21141   vec_free (cmds);
21142   return 0;
21143 }
21144
21145 static int
21146 set (vat_main_t * vam)
21147 {
21148   u8 *name = 0, *value = 0;
21149   unformat_input_t *i = vam->input;
21150
21151   if (unformat (i, "%s", &name))
21152     {
21153       /* The input buffer is a vector, not a string. */
21154       value = vec_dup (i->buffer);
21155       vec_delete (value, i->index, 0);
21156       /* Almost certainly has a trailing newline */
21157       if (value[vec_len (value) - 1] == '\n')
21158         value[vec_len (value) - 1] = 0;
21159       /* Make sure it's a proper string, one way or the other */
21160       vec_add1 (value, 0);
21161       (void) clib_macro_set_value (&vam->macro_main,
21162                                    (char *) name, (char *) value);
21163     }
21164   else
21165     errmsg ("usage: set <name> <value>");
21166
21167   vec_free (name);
21168   vec_free (value);
21169   return 0;
21170 }
21171
21172 static int
21173 unset (vat_main_t * vam)
21174 {
21175   u8 *name = 0;
21176
21177   if (unformat (vam->input, "%s", &name))
21178     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21179       errmsg ("unset: %s wasn't set", name);
21180   vec_free (name);
21181   return 0;
21182 }
21183
21184 typedef struct
21185 {
21186   u8 *name;
21187   u8 *value;
21188 } macro_sort_t;
21189
21190
21191 static int
21192 macro_sort_cmp (void *a1, void *a2)
21193 {
21194   macro_sort_t *s1 = a1;
21195   macro_sort_t *s2 = a2;
21196
21197   return strcmp ((char *) (s1->name), (char *) (s2->name));
21198 }
21199
21200 static int
21201 dump_macro_table (vat_main_t * vam)
21202 {
21203   macro_sort_t *sort_me = 0, *sm;
21204   int i;
21205   hash_pair_t *p;
21206
21207     /* *INDENT-OFF* */
21208     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21209     ({
21210       vec_add2 (sort_me, sm, 1);
21211       sm->name = (u8 *)(p->key);
21212       sm->value = (u8 *) (p->value[0]);
21213     }));
21214     /* *INDENT-ON* */
21215
21216   vec_sort_with_function (sort_me, macro_sort_cmp);
21217
21218   if (vec_len (sort_me))
21219     print (vam->ofp, "%-15s%s", "Name", "Value");
21220   else
21221     print (vam->ofp, "The macro table is empty...");
21222
21223   for (i = 0; i < vec_len (sort_me); i++)
21224     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21225   return 0;
21226 }
21227
21228 static int
21229 dump_node_table (vat_main_t * vam)
21230 {
21231   int i, j;
21232   vlib_node_t *node, *next_node;
21233
21234   if (vec_len (vam->graph_nodes) == 0)
21235     {
21236       print (vam->ofp, "Node table empty, issue get_node_graph...");
21237       return 0;
21238     }
21239
21240   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21241     {
21242       node = vam->graph_nodes[0][i];
21243       print (vam->ofp, "[%d] %s", i, node->name);
21244       for (j = 0; j < vec_len (node->next_nodes); j++)
21245         {
21246           if (node->next_nodes[j] != ~0)
21247             {
21248               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21249               print (vam->ofp, "  [%d] %s", j, next_node->name);
21250             }
21251         }
21252     }
21253   return 0;
21254 }
21255
21256 static int
21257 value_sort_cmp (void *a1, void *a2)
21258 {
21259   name_sort_t *n1 = a1;
21260   name_sort_t *n2 = a2;
21261
21262   if (n1->value < n2->value)
21263     return -1;
21264   if (n1->value > n2->value)
21265     return 1;
21266   return 0;
21267 }
21268
21269
21270 static int
21271 dump_msg_api_table (vat_main_t * vam)
21272 {
21273   api_main_t *am = &api_main;
21274   name_sort_t *nses = 0, *ns;
21275   hash_pair_t *hp;
21276   int i;
21277
21278   /* *INDENT-OFF* */
21279   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21280   ({
21281     vec_add2 (nses, ns, 1);
21282     ns->name = (u8 *)(hp->key);
21283     ns->value = (u32) hp->value[0];
21284   }));
21285   /* *INDENT-ON* */
21286
21287   vec_sort_with_function (nses, value_sort_cmp);
21288
21289   for (i = 0; i < vec_len (nses); i++)
21290     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21291   vec_free (nses);
21292   return 0;
21293 }
21294
21295 static int
21296 get_msg_id (vat_main_t * vam)
21297 {
21298   u8 *name_and_crc;
21299   u32 message_index;
21300
21301   if (unformat (vam->input, "%s", &name_and_crc))
21302     {
21303       message_index = vl_msg_api_get_msg_index (name_and_crc);
21304       if (message_index == ~0)
21305         {
21306           print (vam->ofp, " '%s' not found", name_and_crc);
21307           return 0;
21308         }
21309       print (vam->ofp, " '%s' has message index %d",
21310              name_and_crc, message_index);
21311       return 0;
21312     }
21313   errmsg ("name_and_crc required...");
21314   return 0;
21315 }
21316
21317 static int
21318 search_node_table (vat_main_t * vam)
21319 {
21320   unformat_input_t *line_input = vam->input;
21321   u8 *node_to_find;
21322   int j;
21323   vlib_node_t *node, *next_node;
21324   uword *p;
21325
21326   if (vam->graph_node_index_by_name == 0)
21327     {
21328       print (vam->ofp, "Node table empty, issue get_node_graph...");
21329       return 0;
21330     }
21331
21332   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21333     {
21334       if (unformat (line_input, "%s", &node_to_find))
21335         {
21336           vec_add1 (node_to_find, 0);
21337           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21338           if (p == 0)
21339             {
21340               print (vam->ofp, "%s not found...", node_to_find);
21341               goto out;
21342             }
21343           node = vam->graph_nodes[0][p[0]];
21344           print (vam->ofp, "[%d] %s", p[0], node->name);
21345           for (j = 0; j < vec_len (node->next_nodes); j++)
21346             {
21347               if (node->next_nodes[j] != ~0)
21348                 {
21349                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21350                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21351                 }
21352             }
21353         }
21354
21355       else
21356         {
21357           clib_warning ("parse error '%U'", format_unformat_error,
21358                         line_input);
21359           return -99;
21360         }
21361
21362     out:
21363       vec_free (node_to_find);
21364
21365     }
21366
21367   return 0;
21368 }
21369
21370
21371 static int
21372 script (vat_main_t * vam)
21373 {
21374 #if (VPP_API_TEST_BUILTIN==0)
21375   u8 *s = 0;
21376   char *save_current_file;
21377   unformat_input_t save_input;
21378   jmp_buf save_jump_buf;
21379   u32 save_line_number;
21380
21381   FILE *new_fp, *save_ifp;
21382
21383   if (unformat (vam->input, "%s", &s))
21384     {
21385       new_fp = fopen ((char *) s, "r");
21386       if (new_fp == 0)
21387         {
21388           errmsg ("Couldn't open script file %s", s);
21389           vec_free (s);
21390           return -99;
21391         }
21392     }
21393   else
21394     {
21395       errmsg ("Missing script name");
21396       return -99;
21397     }
21398
21399   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21400   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21401   save_ifp = vam->ifp;
21402   save_line_number = vam->input_line_number;
21403   save_current_file = (char *) vam->current_file;
21404
21405   vam->input_line_number = 0;
21406   vam->ifp = new_fp;
21407   vam->current_file = s;
21408   do_one_file (vam);
21409
21410   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21411   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21412   vam->ifp = save_ifp;
21413   vam->input_line_number = save_line_number;
21414   vam->current_file = (u8 *) save_current_file;
21415   vec_free (s);
21416
21417   return 0;
21418 #else
21419   clib_warning ("use the exec command...");
21420   return -99;
21421 #endif
21422 }
21423
21424 static int
21425 echo (vat_main_t * vam)
21426 {
21427   print (vam->ofp, "%v", vam->input->buffer);
21428   return 0;
21429 }
21430
21431 /* List of API message constructors, CLI names map to api_xxx */
21432 #define foreach_vpe_api_msg                                             \
21433 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21434 _(sw_interface_dump,"")                                                 \
21435 _(sw_interface_set_flags,                                               \
21436   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21437 _(sw_interface_add_del_address,                                         \
21438   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21439 _(sw_interface_set_rx_mode,                                             \
21440   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21441 _(sw_interface_set_rx_placement,                                        \
21442   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21443 _(sw_interface_rx_placement_dump,                                       \
21444   "[<intfc> | sw_if_index <id>]")                                         \
21445 _(sw_interface_set_table,                                               \
21446   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21447 _(sw_interface_set_mpls_enable,                                         \
21448   "<intfc> | sw_if_index [disable | dis]")                              \
21449 _(sw_interface_set_vpath,                                               \
21450   "<intfc> | sw_if_index <id> enable | disable")                        \
21451 _(sw_interface_set_vxlan_bypass,                                        \
21452   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21453 _(sw_interface_set_geneve_bypass,                                       \
21454   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21455 _(sw_interface_set_l2_xconnect,                                         \
21456   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21457   "enable | disable")                                                   \
21458 _(sw_interface_set_l2_bridge,                                           \
21459   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21460   "[shg <split-horizon-group>] [bvi]\n"                                 \
21461   "enable | disable")                                                   \
21462 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21463 _(bridge_domain_add_del,                                                \
21464   "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") \
21465 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21466 _(l2fib_add_del,                                                        \
21467   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21468 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21469 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21470 _(l2_flags,                                                             \
21471   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21472 _(bridge_flags,                                                         \
21473   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21474 _(tap_create_v2,                                                        \
21475   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21476 _(tap_delete_v2,                                                        \
21477   "<vpp-if-name> | sw_if_index <id>")                                   \
21478 _(sw_interface_tap_v2_dump, "")                                         \
21479 _(virtio_pci_create,                                                    \
21480   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21481 _(virtio_pci_delete,                                                    \
21482   "<vpp-if-name> | sw_if_index <id>")                                   \
21483 _(sw_interface_virtio_pci_dump, "")                                     \
21484 _(bond_create,                                                          \
21485   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21486   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21487   "[id <if-id>]")                                                       \
21488 _(bond_delete,                                                          \
21489   "<vpp-if-name> | sw_if_index <id>")                                   \
21490 _(bond_enslave,                                                         \
21491   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21492 _(bond_detach_slave,                                                    \
21493   "sw_if_index <n>")                                                    \
21494  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21495 _(sw_interface_bond_dump, "")                                           \
21496 _(sw_interface_slave_dump,                                              \
21497   "<vpp-if-name> | sw_if_index <id>")                                   \
21498 _(ip_table_add_del,                                                     \
21499   "table <n> [ipv6] [add | del]\n")                                     \
21500 _(ip_route_add_del,                                                     \
21501   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21502   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21503   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21504   "[multipath] [count <n>] [del]")                                      \
21505 _(ip_mroute_add_del,                                                    \
21506   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21507   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21508 _(mpls_table_add_del,                                                   \
21509   "table <n> [add | del]\n")                                            \
21510 _(mpls_route_add_del,                                                   \
21511   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21512   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21513   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21514   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21515   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21516   "[count <n>] [del]")                                                  \
21517 _(mpls_ip_bind_unbind,                                                  \
21518   "<label> <addr/len>")                                                 \
21519 _(mpls_tunnel_add_del,                                                  \
21520   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21521   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21522   "[l2-only]  [out-label <n>]")                                         \
21523 _(sr_mpls_policy_add,                                                   \
21524   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21525 _(sr_mpls_policy_del,                                                   \
21526   "bsid <id>")                                                          \
21527 _(bier_table_add_del,                                                   \
21528   "<label> <sub-domain> <set> <bsl> [del]")                             \
21529 _(bier_route_add_del,                                                   \
21530   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21531   "[<intfc> | sw_if_index <id>]"                                        \
21532   "[weight <n>] [del] [multipath]")                                     \
21533 _(proxy_arp_add_del,                                                    \
21534   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21535 _(proxy_arp_intfc_enable_disable,                                       \
21536   "<intfc> | sw_if_index <id> enable | disable")                        \
21537 _(sw_interface_set_unnumbered,                                          \
21538   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21539 _(ip_neighbor_add_del,                                                  \
21540   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21541   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21542 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21543 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21544   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21545   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21546   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21547 _(reset_fib, "vrf <n> [ipv6]")                                          \
21548 _(set_ip_flow_hash,                                                     \
21549   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21550 _(sw_interface_ip6_enable_disable,                                      \
21551   "<intfc> | sw_if_index <id> enable | disable")                        \
21552 _(ip6nd_proxy_add_del,                                                  \
21553   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21554 _(ip6nd_proxy_dump, "")                                                 \
21555 _(sw_interface_ip6nd_ra_prefix,                                         \
21556   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21557   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21558   "[nolink] [isno]")                                                    \
21559 _(sw_interface_ip6nd_ra_config,                                         \
21560   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21561   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21562   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21563 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21564 _(l2_patch_add_del,                                                     \
21565   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21566   "enable | disable")                                                   \
21567 _(sr_localsid_add_del,                                                  \
21568   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21569   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21570 _(classify_add_del_table,                                               \
21571   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21572   " [del] [del-chain] mask <mask-value>\n"                              \
21573   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21574   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21575 _(classify_add_del_session,                                             \
21576   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21577   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21578   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21579   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21580 _(classify_set_interface_ip_table,                                      \
21581   "<intfc> | sw_if_index <nn> table <nn>")                              \
21582 _(classify_set_interface_l2_tables,                                     \
21583   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21584   "  [other-table <nn>]")                                               \
21585 _(get_node_index, "node <node-name")                                    \
21586 _(add_node_next, "node <node-name> next <next-node-name>")              \
21587 _(l2tpv3_create_tunnel,                                                 \
21588   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21589   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21590   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21591 _(l2tpv3_set_tunnel_cookies,                                            \
21592   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21593   "[new_remote_cookie <nn>]\n")                                         \
21594 _(l2tpv3_interface_enable_disable,                                      \
21595   "<intfc> | sw_if_index <nn> enable | disable")                        \
21596 _(l2tpv3_set_lookup_key,                                                \
21597   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21598 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21599 _(vxlan_offload_rx,                                                     \
21600   "hw { <interface name> | hw_if_index <nn>} "                          \
21601   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21602 _(vxlan_add_del_tunnel,                                                 \
21603   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21604   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21605   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21606 _(geneve_add_del_tunnel,                                                \
21607   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21608   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21609   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21610 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21611 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21612 _(gre_tunnel_add_del,                                                   \
21613   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21614   "[teb | erspan <session-id>] [del]")                                  \
21615 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21616 _(l2_fib_clear_table, "")                                               \
21617 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21618 _(l2_interface_vlan_tag_rewrite,                                        \
21619   "<intfc> | sw_if_index <nn> \n"                                       \
21620   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21621   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21622 _(create_vhost_user_if,                                                 \
21623         "socket <filename> [server] [renumber <dev_instance>] "         \
21624         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21625         "[mac <mac_address>]")                                          \
21626 _(modify_vhost_user_if,                                                 \
21627         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21628         "[server] [renumber <dev_instance>] [gso]")                     \
21629 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21630 _(sw_interface_vhost_user_dump, "")                                     \
21631 _(show_version, "")                                                     \
21632 _(show_threads, "")                                                     \
21633 _(vxlan_gpe_add_del_tunnel,                                             \
21634   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21635   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21636   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21637   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21638 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21639 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21640 _(interface_name_renumber,                                              \
21641   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21642 _(input_acl_set_interface,                                              \
21643   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21644   "  [l2-table <nn>] [del]")                                            \
21645 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21646 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21647   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21648 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21649 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21650 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21651 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21652 _(ip_dump, "ipv4 | ipv6")                                               \
21653 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21654 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21655   "  spid_id <n> ")                                                     \
21656 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21657   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21658   "  integ_alg <alg> integ_key <hex>")                                  \
21659 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21660   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21661   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21662   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21663 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21664   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21665   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21666   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21667   "  [instance <n>]")     \
21668 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21669 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21670 _(delete_loopback,"sw_if_index <nn>")                                   \
21671 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21672 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21673 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21674 _(want_interface_events,  "enable|disable")                             \
21675 _(get_first_msg_id, "client <name>")                                    \
21676 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21677 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21678   "fib-id <nn> [ip4][ip6][default]")                                    \
21679 _(get_node_graph, " ")                                                  \
21680 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21681 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21682 _(ioam_disable, "")                                                     \
21683 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21684                             " sw_if_index <sw_if_index> p <priority> "  \
21685                             "w <weight>] [del]")                        \
21686 _(one_add_del_locator, "locator-set <locator_name> "                    \
21687                         "iface <intf> | sw_if_index <sw_if_index> "     \
21688                         "p <priority> w <weight> [del]")                \
21689 _(one_add_del_local_eid,"vni <vni> eid "                                \
21690                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21691                          "locator-set <locator_name> [del]"             \
21692                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21693 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21694 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21695 _(one_enable_disable, "enable|disable")                                 \
21696 _(one_map_register_enable_disable, "enable|disable")                    \
21697 _(one_map_register_fallback_threshold, "<value>")                       \
21698 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21699 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21700                                "[seid <seid>] "                         \
21701                                "rloc <locator> p <prio> "               \
21702                                "w <weight> [rloc <loc> ... ] "          \
21703                                "action <action> [del-all]")             \
21704 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21705                           "<local-eid>")                                \
21706 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21707 _(one_use_petr, "ip-address> | disable")                                \
21708 _(one_map_request_mode, "src-dst|dst-only")                             \
21709 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21710 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21711 _(one_locator_set_dump, "[local | remote]")                             \
21712 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21713 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21714                        "[local] | [remote]")                            \
21715 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21716 _(one_ndp_bd_get, "")                                                   \
21717 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21718 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21719 _(one_l2_arp_bd_get, "")                                                \
21720 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21721 _(one_stats_enable_disable, "enable|disable")                           \
21722 _(show_one_stats_enable_disable, "")                                    \
21723 _(one_eid_table_vni_dump, "")                                           \
21724 _(one_eid_table_map_dump, "l2|l3")                                      \
21725 _(one_map_resolver_dump, "")                                            \
21726 _(one_map_server_dump, "")                                              \
21727 _(one_adjacencies_get, "vni <vni>")                                     \
21728 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21729 _(show_one_rloc_probe_state, "")                                        \
21730 _(show_one_map_register_state, "")                                      \
21731 _(show_one_status, "")                                                  \
21732 _(one_stats_dump, "")                                                   \
21733 _(one_stats_flush, "")                                                  \
21734 _(one_get_map_request_itr_rlocs, "")                                    \
21735 _(one_map_register_set_ttl, "<ttl>")                                    \
21736 _(one_set_transport_protocol, "udp|api")                                \
21737 _(one_get_transport_protocol, "")                                       \
21738 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21739 _(one_show_xtr_mode, "")                                                \
21740 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21741 _(one_show_pitr_mode, "")                                               \
21742 _(one_enable_disable_petr_mode, "enable|disable")                       \
21743 _(one_show_petr_mode, "")                                               \
21744 _(show_one_nsh_mapping, "")                                             \
21745 _(show_one_pitr, "")                                                    \
21746 _(show_one_use_petr, "")                                                \
21747 _(show_one_map_request_mode, "")                                        \
21748 _(show_one_map_register_ttl, "")                                        \
21749 _(show_one_map_register_fallback_threshold, "")                         \
21750 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21751                             " sw_if_index <sw_if_index> p <priority> "  \
21752                             "w <weight>] [del]")                        \
21753 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21754                         "iface <intf> | sw_if_index <sw_if_index> "     \
21755                         "p <priority> w <weight> [del]")                \
21756 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21757                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21758                          "locator-set <locator_name> [del]"             \
21759                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21760 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21761 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21762 _(lisp_enable_disable, "enable|disable")                                \
21763 _(lisp_map_register_enable_disable, "enable|disable")                   \
21764 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21765 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21766                                "[seid <seid>] "                         \
21767                                "rloc <locator> p <prio> "               \
21768                                "w <weight> [rloc <loc> ... ] "          \
21769                                "action <action> [del-all]")             \
21770 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21771                           "<local-eid>")                                \
21772 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21773 _(lisp_use_petr, "<ip-address> | disable")                              \
21774 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21775 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21776 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21777 _(lisp_locator_set_dump, "[local | remote]")                            \
21778 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21779 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21780                        "[local] | [remote]")                            \
21781 _(lisp_eid_table_vni_dump, "")                                          \
21782 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21783 _(lisp_map_resolver_dump, "")                                           \
21784 _(lisp_map_server_dump, "")                                             \
21785 _(lisp_adjacencies_get, "vni <vni>")                                    \
21786 _(gpe_fwd_entry_vnis_get, "")                                           \
21787 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21788 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21789                                 "[table <table-id>]")                   \
21790 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21791 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21792 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21793 _(gpe_get_encap_mode, "")                                               \
21794 _(lisp_gpe_add_del_iface, "up|down")                                    \
21795 _(lisp_gpe_enable_disable, "enable|disable")                            \
21796 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21797   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21798 _(show_lisp_rloc_probe_state, "")                                       \
21799 _(show_lisp_map_register_state, "")                                     \
21800 _(show_lisp_status, "")                                                 \
21801 _(lisp_get_map_request_itr_rlocs, "")                                   \
21802 _(show_lisp_pitr, "")                                                   \
21803 _(show_lisp_use_petr, "")                                               \
21804 _(show_lisp_map_request_mode, "")                                       \
21805 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21806 _(af_packet_delete, "name <host interface name>")                       \
21807 _(af_packet_dump, "")                                                   \
21808 _(policer_add_del, "name <policer name> <params> [del]")                \
21809 _(policer_dump, "[name <policer name>]")                                \
21810 _(policer_classify_set_interface,                                       \
21811   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21812   "  [l2-table <nn>] [del]")                                            \
21813 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21814 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21815     "[master|slave]")                                                   \
21816 _(netmap_delete, "name <interface name>")                               \
21817 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21818 _(mpls_table_dump, "")                                                  \
21819 _(mpls_route_dump, "table-id <ID>")                                     \
21820 _(classify_table_ids, "")                                               \
21821 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21822 _(classify_table_info, "table_id <nn>")                                 \
21823 _(classify_session_dump, "table_id <nn>")                               \
21824 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21825     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21826     "[template_interval <nn>] [udp_checksum]")                          \
21827 _(ipfix_exporter_dump, "")                                              \
21828 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21829 _(ipfix_classify_stream_dump, "")                                       \
21830 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21831 _(ipfix_classify_table_dump, "")                                        \
21832 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21833 _(sw_interface_span_dump, "[l2]")                                           \
21834 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21835 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21836 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21837 _(pg_enable_disable, "[stream <id>] disable")                           \
21838 _(ip_source_and_port_range_check_add_del,                               \
21839   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21840 _(ip_source_and_port_range_check_interface_add_del,                     \
21841   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21842   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21843 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21844 _(l2_interface_pbb_tag_rewrite,                                         \
21845   "<intfc> | sw_if_index <nn> \n"                                       \
21846   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21847   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21848 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21849 _(flow_classify_set_interface,                                          \
21850   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21851 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21852 _(ip_table_dump, "")                                                    \
21853 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21854 _(ip_mtable_dump, "")                                                   \
21855 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21856 _(feature_enable_disable, "arc_name <arc_name> "                        \
21857   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21858 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21859   "[enable | disable] ")                                                \
21860 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21861 "[disable]")                                                            \
21862 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21863   "mac <mac-address> [del]")                                            \
21864 _(l2_xconnect_dump, "")                                                 \
21865 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21866 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21867 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21868 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21869 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21870 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21871 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21872   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21873 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21874 _(sock_init_shm, "size <nnn>")                                          \
21875 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21876 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21877   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21878 _(session_rules_dump, "")                                               \
21879 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21880 _(output_acl_set_interface,                                             \
21881   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21882   "  [l2-table <nn>] [del]")                                            \
21883 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21884
21885 /* List of command functions, CLI names map directly to functions */
21886 #define foreach_cli_function                                    \
21887 _(comment, "usage: comment <ignore-rest-of-line>")              \
21888 _(dump_interface_table, "usage: dump_interface_table")          \
21889 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21890 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21891 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21892 _(dump_macro_table, "usage: dump_macro_table ")                 \
21893 _(dump_node_table, "usage: dump_node_table")                    \
21894 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21895 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21896 _(elog_disable, "usage: elog_disable")                          \
21897 _(elog_enable, "usage: elog_enable")                            \
21898 _(elog_save, "usage: elog_save <filename>")                     \
21899 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21900 _(echo, "usage: echo <message>")                                \
21901 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21902 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21903 _(help, "usage: help")                                          \
21904 _(q, "usage: quit")                                             \
21905 _(quit, "usage: quit")                                          \
21906 _(search_node_table, "usage: search_node_table <name>...")      \
21907 _(set, "usage: set <variable-name> <value>")                    \
21908 _(script, "usage: script <file-name>")                          \
21909 _(statseg, "usage: statseg")                                    \
21910 _(unset, "usage: unset <variable-name>")
21911
21912 #define _(N,n)                                  \
21913     static void vl_api_##n##_t_handler_uni      \
21914     (vl_api_##n##_t * mp)                       \
21915     {                                           \
21916         vat_main_t * vam = &vat_main;           \
21917         if (vam->json_output) {                 \
21918             vl_api_##n##_t_handler_json(mp);    \
21919         } else {                                \
21920             vl_api_##n##_t_handler(mp);         \
21921         }                                       \
21922     }
21923 foreach_vpe_api_reply_msg;
21924 #if VPP_API_TEST_BUILTIN == 0
21925 foreach_standalone_reply_msg;
21926 #endif
21927 #undef _
21928
21929 void
21930 vat_api_hookup (vat_main_t * vam)
21931 {
21932 #define _(N,n)                                                  \
21933     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21934                            vl_api_##n##_t_handler_uni,          \
21935                            vl_noop_handler,                     \
21936                            vl_api_##n##_t_endian,               \
21937                            vl_api_##n##_t_print,                \
21938                            sizeof(vl_api_##n##_t), 1);
21939   foreach_vpe_api_reply_msg;
21940 #if VPP_API_TEST_BUILTIN == 0
21941   foreach_standalone_reply_msg;
21942 #endif
21943 #undef _
21944
21945 #if (VPP_API_TEST_BUILTIN==0)
21946   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21947
21948   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21949
21950   vam->function_by_name = hash_create_string (0, sizeof (uword));
21951
21952   vam->help_by_name = hash_create_string (0, sizeof (uword));
21953 #endif
21954
21955   /* API messages we can send */
21956 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21957   foreach_vpe_api_msg;
21958 #undef _
21959
21960   /* Help strings */
21961 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21962   foreach_vpe_api_msg;
21963 #undef _
21964
21965   /* CLI functions */
21966 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21967   foreach_cli_function;
21968 #undef _
21969
21970   /* Help strings */
21971 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21972   foreach_cli_function;
21973 #undef _
21974 }
21975
21976 #if VPP_API_TEST_BUILTIN
21977 static clib_error_t *
21978 vat_api_hookup_shim (vlib_main_t * vm)
21979 {
21980   vat_api_hookup (&vat_main);
21981   return 0;
21982 }
21983
21984 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21985 #endif
21986
21987 /*
21988  * fd.io coding-style-patch-verification: ON
21989  *
21990  * Local Variables:
21991  * eval: (c-set-style "gnu")
21992  * End:
21993  */