l2: l2tp API cleanup
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip/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.un.ip4, collector_address.data,
11285           sizeof (collector_address.data));
11286   mp->collector_port = htons ((u16) collector_port);
11287   memcpy (mp->src_address.un.ip4, src_address.data,
11288           sizeof (src_address.data));
11289   mp->vrf_id = htonl (vrf_id);
11290   mp->path_mtu = htonl (path_mtu);
11291   mp->template_interval = htonl (template_interval);
11292   mp->udp_checksum = udp_checksum;
11293
11294   S (mp);
11295   W (ret);
11296   return ret;
11297 }
11298
11299 static int
11300 api_set_ipfix_classify_stream (vat_main_t * vam)
11301 {
11302   unformat_input_t *i = vam->input;
11303   vl_api_set_ipfix_classify_stream_t *mp;
11304   u32 domain_id = 0;
11305   u32 src_port = UDP_DST_PORT_ipfix;
11306   int ret;
11307
11308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11309     {
11310       if (unformat (i, "domain %d", &domain_id))
11311         ;
11312       else if (unformat (i, "src_port %d", &src_port))
11313         ;
11314       else
11315         {
11316           errmsg ("unknown input `%U'", format_unformat_error, i);
11317           return -99;
11318         }
11319     }
11320
11321   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11322
11323   mp->domain_id = htonl (domain_id);
11324   mp->src_port = htons ((u16) src_port);
11325
11326   S (mp);
11327   W (ret);
11328   return ret;
11329 }
11330
11331 static int
11332 api_ipfix_classify_table_add_del (vat_main_t * vam)
11333 {
11334   unformat_input_t *i = vam->input;
11335   vl_api_ipfix_classify_table_add_del_t *mp;
11336   int is_add = -1;
11337   u32 classify_table_index = ~0;
11338   u8 ip_version = 0;
11339   u8 transport_protocol = 255;
11340   int ret;
11341
11342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11343     {
11344       if (unformat (i, "add"))
11345         is_add = 1;
11346       else if (unformat (i, "del"))
11347         is_add = 0;
11348       else if (unformat (i, "table %d", &classify_table_index))
11349         ;
11350       else if (unformat (i, "ip4"))
11351         ip_version = 4;
11352       else if (unformat (i, "ip6"))
11353         ip_version = 6;
11354       else if (unformat (i, "tcp"))
11355         transport_protocol = 6;
11356       else if (unformat (i, "udp"))
11357         transport_protocol = 17;
11358       else
11359         {
11360           errmsg ("unknown input `%U'", format_unformat_error, i);
11361           return -99;
11362         }
11363     }
11364
11365   if (is_add == -1)
11366     {
11367       errmsg ("expecting: add|del");
11368       return -99;
11369     }
11370   if (classify_table_index == ~0)
11371     {
11372       errmsg ("classifier table not specified");
11373       return -99;
11374     }
11375   if (ip_version == 0)
11376     {
11377       errmsg ("IP version not specified");
11378       return -99;
11379     }
11380
11381   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11382
11383   mp->is_add = is_add;
11384   mp->table_id = htonl (classify_table_index);
11385   mp->ip_version = ip_version;
11386   mp->transport_protocol = transport_protocol;
11387
11388   S (mp);
11389   W (ret);
11390   return ret;
11391 }
11392
11393 static int
11394 api_get_node_index (vat_main_t * vam)
11395 {
11396   unformat_input_t *i = vam->input;
11397   vl_api_get_node_index_t *mp;
11398   u8 *name = 0;
11399   int ret;
11400
11401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11402     {
11403       if (unformat (i, "node %s", &name))
11404         ;
11405       else
11406         break;
11407     }
11408   if (name == 0)
11409     {
11410       errmsg ("node name required");
11411       return -99;
11412     }
11413   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11414     {
11415       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11416       return -99;
11417     }
11418
11419   M (GET_NODE_INDEX, mp);
11420   clib_memcpy (mp->node_name, name, vec_len (name));
11421   vec_free (name);
11422
11423   S (mp);
11424   W (ret);
11425   return ret;
11426 }
11427
11428 static int
11429 api_get_next_index (vat_main_t * vam)
11430 {
11431   unformat_input_t *i = vam->input;
11432   vl_api_get_next_index_t *mp;
11433   u8 *node_name = 0, *next_node_name = 0;
11434   int ret;
11435
11436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11437     {
11438       if (unformat (i, "node-name %s", &node_name))
11439         ;
11440       else if (unformat (i, "next-node-name %s", &next_node_name))
11441         break;
11442     }
11443
11444   if (node_name == 0)
11445     {
11446       errmsg ("node name required");
11447       return -99;
11448     }
11449   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11450     {
11451       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11452       return -99;
11453     }
11454
11455   if (next_node_name == 0)
11456     {
11457       errmsg ("next node name required");
11458       return -99;
11459     }
11460   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11461     {
11462       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11463       return -99;
11464     }
11465
11466   M (GET_NEXT_INDEX, mp);
11467   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11468   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11469   vec_free (node_name);
11470   vec_free (next_node_name);
11471
11472   S (mp);
11473   W (ret);
11474   return ret;
11475 }
11476
11477 static int
11478 api_add_node_next (vat_main_t * vam)
11479 {
11480   unformat_input_t *i = vam->input;
11481   vl_api_add_node_next_t *mp;
11482   u8 *name = 0;
11483   u8 *next = 0;
11484   int ret;
11485
11486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11487     {
11488       if (unformat (i, "node %s", &name))
11489         ;
11490       else if (unformat (i, "next %s", &next))
11491         ;
11492       else
11493         break;
11494     }
11495   if (name == 0)
11496     {
11497       errmsg ("node name required");
11498       return -99;
11499     }
11500   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11501     {
11502       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11503       return -99;
11504     }
11505   if (next == 0)
11506     {
11507       errmsg ("next node required");
11508       return -99;
11509     }
11510   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11511     {
11512       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11513       return -99;
11514     }
11515
11516   M (ADD_NODE_NEXT, mp);
11517   clib_memcpy (mp->node_name, name, vec_len (name));
11518   clib_memcpy (mp->next_name, next, vec_len (next));
11519   vec_free (name);
11520   vec_free (next);
11521
11522   S (mp);
11523   W (ret);
11524   return ret;
11525 }
11526
11527 static int
11528 api_l2tpv3_create_tunnel (vat_main_t * vam)
11529 {
11530   unformat_input_t *i = vam->input;
11531   ip6_address_t client_address, our_address;
11532   int client_address_set = 0;
11533   int our_address_set = 0;
11534   u32 local_session_id = 0;
11535   u32 remote_session_id = 0;
11536   u64 local_cookie = 0;
11537   u64 remote_cookie = 0;
11538   u8 l2_sublayer_present = 0;
11539   vl_api_l2tpv3_create_tunnel_t *mp;
11540   int ret;
11541
11542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11543     {
11544       if (unformat (i, "client_address %U", unformat_ip6_address,
11545                     &client_address))
11546         client_address_set = 1;
11547       else if (unformat (i, "our_address %U", unformat_ip6_address,
11548                          &our_address))
11549         our_address_set = 1;
11550       else if (unformat (i, "local_session_id %d", &local_session_id))
11551         ;
11552       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11553         ;
11554       else if (unformat (i, "local_cookie %lld", &local_cookie))
11555         ;
11556       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11557         ;
11558       else if (unformat (i, "l2-sublayer-present"))
11559         l2_sublayer_present = 1;
11560       else
11561         break;
11562     }
11563
11564   if (client_address_set == 0)
11565     {
11566       errmsg ("client_address required");
11567       return -99;
11568     }
11569
11570   if (our_address_set == 0)
11571     {
11572       errmsg ("our_address required");
11573       return -99;
11574     }
11575
11576   M (L2TPV3_CREATE_TUNNEL, mp);
11577
11578   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11579                sizeof (ip6_address_t));
11580
11581   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11582                sizeof (ip6_address_t));
11583
11584   mp->local_session_id = ntohl (local_session_id);
11585   mp->remote_session_id = ntohl (remote_session_id);
11586   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11587   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11588   mp->l2_sublayer_present = l2_sublayer_present;
11589
11590   S (mp);
11591   W (ret);
11592   return ret;
11593 }
11594
11595 static int
11596 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11597 {
11598   unformat_input_t *i = vam->input;
11599   u32 sw_if_index;
11600   u8 sw_if_index_set = 0;
11601   u64 new_local_cookie = 0;
11602   u64 new_remote_cookie = 0;
11603   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11604   int ret;
11605
11606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11607     {
11608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11609         sw_if_index_set = 1;
11610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11611         sw_if_index_set = 1;
11612       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11613         ;
11614       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11615         ;
11616       else
11617         break;
11618     }
11619
11620   if (sw_if_index_set == 0)
11621     {
11622       errmsg ("missing interface name or sw_if_index");
11623       return -99;
11624     }
11625
11626   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11627
11628   mp->sw_if_index = ntohl (sw_if_index);
11629   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11630   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11631
11632   S (mp);
11633   W (ret);
11634   return ret;
11635 }
11636
11637 static int
11638 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11639 {
11640   unformat_input_t *i = vam->input;
11641   vl_api_l2tpv3_interface_enable_disable_t *mp;
11642   u32 sw_if_index;
11643   u8 sw_if_index_set = 0;
11644   u8 enable_disable = 1;
11645   int ret;
11646
11647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11648     {
11649       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11650         sw_if_index_set = 1;
11651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11652         sw_if_index_set = 1;
11653       else if (unformat (i, "enable"))
11654         enable_disable = 1;
11655       else if (unformat (i, "disable"))
11656         enable_disable = 0;
11657       else
11658         break;
11659     }
11660
11661   if (sw_if_index_set == 0)
11662     {
11663       errmsg ("missing interface name or sw_if_index");
11664       return -99;
11665     }
11666
11667   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11668
11669   mp->sw_if_index = ntohl (sw_if_index);
11670   mp->enable_disable = enable_disable;
11671
11672   S (mp);
11673   W (ret);
11674   return ret;
11675 }
11676
11677 static int
11678 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11679 {
11680   unformat_input_t *i = vam->input;
11681   vl_api_l2tpv3_set_lookup_key_t *mp;
11682   u8 key = ~0;
11683   int ret;
11684
11685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11686     {
11687       if (unformat (i, "lookup_v6_src"))
11688         key = L2T_LOOKUP_SRC_ADDRESS;
11689       else if (unformat (i, "lookup_v6_dst"))
11690         key = L2T_LOOKUP_DST_ADDRESS;
11691       else if (unformat (i, "lookup_session_id"))
11692         key = L2T_LOOKUP_SESSION_ID;
11693       else
11694         break;
11695     }
11696
11697   if (key == (u8) ~ 0)
11698     {
11699       errmsg ("l2tp session lookup key unset");
11700       return -99;
11701     }
11702
11703   M (L2TPV3_SET_LOOKUP_KEY, mp);
11704
11705   mp->key = key;
11706
11707   S (mp);
11708   W (ret);
11709   return ret;
11710 }
11711
11712 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11713   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11714 {
11715   vat_main_t *vam = &vat_main;
11716
11717   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11718          format_ip6_address, mp->our_address,
11719          format_ip6_address, mp->client_address,
11720          clib_net_to_host_u32 (mp->sw_if_index));
11721
11722   print (vam->ofp,
11723          "   local cookies %016llx %016llx remote cookie %016llx",
11724          clib_net_to_host_u64 (mp->local_cookie[0]),
11725          clib_net_to_host_u64 (mp->local_cookie[1]),
11726          clib_net_to_host_u64 (mp->remote_cookie));
11727
11728   print (vam->ofp, "   local session-id %d remote session-id %d",
11729          clib_net_to_host_u32 (mp->local_session_id),
11730          clib_net_to_host_u32 (mp->remote_session_id));
11731
11732   print (vam->ofp, "   l2 specific sublayer %s\n",
11733          mp->l2_sublayer_present ? "preset" : "absent");
11734
11735 }
11736
11737 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11738   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11739 {
11740   vat_main_t *vam = &vat_main;
11741   vat_json_node_t *node = NULL;
11742   struct in6_addr addr;
11743
11744   if (VAT_JSON_ARRAY != vam->json_tree.type)
11745     {
11746       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11747       vat_json_init_array (&vam->json_tree);
11748     }
11749   node = vat_json_array_add (&vam->json_tree);
11750
11751   vat_json_init_object (node);
11752
11753   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11754   vat_json_object_add_ip6 (node, "our_address", addr);
11755   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11756   vat_json_object_add_ip6 (node, "client_address", addr);
11757
11758   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11759   vat_json_init_array (lc);
11760   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11761   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11762   vat_json_object_add_uint (node, "remote_cookie",
11763                             clib_net_to_host_u64 (mp->remote_cookie));
11764
11765   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11766   vat_json_object_add_uint (node, "local_session_id",
11767                             clib_net_to_host_u32 (mp->local_session_id));
11768   vat_json_object_add_uint (node, "remote_session_id",
11769                             clib_net_to_host_u32 (mp->remote_session_id));
11770   vat_json_object_add_string_copy (node, "l2_sublayer",
11771                                    mp->l2_sublayer_present ? (u8 *) "present"
11772                                    : (u8 *) "absent");
11773 }
11774
11775 static int
11776 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11777 {
11778   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11779   vl_api_control_ping_t *mp_ping;
11780   int ret;
11781
11782   /* Get list of l2tpv3-tunnel interfaces */
11783   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11784   S (mp);
11785
11786   /* Use a control ping for synchronization */
11787   MPING (CONTROL_PING, mp_ping);
11788   S (mp_ping);
11789
11790   W (ret);
11791   return ret;
11792 }
11793
11794
11795 static void vl_api_sw_interface_tap_v2_details_t_handler
11796   (vl_api_sw_interface_tap_v2_details_t * mp)
11797 {
11798   vat_main_t *vam = &vat_main;
11799
11800   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11801                     mp->host_ip4_prefix_len);
11802   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11803                     mp->host_ip6_prefix_len);
11804
11805   print (vam->ofp,
11806          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11807          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11808          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11809          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11810          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11811
11812   vec_free (ip4);
11813   vec_free (ip6);
11814 }
11815
11816 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11817   (vl_api_sw_interface_tap_v2_details_t * mp)
11818 {
11819   vat_main_t *vam = &vat_main;
11820   vat_json_node_t *node = NULL;
11821
11822   if (VAT_JSON_ARRAY != vam->json_tree.type)
11823     {
11824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11825       vat_json_init_array (&vam->json_tree);
11826     }
11827   node = vat_json_array_add (&vam->json_tree);
11828
11829   vat_json_init_object (node);
11830   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11831   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11832   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11833   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11834   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11835   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11836   vat_json_object_add_string_copy (node, "host_mac_addr",
11837                                    format (0, "%U", format_ethernet_address,
11838                                            &mp->host_mac_addr));
11839   vat_json_object_add_string_copy (node, "host_namespace",
11840                                    mp->host_namespace);
11841   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11842   vat_json_object_add_string_copy (node, "host_ip4_addr",
11843                                    format (0, "%U/%d", format_ip4_address,
11844                                            mp->host_ip4_addr,
11845                                            mp->host_ip4_prefix_len));
11846   vat_json_object_add_string_copy (node, "host_ip6_addr",
11847                                    format (0, "%U/%d", format_ip6_address,
11848                                            mp->host_ip6_addr,
11849                                            mp->host_ip6_prefix_len));
11850
11851 }
11852
11853 static int
11854 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11855 {
11856   vl_api_sw_interface_tap_v2_dump_t *mp;
11857   vl_api_control_ping_t *mp_ping;
11858   int ret;
11859
11860   print (vam->ofp,
11861          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11862          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11863          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11864          "host_ip6_addr");
11865
11866   /* Get list of tap interfaces */
11867   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11868   S (mp);
11869
11870   /* Use a control ping for synchronization */
11871   MPING (CONTROL_PING, mp_ping);
11872   S (mp_ping);
11873
11874   W (ret);
11875   return ret;
11876 }
11877
11878 static void vl_api_sw_interface_virtio_pci_details_t_handler
11879   (vl_api_sw_interface_virtio_pci_details_t * mp)
11880 {
11881   vat_main_t *vam = &vat_main;
11882
11883   typedef union
11884   {
11885     struct
11886     {
11887       u16 domain;
11888       u8 bus;
11889       u8 slot:5;
11890       u8 function:3;
11891     };
11892     u32 as_u32;
11893   } pci_addr_t;
11894   pci_addr_t addr;
11895   addr.as_u32 = ntohl (mp->pci_addr);
11896   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11897                          addr.slot, addr.function);
11898
11899   print (vam->ofp,
11900          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11901          pci_addr, ntohl (mp->sw_if_index),
11902          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11903          format_ethernet_address, mp->mac_addr,
11904          clib_net_to_host_u64 (mp->features));
11905   vec_free (pci_addr);
11906 }
11907
11908 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11909   (vl_api_sw_interface_virtio_pci_details_t * mp)
11910 {
11911   vat_main_t *vam = &vat_main;
11912   vat_json_node_t *node = NULL;
11913
11914   if (VAT_JSON_ARRAY != vam->json_tree.type)
11915     {
11916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11917       vat_json_init_array (&vam->json_tree);
11918     }
11919   node = vat_json_array_add (&vam->json_tree);
11920
11921   vat_json_init_object (node);
11922   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11923   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11924   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11925   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11926   vat_json_object_add_uint (node, "features",
11927                             clib_net_to_host_u64 (mp->features));
11928   vat_json_object_add_string_copy (node, "mac_addr",
11929                                    format (0, "%U", format_ethernet_address,
11930                                            &mp->mac_addr));
11931 }
11932
11933 static int
11934 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11935 {
11936   vl_api_sw_interface_virtio_pci_dump_t *mp;
11937   vl_api_control_ping_t *mp_ping;
11938   int ret;
11939
11940   print (vam->ofp,
11941          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11942          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11943          "mac_addr", "features");
11944
11945   /* Get list of tap interfaces */
11946   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11947   S (mp);
11948
11949   /* Use a control ping for synchronization */
11950   MPING (CONTROL_PING, mp_ping);
11951   S (mp_ping);
11952
11953   W (ret);
11954   return ret;
11955 }
11956
11957 static int
11958 api_vxlan_offload_rx (vat_main_t * vam)
11959 {
11960   unformat_input_t *line_input = vam->input;
11961   vl_api_vxlan_offload_rx_t *mp;
11962   u32 hw_if_index = ~0, rx_if_index = ~0;
11963   u8 is_add = 1;
11964   int ret;
11965
11966   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (line_input, "del"))
11969         is_add = 0;
11970       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11971                          &hw_if_index))
11972         ;
11973       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11974         ;
11975       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11976                          &rx_if_index))
11977         ;
11978       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11979         ;
11980       else
11981         {
11982           errmsg ("parse error '%U'", format_unformat_error, line_input);
11983           return -99;
11984         }
11985     }
11986
11987   if (hw_if_index == ~0)
11988     {
11989       errmsg ("no hw interface");
11990       return -99;
11991     }
11992
11993   if (rx_if_index == ~0)
11994     {
11995       errmsg ("no rx tunnel");
11996       return -99;
11997     }
11998
11999   M (VXLAN_OFFLOAD_RX, mp);
12000
12001   mp->hw_if_index = ntohl (hw_if_index);
12002   mp->sw_if_index = ntohl (rx_if_index);
12003   mp->enable = is_add;
12004
12005   S (mp);
12006   W (ret);
12007   return ret;
12008 }
12009
12010 static uword unformat_vxlan_decap_next
12011   (unformat_input_t * input, va_list * args)
12012 {
12013   u32 *result = va_arg (*args, u32 *);
12014   u32 tmp;
12015
12016   if (unformat (input, "l2"))
12017     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12018   else if (unformat (input, "%d", &tmp))
12019     *result = tmp;
12020   else
12021     return 0;
12022   return 1;
12023 }
12024
12025 static int
12026 api_vxlan_add_del_tunnel (vat_main_t * vam)
12027 {
12028   unformat_input_t *line_input = vam->input;
12029   vl_api_vxlan_add_del_tunnel_t *mp;
12030   ip46_address_t src, dst;
12031   u8 is_add = 1;
12032   u8 ipv4_set = 0, ipv6_set = 0;
12033   u8 src_set = 0;
12034   u8 dst_set = 0;
12035   u8 grp_set = 0;
12036   u32 instance = ~0;
12037   u32 mcast_sw_if_index = ~0;
12038   u32 encap_vrf_id = 0;
12039   u32 decap_next_index = ~0;
12040   u32 vni = 0;
12041   int ret;
12042
12043   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12044   clib_memset (&src, 0, sizeof src);
12045   clib_memset (&dst, 0, sizeof dst);
12046
12047   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12048     {
12049       if (unformat (line_input, "del"))
12050         is_add = 0;
12051       else if (unformat (line_input, "instance %d", &instance))
12052         ;
12053       else
12054         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12055         {
12056           ipv4_set = 1;
12057           src_set = 1;
12058         }
12059       else
12060         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12061         {
12062           ipv4_set = 1;
12063           dst_set = 1;
12064         }
12065       else
12066         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12067         {
12068           ipv6_set = 1;
12069           src_set = 1;
12070         }
12071       else
12072         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12073         {
12074           ipv6_set = 1;
12075           dst_set = 1;
12076         }
12077       else if (unformat (line_input, "group %U %U",
12078                          unformat_ip4_address, &dst.ip4,
12079                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12080         {
12081           grp_set = dst_set = 1;
12082           ipv4_set = 1;
12083         }
12084       else if (unformat (line_input, "group %U",
12085                          unformat_ip4_address, &dst.ip4))
12086         {
12087           grp_set = dst_set = 1;
12088           ipv4_set = 1;
12089         }
12090       else if (unformat (line_input, "group %U %U",
12091                          unformat_ip6_address, &dst.ip6,
12092                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12093         {
12094           grp_set = dst_set = 1;
12095           ipv6_set = 1;
12096         }
12097       else if (unformat (line_input, "group %U",
12098                          unformat_ip6_address, &dst.ip6))
12099         {
12100           grp_set = dst_set = 1;
12101           ipv6_set = 1;
12102         }
12103       else
12104         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12105         ;
12106       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12107         ;
12108       else if (unformat (line_input, "decap-next %U",
12109                          unformat_vxlan_decap_next, &decap_next_index))
12110         ;
12111       else if (unformat (line_input, "vni %d", &vni))
12112         ;
12113       else
12114         {
12115           errmsg ("parse error '%U'", format_unformat_error, line_input);
12116           return -99;
12117         }
12118     }
12119
12120   if (src_set == 0)
12121     {
12122       errmsg ("tunnel src address not specified");
12123       return -99;
12124     }
12125   if (dst_set == 0)
12126     {
12127       errmsg ("tunnel dst address not specified");
12128       return -99;
12129     }
12130
12131   if (grp_set && !ip46_address_is_multicast (&dst))
12132     {
12133       errmsg ("tunnel group address not multicast");
12134       return -99;
12135     }
12136   if (grp_set && mcast_sw_if_index == ~0)
12137     {
12138       errmsg ("tunnel nonexistent multicast device");
12139       return -99;
12140     }
12141   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12142     {
12143       errmsg ("tunnel dst address must be unicast");
12144       return -99;
12145     }
12146
12147
12148   if (ipv4_set && ipv6_set)
12149     {
12150       errmsg ("both IPv4 and IPv6 addresses specified");
12151       return -99;
12152     }
12153
12154   if ((vni == 0) || (vni >> 24))
12155     {
12156       errmsg ("vni not specified or out of range");
12157       return -99;
12158     }
12159
12160   M (VXLAN_ADD_DEL_TUNNEL, mp);
12161
12162   if (ipv6_set)
12163     {
12164       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12165       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12166     }
12167   else
12168     {
12169       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12170       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12171     }
12172
12173   mp->instance = htonl (instance);
12174   mp->encap_vrf_id = ntohl (encap_vrf_id);
12175   mp->decap_next_index = ntohl (decap_next_index);
12176   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12177   mp->vni = ntohl (vni);
12178   mp->is_add = is_add;
12179   mp->is_ipv6 = ipv6_set;
12180
12181   S (mp);
12182   W (ret);
12183   return ret;
12184 }
12185
12186 static void vl_api_vxlan_tunnel_details_t_handler
12187   (vl_api_vxlan_tunnel_details_t * mp)
12188 {
12189   vat_main_t *vam = &vat_main;
12190   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12191   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12192
12193   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12194          ntohl (mp->sw_if_index),
12195          ntohl (mp->instance),
12196          format_ip46_address, &src, IP46_TYPE_ANY,
12197          format_ip46_address, &dst, IP46_TYPE_ANY,
12198          ntohl (mp->encap_vrf_id),
12199          ntohl (mp->decap_next_index), ntohl (mp->vni),
12200          ntohl (mp->mcast_sw_if_index));
12201 }
12202
12203 static void vl_api_vxlan_tunnel_details_t_handler_json
12204   (vl_api_vxlan_tunnel_details_t * mp)
12205 {
12206   vat_main_t *vam = &vat_main;
12207   vat_json_node_t *node = NULL;
12208
12209   if (VAT_JSON_ARRAY != vam->json_tree.type)
12210     {
12211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12212       vat_json_init_array (&vam->json_tree);
12213     }
12214   node = vat_json_array_add (&vam->json_tree);
12215
12216   vat_json_init_object (node);
12217   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12218
12219   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12220
12221   if (mp->is_ipv6)
12222     {
12223       struct in6_addr ip6;
12224
12225       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12226       vat_json_object_add_ip6 (node, "src_address", ip6);
12227       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12228       vat_json_object_add_ip6 (node, "dst_address", ip6);
12229     }
12230   else
12231     {
12232       struct in_addr ip4;
12233
12234       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12235       vat_json_object_add_ip4 (node, "src_address", ip4);
12236       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12237       vat_json_object_add_ip4 (node, "dst_address", ip4);
12238     }
12239   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12240   vat_json_object_add_uint (node, "decap_next_index",
12241                             ntohl (mp->decap_next_index));
12242   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12243   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12244   vat_json_object_add_uint (node, "mcast_sw_if_index",
12245                             ntohl (mp->mcast_sw_if_index));
12246 }
12247
12248 static int
12249 api_vxlan_tunnel_dump (vat_main_t * vam)
12250 {
12251   unformat_input_t *i = vam->input;
12252   vl_api_vxlan_tunnel_dump_t *mp;
12253   vl_api_control_ping_t *mp_ping;
12254   u32 sw_if_index;
12255   u8 sw_if_index_set = 0;
12256   int ret;
12257
12258   /* Parse args required to build the message */
12259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12260     {
12261       if (unformat (i, "sw_if_index %d", &sw_if_index))
12262         sw_if_index_set = 1;
12263       else
12264         break;
12265     }
12266
12267   if (sw_if_index_set == 0)
12268     {
12269       sw_if_index = ~0;
12270     }
12271
12272   if (!vam->json_output)
12273     {
12274       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12275              "sw_if_index", "instance", "src_address", "dst_address",
12276              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12277     }
12278
12279   /* Get list of vxlan-tunnel interfaces */
12280   M (VXLAN_TUNNEL_DUMP, mp);
12281
12282   mp->sw_if_index = htonl (sw_if_index);
12283
12284   S (mp);
12285
12286   /* Use a control ping for synchronization */
12287   MPING (CONTROL_PING, mp_ping);
12288   S (mp_ping);
12289
12290   W (ret);
12291   return ret;
12292 }
12293
12294 static uword unformat_geneve_decap_next
12295   (unformat_input_t * input, va_list * args)
12296 {
12297   u32 *result = va_arg (*args, u32 *);
12298   u32 tmp;
12299
12300   if (unformat (input, "l2"))
12301     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12302   else if (unformat (input, "%d", &tmp))
12303     *result = tmp;
12304   else
12305     return 0;
12306   return 1;
12307 }
12308
12309 static int
12310 api_geneve_add_del_tunnel (vat_main_t * vam)
12311 {
12312   unformat_input_t *line_input = vam->input;
12313   vl_api_geneve_add_del_tunnel_t *mp;
12314   ip46_address_t src, dst;
12315   u8 is_add = 1;
12316   u8 ipv4_set = 0, ipv6_set = 0;
12317   u8 src_set = 0;
12318   u8 dst_set = 0;
12319   u8 grp_set = 0;
12320   u32 mcast_sw_if_index = ~0;
12321   u32 encap_vrf_id = 0;
12322   u32 decap_next_index = ~0;
12323   u32 vni = 0;
12324   int ret;
12325
12326   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12327   clib_memset (&src, 0, sizeof src);
12328   clib_memset (&dst, 0, sizeof dst);
12329
12330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (line_input, "del"))
12333         is_add = 0;
12334       else
12335         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12336         {
12337           ipv4_set = 1;
12338           src_set = 1;
12339         }
12340       else
12341         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12342         {
12343           ipv4_set = 1;
12344           dst_set = 1;
12345         }
12346       else
12347         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12348         {
12349           ipv6_set = 1;
12350           src_set = 1;
12351         }
12352       else
12353         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12354         {
12355           ipv6_set = 1;
12356           dst_set = 1;
12357         }
12358       else if (unformat (line_input, "group %U %U",
12359                          unformat_ip4_address, &dst.ip4,
12360                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12361         {
12362           grp_set = dst_set = 1;
12363           ipv4_set = 1;
12364         }
12365       else if (unformat (line_input, "group %U",
12366                          unformat_ip4_address, &dst.ip4))
12367         {
12368           grp_set = dst_set = 1;
12369           ipv4_set = 1;
12370         }
12371       else if (unformat (line_input, "group %U %U",
12372                          unformat_ip6_address, &dst.ip6,
12373                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12374         {
12375           grp_set = dst_set = 1;
12376           ipv6_set = 1;
12377         }
12378       else if (unformat (line_input, "group %U",
12379                          unformat_ip6_address, &dst.ip6))
12380         {
12381           grp_set = dst_set = 1;
12382           ipv6_set = 1;
12383         }
12384       else
12385         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12386         ;
12387       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12388         ;
12389       else if (unformat (line_input, "decap-next %U",
12390                          unformat_geneve_decap_next, &decap_next_index))
12391         ;
12392       else if (unformat (line_input, "vni %d", &vni))
12393         ;
12394       else
12395         {
12396           errmsg ("parse error '%U'", format_unformat_error, line_input);
12397           return -99;
12398         }
12399     }
12400
12401   if (src_set == 0)
12402     {
12403       errmsg ("tunnel src address not specified");
12404       return -99;
12405     }
12406   if (dst_set == 0)
12407     {
12408       errmsg ("tunnel dst address not specified");
12409       return -99;
12410     }
12411
12412   if (grp_set && !ip46_address_is_multicast (&dst))
12413     {
12414       errmsg ("tunnel group address not multicast");
12415       return -99;
12416     }
12417   if (grp_set && mcast_sw_if_index == ~0)
12418     {
12419       errmsg ("tunnel nonexistent multicast device");
12420       return -99;
12421     }
12422   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12423     {
12424       errmsg ("tunnel dst address must be unicast");
12425       return -99;
12426     }
12427
12428
12429   if (ipv4_set && ipv6_set)
12430     {
12431       errmsg ("both IPv4 and IPv6 addresses specified");
12432       return -99;
12433     }
12434
12435   if ((vni == 0) || (vni >> 24))
12436     {
12437       errmsg ("vni not specified or out of range");
12438       return -99;
12439     }
12440
12441   M (GENEVE_ADD_DEL_TUNNEL, mp);
12442
12443   if (ipv6_set)
12444     {
12445       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12446       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12447     }
12448   else
12449     {
12450       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12451       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12452     }
12453   mp->encap_vrf_id = ntohl (encap_vrf_id);
12454   mp->decap_next_index = ntohl (decap_next_index);
12455   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12456   mp->vni = ntohl (vni);
12457   mp->is_add = is_add;
12458
12459   S (mp);
12460   W (ret);
12461   return ret;
12462 }
12463
12464 static void vl_api_geneve_tunnel_details_t_handler
12465   (vl_api_geneve_tunnel_details_t * mp)
12466 {
12467   vat_main_t *vam = &vat_main;
12468   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12469   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12470
12471   if (mp->src_address.af == ADDRESS_IP6)
12472     {
12473       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12474       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12475     }
12476   else
12477     {
12478       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12479       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12480     }
12481
12482   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12483          ntohl (mp->sw_if_index),
12484          format_ip46_address, &src, IP46_TYPE_ANY,
12485          format_ip46_address, &dst, IP46_TYPE_ANY,
12486          ntohl (mp->encap_vrf_id),
12487          ntohl (mp->decap_next_index), ntohl (mp->vni),
12488          ntohl (mp->mcast_sw_if_index));
12489 }
12490
12491 static void vl_api_geneve_tunnel_details_t_handler_json
12492   (vl_api_geneve_tunnel_details_t * mp)
12493 {
12494   vat_main_t *vam = &vat_main;
12495   vat_json_node_t *node = NULL;
12496   bool is_ipv6;
12497
12498   if (VAT_JSON_ARRAY != vam->json_tree.type)
12499     {
12500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12501       vat_json_init_array (&vam->json_tree);
12502     }
12503   node = vat_json_array_add (&vam->json_tree);
12504
12505   vat_json_init_object (node);
12506   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12507   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12508   if (is_ipv6)
12509     {
12510       struct in6_addr ip6;
12511
12512       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12513       vat_json_object_add_ip6 (node, "src_address", ip6);
12514       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12515       vat_json_object_add_ip6 (node, "dst_address", ip6);
12516     }
12517   else
12518     {
12519       struct in_addr ip4;
12520
12521       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12522       vat_json_object_add_ip4 (node, "src_address", ip4);
12523       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12524       vat_json_object_add_ip4 (node, "dst_address", ip4);
12525     }
12526   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12527   vat_json_object_add_uint (node, "decap_next_index",
12528                             ntohl (mp->decap_next_index));
12529   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12530   vat_json_object_add_uint (node, "mcast_sw_if_index",
12531                             ntohl (mp->mcast_sw_if_index));
12532 }
12533
12534 static int
12535 api_geneve_tunnel_dump (vat_main_t * vam)
12536 {
12537   unformat_input_t *i = vam->input;
12538   vl_api_geneve_tunnel_dump_t *mp;
12539   vl_api_control_ping_t *mp_ping;
12540   u32 sw_if_index;
12541   u8 sw_if_index_set = 0;
12542   int ret;
12543
12544   /* Parse args required to build the message */
12545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12546     {
12547       if (unformat (i, "sw_if_index %d", &sw_if_index))
12548         sw_if_index_set = 1;
12549       else
12550         break;
12551     }
12552
12553   if (sw_if_index_set == 0)
12554     {
12555       sw_if_index = ~0;
12556     }
12557
12558   if (!vam->json_output)
12559     {
12560       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12561              "sw_if_index", "local_address", "remote_address",
12562              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12563     }
12564
12565   /* Get list of geneve-tunnel interfaces */
12566   M (GENEVE_TUNNEL_DUMP, mp);
12567
12568   mp->sw_if_index = htonl (sw_if_index);
12569
12570   S (mp);
12571
12572   /* Use a control ping for synchronization */
12573   M (CONTROL_PING, mp_ping);
12574   S (mp_ping);
12575
12576   W (ret);
12577   return ret;
12578 }
12579
12580 static int
12581 api_gre_tunnel_add_del (vat_main_t * vam)
12582 {
12583   unformat_input_t *line_input = vam->input;
12584   vl_api_address_t src = { }, dst =
12585   {
12586   };
12587   vl_api_gre_tunnel_add_del_t *mp;
12588   vl_api_gre_tunnel_type_t t_type;
12589   u8 is_add = 1;
12590   u8 src_set = 0;
12591   u8 dst_set = 0;
12592   u32 outer_fib_id = 0;
12593   u32 session_id = 0;
12594   u32 instance = ~0;
12595   int ret;
12596
12597   t_type = GRE_API_TUNNEL_TYPE_L3;
12598
12599   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12600     {
12601       if (unformat (line_input, "del"))
12602         is_add = 0;
12603       else if (unformat (line_input, "instance %d", &instance))
12604         ;
12605       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12606         {
12607           src_set = 1;
12608         }
12609       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12610         {
12611           dst_set = 1;
12612         }
12613       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12614         ;
12615       else if (unformat (line_input, "teb"))
12616         t_type = GRE_API_TUNNEL_TYPE_TEB;
12617       else if (unformat (line_input, "erspan %d", &session_id))
12618         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12619       else
12620         {
12621           errmsg ("parse error '%U'", format_unformat_error, line_input);
12622           return -99;
12623         }
12624     }
12625
12626   if (src_set == 0)
12627     {
12628       errmsg ("tunnel src address not specified");
12629       return -99;
12630     }
12631   if (dst_set == 0)
12632     {
12633       errmsg ("tunnel dst address not specified");
12634       return -99;
12635     }
12636
12637   M (GRE_TUNNEL_ADD_DEL, mp);
12638
12639   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12640   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12641
12642   mp->tunnel.instance = htonl (instance);
12643   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12644   mp->is_add = is_add;
12645   mp->tunnel.session_id = htons ((u16) session_id);
12646   mp->tunnel.type = htonl (t_type);
12647
12648   S (mp);
12649   W (ret);
12650   return ret;
12651 }
12652
12653 static void vl_api_gre_tunnel_details_t_handler
12654   (vl_api_gre_tunnel_details_t * mp)
12655 {
12656   vat_main_t *vam = &vat_main;
12657
12658   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12659          ntohl (mp->tunnel.sw_if_index),
12660          ntohl (mp->tunnel.instance),
12661          format_vl_api_address, &mp->tunnel.src,
12662          format_vl_api_address, &mp->tunnel.dst,
12663          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12664          ntohl (mp->tunnel.session_id));
12665 }
12666
12667 static void vl_api_gre_tunnel_details_t_handler_json
12668   (vl_api_gre_tunnel_details_t * mp)
12669 {
12670   vat_main_t *vam = &vat_main;
12671   vat_json_node_t *node = NULL;
12672
12673   if (VAT_JSON_ARRAY != vam->json_tree.type)
12674     {
12675       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12676       vat_json_init_array (&vam->json_tree);
12677     }
12678   node = vat_json_array_add (&vam->json_tree);
12679
12680   vat_json_init_object (node);
12681   vat_json_object_add_uint (node, "sw_if_index",
12682                             ntohl (mp->tunnel.sw_if_index));
12683   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12684
12685   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12686   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12687   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12688   vat_json_object_add_uint (node, "outer_fib_id",
12689                             ntohl (mp->tunnel.outer_fib_id));
12690   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12691 }
12692
12693 static int
12694 api_gre_tunnel_dump (vat_main_t * vam)
12695 {
12696   unformat_input_t *i = vam->input;
12697   vl_api_gre_tunnel_dump_t *mp;
12698   vl_api_control_ping_t *mp_ping;
12699   u32 sw_if_index;
12700   u8 sw_if_index_set = 0;
12701   int ret;
12702
12703   /* Parse args required to build the message */
12704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12705     {
12706       if (unformat (i, "sw_if_index %d", &sw_if_index))
12707         sw_if_index_set = 1;
12708       else
12709         break;
12710     }
12711
12712   if (sw_if_index_set == 0)
12713     {
12714       sw_if_index = ~0;
12715     }
12716
12717   if (!vam->json_output)
12718     {
12719       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12720              "sw_if_index", "instance", "src_address", "dst_address",
12721              "tunnel_type", "outer_fib_id", "session_id");
12722     }
12723
12724   /* Get list of gre-tunnel interfaces */
12725   M (GRE_TUNNEL_DUMP, mp);
12726
12727   mp->sw_if_index = htonl (sw_if_index);
12728
12729   S (mp);
12730
12731   /* Use a control ping for synchronization */
12732   MPING (CONTROL_PING, mp_ping);
12733   S (mp_ping);
12734
12735   W (ret);
12736   return ret;
12737 }
12738
12739 static int
12740 api_l2_fib_clear_table (vat_main_t * vam)
12741 {
12742 //  unformat_input_t * i = vam->input;
12743   vl_api_l2_fib_clear_table_t *mp;
12744   int ret;
12745
12746   M (L2_FIB_CLEAR_TABLE, mp);
12747
12748   S (mp);
12749   W (ret);
12750   return ret;
12751 }
12752
12753 static int
12754 api_l2_interface_efp_filter (vat_main_t * vam)
12755 {
12756   unformat_input_t *i = vam->input;
12757   vl_api_l2_interface_efp_filter_t *mp;
12758   u32 sw_if_index;
12759   u8 enable = 1;
12760   u8 sw_if_index_set = 0;
12761   int ret;
12762
12763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12764     {
12765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12766         sw_if_index_set = 1;
12767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12768         sw_if_index_set = 1;
12769       else if (unformat (i, "enable"))
12770         enable = 1;
12771       else if (unformat (i, "disable"))
12772         enable = 0;
12773       else
12774         {
12775           clib_warning ("parse error '%U'", format_unformat_error, i);
12776           return -99;
12777         }
12778     }
12779
12780   if (sw_if_index_set == 0)
12781     {
12782       errmsg ("missing sw_if_index");
12783       return -99;
12784     }
12785
12786   M (L2_INTERFACE_EFP_FILTER, mp);
12787
12788   mp->sw_if_index = ntohl (sw_if_index);
12789   mp->enable_disable = enable;
12790
12791   S (mp);
12792   W (ret);
12793   return ret;
12794 }
12795
12796 #define foreach_vtr_op                          \
12797 _("disable",  L2_VTR_DISABLED)                  \
12798 _("push-1",  L2_VTR_PUSH_1)                     \
12799 _("push-2",  L2_VTR_PUSH_2)                     \
12800 _("pop-1",  L2_VTR_POP_1)                       \
12801 _("pop-2",  L2_VTR_POP_2)                       \
12802 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12803 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12804 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12805 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12806
12807 static int
12808 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12809 {
12810   unformat_input_t *i = vam->input;
12811   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12812   u32 sw_if_index;
12813   u8 sw_if_index_set = 0;
12814   u8 vtr_op_set = 0;
12815   u32 vtr_op = 0;
12816   u32 push_dot1q = 1;
12817   u32 tag1 = ~0;
12818   u32 tag2 = ~0;
12819   int ret;
12820
12821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12822     {
12823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12824         sw_if_index_set = 1;
12825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12826         sw_if_index_set = 1;
12827       else if (unformat (i, "vtr_op %d", &vtr_op))
12828         vtr_op_set = 1;
12829 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12830       foreach_vtr_op
12831 #undef _
12832         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12833         ;
12834       else if (unformat (i, "tag1 %d", &tag1))
12835         ;
12836       else if (unformat (i, "tag2 %d", &tag2))
12837         ;
12838       else
12839         {
12840           clib_warning ("parse error '%U'", format_unformat_error, i);
12841           return -99;
12842         }
12843     }
12844
12845   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12846     {
12847       errmsg ("missing vtr operation or sw_if_index");
12848       return -99;
12849     }
12850
12851   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12852   mp->sw_if_index = ntohl (sw_if_index);
12853   mp->vtr_op = ntohl (vtr_op);
12854   mp->push_dot1q = ntohl (push_dot1q);
12855   mp->tag1 = ntohl (tag1);
12856   mp->tag2 = ntohl (tag2);
12857
12858   S (mp);
12859   W (ret);
12860   return ret;
12861 }
12862
12863 static int
12864 api_create_vhost_user_if (vat_main_t * vam)
12865 {
12866   unformat_input_t *i = vam->input;
12867   vl_api_create_vhost_user_if_t *mp;
12868   u8 *file_name;
12869   u8 is_server = 0;
12870   u8 file_name_set = 0;
12871   u32 custom_dev_instance = ~0;
12872   u8 hwaddr[6];
12873   u8 use_custom_mac = 0;
12874   u8 disable_mrg_rxbuf = 0;
12875   u8 disable_indirect_desc = 0;
12876   u8 *tag = 0;
12877   u8 enable_gso = 0;
12878   int ret;
12879
12880   /* Shut up coverity */
12881   clib_memset (hwaddr, 0, sizeof (hwaddr));
12882
12883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12884     {
12885       if (unformat (i, "socket %s", &file_name))
12886         {
12887           file_name_set = 1;
12888         }
12889       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12890         ;
12891       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12892         use_custom_mac = 1;
12893       else if (unformat (i, "server"))
12894         is_server = 1;
12895       else if (unformat (i, "disable_mrg_rxbuf"))
12896         disable_mrg_rxbuf = 1;
12897       else if (unformat (i, "disable_indirect_desc"))
12898         disable_indirect_desc = 1;
12899       else if (unformat (i, "gso"))
12900         enable_gso = 1;
12901       else if (unformat (i, "tag %s", &tag))
12902         ;
12903       else
12904         break;
12905     }
12906
12907   if (file_name_set == 0)
12908     {
12909       errmsg ("missing socket file name");
12910       return -99;
12911     }
12912
12913   if (vec_len (file_name) > 255)
12914     {
12915       errmsg ("socket file name too long");
12916       return -99;
12917     }
12918   vec_add1 (file_name, 0);
12919
12920   M (CREATE_VHOST_USER_IF, mp);
12921
12922   mp->is_server = is_server;
12923   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12924   mp->disable_indirect_desc = disable_indirect_desc;
12925   mp->enable_gso = enable_gso;
12926   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12927   vec_free (file_name);
12928   if (custom_dev_instance != ~0)
12929     {
12930       mp->renumber = 1;
12931       mp->custom_dev_instance = ntohl (custom_dev_instance);
12932     }
12933
12934   mp->use_custom_mac = use_custom_mac;
12935   clib_memcpy (mp->mac_address, hwaddr, 6);
12936   if (tag)
12937     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12938   vec_free (tag);
12939
12940   S (mp);
12941   W (ret);
12942   return ret;
12943 }
12944
12945 static int
12946 api_modify_vhost_user_if (vat_main_t * vam)
12947 {
12948   unformat_input_t *i = vam->input;
12949   vl_api_modify_vhost_user_if_t *mp;
12950   u8 *file_name;
12951   u8 is_server = 0;
12952   u8 file_name_set = 0;
12953   u32 custom_dev_instance = ~0;
12954   u8 sw_if_index_set = 0;
12955   u32 sw_if_index = (u32) ~ 0;
12956   u8 enable_gso = 0;
12957   int ret;
12958
12959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12960     {
12961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12962         sw_if_index_set = 1;
12963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12964         sw_if_index_set = 1;
12965       else if (unformat (i, "socket %s", &file_name))
12966         {
12967           file_name_set = 1;
12968         }
12969       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12970         ;
12971       else if (unformat (i, "server"))
12972         is_server = 1;
12973       else if (unformat (i, "gso"))
12974         enable_gso = 1;
12975       else
12976         break;
12977     }
12978
12979   if (sw_if_index_set == 0)
12980     {
12981       errmsg ("missing sw_if_index or interface name");
12982       return -99;
12983     }
12984
12985   if (file_name_set == 0)
12986     {
12987       errmsg ("missing socket file name");
12988       return -99;
12989     }
12990
12991   if (vec_len (file_name) > 255)
12992     {
12993       errmsg ("socket file name too long");
12994       return -99;
12995     }
12996   vec_add1 (file_name, 0);
12997
12998   M (MODIFY_VHOST_USER_IF, mp);
12999
13000   mp->sw_if_index = ntohl (sw_if_index);
13001   mp->is_server = is_server;
13002   mp->enable_gso = enable_gso;
13003   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13004   vec_free (file_name);
13005   if (custom_dev_instance != ~0)
13006     {
13007       mp->renumber = 1;
13008       mp->custom_dev_instance = ntohl (custom_dev_instance);
13009     }
13010
13011   S (mp);
13012   W (ret);
13013   return ret;
13014 }
13015
13016 static int
13017 api_delete_vhost_user_if (vat_main_t * vam)
13018 {
13019   unformat_input_t *i = vam->input;
13020   vl_api_delete_vhost_user_if_t *mp;
13021   u32 sw_if_index = ~0;
13022   u8 sw_if_index_set = 0;
13023   int ret;
13024
13025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13028         sw_if_index_set = 1;
13029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13030         sw_if_index_set = 1;
13031       else
13032         break;
13033     }
13034
13035   if (sw_if_index_set == 0)
13036     {
13037       errmsg ("missing sw_if_index or interface name");
13038       return -99;
13039     }
13040
13041
13042   M (DELETE_VHOST_USER_IF, mp);
13043
13044   mp->sw_if_index = ntohl (sw_if_index);
13045
13046   S (mp);
13047   W (ret);
13048   return ret;
13049 }
13050
13051 static void vl_api_sw_interface_vhost_user_details_t_handler
13052   (vl_api_sw_interface_vhost_user_details_t * mp)
13053 {
13054   vat_main_t *vam = &vat_main;
13055
13056   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13057          (char *) mp->interface_name,
13058          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13059          clib_net_to_host_u64 (mp->features), mp->is_server,
13060          ntohl (mp->num_regions), (char *) mp->sock_filename);
13061   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13062 }
13063
13064 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13065   (vl_api_sw_interface_vhost_user_details_t * mp)
13066 {
13067   vat_main_t *vam = &vat_main;
13068   vat_json_node_t *node = NULL;
13069
13070   if (VAT_JSON_ARRAY != vam->json_tree.type)
13071     {
13072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13073       vat_json_init_array (&vam->json_tree);
13074     }
13075   node = vat_json_array_add (&vam->json_tree);
13076
13077   vat_json_init_object (node);
13078   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13079   vat_json_object_add_string_copy (node, "interface_name",
13080                                    mp->interface_name);
13081   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13082                             ntohl (mp->virtio_net_hdr_sz));
13083   vat_json_object_add_uint (node, "features",
13084                             clib_net_to_host_u64 (mp->features));
13085   vat_json_object_add_uint (node, "is_server", mp->is_server);
13086   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13087   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13088   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13089 }
13090
13091 static int
13092 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13093 {
13094   vl_api_sw_interface_vhost_user_dump_t *mp;
13095   vl_api_control_ping_t *mp_ping;
13096   int ret;
13097   print (vam->ofp,
13098          "Interface name            idx hdr_sz features server regions filename");
13099
13100   /* Get list of vhost-user interfaces */
13101   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13102   S (mp);
13103
13104   /* Use a control ping for synchronization */
13105   MPING (CONTROL_PING, mp_ping);
13106   S (mp_ping);
13107
13108   W (ret);
13109   return ret;
13110 }
13111
13112 static int
13113 api_show_version (vat_main_t * vam)
13114 {
13115   vl_api_show_version_t *mp;
13116   int ret;
13117
13118   M (SHOW_VERSION, mp);
13119
13120   S (mp);
13121   W (ret);
13122   return ret;
13123 }
13124
13125
13126 static int
13127 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13128 {
13129   unformat_input_t *line_input = vam->input;
13130   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13131   ip4_address_t local4, remote4;
13132   ip6_address_t local6, remote6;
13133   u8 is_add = 1;
13134   u8 ipv4_set = 0, ipv6_set = 0;
13135   u8 local_set = 0;
13136   u8 remote_set = 0;
13137   u8 grp_set = 0;
13138   u32 mcast_sw_if_index = ~0;
13139   u32 encap_vrf_id = 0;
13140   u32 decap_vrf_id = 0;
13141   u8 protocol = ~0;
13142   u32 vni;
13143   u8 vni_set = 0;
13144   int ret;
13145
13146   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13147   clib_memset (&local4, 0, sizeof local4);
13148   clib_memset (&remote4, 0, sizeof remote4);
13149   clib_memset (&local6, 0, sizeof local6);
13150   clib_memset (&remote6, 0, sizeof remote6);
13151
13152   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13153     {
13154       if (unformat (line_input, "del"))
13155         is_add = 0;
13156       else if (unformat (line_input, "local %U",
13157                          unformat_ip4_address, &local4))
13158         {
13159           local_set = 1;
13160           ipv4_set = 1;
13161         }
13162       else if (unformat (line_input, "remote %U",
13163                          unformat_ip4_address, &remote4))
13164         {
13165           remote_set = 1;
13166           ipv4_set = 1;
13167         }
13168       else if (unformat (line_input, "local %U",
13169                          unformat_ip6_address, &local6))
13170         {
13171           local_set = 1;
13172           ipv6_set = 1;
13173         }
13174       else if (unformat (line_input, "remote %U",
13175                          unformat_ip6_address, &remote6))
13176         {
13177           remote_set = 1;
13178           ipv6_set = 1;
13179         }
13180       else if (unformat (line_input, "group %U %U",
13181                          unformat_ip4_address, &remote4,
13182                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13183         {
13184           grp_set = remote_set = 1;
13185           ipv4_set = 1;
13186         }
13187       else if (unformat (line_input, "group %U",
13188                          unformat_ip4_address, &remote4))
13189         {
13190           grp_set = remote_set = 1;
13191           ipv4_set = 1;
13192         }
13193       else if (unformat (line_input, "group %U %U",
13194                          unformat_ip6_address, &remote6,
13195                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13196         {
13197           grp_set = remote_set = 1;
13198           ipv6_set = 1;
13199         }
13200       else if (unformat (line_input, "group %U",
13201                          unformat_ip6_address, &remote6))
13202         {
13203           grp_set = remote_set = 1;
13204           ipv6_set = 1;
13205         }
13206       else
13207         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13208         ;
13209       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13210         ;
13211       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13212         ;
13213       else if (unformat (line_input, "vni %d", &vni))
13214         vni_set = 1;
13215       else if (unformat (line_input, "next-ip4"))
13216         protocol = 1;
13217       else if (unformat (line_input, "next-ip6"))
13218         protocol = 2;
13219       else if (unformat (line_input, "next-ethernet"))
13220         protocol = 3;
13221       else if (unformat (line_input, "next-nsh"))
13222         protocol = 4;
13223       else
13224         {
13225           errmsg ("parse error '%U'", format_unformat_error, line_input);
13226           return -99;
13227         }
13228     }
13229
13230   if (local_set == 0)
13231     {
13232       errmsg ("tunnel local address not specified");
13233       return -99;
13234     }
13235   if (remote_set == 0)
13236     {
13237       errmsg ("tunnel remote address not specified");
13238       return -99;
13239     }
13240   if (grp_set && mcast_sw_if_index == ~0)
13241     {
13242       errmsg ("tunnel nonexistent multicast device");
13243       return -99;
13244     }
13245   if (ipv4_set && ipv6_set)
13246     {
13247       errmsg ("both IPv4 and IPv6 addresses specified");
13248       return -99;
13249     }
13250
13251   if (vni_set == 0)
13252     {
13253       errmsg ("vni not specified");
13254       return -99;
13255     }
13256
13257   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13258
13259
13260   if (ipv6_set)
13261     {
13262       clib_memcpy (&mp->local, &local6, sizeof (local6));
13263       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13264     }
13265   else
13266     {
13267       clib_memcpy (&mp->local, &local4, sizeof (local4));
13268       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13269     }
13270
13271   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13272   mp->encap_vrf_id = ntohl (encap_vrf_id);
13273   mp->decap_vrf_id = ntohl (decap_vrf_id);
13274   mp->protocol = protocol;
13275   mp->vni = ntohl (vni);
13276   mp->is_add = is_add;
13277   mp->is_ipv6 = ipv6_set;
13278
13279   S (mp);
13280   W (ret);
13281   return ret;
13282 }
13283
13284 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13285   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13286 {
13287   vat_main_t *vam = &vat_main;
13288   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13289   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13290
13291   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13292          ntohl (mp->sw_if_index),
13293          format_ip46_address, &local, IP46_TYPE_ANY,
13294          format_ip46_address, &remote, IP46_TYPE_ANY,
13295          ntohl (mp->vni), mp->protocol,
13296          ntohl (mp->mcast_sw_if_index),
13297          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13298 }
13299
13300
13301 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13302   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13303 {
13304   vat_main_t *vam = &vat_main;
13305   vat_json_node_t *node = NULL;
13306   struct in_addr ip4;
13307   struct in6_addr ip6;
13308
13309   if (VAT_JSON_ARRAY != vam->json_tree.type)
13310     {
13311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13312       vat_json_init_array (&vam->json_tree);
13313     }
13314   node = vat_json_array_add (&vam->json_tree);
13315
13316   vat_json_init_object (node);
13317   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13318   if (mp->is_ipv6)
13319     {
13320       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13321       vat_json_object_add_ip6 (node, "local", ip6);
13322       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13323       vat_json_object_add_ip6 (node, "remote", ip6);
13324     }
13325   else
13326     {
13327       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13328       vat_json_object_add_ip4 (node, "local", ip4);
13329       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13330       vat_json_object_add_ip4 (node, "remote", ip4);
13331     }
13332   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13333   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13334   vat_json_object_add_uint (node, "mcast_sw_if_index",
13335                             ntohl (mp->mcast_sw_if_index));
13336   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13337   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13338   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13339 }
13340
13341 static int
13342 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13343 {
13344   unformat_input_t *i = vam->input;
13345   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13346   vl_api_control_ping_t *mp_ping;
13347   u32 sw_if_index;
13348   u8 sw_if_index_set = 0;
13349   int ret;
13350
13351   /* Parse args required to build the message */
13352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (i, "sw_if_index %d", &sw_if_index))
13355         sw_if_index_set = 1;
13356       else
13357         break;
13358     }
13359
13360   if (sw_if_index_set == 0)
13361     {
13362       sw_if_index = ~0;
13363     }
13364
13365   if (!vam->json_output)
13366     {
13367       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13368              "sw_if_index", "local", "remote", "vni",
13369              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13370     }
13371
13372   /* Get list of vxlan-tunnel interfaces */
13373   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13374
13375   mp->sw_if_index = htonl (sw_if_index);
13376
13377   S (mp);
13378
13379   /* Use a control ping for synchronization */
13380   MPING (CONTROL_PING, mp_ping);
13381   S (mp_ping);
13382
13383   W (ret);
13384   return ret;
13385 }
13386
13387 static void vl_api_l2_fib_table_details_t_handler
13388   (vl_api_l2_fib_table_details_t * mp)
13389 {
13390   vat_main_t *vam = &vat_main;
13391
13392   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13393          "       %d       %d     %d",
13394          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13395          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13396          mp->bvi_mac);
13397 }
13398
13399 static void vl_api_l2_fib_table_details_t_handler_json
13400   (vl_api_l2_fib_table_details_t * mp)
13401 {
13402   vat_main_t *vam = &vat_main;
13403   vat_json_node_t *node = NULL;
13404
13405   if (VAT_JSON_ARRAY != vam->json_tree.type)
13406     {
13407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13408       vat_json_init_array (&vam->json_tree);
13409     }
13410   node = vat_json_array_add (&vam->json_tree);
13411
13412   vat_json_init_object (node);
13413   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13414   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13415   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13416   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13417   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13418   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13419 }
13420
13421 static int
13422 api_l2_fib_table_dump (vat_main_t * vam)
13423 {
13424   unformat_input_t *i = vam->input;
13425   vl_api_l2_fib_table_dump_t *mp;
13426   vl_api_control_ping_t *mp_ping;
13427   u32 bd_id;
13428   u8 bd_id_set = 0;
13429   int ret;
13430
13431   /* Parse args required to build the message */
13432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13433     {
13434       if (unformat (i, "bd_id %d", &bd_id))
13435         bd_id_set = 1;
13436       else
13437         break;
13438     }
13439
13440   if (bd_id_set == 0)
13441     {
13442       errmsg ("missing bridge domain");
13443       return -99;
13444     }
13445
13446   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13447
13448   /* Get list of l2 fib entries */
13449   M (L2_FIB_TABLE_DUMP, mp);
13450
13451   mp->bd_id = ntohl (bd_id);
13452   S (mp);
13453
13454   /* Use a control ping for synchronization */
13455   MPING (CONTROL_PING, mp_ping);
13456   S (mp_ping);
13457
13458   W (ret);
13459   return ret;
13460 }
13461
13462
13463 static int
13464 api_interface_name_renumber (vat_main_t * vam)
13465 {
13466   unformat_input_t *line_input = vam->input;
13467   vl_api_interface_name_renumber_t *mp;
13468   u32 sw_if_index = ~0;
13469   u32 new_show_dev_instance = ~0;
13470   int ret;
13471
13472   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13473     {
13474       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13475                     &sw_if_index))
13476         ;
13477       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13478         ;
13479       else if (unformat (line_input, "new_show_dev_instance %d",
13480                          &new_show_dev_instance))
13481         ;
13482       else
13483         break;
13484     }
13485
13486   if (sw_if_index == ~0)
13487     {
13488       errmsg ("missing interface name or sw_if_index");
13489       return -99;
13490     }
13491
13492   if (new_show_dev_instance == ~0)
13493     {
13494       errmsg ("missing new_show_dev_instance");
13495       return -99;
13496     }
13497
13498   M (INTERFACE_NAME_RENUMBER, mp);
13499
13500   mp->sw_if_index = ntohl (sw_if_index);
13501   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13502
13503   S (mp);
13504   W (ret);
13505   return ret;
13506 }
13507
13508 static int
13509 api_ip_probe_neighbor (vat_main_t * vam)
13510 {
13511   unformat_input_t *i = vam->input;
13512   vl_api_ip_probe_neighbor_t *mp;
13513   vl_api_address_t dst_adr = { };
13514   u8 int_set = 0;
13515   u8 adr_set = 0;
13516   u32 sw_if_index;
13517   int ret;
13518
13519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13520     {
13521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13522         int_set = 1;
13523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13524         int_set = 1;
13525       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13526         adr_set = 1;
13527       else
13528         break;
13529     }
13530
13531   if (int_set == 0)
13532     {
13533       errmsg ("missing interface");
13534       return -99;
13535     }
13536
13537   if (adr_set == 0)
13538     {
13539       errmsg ("missing addresses");
13540       return -99;
13541     }
13542
13543   M (IP_PROBE_NEIGHBOR, mp);
13544
13545   mp->sw_if_index = ntohl (sw_if_index);
13546   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13547
13548   S (mp);
13549   W (ret);
13550   return ret;
13551 }
13552
13553 static int
13554 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13555 {
13556   unformat_input_t *i = vam->input;
13557   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13558   u8 mode = IP_SCAN_V46_NEIGHBORS;
13559   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13560   int ret;
13561
13562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13563     {
13564       if (unformat (i, "ip4"))
13565         mode = IP_SCAN_V4_NEIGHBORS;
13566       else if (unformat (i, "ip6"))
13567         mode = IP_SCAN_V6_NEIGHBORS;
13568       if (unformat (i, "both"))
13569         mode = IP_SCAN_V46_NEIGHBORS;
13570       else if (unformat (i, "disable"))
13571         mode = IP_SCAN_DISABLED;
13572       else if (unformat (i, "interval %d", &interval))
13573         ;
13574       else if (unformat (i, "max-time %d", &time))
13575         ;
13576       else if (unformat (i, "max-update %d", &update))
13577         ;
13578       else if (unformat (i, "delay %d", &delay))
13579         ;
13580       else if (unformat (i, "stale %d", &stale))
13581         ;
13582       else
13583         break;
13584     }
13585
13586   if (interval > 255)
13587     {
13588       errmsg ("interval cannot exceed 255 minutes.");
13589       return -99;
13590     }
13591   if (time > 255)
13592     {
13593       errmsg ("max-time cannot exceed 255 usec.");
13594       return -99;
13595     }
13596   if (update > 255)
13597     {
13598       errmsg ("max-update cannot exceed 255.");
13599       return -99;
13600     }
13601   if (delay > 255)
13602     {
13603       errmsg ("delay cannot exceed 255 msec.");
13604       return -99;
13605     }
13606   if (stale > 255)
13607     {
13608       errmsg ("stale cannot exceed 255 minutes.");
13609       return -99;
13610     }
13611
13612   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13613   mp->mode = mode;
13614   mp->scan_interval = interval;
13615   mp->max_proc_time = time;
13616   mp->max_update = update;
13617   mp->scan_int_delay = delay;
13618   mp->stale_threshold = stale;
13619
13620   S (mp);
13621   W (ret);
13622   return ret;
13623 }
13624
13625 static int
13626 api_want_ip4_arp_events (vat_main_t * vam)
13627 {
13628   unformat_input_t *line_input = vam->input;
13629   vl_api_want_ip4_arp_events_t *mp;
13630   ip4_address_t address;
13631   int address_set = 0;
13632   u32 enable_disable = 1;
13633   int ret;
13634
13635   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13636     {
13637       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13638         address_set = 1;
13639       else if (unformat (line_input, "del"))
13640         enable_disable = 0;
13641       else
13642         break;
13643     }
13644
13645   if (address_set == 0)
13646     {
13647       errmsg ("missing addresses");
13648       return -99;
13649     }
13650
13651   M (WANT_IP4_ARP_EVENTS, mp);
13652   mp->enable_disable = enable_disable;
13653   mp->pid = htonl (getpid ());
13654   clib_memcpy (mp->ip, &address, sizeof (address));
13655
13656   S (mp);
13657   W (ret);
13658   return ret;
13659 }
13660
13661 static int
13662 api_want_ip6_nd_events (vat_main_t * vam)
13663 {
13664   unformat_input_t *line_input = vam->input;
13665   vl_api_want_ip6_nd_events_t *mp;
13666   vl_api_ip6_address_t address;
13667   int address_set = 0;
13668   u32 enable_disable = 1;
13669   int ret;
13670
13671   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13672     {
13673       if (unformat
13674           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13675         address_set = 1;
13676       else if (unformat (line_input, "del"))
13677         enable_disable = 0;
13678       else
13679         break;
13680     }
13681
13682   if (address_set == 0)
13683     {
13684       errmsg ("missing addresses");
13685       return -99;
13686     }
13687
13688   M (WANT_IP6_ND_EVENTS, mp);
13689   mp->enable_disable = enable_disable;
13690   mp->pid = htonl (getpid ());
13691   clib_memcpy (&mp->ip, &address, sizeof (address));
13692
13693   S (mp);
13694   W (ret);
13695   return ret;
13696 }
13697
13698 static int
13699 api_want_l2_macs_events (vat_main_t * vam)
13700 {
13701   unformat_input_t *line_input = vam->input;
13702   vl_api_want_l2_macs_events_t *mp;
13703   u8 enable_disable = 1;
13704   u32 scan_delay = 0;
13705   u32 max_macs_in_event = 0;
13706   u32 learn_limit = 0;
13707   int ret;
13708
13709   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13710     {
13711       if (unformat (line_input, "learn-limit %d", &learn_limit))
13712         ;
13713       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13714         ;
13715       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13716         ;
13717       else if (unformat (line_input, "disable"))
13718         enable_disable = 0;
13719       else
13720         break;
13721     }
13722
13723   M (WANT_L2_MACS_EVENTS, mp);
13724   mp->enable_disable = enable_disable;
13725   mp->pid = htonl (getpid ());
13726   mp->learn_limit = htonl (learn_limit);
13727   mp->scan_delay = (u8) scan_delay;
13728   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13729   S (mp);
13730   W (ret);
13731   return ret;
13732 }
13733
13734 static int
13735 api_input_acl_set_interface (vat_main_t * vam)
13736 {
13737   unformat_input_t *i = vam->input;
13738   vl_api_input_acl_set_interface_t *mp;
13739   u32 sw_if_index;
13740   int sw_if_index_set;
13741   u32 ip4_table_index = ~0;
13742   u32 ip6_table_index = ~0;
13743   u32 l2_table_index = ~0;
13744   u8 is_add = 1;
13745   int ret;
13746
13747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13748     {
13749       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13750         sw_if_index_set = 1;
13751       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13752         sw_if_index_set = 1;
13753       else if (unformat (i, "del"))
13754         is_add = 0;
13755       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13756         ;
13757       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13758         ;
13759       else if (unformat (i, "l2-table %d", &l2_table_index))
13760         ;
13761       else
13762         {
13763           clib_warning ("parse error '%U'", format_unformat_error, i);
13764           return -99;
13765         }
13766     }
13767
13768   if (sw_if_index_set == 0)
13769     {
13770       errmsg ("missing interface name or sw_if_index");
13771       return -99;
13772     }
13773
13774   M (INPUT_ACL_SET_INTERFACE, mp);
13775
13776   mp->sw_if_index = ntohl (sw_if_index);
13777   mp->ip4_table_index = ntohl (ip4_table_index);
13778   mp->ip6_table_index = ntohl (ip6_table_index);
13779   mp->l2_table_index = ntohl (l2_table_index);
13780   mp->is_add = is_add;
13781
13782   S (mp);
13783   W (ret);
13784   return ret;
13785 }
13786
13787 static int
13788 api_output_acl_set_interface (vat_main_t * vam)
13789 {
13790   unformat_input_t *i = vam->input;
13791   vl_api_output_acl_set_interface_t *mp;
13792   u32 sw_if_index;
13793   int sw_if_index_set;
13794   u32 ip4_table_index = ~0;
13795   u32 ip6_table_index = ~0;
13796   u32 l2_table_index = ~0;
13797   u8 is_add = 1;
13798   int ret;
13799
13800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13801     {
13802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13803         sw_if_index_set = 1;
13804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13805         sw_if_index_set = 1;
13806       else if (unformat (i, "del"))
13807         is_add = 0;
13808       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13809         ;
13810       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13811         ;
13812       else if (unformat (i, "l2-table %d", &l2_table_index))
13813         ;
13814       else
13815         {
13816           clib_warning ("parse error '%U'", format_unformat_error, i);
13817           return -99;
13818         }
13819     }
13820
13821   if (sw_if_index_set == 0)
13822     {
13823       errmsg ("missing interface name or sw_if_index");
13824       return -99;
13825     }
13826
13827   M (OUTPUT_ACL_SET_INTERFACE, mp);
13828
13829   mp->sw_if_index = ntohl (sw_if_index);
13830   mp->ip4_table_index = ntohl (ip4_table_index);
13831   mp->ip6_table_index = ntohl (ip6_table_index);
13832   mp->l2_table_index = ntohl (l2_table_index);
13833   mp->is_add = is_add;
13834
13835   S (mp);
13836   W (ret);
13837   return ret;
13838 }
13839
13840 static int
13841 api_ip_address_dump (vat_main_t * vam)
13842 {
13843   unformat_input_t *i = vam->input;
13844   vl_api_ip_address_dump_t *mp;
13845   vl_api_control_ping_t *mp_ping;
13846   u32 sw_if_index = ~0;
13847   u8 sw_if_index_set = 0;
13848   u8 ipv4_set = 0;
13849   u8 ipv6_set = 0;
13850   int ret;
13851
13852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13853     {
13854       if (unformat (i, "sw_if_index %d", &sw_if_index))
13855         sw_if_index_set = 1;
13856       else
13857         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13858         sw_if_index_set = 1;
13859       else if (unformat (i, "ipv4"))
13860         ipv4_set = 1;
13861       else if (unformat (i, "ipv6"))
13862         ipv6_set = 1;
13863       else
13864         break;
13865     }
13866
13867   if (ipv4_set && ipv6_set)
13868     {
13869       errmsg ("ipv4 and ipv6 flags cannot be both set");
13870       return -99;
13871     }
13872
13873   if ((!ipv4_set) && (!ipv6_set))
13874     {
13875       errmsg ("no ipv4 nor ipv6 flag set");
13876       return -99;
13877     }
13878
13879   if (sw_if_index_set == 0)
13880     {
13881       errmsg ("missing interface name or sw_if_index");
13882       return -99;
13883     }
13884
13885   vam->current_sw_if_index = sw_if_index;
13886   vam->is_ipv6 = ipv6_set;
13887
13888   M (IP_ADDRESS_DUMP, mp);
13889   mp->sw_if_index = ntohl (sw_if_index);
13890   mp->is_ipv6 = ipv6_set;
13891   S (mp);
13892
13893   /* Use a control ping for synchronization */
13894   MPING (CONTROL_PING, mp_ping);
13895   S (mp_ping);
13896
13897   W (ret);
13898   return ret;
13899 }
13900
13901 static int
13902 api_ip_dump (vat_main_t * vam)
13903 {
13904   vl_api_ip_dump_t *mp;
13905   vl_api_control_ping_t *mp_ping;
13906   unformat_input_t *in = vam->input;
13907   int ipv4_set = 0;
13908   int ipv6_set = 0;
13909   int is_ipv6;
13910   int i;
13911   int ret;
13912
13913   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13914     {
13915       if (unformat (in, "ipv4"))
13916         ipv4_set = 1;
13917       else if (unformat (in, "ipv6"))
13918         ipv6_set = 1;
13919       else
13920         break;
13921     }
13922
13923   if (ipv4_set && ipv6_set)
13924     {
13925       errmsg ("ipv4 and ipv6 flags cannot be both set");
13926       return -99;
13927     }
13928
13929   if ((!ipv4_set) && (!ipv6_set))
13930     {
13931       errmsg ("no ipv4 nor ipv6 flag set");
13932       return -99;
13933     }
13934
13935   is_ipv6 = ipv6_set;
13936   vam->is_ipv6 = is_ipv6;
13937
13938   /* free old data */
13939   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13940     {
13941       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13942     }
13943   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13944
13945   M (IP_DUMP, mp);
13946   mp->is_ipv6 = ipv6_set;
13947   S (mp);
13948
13949   /* Use a control ping for synchronization */
13950   MPING (CONTROL_PING, mp_ping);
13951   S (mp_ping);
13952
13953   W (ret);
13954   return ret;
13955 }
13956
13957 static int
13958 api_ipsec_spd_add_del (vat_main_t * vam)
13959 {
13960   unformat_input_t *i = vam->input;
13961   vl_api_ipsec_spd_add_del_t *mp;
13962   u32 spd_id = ~0;
13963   u8 is_add = 1;
13964   int ret;
13965
13966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13967     {
13968       if (unformat (i, "spd_id %d", &spd_id))
13969         ;
13970       else if (unformat (i, "del"))
13971         is_add = 0;
13972       else
13973         {
13974           clib_warning ("parse error '%U'", format_unformat_error, i);
13975           return -99;
13976         }
13977     }
13978   if (spd_id == ~0)
13979     {
13980       errmsg ("spd_id must be set");
13981       return -99;
13982     }
13983
13984   M (IPSEC_SPD_ADD_DEL, mp);
13985
13986   mp->spd_id = ntohl (spd_id);
13987   mp->is_add = is_add;
13988
13989   S (mp);
13990   W (ret);
13991   return ret;
13992 }
13993
13994 static int
13995 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13996 {
13997   unformat_input_t *i = vam->input;
13998   vl_api_ipsec_interface_add_del_spd_t *mp;
13999   u32 sw_if_index;
14000   u8 sw_if_index_set = 0;
14001   u32 spd_id = (u32) ~ 0;
14002   u8 is_add = 1;
14003   int ret;
14004
14005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14006     {
14007       if (unformat (i, "del"))
14008         is_add = 0;
14009       else if (unformat (i, "spd_id %d", &spd_id))
14010         ;
14011       else
14012         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14013         sw_if_index_set = 1;
14014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14015         sw_if_index_set = 1;
14016       else
14017         {
14018           clib_warning ("parse error '%U'", format_unformat_error, i);
14019           return -99;
14020         }
14021
14022     }
14023
14024   if (spd_id == (u32) ~ 0)
14025     {
14026       errmsg ("spd_id must be set");
14027       return -99;
14028     }
14029
14030   if (sw_if_index_set == 0)
14031     {
14032       errmsg ("missing interface name or sw_if_index");
14033       return -99;
14034     }
14035
14036   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14037
14038   mp->spd_id = ntohl (spd_id);
14039   mp->sw_if_index = ntohl (sw_if_index);
14040   mp->is_add = is_add;
14041
14042   S (mp);
14043   W (ret);
14044   return ret;
14045 }
14046
14047 static int
14048 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14049 {
14050   unformat_input_t *i = vam->input;
14051   vl_api_ipsec_spd_entry_add_del_t *mp;
14052   u8 is_add = 1, is_outbound = 0;
14053   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14054   i32 priority = 0;
14055   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14056   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14057   vl_api_address_t laddr_start = { }, laddr_stop =
14058   {
14059   }, raddr_start =
14060   {
14061   }, raddr_stop =
14062   {
14063   };
14064   int ret;
14065
14066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14067     {
14068       if (unformat (i, "del"))
14069         is_add = 0;
14070       if (unformat (i, "outbound"))
14071         is_outbound = 1;
14072       if (unformat (i, "inbound"))
14073         is_outbound = 0;
14074       else if (unformat (i, "spd_id %d", &spd_id))
14075         ;
14076       else if (unformat (i, "sa_id %d", &sa_id))
14077         ;
14078       else if (unformat (i, "priority %d", &priority))
14079         ;
14080       else if (unformat (i, "protocol %d", &protocol))
14081         ;
14082       else if (unformat (i, "lport_start %d", &lport_start))
14083         ;
14084       else if (unformat (i, "lport_stop %d", &lport_stop))
14085         ;
14086       else if (unformat (i, "rport_start %d", &rport_start))
14087         ;
14088       else if (unformat (i, "rport_stop %d", &rport_stop))
14089         ;
14090       else if (unformat (i, "laddr_start %U",
14091                          unformat_vl_api_address, &laddr_start))
14092         ;
14093       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14094                          &laddr_stop))
14095         ;
14096       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14097                          &raddr_start))
14098         ;
14099       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14100                          &raddr_stop))
14101         ;
14102       else
14103         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14104         {
14105           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14106             {
14107               clib_warning ("unsupported action: 'resolve'");
14108               return -99;
14109             }
14110         }
14111       else
14112         {
14113           clib_warning ("parse error '%U'", format_unformat_error, i);
14114           return -99;
14115         }
14116
14117     }
14118
14119   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14120
14121   mp->is_add = is_add;
14122
14123   mp->entry.spd_id = ntohl (spd_id);
14124   mp->entry.priority = ntohl (priority);
14125   mp->entry.is_outbound = is_outbound;
14126
14127   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14128                sizeof (vl_api_address_t));
14129   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14130                sizeof (vl_api_address_t));
14131   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14132                sizeof (vl_api_address_t));
14133   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14134                sizeof (vl_api_address_t));
14135
14136   mp->entry.protocol = (u8) protocol;
14137   mp->entry.local_port_start = ntohs ((u16) lport_start);
14138   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14139   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14140   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14141   mp->entry.policy = (u8) policy;
14142   mp->entry.sa_id = ntohl (sa_id);
14143
14144   S (mp);
14145   W (ret);
14146   return ret;
14147 }
14148
14149 static int
14150 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14151 {
14152   unformat_input_t *i = vam->input;
14153   vl_api_ipsec_sad_entry_add_del_t *mp;
14154   u32 sad_id = 0, spi = 0;
14155   u8 *ck = 0, *ik = 0;
14156   u8 is_add = 1;
14157
14158   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14159   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14160   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14161   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14162   vl_api_address_t tun_src, tun_dst;
14163   int ret;
14164
14165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14166     {
14167       if (unformat (i, "del"))
14168         is_add = 0;
14169       else if (unformat (i, "sad_id %d", &sad_id))
14170         ;
14171       else if (unformat (i, "spi %d", &spi))
14172         ;
14173       else if (unformat (i, "esp"))
14174         protocol = IPSEC_API_PROTO_ESP;
14175       else
14176         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14177         {
14178           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14179           if (ADDRESS_IP6 == tun_src.af)
14180             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14181         }
14182       else
14183         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14184         {
14185           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14186           if (ADDRESS_IP6 == tun_src.af)
14187             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14188         }
14189       else
14190         if (unformat (i, "crypto_alg %U",
14191                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14192         ;
14193       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14194         ;
14195       else if (unformat (i, "integ_alg %U",
14196                          unformat_ipsec_api_integ_alg, &integ_alg))
14197         ;
14198       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14199         ;
14200       else
14201         {
14202           clib_warning ("parse error '%U'", format_unformat_error, i);
14203           return -99;
14204         }
14205
14206     }
14207
14208   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14209
14210   mp->is_add = is_add;
14211   mp->entry.sad_id = ntohl (sad_id);
14212   mp->entry.protocol = protocol;
14213   mp->entry.spi = ntohl (spi);
14214   mp->entry.flags = flags;
14215
14216   mp->entry.crypto_algorithm = crypto_alg;
14217   mp->entry.integrity_algorithm = integ_alg;
14218   mp->entry.crypto_key.length = vec_len (ck);
14219   mp->entry.integrity_key.length = vec_len (ik);
14220
14221   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14222     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14223
14224   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14225     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14226
14227   if (ck)
14228     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14229   if (ik)
14230     clib_memcpy (mp->entry.integrity_key.data, ik,
14231                  mp->entry.integrity_key.length);
14232
14233   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14234     {
14235       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14236                    sizeof (mp->entry.tunnel_src));
14237       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14238                    sizeof (mp->entry.tunnel_dst));
14239     }
14240
14241   S (mp);
14242   W (ret);
14243   return ret;
14244 }
14245
14246 static int
14247 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14248 {
14249   unformat_input_t *i = vam->input;
14250   vl_api_ipsec_tunnel_if_add_del_t *mp;
14251   u32 local_spi = 0, remote_spi = 0;
14252   u32 crypto_alg = 0, integ_alg = 0;
14253   u8 *lck = NULL, *rck = NULL;
14254   u8 *lik = NULL, *rik = NULL;
14255   vl_api_address_t local_ip = { 0 };
14256   vl_api_address_t remote_ip = { 0 };
14257   f64 before = 0;
14258   u8 is_add = 1;
14259   u8 esn = 0;
14260   u8 anti_replay = 0;
14261   u8 renumber = 0;
14262   u32 instance = ~0;
14263   u32 count = 1, jj;
14264   int ret = -1;
14265
14266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14267     {
14268       if (unformat (i, "del"))
14269         is_add = 0;
14270       else if (unformat (i, "esn"))
14271         esn = 1;
14272       else if (unformat (i, "anti-replay"))
14273         anti_replay = 1;
14274       else if (unformat (i, "count %d", &count))
14275         ;
14276       else if (unformat (i, "local_spi %d", &local_spi))
14277         ;
14278       else if (unformat (i, "remote_spi %d", &remote_spi))
14279         ;
14280       else
14281         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14282         ;
14283       else
14284         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14285         ;
14286       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14287         ;
14288       else
14289         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14290         ;
14291       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14292         ;
14293       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14294         ;
14295       else
14296         if (unformat
14297             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14298         {
14299           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14300             {
14301               errmsg ("unsupported crypto-alg: '%U'\n",
14302                       format_ipsec_crypto_alg, crypto_alg);
14303               return -99;
14304             }
14305         }
14306       else
14307         if (unformat
14308             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14309         {
14310           if (integ_alg >= IPSEC_INTEG_N_ALG)
14311             {
14312               errmsg ("unsupported integ-alg: '%U'\n",
14313                       format_ipsec_integ_alg, integ_alg);
14314               return -99;
14315             }
14316         }
14317       else if (unformat (i, "instance %u", &instance))
14318         renumber = 1;
14319       else
14320         {
14321           errmsg ("parse error '%U'\n", format_unformat_error, i);
14322           return -99;
14323         }
14324     }
14325
14326   if (count > 1)
14327     {
14328       /* Turn on async mode */
14329       vam->async_mode = 1;
14330       vam->async_errors = 0;
14331       before = vat_time_now (vam);
14332     }
14333
14334   for (jj = 0; jj < count; jj++)
14335     {
14336       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14337
14338       mp->is_add = is_add;
14339       mp->esn = esn;
14340       mp->anti_replay = anti_replay;
14341
14342       if (jj > 0)
14343         increment_address (&remote_ip);
14344
14345       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14346       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14347
14348       mp->local_spi = htonl (local_spi + jj);
14349       mp->remote_spi = htonl (remote_spi + jj);
14350       mp->crypto_alg = (u8) crypto_alg;
14351
14352       mp->local_crypto_key_len = 0;
14353       if (lck)
14354         {
14355           mp->local_crypto_key_len = vec_len (lck);
14356           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14357             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14358           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14359         }
14360
14361       mp->remote_crypto_key_len = 0;
14362       if (rck)
14363         {
14364           mp->remote_crypto_key_len = vec_len (rck);
14365           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14366             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14367           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14368         }
14369
14370       mp->integ_alg = (u8) integ_alg;
14371
14372       mp->local_integ_key_len = 0;
14373       if (lik)
14374         {
14375           mp->local_integ_key_len = vec_len (lik);
14376           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14377             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14378           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14379         }
14380
14381       mp->remote_integ_key_len = 0;
14382       if (rik)
14383         {
14384           mp->remote_integ_key_len = vec_len (rik);
14385           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14386             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14387           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14388         }
14389
14390       if (renumber)
14391         {
14392           mp->renumber = renumber;
14393           mp->show_instance = ntohl (instance);
14394         }
14395       S (mp);
14396     }
14397
14398   /* When testing multiple add/del ops, use a control-ping to sync */
14399   if (count > 1)
14400     {
14401       vl_api_control_ping_t *mp_ping;
14402       f64 after;
14403       f64 timeout;
14404
14405       /* Shut off async mode */
14406       vam->async_mode = 0;
14407
14408       MPING (CONTROL_PING, mp_ping);
14409       S (mp_ping);
14410
14411       timeout = vat_time_now (vam) + 1.0;
14412       while (vat_time_now (vam) < timeout)
14413         if (vam->result_ready == 1)
14414           goto out;
14415       vam->retval = -99;
14416
14417     out:
14418       if (vam->retval == -99)
14419         errmsg ("timeout");
14420
14421       if (vam->async_errors > 0)
14422         {
14423           errmsg ("%d asynchronous errors", vam->async_errors);
14424           vam->retval = -98;
14425         }
14426       vam->async_errors = 0;
14427       after = vat_time_now (vam);
14428
14429       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14430       if (jj > 0)
14431         count = jj;
14432
14433       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14434              count, after - before, count / (after - before));
14435     }
14436   else
14437     {
14438       /* Wait for a reply... */
14439       W (ret);
14440       return ret;
14441     }
14442
14443   return ret;
14444 }
14445
14446 static void
14447 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14448 {
14449   vat_main_t *vam = &vat_main;
14450
14451   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14452          "crypto_key %U integ_alg %u integ_key %U flags %x "
14453          "tunnel_src_addr %U tunnel_dst_addr %U "
14454          "salt %u seq_outbound %lu last_seq_inbound %lu "
14455          "replay_window %lu\n",
14456          ntohl (mp->entry.sad_id),
14457          ntohl (mp->sw_if_index),
14458          ntohl (mp->entry.spi),
14459          ntohl (mp->entry.protocol),
14460          ntohl (mp->entry.crypto_algorithm),
14461          format_hex_bytes, mp->entry.crypto_key.data,
14462          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14463          format_hex_bytes, mp->entry.integrity_key.data,
14464          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14465          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14466          &mp->entry.tunnel_dst, ntohl (mp->salt),
14467          clib_net_to_host_u64 (mp->seq_outbound),
14468          clib_net_to_host_u64 (mp->last_seq_inbound),
14469          clib_net_to_host_u64 (mp->replay_window));
14470 }
14471
14472 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14473 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14474
14475 static void vl_api_ipsec_sa_details_t_handler_json
14476   (vl_api_ipsec_sa_details_t * mp)
14477 {
14478   vat_main_t *vam = &vat_main;
14479   vat_json_node_t *node = NULL;
14480   vl_api_ipsec_sad_flags_t flags;
14481
14482   if (VAT_JSON_ARRAY != vam->json_tree.type)
14483     {
14484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14485       vat_json_init_array (&vam->json_tree);
14486     }
14487   node = vat_json_array_add (&vam->json_tree);
14488
14489   vat_json_init_object (node);
14490   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14491   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14492   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14493   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14494   vat_json_object_add_uint (node, "crypto_alg",
14495                             ntohl (mp->entry.crypto_algorithm));
14496   vat_json_object_add_uint (node, "integ_alg",
14497                             ntohl (mp->entry.integrity_algorithm));
14498   flags = ntohl (mp->entry.flags);
14499   vat_json_object_add_uint (node, "use_esn",
14500                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14501   vat_json_object_add_uint (node, "use_anti_replay",
14502                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14503   vat_json_object_add_uint (node, "is_tunnel",
14504                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14505   vat_json_object_add_uint (node, "is_tunnel_ip6",
14506                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14507   vat_json_object_add_uint (node, "udp_encap",
14508                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14509   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14510                              mp->entry.crypto_key.length);
14511   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14512                              mp->entry.integrity_key.length);
14513   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14514   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14515   vat_json_object_add_uint (node, "replay_window",
14516                             clib_net_to_host_u64 (mp->replay_window));
14517 }
14518
14519 static int
14520 api_ipsec_sa_dump (vat_main_t * vam)
14521 {
14522   unformat_input_t *i = vam->input;
14523   vl_api_ipsec_sa_dump_t *mp;
14524   vl_api_control_ping_t *mp_ping;
14525   u32 sa_id = ~0;
14526   int ret;
14527
14528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14529     {
14530       if (unformat (i, "sa_id %d", &sa_id))
14531         ;
14532       else
14533         {
14534           clib_warning ("parse error '%U'", format_unformat_error, i);
14535           return -99;
14536         }
14537     }
14538
14539   M (IPSEC_SA_DUMP, mp);
14540
14541   mp->sa_id = ntohl (sa_id);
14542
14543   S (mp);
14544
14545   /* Use a control ping for synchronization */
14546   M (CONTROL_PING, mp_ping);
14547   S (mp_ping);
14548
14549   W (ret);
14550   return ret;
14551 }
14552
14553 static int
14554 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14555 {
14556   unformat_input_t *i = vam->input;
14557   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14558   u32 sw_if_index = ~0;
14559   u32 sa_id = ~0;
14560   u8 is_outbound = (u8) ~ 0;
14561   int ret;
14562
14563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14564     {
14565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14566         ;
14567       else if (unformat (i, "sa_id %d", &sa_id))
14568         ;
14569       else if (unformat (i, "outbound"))
14570         is_outbound = 1;
14571       else if (unformat (i, "inbound"))
14572         is_outbound = 0;
14573       else
14574         {
14575           clib_warning ("parse error '%U'", format_unformat_error, i);
14576           return -99;
14577         }
14578     }
14579
14580   if (sw_if_index == ~0)
14581     {
14582       errmsg ("interface must be specified");
14583       return -99;
14584     }
14585
14586   if (sa_id == ~0)
14587     {
14588       errmsg ("SA ID must be specified");
14589       return -99;
14590     }
14591
14592   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14593
14594   mp->sw_if_index = htonl (sw_if_index);
14595   mp->sa_id = htonl (sa_id);
14596   mp->is_outbound = is_outbound;
14597
14598   S (mp);
14599   W (ret);
14600
14601   return ret;
14602 }
14603
14604 static int
14605 api_get_first_msg_id (vat_main_t * vam)
14606 {
14607   vl_api_get_first_msg_id_t *mp;
14608   unformat_input_t *i = vam->input;
14609   u8 *name;
14610   u8 name_set = 0;
14611   int ret;
14612
14613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14614     {
14615       if (unformat (i, "client %s", &name))
14616         name_set = 1;
14617       else
14618         break;
14619     }
14620
14621   if (name_set == 0)
14622     {
14623       errmsg ("missing client name");
14624       return -99;
14625     }
14626   vec_add1 (name, 0);
14627
14628   if (vec_len (name) > 63)
14629     {
14630       errmsg ("client name too long");
14631       return -99;
14632     }
14633
14634   M (GET_FIRST_MSG_ID, mp);
14635   clib_memcpy (mp->name, name, vec_len (name));
14636   S (mp);
14637   W (ret);
14638   return ret;
14639 }
14640
14641 static int
14642 api_cop_interface_enable_disable (vat_main_t * vam)
14643 {
14644   unformat_input_t *line_input = vam->input;
14645   vl_api_cop_interface_enable_disable_t *mp;
14646   u32 sw_if_index = ~0;
14647   u8 enable_disable = 1;
14648   int ret;
14649
14650   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14651     {
14652       if (unformat (line_input, "disable"))
14653         enable_disable = 0;
14654       if (unformat (line_input, "enable"))
14655         enable_disable = 1;
14656       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14657                          vam, &sw_if_index))
14658         ;
14659       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14660         ;
14661       else
14662         break;
14663     }
14664
14665   if (sw_if_index == ~0)
14666     {
14667       errmsg ("missing interface name or sw_if_index");
14668       return -99;
14669     }
14670
14671   /* Construct the API message */
14672   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14673   mp->sw_if_index = ntohl (sw_if_index);
14674   mp->enable_disable = enable_disable;
14675
14676   /* send it... */
14677   S (mp);
14678   /* Wait for the reply */
14679   W (ret);
14680   return ret;
14681 }
14682
14683 static int
14684 api_cop_whitelist_enable_disable (vat_main_t * vam)
14685 {
14686   unformat_input_t *line_input = vam->input;
14687   vl_api_cop_whitelist_enable_disable_t *mp;
14688   u32 sw_if_index = ~0;
14689   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14690   u32 fib_id = 0;
14691   int ret;
14692
14693   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14694     {
14695       if (unformat (line_input, "ip4"))
14696         ip4 = 1;
14697       else if (unformat (line_input, "ip6"))
14698         ip6 = 1;
14699       else if (unformat (line_input, "default"))
14700         default_cop = 1;
14701       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14702                          vam, &sw_if_index))
14703         ;
14704       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14705         ;
14706       else if (unformat (line_input, "fib-id %d", &fib_id))
14707         ;
14708       else
14709         break;
14710     }
14711
14712   if (sw_if_index == ~0)
14713     {
14714       errmsg ("missing interface name or sw_if_index");
14715       return -99;
14716     }
14717
14718   /* Construct the API message */
14719   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14720   mp->sw_if_index = ntohl (sw_if_index);
14721   mp->fib_id = ntohl (fib_id);
14722   mp->ip4 = ip4;
14723   mp->ip6 = ip6;
14724   mp->default_cop = default_cop;
14725
14726   /* send it... */
14727   S (mp);
14728   /* Wait for the reply */
14729   W (ret);
14730   return ret;
14731 }
14732
14733 static int
14734 api_get_node_graph (vat_main_t * vam)
14735 {
14736   vl_api_get_node_graph_t *mp;
14737   int ret;
14738
14739   M (GET_NODE_GRAPH, mp);
14740
14741   /* send it... */
14742   S (mp);
14743   /* Wait for the reply */
14744   W (ret);
14745   return ret;
14746 }
14747
14748 /* *INDENT-OFF* */
14749 /** Used for parsing LISP eids */
14750 typedef CLIB_PACKED(struct{
14751   u8 addr[16];   /**< eid address */
14752   u32 len;       /**< prefix length if IP */
14753   u8 type;      /**< type of eid */
14754 }) lisp_eid_vat_t;
14755 /* *INDENT-ON* */
14756
14757 static uword
14758 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14759 {
14760   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14761
14762   clib_memset (a, 0, sizeof (a[0]));
14763
14764   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14765     {
14766       a->type = 0;              /* ipv4 type */
14767     }
14768   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14769     {
14770       a->type = 1;              /* ipv6 type */
14771     }
14772   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14773     {
14774       a->type = 2;              /* mac type */
14775     }
14776   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14777     {
14778       a->type = 3;              /* NSH type */
14779       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14780       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14781     }
14782   else
14783     {
14784       return 0;
14785     }
14786
14787   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14788     {
14789       return 0;
14790     }
14791
14792   return 1;
14793 }
14794
14795 static int
14796 lisp_eid_size_vat (u8 type)
14797 {
14798   switch (type)
14799     {
14800     case 0:
14801       return 4;
14802     case 1:
14803       return 16;
14804     case 2:
14805       return 6;
14806     case 3:
14807       return 5;
14808     }
14809   return 0;
14810 }
14811
14812 static void
14813 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14814 {
14815   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14816 }
14817
14818 static int
14819 api_one_add_del_locator_set (vat_main_t * vam)
14820 {
14821   unformat_input_t *input = vam->input;
14822   vl_api_one_add_del_locator_set_t *mp;
14823   u8 is_add = 1;
14824   u8 *locator_set_name = NULL;
14825   u8 locator_set_name_set = 0;
14826   vl_api_local_locator_t locator, *locators = 0;
14827   u32 sw_if_index, priority, weight;
14828   u32 data_len = 0;
14829
14830   int ret;
14831   /* Parse args required to build the message */
14832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14833     {
14834       if (unformat (input, "del"))
14835         {
14836           is_add = 0;
14837         }
14838       else if (unformat (input, "locator-set %s", &locator_set_name))
14839         {
14840           locator_set_name_set = 1;
14841         }
14842       else if (unformat (input, "sw_if_index %u p %u w %u",
14843                          &sw_if_index, &priority, &weight))
14844         {
14845           locator.sw_if_index = htonl (sw_if_index);
14846           locator.priority = priority;
14847           locator.weight = weight;
14848           vec_add1 (locators, locator);
14849         }
14850       else
14851         if (unformat
14852             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14853              &sw_if_index, &priority, &weight))
14854         {
14855           locator.sw_if_index = htonl (sw_if_index);
14856           locator.priority = priority;
14857           locator.weight = weight;
14858           vec_add1 (locators, locator);
14859         }
14860       else
14861         break;
14862     }
14863
14864   if (locator_set_name_set == 0)
14865     {
14866       errmsg ("missing locator-set name");
14867       vec_free (locators);
14868       return -99;
14869     }
14870
14871   if (vec_len (locator_set_name) > 64)
14872     {
14873       errmsg ("locator-set name too long");
14874       vec_free (locator_set_name);
14875       vec_free (locators);
14876       return -99;
14877     }
14878   vec_add1 (locator_set_name, 0);
14879
14880   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14881
14882   /* Construct the API message */
14883   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14884
14885   mp->is_add = is_add;
14886   clib_memcpy (mp->locator_set_name, locator_set_name,
14887                vec_len (locator_set_name));
14888   vec_free (locator_set_name);
14889
14890   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14891   if (locators)
14892     clib_memcpy (mp->locators, locators, data_len);
14893   vec_free (locators);
14894
14895   /* send it... */
14896   S (mp);
14897
14898   /* Wait for a reply... */
14899   W (ret);
14900   return ret;
14901 }
14902
14903 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14904
14905 static int
14906 api_one_add_del_locator (vat_main_t * vam)
14907 {
14908   unformat_input_t *input = vam->input;
14909   vl_api_one_add_del_locator_t *mp;
14910   u32 tmp_if_index = ~0;
14911   u32 sw_if_index = ~0;
14912   u8 sw_if_index_set = 0;
14913   u8 sw_if_index_if_name_set = 0;
14914   u32 priority = ~0;
14915   u8 priority_set = 0;
14916   u32 weight = ~0;
14917   u8 weight_set = 0;
14918   u8 is_add = 1;
14919   u8 *locator_set_name = NULL;
14920   u8 locator_set_name_set = 0;
14921   int ret;
14922
14923   /* Parse args required to build the message */
14924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14925     {
14926       if (unformat (input, "del"))
14927         {
14928           is_add = 0;
14929         }
14930       else if (unformat (input, "locator-set %s", &locator_set_name))
14931         {
14932           locator_set_name_set = 1;
14933         }
14934       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14935                          &tmp_if_index))
14936         {
14937           sw_if_index_if_name_set = 1;
14938           sw_if_index = tmp_if_index;
14939         }
14940       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14941         {
14942           sw_if_index_set = 1;
14943           sw_if_index = tmp_if_index;
14944         }
14945       else if (unformat (input, "p %d", &priority))
14946         {
14947           priority_set = 1;
14948         }
14949       else if (unformat (input, "w %d", &weight))
14950         {
14951           weight_set = 1;
14952         }
14953       else
14954         break;
14955     }
14956
14957   if (locator_set_name_set == 0)
14958     {
14959       errmsg ("missing locator-set name");
14960       return -99;
14961     }
14962
14963   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14964     {
14965       errmsg ("missing sw_if_index");
14966       vec_free (locator_set_name);
14967       return -99;
14968     }
14969
14970   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14971     {
14972       errmsg ("cannot use both params interface name and sw_if_index");
14973       vec_free (locator_set_name);
14974       return -99;
14975     }
14976
14977   if (priority_set == 0)
14978     {
14979       errmsg ("missing locator-set priority");
14980       vec_free (locator_set_name);
14981       return -99;
14982     }
14983
14984   if (weight_set == 0)
14985     {
14986       errmsg ("missing locator-set weight");
14987       vec_free (locator_set_name);
14988       return -99;
14989     }
14990
14991   if (vec_len (locator_set_name) > 64)
14992     {
14993       errmsg ("locator-set name too long");
14994       vec_free (locator_set_name);
14995       return -99;
14996     }
14997   vec_add1 (locator_set_name, 0);
14998
14999   /* Construct the API message */
15000   M (ONE_ADD_DEL_LOCATOR, mp);
15001
15002   mp->is_add = is_add;
15003   mp->sw_if_index = ntohl (sw_if_index);
15004   mp->priority = priority;
15005   mp->weight = weight;
15006   clib_memcpy (mp->locator_set_name, locator_set_name,
15007                vec_len (locator_set_name));
15008   vec_free (locator_set_name);
15009
15010   /* send it... */
15011   S (mp);
15012
15013   /* Wait for a reply... */
15014   W (ret);
15015   return ret;
15016 }
15017
15018 #define api_lisp_add_del_locator api_one_add_del_locator
15019
15020 uword
15021 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15022 {
15023   u32 *key_id = va_arg (*args, u32 *);
15024   u8 *s = 0;
15025
15026   if (unformat (input, "%s", &s))
15027     {
15028       if (!strcmp ((char *) s, "sha1"))
15029         key_id[0] = HMAC_SHA_1_96;
15030       else if (!strcmp ((char *) s, "sha256"))
15031         key_id[0] = HMAC_SHA_256_128;
15032       else
15033         {
15034           clib_warning ("invalid key_id: '%s'", s);
15035           key_id[0] = HMAC_NO_KEY;
15036         }
15037     }
15038   else
15039     return 0;
15040
15041   vec_free (s);
15042   return 1;
15043 }
15044
15045 static int
15046 api_one_add_del_local_eid (vat_main_t * vam)
15047 {
15048   unformat_input_t *input = vam->input;
15049   vl_api_one_add_del_local_eid_t *mp;
15050   u8 is_add = 1;
15051   u8 eid_set = 0;
15052   lisp_eid_vat_t _eid, *eid = &_eid;
15053   u8 *locator_set_name = 0;
15054   u8 locator_set_name_set = 0;
15055   u32 vni = 0;
15056   u16 key_id = 0;
15057   u8 *key = 0;
15058   int ret;
15059
15060   /* Parse args required to build the message */
15061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (input, "del"))
15064         {
15065           is_add = 0;
15066         }
15067       else if (unformat (input, "vni %d", &vni))
15068         {
15069           ;
15070         }
15071       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15072         {
15073           eid_set = 1;
15074         }
15075       else if (unformat (input, "locator-set %s", &locator_set_name))
15076         {
15077           locator_set_name_set = 1;
15078         }
15079       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15080         ;
15081       else if (unformat (input, "secret-key %_%v%_", &key))
15082         ;
15083       else
15084         break;
15085     }
15086
15087   if (locator_set_name_set == 0)
15088     {
15089       errmsg ("missing locator-set name");
15090       return -99;
15091     }
15092
15093   if (0 == eid_set)
15094     {
15095       errmsg ("EID address not set!");
15096       vec_free (locator_set_name);
15097       return -99;
15098     }
15099
15100   if (key && (0 == key_id))
15101     {
15102       errmsg ("invalid key_id!");
15103       return -99;
15104     }
15105
15106   if (vec_len (key) > 64)
15107     {
15108       errmsg ("key too long");
15109       vec_free (key);
15110       return -99;
15111     }
15112
15113   if (vec_len (locator_set_name) > 64)
15114     {
15115       errmsg ("locator-set name too long");
15116       vec_free (locator_set_name);
15117       return -99;
15118     }
15119   vec_add1 (locator_set_name, 0);
15120
15121   /* Construct the API message */
15122   M (ONE_ADD_DEL_LOCAL_EID, mp);
15123
15124   mp->is_add = is_add;
15125   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15126   mp->eid_type = eid->type;
15127   mp->prefix_len = eid->len;
15128   mp->vni = clib_host_to_net_u32 (vni);
15129   mp->key_id = clib_host_to_net_u16 (key_id);
15130   clib_memcpy (mp->locator_set_name, locator_set_name,
15131                vec_len (locator_set_name));
15132   clib_memcpy (mp->key, key, vec_len (key));
15133
15134   vec_free (locator_set_name);
15135   vec_free (key);
15136
15137   /* send it... */
15138   S (mp);
15139
15140   /* Wait for a reply... */
15141   W (ret);
15142   return ret;
15143 }
15144
15145 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15146
15147 static int
15148 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15149 {
15150   u32 dp_table = 0, vni = 0;;
15151   unformat_input_t *input = vam->input;
15152   vl_api_gpe_add_del_fwd_entry_t *mp;
15153   u8 is_add = 1;
15154   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15155   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15156   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15157   u32 action = ~0, w;
15158   ip4_address_t rmt_rloc4, lcl_rloc4;
15159   ip6_address_t rmt_rloc6, lcl_rloc6;
15160   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15161   int ret;
15162
15163   clib_memset (&rloc, 0, sizeof (rloc));
15164
15165   /* Parse args required to build the message */
15166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15167     {
15168       if (unformat (input, "del"))
15169         is_add = 0;
15170       else if (unformat (input, "add"))
15171         is_add = 1;
15172       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15173         {
15174           rmt_eid_set = 1;
15175         }
15176       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15177         {
15178           lcl_eid_set = 1;
15179         }
15180       else if (unformat (input, "vrf %d", &dp_table))
15181         ;
15182       else if (unformat (input, "bd %d", &dp_table))
15183         ;
15184       else if (unformat (input, "vni %d", &vni))
15185         ;
15186       else if (unformat (input, "w %d", &w))
15187         {
15188           if (!curr_rloc)
15189             {
15190               errmsg ("No RLOC configured for setting priority/weight!");
15191               return -99;
15192             }
15193           curr_rloc->weight = w;
15194         }
15195       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15196                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15197         {
15198           rloc.is_ip4 = 1;
15199
15200           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15201           rloc.weight = 0;
15202           vec_add1 (lcl_locs, rloc);
15203
15204           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15205           vec_add1 (rmt_locs, rloc);
15206           /* weight saved in rmt loc */
15207           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15208         }
15209       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15210                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15211         {
15212           rloc.is_ip4 = 0;
15213           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15214           rloc.weight = 0;
15215           vec_add1 (lcl_locs, rloc);
15216
15217           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15218           vec_add1 (rmt_locs, rloc);
15219           /* weight saved in rmt loc */
15220           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15221         }
15222       else if (unformat (input, "action %d", &action))
15223         {
15224           ;
15225         }
15226       else
15227         {
15228           clib_warning ("parse error '%U'", format_unformat_error, input);
15229           return -99;
15230         }
15231     }
15232
15233   if (!rmt_eid_set)
15234     {
15235       errmsg ("remote eid addresses not set");
15236       return -99;
15237     }
15238
15239   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15240     {
15241       errmsg ("eid types don't match");
15242       return -99;
15243     }
15244
15245   if (0 == rmt_locs && (u32) ~ 0 == action)
15246     {
15247       errmsg ("action not set for negative mapping");
15248       return -99;
15249     }
15250
15251   /* Construct the API message */
15252   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15253       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15254
15255   mp->is_add = is_add;
15256   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15257   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15258   mp->eid_type = rmt_eid->type;
15259   mp->dp_table = clib_host_to_net_u32 (dp_table);
15260   mp->vni = clib_host_to_net_u32 (vni);
15261   mp->rmt_len = rmt_eid->len;
15262   mp->lcl_len = lcl_eid->len;
15263   mp->action = action;
15264
15265   if (0 != rmt_locs && 0 != lcl_locs)
15266     {
15267       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15268       clib_memcpy (mp->locs, lcl_locs,
15269                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15270
15271       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15272       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15273                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15274     }
15275   vec_free (lcl_locs);
15276   vec_free (rmt_locs);
15277
15278   /* send it... */
15279   S (mp);
15280
15281   /* Wait for a reply... */
15282   W (ret);
15283   return ret;
15284 }
15285
15286 static int
15287 api_one_add_del_map_server (vat_main_t * vam)
15288 {
15289   unformat_input_t *input = vam->input;
15290   vl_api_one_add_del_map_server_t *mp;
15291   u8 is_add = 1;
15292   u8 ipv4_set = 0;
15293   u8 ipv6_set = 0;
15294   ip4_address_t ipv4;
15295   ip6_address_t ipv6;
15296   int ret;
15297
15298   /* Parse args required to build the message */
15299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15300     {
15301       if (unformat (input, "del"))
15302         {
15303           is_add = 0;
15304         }
15305       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15306         {
15307           ipv4_set = 1;
15308         }
15309       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15310         {
15311           ipv6_set = 1;
15312         }
15313       else
15314         break;
15315     }
15316
15317   if (ipv4_set && ipv6_set)
15318     {
15319       errmsg ("both eid v4 and v6 addresses set");
15320       return -99;
15321     }
15322
15323   if (!ipv4_set && !ipv6_set)
15324     {
15325       errmsg ("eid addresses not set");
15326       return -99;
15327     }
15328
15329   /* Construct the API message */
15330   M (ONE_ADD_DEL_MAP_SERVER, mp);
15331
15332   mp->is_add = is_add;
15333   if (ipv6_set)
15334     {
15335       mp->is_ipv6 = 1;
15336       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15337     }
15338   else
15339     {
15340       mp->is_ipv6 = 0;
15341       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15342     }
15343
15344   /* send it... */
15345   S (mp);
15346
15347   /* Wait for a reply... */
15348   W (ret);
15349   return ret;
15350 }
15351
15352 #define api_lisp_add_del_map_server api_one_add_del_map_server
15353
15354 static int
15355 api_one_add_del_map_resolver (vat_main_t * vam)
15356 {
15357   unformat_input_t *input = vam->input;
15358   vl_api_one_add_del_map_resolver_t *mp;
15359   u8 is_add = 1;
15360   u8 ipv4_set = 0;
15361   u8 ipv6_set = 0;
15362   ip4_address_t ipv4;
15363   ip6_address_t ipv6;
15364   int ret;
15365
15366   /* Parse args required to build the message */
15367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (input, "del"))
15370         {
15371           is_add = 0;
15372         }
15373       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15374         {
15375           ipv4_set = 1;
15376         }
15377       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15378         {
15379           ipv6_set = 1;
15380         }
15381       else
15382         break;
15383     }
15384
15385   if (ipv4_set && ipv6_set)
15386     {
15387       errmsg ("both eid v4 and v6 addresses set");
15388       return -99;
15389     }
15390
15391   if (!ipv4_set && !ipv6_set)
15392     {
15393       errmsg ("eid addresses not set");
15394       return -99;
15395     }
15396
15397   /* Construct the API message */
15398   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15399
15400   mp->is_add = is_add;
15401   if (ipv6_set)
15402     {
15403       mp->is_ipv6 = 1;
15404       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15405     }
15406   else
15407     {
15408       mp->is_ipv6 = 0;
15409       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15410     }
15411
15412   /* send it... */
15413   S (mp);
15414
15415   /* Wait for a reply... */
15416   W (ret);
15417   return ret;
15418 }
15419
15420 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15421
15422 static int
15423 api_lisp_gpe_enable_disable (vat_main_t * vam)
15424 {
15425   unformat_input_t *input = vam->input;
15426   vl_api_gpe_enable_disable_t *mp;
15427   u8 is_set = 0;
15428   u8 is_en = 1;
15429   int ret;
15430
15431   /* Parse args required to build the message */
15432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15433     {
15434       if (unformat (input, "enable"))
15435         {
15436           is_set = 1;
15437           is_en = 1;
15438         }
15439       else if (unformat (input, "disable"))
15440         {
15441           is_set = 1;
15442           is_en = 0;
15443         }
15444       else
15445         break;
15446     }
15447
15448   if (is_set == 0)
15449     {
15450       errmsg ("Value not set");
15451       return -99;
15452     }
15453
15454   /* Construct the API message */
15455   M (GPE_ENABLE_DISABLE, mp);
15456
15457   mp->is_en = is_en;
15458
15459   /* send it... */
15460   S (mp);
15461
15462   /* Wait for a reply... */
15463   W (ret);
15464   return ret;
15465 }
15466
15467 static int
15468 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15469 {
15470   unformat_input_t *input = vam->input;
15471   vl_api_one_rloc_probe_enable_disable_t *mp;
15472   u8 is_set = 0;
15473   u8 is_en = 0;
15474   int ret;
15475
15476   /* Parse args required to build the message */
15477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15478     {
15479       if (unformat (input, "enable"))
15480         {
15481           is_set = 1;
15482           is_en = 1;
15483         }
15484       else if (unformat (input, "disable"))
15485         is_set = 1;
15486       else
15487         break;
15488     }
15489
15490   if (!is_set)
15491     {
15492       errmsg ("Value not set");
15493       return -99;
15494     }
15495
15496   /* Construct the API message */
15497   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15498
15499   mp->is_enabled = is_en;
15500
15501   /* send it... */
15502   S (mp);
15503
15504   /* Wait for a reply... */
15505   W (ret);
15506   return ret;
15507 }
15508
15509 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15510
15511 static int
15512 api_one_map_register_enable_disable (vat_main_t * vam)
15513 {
15514   unformat_input_t *input = vam->input;
15515   vl_api_one_map_register_enable_disable_t *mp;
15516   u8 is_set = 0;
15517   u8 is_en = 0;
15518   int ret;
15519
15520   /* Parse args required to build the message */
15521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15522     {
15523       if (unformat (input, "enable"))
15524         {
15525           is_set = 1;
15526           is_en = 1;
15527         }
15528       else if (unformat (input, "disable"))
15529         is_set = 1;
15530       else
15531         break;
15532     }
15533
15534   if (!is_set)
15535     {
15536       errmsg ("Value not set");
15537       return -99;
15538     }
15539
15540   /* Construct the API message */
15541   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15542
15543   mp->is_enabled = is_en;
15544
15545   /* send it... */
15546   S (mp);
15547
15548   /* Wait for a reply... */
15549   W (ret);
15550   return ret;
15551 }
15552
15553 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15554
15555 static int
15556 api_one_enable_disable (vat_main_t * vam)
15557 {
15558   unformat_input_t *input = vam->input;
15559   vl_api_one_enable_disable_t *mp;
15560   u8 is_set = 0;
15561   u8 is_en = 0;
15562   int ret;
15563
15564   /* Parse args required to build the message */
15565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15566     {
15567       if (unformat (input, "enable"))
15568         {
15569           is_set = 1;
15570           is_en = 1;
15571         }
15572       else if (unformat (input, "disable"))
15573         {
15574           is_set = 1;
15575         }
15576       else
15577         break;
15578     }
15579
15580   if (!is_set)
15581     {
15582       errmsg ("Value not set");
15583       return -99;
15584     }
15585
15586   /* Construct the API message */
15587   M (ONE_ENABLE_DISABLE, mp);
15588
15589   mp->is_en = is_en;
15590
15591   /* send it... */
15592   S (mp);
15593
15594   /* Wait for a reply... */
15595   W (ret);
15596   return ret;
15597 }
15598
15599 #define api_lisp_enable_disable api_one_enable_disable
15600
15601 static int
15602 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15603 {
15604   unformat_input_t *input = vam->input;
15605   vl_api_one_enable_disable_xtr_mode_t *mp;
15606   u8 is_set = 0;
15607   u8 is_en = 0;
15608   int ret;
15609
15610   /* Parse args required to build the message */
15611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15612     {
15613       if (unformat (input, "enable"))
15614         {
15615           is_set = 1;
15616           is_en = 1;
15617         }
15618       else if (unformat (input, "disable"))
15619         {
15620           is_set = 1;
15621         }
15622       else
15623         break;
15624     }
15625
15626   if (!is_set)
15627     {
15628       errmsg ("Value not set");
15629       return -99;
15630     }
15631
15632   /* Construct the API message */
15633   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15634
15635   mp->is_en = is_en;
15636
15637   /* send it... */
15638   S (mp);
15639
15640   /* Wait for a reply... */
15641   W (ret);
15642   return ret;
15643 }
15644
15645 static int
15646 api_one_show_xtr_mode (vat_main_t * vam)
15647 {
15648   vl_api_one_show_xtr_mode_t *mp;
15649   int ret;
15650
15651   /* Construct the API message */
15652   M (ONE_SHOW_XTR_MODE, mp);
15653
15654   /* send it... */
15655   S (mp);
15656
15657   /* Wait for a reply... */
15658   W (ret);
15659   return ret;
15660 }
15661
15662 static int
15663 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15664 {
15665   unformat_input_t *input = vam->input;
15666   vl_api_one_enable_disable_pitr_mode_t *mp;
15667   u8 is_set = 0;
15668   u8 is_en = 0;
15669   int ret;
15670
15671   /* Parse args required to build the message */
15672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15673     {
15674       if (unformat (input, "enable"))
15675         {
15676           is_set = 1;
15677           is_en = 1;
15678         }
15679       else if (unformat (input, "disable"))
15680         {
15681           is_set = 1;
15682         }
15683       else
15684         break;
15685     }
15686
15687   if (!is_set)
15688     {
15689       errmsg ("Value not set");
15690       return -99;
15691     }
15692
15693   /* Construct the API message */
15694   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15695
15696   mp->is_en = is_en;
15697
15698   /* send it... */
15699   S (mp);
15700
15701   /* Wait for a reply... */
15702   W (ret);
15703   return ret;
15704 }
15705
15706 static int
15707 api_one_show_pitr_mode (vat_main_t * vam)
15708 {
15709   vl_api_one_show_pitr_mode_t *mp;
15710   int ret;
15711
15712   /* Construct the API message */
15713   M (ONE_SHOW_PITR_MODE, mp);
15714
15715   /* send it... */
15716   S (mp);
15717
15718   /* Wait for a reply... */
15719   W (ret);
15720   return ret;
15721 }
15722
15723 static int
15724 api_one_enable_disable_petr_mode (vat_main_t * vam)
15725 {
15726   unformat_input_t *input = vam->input;
15727   vl_api_one_enable_disable_petr_mode_t *mp;
15728   u8 is_set = 0;
15729   u8 is_en = 0;
15730   int ret;
15731
15732   /* Parse args required to build the message */
15733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15734     {
15735       if (unformat (input, "enable"))
15736         {
15737           is_set = 1;
15738           is_en = 1;
15739         }
15740       else if (unformat (input, "disable"))
15741         {
15742           is_set = 1;
15743         }
15744       else
15745         break;
15746     }
15747
15748   if (!is_set)
15749     {
15750       errmsg ("Value not set");
15751       return -99;
15752     }
15753
15754   /* Construct the API message */
15755   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15756
15757   mp->is_en = is_en;
15758
15759   /* send it... */
15760   S (mp);
15761
15762   /* Wait for a reply... */
15763   W (ret);
15764   return ret;
15765 }
15766
15767 static int
15768 api_one_show_petr_mode (vat_main_t * vam)
15769 {
15770   vl_api_one_show_petr_mode_t *mp;
15771   int ret;
15772
15773   /* Construct the API message */
15774   M (ONE_SHOW_PETR_MODE, mp);
15775
15776   /* send it... */
15777   S (mp);
15778
15779   /* Wait for a reply... */
15780   W (ret);
15781   return ret;
15782 }
15783
15784 static int
15785 api_show_one_map_register_state (vat_main_t * vam)
15786 {
15787   vl_api_show_one_map_register_state_t *mp;
15788   int ret;
15789
15790   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15791
15792   /* send */
15793   S (mp);
15794
15795   /* wait for reply */
15796   W (ret);
15797   return ret;
15798 }
15799
15800 #define api_show_lisp_map_register_state api_show_one_map_register_state
15801
15802 static int
15803 api_show_one_rloc_probe_state (vat_main_t * vam)
15804 {
15805   vl_api_show_one_rloc_probe_state_t *mp;
15806   int ret;
15807
15808   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15809
15810   /* send */
15811   S (mp);
15812
15813   /* wait for reply */
15814   W (ret);
15815   return ret;
15816 }
15817
15818 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15819
15820 static int
15821 api_one_add_del_ndp_entry (vat_main_t * vam)
15822 {
15823   vl_api_one_add_del_ndp_entry_t *mp;
15824   unformat_input_t *input = vam->input;
15825   u8 is_add = 1;
15826   u8 mac_set = 0;
15827   u8 bd_set = 0;
15828   u8 ip_set = 0;
15829   u8 mac[6] = { 0, };
15830   u8 ip6[16] = { 0, };
15831   u32 bd = ~0;
15832   int ret;
15833
15834   /* Parse args required to build the message */
15835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15836     {
15837       if (unformat (input, "del"))
15838         is_add = 0;
15839       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15840         mac_set = 1;
15841       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15842         ip_set = 1;
15843       else if (unformat (input, "bd %d", &bd))
15844         bd_set = 1;
15845       else
15846         {
15847           errmsg ("parse error '%U'", format_unformat_error, input);
15848           return -99;
15849         }
15850     }
15851
15852   if (!bd_set || !ip_set || (!mac_set && is_add))
15853     {
15854       errmsg ("Missing BD, IP or MAC!");
15855       return -99;
15856     }
15857
15858   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15859   mp->is_add = is_add;
15860   clib_memcpy (mp->mac, mac, 6);
15861   mp->bd = clib_host_to_net_u32 (bd);
15862   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15863
15864   /* send */
15865   S (mp);
15866
15867   /* wait for reply */
15868   W (ret);
15869   return ret;
15870 }
15871
15872 static int
15873 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15874 {
15875   vl_api_one_add_del_l2_arp_entry_t *mp;
15876   unformat_input_t *input = vam->input;
15877   u8 is_add = 1;
15878   u8 mac_set = 0;
15879   u8 bd_set = 0;
15880   u8 ip_set = 0;
15881   u8 mac[6] = { 0, };
15882   u32 ip4 = 0, bd = ~0;
15883   int ret;
15884
15885   /* Parse args required to build the message */
15886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15887     {
15888       if (unformat (input, "del"))
15889         is_add = 0;
15890       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15891         mac_set = 1;
15892       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15893         ip_set = 1;
15894       else if (unformat (input, "bd %d", &bd))
15895         bd_set = 1;
15896       else
15897         {
15898           errmsg ("parse error '%U'", format_unformat_error, input);
15899           return -99;
15900         }
15901     }
15902
15903   if (!bd_set || !ip_set || (!mac_set && is_add))
15904     {
15905       errmsg ("Missing BD, IP or MAC!");
15906       return -99;
15907     }
15908
15909   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15910   mp->is_add = is_add;
15911   clib_memcpy (mp->mac, mac, 6);
15912   mp->bd = clib_host_to_net_u32 (bd);
15913   mp->ip4 = ip4;
15914
15915   /* send */
15916   S (mp);
15917
15918   /* wait for reply */
15919   W (ret);
15920   return ret;
15921 }
15922
15923 static int
15924 api_one_ndp_bd_get (vat_main_t * vam)
15925 {
15926   vl_api_one_ndp_bd_get_t *mp;
15927   int ret;
15928
15929   M (ONE_NDP_BD_GET, mp);
15930
15931   /* send */
15932   S (mp);
15933
15934   /* wait for reply */
15935   W (ret);
15936   return ret;
15937 }
15938
15939 static int
15940 api_one_ndp_entries_get (vat_main_t * vam)
15941 {
15942   vl_api_one_ndp_entries_get_t *mp;
15943   unformat_input_t *input = vam->input;
15944   u8 bd_set = 0;
15945   u32 bd = ~0;
15946   int ret;
15947
15948   /* Parse args required to build the message */
15949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15950     {
15951       if (unformat (input, "bd %d", &bd))
15952         bd_set = 1;
15953       else
15954         {
15955           errmsg ("parse error '%U'", format_unformat_error, input);
15956           return -99;
15957         }
15958     }
15959
15960   if (!bd_set)
15961     {
15962       errmsg ("Expected bridge domain!");
15963       return -99;
15964     }
15965
15966   M (ONE_NDP_ENTRIES_GET, mp);
15967   mp->bd = clib_host_to_net_u32 (bd);
15968
15969   /* send */
15970   S (mp);
15971
15972   /* wait for reply */
15973   W (ret);
15974   return ret;
15975 }
15976
15977 static int
15978 api_one_l2_arp_bd_get (vat_main_t * vam)
15979 {
15980   vl_api_one_l2_arp_bd_get_t *mp;
15981   int ret;
15982
15983   M (ONE_L2_ARP_BD_GET, mp);
15984
15985   /* send */
15986   S (mp);
15987
15988   /* wait for reply */
15989   W (ret);
15990   return ret;
15991 }
15992
15993 static int
15994 api_one_l2_arp_entries_get (vat_main_t * vam)
15995 {
15996   vl_api_one_l2_arp_entries_get_t *mp;
15997   unformat_input_t *input = vam->input;
15998   u8 bd_set = 0;
15999   u32 bd = ~0;
16000   int ret;
16001
16002   /* Parse args required to build the message */
16003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16004     {
16005       if (unformat (input, "bd %d", &bd))
16006         bd_set = 1;
16007       else
16008         {
16009           errmsg ("parse error '%U'", format_unformat_error, input);
16010           return -99;
16011         }
16012     }
16013
16014   if (!bd_set)
16015     {
16016       errmsg ("Expected bridge domain!");
16017       return -99;
16018     }
16019
16020   M (ONE_L2_ARP_ENTRIES_GET, mp);
16021   mp->bd = clib_host_to_net_u32 (bd);
16022
16023   /* send */
16024   S (mp);
16025
16026   /* wait for reply */
16027   W (ret);
16028   return ret;
16029 }
16030
16031 static int
16032 api_one_stats_enable_disable (vat_main_t * vam)
16033 {
16034   vl_api_one_stats_enable_disable_t *mp;
16035   unformat_input_t *input = vam->input;
16036   u8 is_set = 0;
16037   u8 is_en = 0;
16038   int ret;
16039
16040   /* Parse args required to build the message */
16041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16042     {
16043       if (unformat (input, "enable"))
16044         {
16045           is_set = 1;
16046           is_en = 1;
16047         }
16048       else if (unformat (input, "disable"))
16049         {
16050           is_set = 1;
16051         }
16052       else
16053         break;
16054     }
16055
16056   if (!is_set)
16057     {
16058       errmsg ("Value not set");
16059       return -99;
16060     }
16061
16062   M (ONE_STATS_ENABLE_DISABLE, mp);
16063   mp->is_en = is_en;
16064
16065   /* send */
16066   S (mp);
16067
16068   /* wait for reply */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static int
16074 api_show_one_stats_enable_disable (vat_main_t * vam)
16075 {
16076   vl_api_show_one_stats_enable_disable_t *mp;
16077   int ret;
16078
16079   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16080
16081   /* send */
16082   S (mp);
16083
16084   /* wait for reply */
16085   W (ret);
16086   return ret;
16087 }
16088
16089 static int
16090 api_show_one_map_request_mode (vat_main_t * vam)
16091 {
16092   vl_api_show_one_map_request_mode_t *mp;
16093   int ret;
16094
16095   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16096
16097   /* send */
16098   S (mp);
16099
16100   /* wait for reply */
16101   W (ret);
16102   return ret;
16103 }
16104
16105 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16106
16107 static int
16108 api_one_map_request_mode (vat_main_t * vam)
16109 {
16110   unformat_input_t *input = vam->input;
16111   vl_api_one_map_request_mode_t *mp;
16112   u8 mode = 0;
16113   int ret;
16114
16115   /* Parse args required to build the message */
16116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16117     {
16118       if (unformat (input, "dst-only"))
16119         mode = 0;
16120       else if (unformat (input, "src-dst"))
16121         mode = 1;
16122       else
16123         {
16124           errmsg ("parse error '%U'", format_unformat_error, input);
16125           return -99;
16126         }
16127     }
16128
16129   M (ONE_MAP_REQUEST_MODE, mp);
16130
16131   mp->mode = mode;
16132
16133   /* send */
16134   S (mp);
16135
16136   /* wait for reply */
16137   W (ret);
16138   return ret;
16139 }
16140
16141 #define api_lisp_map_request_mode api_one_map_request_mode
16142
16143 /**
16144  * Enable/disable ONE proxy ITR.
16145  *
16146  * @param vam vpp API test context
16147  * @return return code
16148  */
16149 static int
16150 api_one_pitr_set_locator_set (vat_main_t * vam)
16151 {
16152   u8 ls_name_set = 0;
16153   unformat_input_t *input = vam->input;
16154   vl_api_one_pitr_set_locator_set_t *mp;
16155   u8 is_add = 1;
16156   u8 *ls_name = 0;
16157   int ret;
16158
16159   /* Parse args required to build the message */
16160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16161     {
16162       if (unformat (input, "del"))
16163         is_add = 0;
16164       else if (unformat (input, "locator-set %s", &ls_name))
16165         ls_name_set = 1;
16166       else
16167         {
16168           errmsg ("parse error '%U'", format_unformat_error, input);
16169           return -99;
16170         }
16171     }
16172
16173   if (!ls_name_set)
16174     {
16175       errmsg ("locator-set name not set!");
16176       return -99;
16177     }
16178
16179   M (ONE_PITR_SET_LOCATOR_SET, mp);
16180
16181   mp->is_add = is_add;
16182   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16183   vec_free (ls_name);
16184
16185   /* send */
16186   S (mp);
16187
16188   /* wait for reply */
16189   W (ret);
16190   return ret;
16191 }
16192
16193 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16194
16195 static int
16196 api_one_nsh_set_locator_set (vat_main_t * vam)
16197 {
16198   u8 ls_name_set = 0;
16199   unformat_input_t *input = vam->input;
16200   vl_api_one_nsh_set_locator_set_t *mp;
16201   u8 is_add = 1;
16202   u8 *ls_name = 0;
16203   int ret;
16204
16205   /* Parse args required to build the message */
16206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16207     {
16208       if (unformat (input, "del"))
16209         is_add = 0;
16210       else if (unformat (input, "ls %s", &ls_name))
16211         ls_name_set = 1;
16212       else
16213         {
16214           errmsg ("parse error '%U'", format_unformat_error, input);
16215           return -99;
16216         }
16217     }
16218
16219   if (!ls_name_set && is_add)
16220     {
16221       errmsg ("locator-set name not set!");
16222       return -99;
16223     }
16224
16225   M (ONE_NSH_SET_LOCATOR_SET, mp);
16226
16227   mp->is_add = is_add;
16228   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16229   vec_free (ls_name);
16230
16231   /* send */
16232   S (mp);
16233
16234   /* wait for reply */
16235   W (ret);
16236   return ret;
16237 }
16238
16239 static int
16240 api_show_one_pitr (vat_main_t * vam)
16241 {
16242   vl_api_show_one_pitr_t *mp;
16243   int ret;
16244
16245   if (!vam->json_output)
16246     {
16247       print (vam->ofp, "%=20s", "lisp status:");
16248     }
16249
16250   M (SHOW_ONE_PITR, mp);
16251   /* send it... */
16252   S (mp);
16253
16254   /* Wait for a reply... */
16255   W (ret);
16256   return ret;
16257 }
16258
16259 #define api_show_lisp_pitr api_show_one_pitr
16260
16261 static int
16262 api_one_use_petr (vat_main_t * vam)
16263 {
16264   unformat_input_t *input = vam->input;
16265   vl_api_one_use_petr_t *mp;
16266   u8 is_add = 0;
16267   ip_address_t ip;
16268   int ret;
16269
16270   clib_memset (&ip, 0, sizeof (ip));
16271
16272   /* Parse args required to build the message */
16273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16274     {
16275       if (unformat (input, "disable"))
16276         is_add = 0;
16277       else
16278         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16279         {
16280           is_add = 1;
16281           ip_addr_version (&ip) = IP4;
16282         }
16283       else
16284         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16285         {
16286           is_add = 1;
16287           ip_addr_version (&ip) = IP6;
16288         }
16289       else
16290         {
16291           errmsg ("parse error '%U'", format_unformat_error, input);
16292           return -99;
16293         }
16294     }
16295
16296   M (ONE_USE_PETR, mp);
16297
16298   mp->is_add = is_add;
16299   if (is_add)
16300     {
16301       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16302       if (mp->is_ip4)
16303         clib_memcpy (mp->address, &ip, 4);
16304       else
16305         clib_memcpy (mp->address, &ip, 16);
16306     }
16307
16308   /* send */
16309   S (mp);
16310
16311   /* wait for reply */
16312   W (ret);
16313   return ret;
16314 }
16315
16316 #define api_lisp_use_petr api_one_use_petr
16317
16318 static int
16319 api_show_one_nsh_mapping (vat_main_t * vam)
16320 {
16321   vl_api_show_one_use_petr_t *mp;
16322   int ret;
16323
16324   if (!vam->json_output)
16325     {
16326       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16327     }
16328
16329   M (SHOW_ONE_NSH_MAPPING, mp);
16330   /* send it... */
16331   S (mp);
16332
16333   /* Wait for a reply... */
16334   W (ret);
16335   return ret;
16336 }
16337
16338 static int
16339 api_show_one_use_petr (vat_main_t * vam)
16340 {
16341   vl_api_show_one_use_petr_t *mp;
16342   int ret;
16343
16344   if (!vam->json_output)
16345     {
16346       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16347     }
16348
16349   M (SHOW_ONE_USE_PETR, mp);
16350   /* send it... */
16351   S (mp);
16352
16353   /* Wait for a reply... */
16354   W (ret);
16355   return ret;
16356 }
16357
16358 #define api_show_lisp_use_petr api_show_one_use_petr
16359
16360 /**
16361  * Add/delete mapping between vni and vrf
16362  */
16363 static int
16364 api_one_eid_table_add_del_map (vat_main_t * vam)
16365 {
16366   unformat_input_t *input = vam->input;
16367   vl_api_one_eid_table_add_del_map_t *mp;
16368   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16369   u32 vni, vrf, bd_index;
16370   int ret;
16371
16372   /* Parse args required to build the message */
16373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (input, "del"))
16376         is_add = 0;
16377       else if (unformat (input, "vrf %d", &vrf))
16378         vrf_set = 1;
16379       else if (unformat (input, "bd_index %d", &bd_index))
16380         bd_index_set = 1;
16381       else if (unformat (input, "vni %d", &vni))
16382         vni_set = 1;
16383       else
16384         break;
16385     }
16386
16387   if (!vni_set || (!vrf_set && !bd_index_set))
16388     {
16389       errmsg ("missing arguments!");
16390       return -99;
16391     }
16392
16393   if (vrf_set && bd_index_set)
16394     {
16395       errmsg ("error: both vrf and bd entered!");
16396       return -99;
16397     }
16398
16399   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16400
16401   mp->is_add = is_add;
16402   mp->vni = htonl (vni);
16403   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16404   mp->is_l2 = bd_index_set;
16405
16406   /* send */
16407   S (mp);
16408
16409   /* wait for reply */
16410   W (ret);
16411   return ret;
16412 }
16413
16414 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16415
16416 uword
16417 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16418 {
16419   u32 *action = va_arg (*args, u32 *);
16420   u8 *s = 0;
16421
16422   if (unformat (input, "%s", &s))
16423     {
16424       if (!strcmp ((char *) s, "no-action"))
16425         action[0] = 0;
16426       else if (!strcmp ((char *) s, "natively-forward"))
16427         action[0] = 1;
16428       else if (!strcmp ((char *) s, "send-map-request"))
16429         action[0] = 2;
16430       else if (!strcmp ((char *) s, "drop"))
16431         action[0] = 3;
16432       else
16433         {
16434           clib_warning ("invalid action: '%s'", s);
16435           action[0] = 3;
16436         }
16437     }
16438   else
16439     return 0;
16440
16441   vec_free (s);
16442   return 1;
16443 }
16444
16445 /**
16446  * Add/del remote mapping to/from ONE control plane
16447  *
16448  * @param vam vpp API test context
16449  * @return return code
16450  */
16451 static int
16452 api_one_add_del_remote_mapping (vat_main_t * vam)
16453 {
16454   unformat_input_t *input = vam->input;
16455   vl_api_one_add_del_remote_mapping_t *mp;
16456   u32 vni = 0;
16457   lisp_eid_vat_t _eid, *eid = &_eid;
16458   lisp_eid_vat_t _seid, *seid = &_seid;
16459   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16460   u32 action = ~0, p, w, data_len;
16461   ip4_address_t rloc4;
16462   ip6_address_t rloc6;
16463   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16464   int ret;
16465
16466   clib_memset (&rloc, 0, sizeof (rloc));
16467
16468   /* Parse args required to build the message */
16469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16470     {
16471       if (unformat (input, "del-all"))
16472         {
16473           del_all = 1;
16474         }
16475       else if (unformat (input, "del"))
16476         {
16477           is_add = 0;
16478         }
16479       else if (unformat (input, "add"))
16480         {
16481           is_add = 1;
16482         }
16483       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16484         {
16485           eid_set = 1;
16486         }
16487       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16488         {
16489           seid_set = 1;
16490         }
16491       else if (unformat (input, "vni %d", &vni))
16492         {
16493           ;
16494         }
16495       else if (unformat (input, "p %d w %d", &p, &w))
16496         {
16497           if (!curr_rloc)
16498             {
16499               errmsg ("No RLOC configured for setting priority/weight!");
16500               return -99;
16501             }
16502           curr_rloc->priority = p;
16503           curr_rloc->weight = w;
16504         }
16505       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16506         {
16507           rloc.is_ip4 = 1;
16508           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16509           vec_add1 (rlocs, rloc);
16510           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16511         }
16512       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16513         {
16514           rloc.is_ip4 = 0;
16515           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16516           vec_add1 (rlocs, rloc);
16517           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16518         }
16519       else if (unformat (input, "action %U",
16520                          unformat_negative_mapping_action, &action))
16521         {
16522           ;
16523         }
16524       else
16525         {
16526           clib_warning ("parse error '%U'", format_unformat_error, input);
16527           return -99;
16528         }
16529     }
16530
16531   if (0 == eid_set)
16532     {
16533       errmsg ("missing params!");
16534       return -99;
16535     }
16536
16537   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16538     {
16539       errmsg ("no action set for negative map-reply!");
16540       return -99;
16541     }
16542
16543   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16544
16545   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16546   mp->is_add = is_add;
16547   mp->vni = htonl (vni);
16548   mp->action = (u8) action;
16549   mp->is_src_dst = seid_set;
16550   mp->eid_len = eid->len;
16551   mp->seid_len = seid->len;
16552   mp->del_all = del_all;
16553   mp->eid_type = eid->type;
16554   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16555   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16556
16557   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16558   clib_memcpy (mp->rlocs, rlocs, data_len);
16559   vec_free (rlocs);
16560
16561   /* send it... */
16562   S (mp);
16563
16564   /* Wait for a reply... */
16565   W (ret);
16566   return ret;
16567 }
16568
16569 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16570
16571 /**
16572  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16573  * forwarding entries in data-plane accordingly.
16574  *
16575  * @param vam vpp API test context
16576  * @return return code
16577  */
16578 static int
16579 api_one_add_del_adjacency (vat_main_t * vam)
16580 {
16581   unformat_input_t *input = vam->input;
16582   vl_api_one_add_del_adjacency_t *mp;
16583   u32 vni = 0;
16584   ip4_address_t leid4, reid4;
16585   ip6_address_t leid6, reid6;
16586   u8 reid_mac[6] = { 0 };
16587   u8 leid_mac[6] = { 0 };
16588   u8 reid_type, leid_type;
16589   u32 leid_len = 0, reid_len = 0, len;
16590   u8 is_add = 1;
16591   int ret;
16592
16593   leid_type = reid_type = (u8) ~ 0;
16594
16595   /* Parse args required to build the message */
16596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16597     {
16598       if (unformat (input, "del"))
16599         {
16600           is_add = 0;
16601         }
16602       else if (unformat (input, "add"))
16603         {
16604           is_add = 1;
16605         }
16606       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16607                          &reid4, &len))
16608         {
16609           reid_type = 0;        /* ipv4 */
16610           reid_len = len;
16611         }
16612       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16613                          &reid6, &len))
16614         {
16615           reid_type = 1;        /* ipv6 */
16616           reid_len = len;
16617         }
16618       else if (unformat (input, "reid %U", unformat_ethernet_address,
16619                          reid_mac))
16620         {
16621           reid_type = 2;        /* mac */
16622         }
16623       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16624                          &leid4, &len))
16625         {
16626           leid_type = 0;        /* ipv4 */
16627           leid_len = len;
16628         }
16629       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16630                          &leid6, &len))
16631         {
16632           leid_type = 1;        /* ipv6 */
16633           leid_len = len;
16634         }
16635       else if (unformat (input, "leid %U", unformat_ethernet_address,
16636                          leid_mac))
16637         {
16638           leid_type = 2;        /* mac */
16639         }
16640       else if (unformat (input, "vni %d", &vni))
16641         {
16642           ;
16643         }
16644       else
16645         {
16646           errmsg ("parse error '%U'", format_unformat_error, input);
16647           return -99;
16648         }
16649     }
16650
16651   if ((u8) ~ 0 == reid_type)
16652     {
16653       errmsg ("missing params!");
16654       return -99;
16655     }
16656
16657   if (leid_type != reid_type)
16658     {
16659       errmsg ("remote and local EIDs are of different types!");
16660       return -99;
16661     }
16662
16663   M (ONE_ADD_DEL_ADJACENCY, mp);
16664   mp->is_add = is_add;
16665   mp->vni = htonl (vni);
16666   mp->leid_len = leid_len;
16667   mp->reid_len = reid_len;
16668   mp->eid_type = reid_type;
16669
16670   switch (mp->eid_type)
16671     {
16672     case 0:
16673       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16674       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16675       break;
16676     case 1:
16677       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16678       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16679       break;
16680     case 2:
16681       clib_memcpy (mp->leid, leid_mac, 6);
16682       clib_memcpy (mp->reid, reid_mac, 6);
16683       break;
16684     default:
16685       errmsg ("unknown EID type %d!", mp->eid_type);
16686       return 0;
16687     }
16688
16689   /* send it... */
16690   S (mp);
16691
16692   /* Wait for a reply... */
16693   W (ret);
16694   return ret;
16695 }
16696
16697 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16698
16699 uword
16700 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16701 {
16702   u32 *mode = va_arg (*args, u32 *);
16703
16704   if (unformat (input, "lisp"))
16705     *mode = 0;
16706   else if (unformat (input, "vxlan"))
16707     *mode = 1;
16708   else
16709     return 0;
16710
16711   return 1;
16712 }
16713
16714 static int
16715 api_gpe_get_encap_mode (vat_main_t * vam)
16716 {
16717   vl_api_gpe_get_encap_mode_t *mp;
16718   int ret;
16719
16720   /* Construct the API message */
16721   M (GPE_GET_ENCAP_MODE, mp);
16722
16723   /* send it... */
16724   S (mp);
16725
16726   /* Wait for a reply... */
16727   W (ret);
16728   return ret;
16729 }
16730
16731 static int
16732 api_gpe_set_encap_mode (vat_main_t * vam)
16733 {
16734   unformat_input_t *input = vam->input;
16735   vl_api_gpe_set_encap_mode_t *mp;
16736   int ret;
16737   u32 mode = 0;
16738
16739   /* Parse args required to build the message */
16740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16741     {
16742       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16743         ;
16744       else
16745         break;
16746     }
16747
16748   /* Construct the API message */
16749   M (GPE_SET_ENCAP_MODE, mp);
16750
16751   mp->mode = mode;
16752
16753   /* send it... */
16754   S (mp);
16755
16756   /* Wait for a reply... */
16757   W (ret);
16758   return ret;
16759 }
16760
16761 static int
16762 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16763 {
16764   unformat_input_t *input = vam->input;
16765   vl_api_gpe_add_del_iface_t *mp;
16766   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16767   u32 dp_table = 0, vni = 0;
16768   int ret;
16769
16770   /* Parse args required to build the message */
16771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16772     {
16773       if (unformat (input, "up"))
16774         {
16775           action_set = 1;
16776           is_add = 1;
16777         }
16778       else if (unformat (input, "down"))
16779         {
16780           action_set = 1;
16781           is_add = 0;
16782         }
16783       else if (unformat (input, "table_id %d", &dp_table))
16784         {
16785           dp_table_set = 1;
16786         }
16787       else if (unformat (input, "bd_id %d", &dp_table))
16788         {
16789           dp_table_set = 1;
16790           is_l2 = 1;
16791         }
16792       else if (unformat (input, "vni %d", &vni))
16793         {
16794           vni_set = 1;
16795         }
16796       else
16797         break;
16798     }
16799
16800   if (action_set == 0)
16801     {
16802       errmsg ("Action not set");
16803       return -99;
16804     }
16805   if (dp_table_set == 0 || vni_set == 0)
16806     {
16807       errmsg ("vni and dp_table must be set");
16808       return -99;
16809     }
16810
16811   /* Construct the API message */
16812   M (GPE_ADD_DEL_IFACE, mp);
16813
16814   mp->is_add = is_add;
16815   mp->dp_table = clib_host_to_net_u32 (dp_table);
16816   mp->is_l2 = is_l2;
16817   mp->vni = clib_host_to_net_u32 (vni);
16818
16819   /* send it... */
16820   S (mp);
16821
16822   /* Wait for a reply... */
16823   W (ret);
16824   return ret;
16825 }
16826
16827 static int
16828 api_one_map_register_fallback_threshold (vat_main_t * vam)
16829 {
16830   unformat_input_t *input = vam->input;
16831   vl_api_one_map_register_fallback_threshold_t *mp;
16832   u32 value = 0;
16833   u8 is_set = 0;
16834   int ret;
16835
16836   /* Parse args required to build the message */
16837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16838     {
16839       if (unformat (input, "%u", &value))
16840         is_set = 1;
16841       else
16842         {
16843           clib_warning ("parse error '%U'", format_unformat_error, input);
16844           return -99;
16845         }
16846     }
16847
16848   if (!is_set)
16849     {
16850       errmsg ("fallback threshold value is missing!");
16851       return -99;
16852     }
16853
16854   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16855   mp->value = clib_host_to_net_u32 (value);
16856
16857   /* send it... */
16858   S (mp);
16859
16860   /* Wait for a reply... */
16861   W (ret);
16862   return ret;
16863 }
16864
16865 static int
16866 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16867 {
16868   vl_api_show_one_map_register_fallback_threshold_t *mp;
16869   int ret;
16870
16871   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16872
16873   /* send it... */
16874   S (mp);
16875
16876   /* Wait for a reply... */
16877   W (ret);
16878   return ret;
16879 }
16880
16881 uword
16882 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16883 {
16884   u32 *proto = va_arg (*args, u32 *);
16885
16886   if (unformat (input, "udp"))
16887     *proto = 1;
16888   else if (unformat (input, "api"))
16889     *proto = 2;
16890   else
16891     return 0;
16892
16893   return 1;
16894 }
16895
16896 static int
16897 api_one_set_transport_protocol (vat_main_t * vam)
16898 {
16899   unformat_input_t *input = vam->input;
16900   vl_api_one_set_transport_protocol_t *mp;
16901   u8 is_set = 0;
16902   u32 protocol = 0;
16903   int ret;
16904
16905   /* Parse args required to build the message */
16906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16907     {
16908       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16909         is_set = 1;
16910       else
16911         {
16912           clib_warning ("parse error '%U'", format_unformat_error, input);
16913           return -99;
16914         }
16915     }
16916
16917   if (!is_set)
16918     {
16919       errmsg ("Transport protocol missing!");
16920       return -99;
16921     }
16922
16923   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16924   mp->protocol = (u8) protocol;
16925
16926   /* send it... */
16927   S (mp);
16928
16929   /* Wait for a reply... */
16930   W (ret);
16931   return ret;
16932 }
16933
16934 static int
16935 api_one_get_transport_protocol (vat_main_t * vam)
16936 {
16937   vl_api_one_get_transport_protocol_t *mp;
16938   int ret;
16939
16940   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16941
16942   /* send it... */
16943   S (mp);
16944
16945   /* Wait for a reply... */
16946   W (ret);
16947   return ret;
16948 }
16949
16950 static int
16951 api_one_map_register_set_ttl (vat_main_t * vam)
16952 {
16953   unformat_input_t *input = vam->input;
16954   vl_api_one_map_register_set_ttl_t *mp;
16955   u32 ttl = 0;
16956   u8 is_set = 0;
16957   int ret;
16958
16959   /* Parse args required to build the message */
16960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16961     {
16962       if (unformat (input, "%u", &ttl))
16963         is_set = 1;
16964       else
16965         {
16966           clib_warning ("parse error '%U'", format_unformat_error, input);
16967           return -99;
16968         }
16969     }
16970
16971   if (!is_set)
16972     {
16973       errmsg ("TTL value missing!");
16974       return -99;
16975     }
16976
16977   M (ONE_MAP_REGISTER_SET_TTL, mp);
16978   mp->ttl = clib_host_to_net_u32 (ttl);
16979
16980   /* send it... */
16981   S (mp);
16982
16983   /* Wait for a reply... */
16984   W (ret);
16985   return ret;
16986 }
16987
16988 static int
16989 api_show_one_map_register_ttl (vat_main_t * vam)
16990 {
16991   vl_api_show_one_map_register_ttl_t *mp;
16992   int ret;
16993
16994   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16995
16996   /* send it... */
16997   S (mp);
16998
16999   /* Wait for a reply... */
17000   W (ret);
17001   return ret;
17002 }
17003
17004 /**
17005  * Add/del map request itr rlocs from ONE control plane and updates
17006  *
17007  * @param vam vpp API test context
17008  * @return return code
17009  */
17010 static int
17011 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17012 {
17013   unformat_input_t *input = vam->input;
17014   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17015   u8 *locator_set_name = 0;
17016   u8 locator_set_name_set = 0;
17017   u8 is_add = 1;
17018   int ret;
17019
17020   /* Parse args required to build the message */
17021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17022     {
17023       if (unformat (input, "del"))
17024         {
17025           is_add = 0;
17026         }
17027       else if (unformat (input, "%_%v%_", &locator_set_name))
17028         {
17029           locator_set_name_set = 1;
17030         }
17031       else
17032         {
17033           clib_warning ("parse error '%U'", format_unformat_error, input);
17034           return -99;
17035         }
17036     }
17037
17038   if (is_add && !locator_set_name_set)
17039     {
17040       errmsg ("itr-rloc is not set!");
17041       return -99;
17042     }
17043
17044   if (is_add && vec_len (locator_set_name) > 64)
17045     {
17046       errmsg ("itr-rloc locator-set name too long");
17047       vec_free (locator_set_name);
17048       return -99;
17049     }
17050
17051   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17052   mp->is_add = is_add;
17053   if (is_add)
17054     {
17055       clib_memcpy (mp->locator_set_name, locator_set_name,
17056                    vec_len (locator_set_name));
17057     }
17058   else
17059     {
17060       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17061     }
17062   vec_free (locator_set_name);
17063
17064   /* send it... */
17065   S (mp);
17066
17067   /* Wait for a reply... */
17068   W (ret);
17069   return ret;
17070 }
17071
17072 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17073
17074 static int
17075 api_one_locator_dump (vat_main_t * vam)
17076 {
17077   unformat_input_t *input = vam->input;
17078   vl_api_one_locator_dump_t *mp;
17079   vl_api_control_ping_t *mp_ping;
17080   u8 is_index_set = 0, is_name_set = 0;
17081   u8 *ls_name = 0;
17082   u32 ls_index = ~0;
17083   int ret;
17084
17085   /* Parse args required to build the message */
17086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17087     {
17088       if (unformat (input, "ls_name %_%v%_", &ls_name))
17089         {
17090           is_name_set = 1;
17091         }
17092       else if (unformat (input, "ls_index %d", &ls_index))
17093         {
17094           is_index_set = 1;
17095         }
17096       else
17097         {
17098           errmsg ("parse error '%U'", format_unformat_error, input);
17099           return -99;
17100         }
17101     }
17102
17103   if (!is_index_set && !is_name_set)
17104     {
17105       errmsg ("error: expected one of index or name!");
17106       return -99;
17107     }
17108
17109   if (is_index_set && is_name_set)
17110     {
17111       errmsg ("error: only one param expected!");
17112       return -99;
17113     }
17114
17115   if (vec_len (ls_name) > 62)
17116     {
17117       errmsg ("error: locator set name too long!");
17118       return -99;
17119     }
17120
17121   if (!vam->json_output)
17122     {
17123       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17124     }
17125
17126   M (ONE_LOCATOR_DUMP, mp);
17127   mp->is_index_set = is_index_set;
17128
17129   if (is_index_set)
17130     mp->ls_index = clib_host_to_net_u32 (ls_index);
17131   else
17132     {
17133       vec_add1 (ls_name, 0);
17134       strncpy ((char *) mp->ls_name, (char *) ls_name,
17135                sizeof (mp->ls_name) - 1);
17136     }
17137
17138   /* send it... */
17139   S (mp);
17140
17141   /* Use a control ping for synchronization */
17142   MPING (CONTROL_PING, mp_ping);
17143   S (mp_ping);
17144
17145   /* Wait for a reply... */
17146   W (ret);
17147   return ret;
17148 }
17149
17150 #define api_lisp_locator_dump api_one_locator_dump
17151
17152 static int
17153 api_one_locator_set_dump (vat_main_t * vam)
17154 {
17155   vl_api_one_locator_set_dump_t *mp;
17156   vl_api_control_ping_t *mp_ping;
17157   unformat_input_t *input = vam->input;
17158   u8 filter = 0;
17159   int ret;
17160
17161   /* Parse args required to build the message */
17162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17163     {
17164       if (unformat (input, "local"))
17165         {
17166           filter = 1;
17167         }
17168       else if (unformat (input, "remote"))
17169         {
17170           filter = 2;
17171         }
17172       else
17173         {
17174           errmsg ("parse error '%U'", format_unformat_error, input);
17175           return -99;
17176         }
17177     }
17178
17179   if (!vam->json_output)
17180     {
17181       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17182     }
17183
17184   M (ONE_LOCATOR_SET_DUMP, mp);
17185
17186   mp->filter = filter;
17187
17188   /* send it... */
17189   S (mp);
17190
17191   /* Use a control ping for synchronization */
17192   MPING (CONTROL_PING, mp_ping);
17193   S (mp_ping);
17194
17195   /* Wait for a reply... */
17196   W (ret);
17197   return ret;
17198 }
17199
17200 #define api_lisp_locator_set_dump api_one_locator_set_dump
17201
17202 static int
17203 api_one_eid_table_map_dump (vat_main_t * vam)
17204 {
17205   u8 is_l2 = 0;
17206   u8 mode_set = 0;
17207   unformat_input_t *input = vam->input;
17208   vl_api_one_eid_table_map_dump_t *mp;
17209   vl_api_control_ping_t *mp_ping;
17210   int ret;
17211
17212   /* Parse args required to build the message */
17213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17214     {
17215       if (unformat (input, "l2"))
17216         {
17217           is_l2 = 1;
17218           mode_set = 1;
17219         }
17220       else if (unformat (input, "l3"))
17221         {
17222           is_l2 = 0;
17223           mode_set = 1;
17224         }
17225       else
17226         {
17227           errmsg ("parse error '%U'", format_unformat_error, input);
17228           return -99;
17229         }
17230     }
17231
17232   if (!mode_set)
17233     {
17234       errmsg ("expected one of 'l2' or 'l3' parameter!");
17235       return -99;
17236     }
17237
17238   if (!vam->json_output)
17239     {
17240       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17241     }
17242
17243   M (ONE_EID_TABLE_MAP_DUMP, mp);
17244   mp->is_l2 = is_l2;
17245
17246   /* send it... */
17247   S (mp);
17248
17249   /* Use a control ping for synchronization */
17250   MPING (CONTROL_PING, mp_ping);
17251   S (mp_ping);
17252
17253   /* Wait for a reply... */
17254   W (ret);
17255   return ret;
17256 }
17257
17258 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17259
17260 static int
17261 api_one_eid_table_vni_dump (vat_main_t * vam)
17262 {
17263   vl_api_one_eid_table_vni_dump_t *mp;
17264   vl_api_control_ping_t *mp_ping;
17265   int ret;
17266
17267   if (!vam->json_output)
17268     {
17269       print (vam->ofp, "VNI");
17270     }
17271
17272   M (ONE_EID_TABLE_VNI_DUMP, mp);
17273
17274   /* send it... */
17275   S (mp);
17276
17277   /* Use a control ping for synchronization */
17278   MPING (CONTROL_PING, mp_ping);
17279   S (mp_ping);
17280
17281   /* Wait for a reply... */
17282   W (ret);
17283   return ret;
17284 }
17285
17286 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17287
17288 static int
17289 api_one_eid_table_dump (vat_main_t * vam)
17290 {
17291   unformat_input_t *i = vam->input;
17292   vl_api_one_eid_table_dump_t *mp;
17293   vl_api_control_ping_t *mp_ping;
17294   struct in_addr ip4;
17295   struct in6_addr ip6;
17296   u8 mac[6];
17297   u8 eid_type = ~0, eid_set = 0;
17298   u32 prefix_length = ~0, t, vni = 0;
17299   u8 filter = 0;
17300   int ret;
17301   lisp_nsh_api_t nsh;
17302
17303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17304     {
17305       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17306         {
17307           eid_set = 1;
17308           eid_type = 0;
17309           prefix_length = t;
17310         }
17311       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17312         {
17313           eid_set = 1;
17314           eid_type = 1;
17315           prefix_length = t;
17316         }
17317       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17318         {
17319           eid_set = 1;
17320           eid_type = 2;
17321         }
17322       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17323         {
17324           eid_set = 1;
17325           eid_type = 3;
17326         }
17327       else if (unformat (i, "vni %d", &t))
17328         {
17329           vni = t;
17330         }
17331       else if (unformat (i, "local"))
17332         {
17333           filter = 1;
17334         }
17335       else if (unformat (i, "remote"))
17336         {
17337           filter = 2;
17338         }
17339       else
17340         {
17341           errmsg ("parse error '%U'", format_unformat_error, i);
17342           return -99;
17343         }
17344     }
17345
17346   if (!vam->json_output)
17347     {
17348       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17349              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17350     }
17351
17352   M (ONE_EID_TABLE_DUMP, mp);
17353
17354   mp->filter = filter;
17355   if (eid_set)
17356     {
17357       mp->eid_set = 1;
17358       mp->vni = htonl (vni);
17359       mp->eid_type = eid_type;
17360       switch (eid_type)
17361         {
17362         case 0:
17363           mp->prefix_length = prefix_length;
17364           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17365           break;
17366         case 1:
17367           mp->prefix_length = prefix_length;
17368           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17369           break;
17370         case 2:
17371           clib_memcpy (mp->eid, mac, sizeof (mac));
17372           break;
17373         case 3:
17374           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17375           break;
17376         default:
17377           errmsg ("unknown EID type %d!", eid_type);
17378           return -99;
17379         }
17380     }
17381
17382   /* send it... */
17383   S (mp);
17384
17385   /* Use a control ping for synchronization */
17386   MPING (CONTROL_PING, mp_ping);
17387   S (mp_ping);
17388
17389   /* Wait for a reply... */
17390   W (ret);
17391   return ret;
17392 }
17393
17394 #define api_lisp_eid_table_dump api_one_eid_table_dump
17395
17396 static int
17397 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17398 {
17399   unformat_input_t *i = vam->input;
17400   vl_api_gpe_fwd_entries_get_t *mp;
17401   u8 vni_set = 0;
17402   u32 vni = ~0;
17403   int ret;
17404
17405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17406     {
17407       if (unformat (i, "vni %d", &vni))
17408         {
17409           vni_set = 1;
17410         }
17411       else
17412         {
17413           errmsg ("parse error '%U'", format_unformat_error, i);
17414           return -99;
17415         }
17416     }
17417
17418   if (!vni_set)
17419     {
17420       errmsg ("vni not set!");
17421       return -99;
17422     }
17423
17424   if (!vam->json_output)
17425     {
17426       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17427              "leid", "reid");
17428     }
17429
17430   M (GPE_FWD_ENTRIES_GET, mp);
17431   mp->vni = clib_host_to_net_u32 (vni);
17432
17433   /* send it... */
17434   S (mp);
17435
17436   /* Wait for a reply... */
17437   W (ret);
17438   return ret;
17439 }
17440
17441 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17442 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17443 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17444 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17445 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17446 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17447 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17448 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17449
17450 static int
17451 api_one_adjacencies_get (vat_main_t * vam)
17452 {
17453   unformat_input_t *i = vam->input;
17454   vl_api_one_adjacencies_get_t *mp;
17455   u8 vni_set = 0;
17456   u32 vni = ~0;
17457   int ret;
17458
17459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17460     {
17461       if (unformat (i, "vni %d", &vni))
17462         {
17463           vni_set = 1;
17464         }
17465       else
17466         {
17467           errmsg ("parse error '%U'", format_unformat_error, i);
17468           return -99;
17469         }
17470     }
17471
17472   if (!vni_set)
17473     {
17474       errmsg ("vni not set!");
17475       return -99;
17476     }
17477
17478   if (!vam->json_output)
17479     {
17480       print (vam->ofp, "%s %40s", "leid", "reid");
17481     }
17482
17483   M (ONE_ADJACENCIES_GET, mp);
17484   mp->vni = clib_host_to_net_u32 (vni);
17485
17486   /* send it... */
17487   S (mp);
17488
17489   /* Wait for a reply... */
17490   W (ret);
17491   return ret;
17492 }
17493
17494 #define api_lisp_adjacencies_get api_one_adjacencies_get
17495
17496 static int
17497 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17498 {
17499   unformat_input_t *i = vam->input;
17500   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17501   int ret;
17502   u8 ip_family_set = 0, is_ip4 = 1;
17503
17504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17505     {
17506       if (unformat (i, "ip4"))
17507         {
17508           ip_family_set = 1;
17509           is_ip4 = 1;
17510         }
17511       else if (unformat (i, "ip6"))
17512         {
17513           ip_family_set = 1;
17514           is_ip4 = 0;
17515         }
17516       else
17517         {
17518           errmsg ("parse error '%U'", format_unformat_error, i);
17519           return -99;
17520         }
17521     }
17522
17523   if (!ip_family_set)
17524     {
17525       errmsg ("ip family not set!");
17526       return -99;
17527     }
17528
17529   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17530   mp->is_ip4 = is_ip4;
17531
17532   /* send it... */
17533   S (mp);
17534
17535   /* Wait for a reply... */
17536   W (ret);
17537   return ret;
17538 }
17539
17540 static int
17541 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17542 {
17543   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17544   int ret;
17545
17546   if (!vam->json_output)
17547     {
17548       print (vam->ofp, "VNIs");
17549     }
17550
17551   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17552
17553   /* send it... */
17554   S (mp);
17555
17556   /* Wait for a reply... */
17557   W (ret);
17558   return ret;
17559 }
17560
17561 static int
17562 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17563 {
17564   unformat_input_t *i = vam->input;
17565   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17566   int ret = 0;
17567   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17568   struct in_addr ip4;
17569   struct in6_addr ip6;
17570   u32 table_id = 0, nh_sw_if_index = ~0;
17571
17572   clib_memset (&ip4, 0, sizeof (ip4));
17573   clib_memset (&ip6, 0, sizeof (ip6));
17574
17575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17576     {
17577       if (unformat (i, "del"))
17578         is_add = 0;
17579       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17580                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17581         {
17582           ip_set = 1;
17583           is_ip4 = 1;
17584         }
17585       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17586                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17587         {
17588           ip_set = 1;
17589           is_ip4 = 0;
17590         }
17591       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17592         {
17593           ip_set = 1;
17594           is_ip4 = 1;
17595           nh_sw_if_index = ~0;
17596         }
17597       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17598         {
17599           ip_set = 1;
17600           is_ip4 = 0;
17601           nh_sw_if_index = ~0;
17602         }
17603       else if (unformat (i, "table %d", &table_id))
17604         ;
17605       else
17606         {
17607           errmsg ("parse error '%U'", format_unformat_error, i);
17608           return -99;
17609         }
17610     }
17611
17612   if (!ip_set)
17613     {
17614       errmsg ("nh addr not set!");
17615       return -99;
17616     }
17617
17618   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17619   mp->is_add = is_add;
17620   mp->table_id = clib_host_to_net_u32 (table_id);
17621   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17622   mp->is_ip4 = is_ip4;
17623   if (is_ip4)
17624     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17625   else
17626     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17627
17628   /* send it... */
17629   S (mp);
17630
17631   /* Wait for a reply... */
17632   W (ret);
17633   return ret;
17634 }
17635
17636 static int
17637 api_one_map_server_dump (vat_main_t * vam)
17638 {
17639   vl_api_one_map_server_dump_t *mp;
17640   vl_api_control_ping_t *mp_ping;
17641   int ret;
17642
17643   if (!vam->json_output)
17644     {
17645       print (vam->ofp, "%=20s", "Map server");
17646     }
17647
17648   M (ONE_MAP_SERVER_DUMP, mp);
17649   /* send it... */
17650   S (mp);
17651
17652   /* Use a control ping for synchronization */
17653   MPING (CONTROL_PING, mp_ping);
17654   S (mp_ping);
17655
17656   /* Wait for a reply... */
17657   W (ret);
17658   return ret;
17659 }
17660
17661 #define api_lisp_map_server_dump api_one_map_server_dump
17662
17663 static int
17664 api_one_map_resolver_dump (vat_main_t * vam)
17665 {
17666   vl_api_one_map_resolver_dump_t *mp;
17667   vl_api_control_ping_t *mp_ping;
17668   int ret;
17669
17670   if (!vam->json_output)
17671     {
17672       print (vam->ofp, "%=20s", "Map resolver");
17673     }
17674
17675   M (ONE_MAP_RESOLVER_DUMP, mp);
17676   /* send it... */
17677   S (mp);
17678
17679   /* Use a control ping for synchronization */
17680   MPING (CONTROL_PING, mp_ping);
17681   S (mp_ping);
17682
17683   /* Wait for a reply... */
17684   W (ret);
17685   return ret;
17686 }
17687
17688 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17689
17690 static int
17691 api_one_stats_flush (vat_main_t * vam)
17692 {
17693   vl_api_one_stats_flush_t *mp;
17694   int ret = 0;
17695
17696   M (ONE_STATS_FLUSH, mp);
17697   S (mp);
17698   W (ret);
17699   return ret;
17700 }
17701
17702 static int
17703 api_one_stats_dump (vat_main_t * vam)
17704 {
17705   vl_api_one_stats_dump_t *mp;
17706   vl_api_control_ping_t *mp_ping;
17707   int ret;
17708
17709   M (ONE_STATS_DUMP, mp);
17710   /* send it... */
17711   S (mp);
17712
17713   /* Use a control ping for synchronization */
17714   MPING (CONTROL_PING, mp_ping);
17715   S (mp_ping);
17716
17717   /* Wait for a reply... */
17718   W (ret);
17719   return ret;
17720 }
17721
17722 static int
17723 api_show_one_status (vat_main_t * vam)
17724 {
17725   vl_api_show_one_status_t *mp;
17726   int ret;
17727
17728   if (!vam->json_output)
17729     {
17730       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17731     }
17732
17733   M (SHOW_ONE_STATUS, mp);
17734   /* send it... */
17735   S (mp);
17736   /* Wait for a reply... */
17737   W (ret);
17738   return ret;
17739 }
17740
17741 #define api_show_lisp_status api_show_one_status
17742
17743 static int
17744 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17745 {
17746   vl_api_gpe_fwd_entry_path_dump_t *mp;
17747   vl_api_control_ping_t *mp_ping;
17748   unformat_input_t *i = vam->input;
17749   u32 fwd_entry_index = ~0;
17750   int ret;
17751
17752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17753     {
17754       if (unformat (i, "index %d", &fwd_entry_index))
17755         ;
17756       else
17757         break;
17758     }
17759
17760   if (~0 == fwd_entry_index)
17761     {
17762       errmsg ("no index specified!");
17763       return -99;
17764     }
17765
17766   if (!vam->json_output)
17767     {
17768       print (vam->ofp, "first line");
17769     }
17770
17771   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17772
17773   /* send it... */
17774   S (mp);
17775   /* Use a control ping for synchronization */
17776   MPING (CONTROL_PING, mp_ping);
17777   S (mp_ping);
17778
17779   /* Wait for a reply... */
17780   W (ret);
17781   return ret;
17782 }
17783
17784 static int
17785 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17786 {
17787   vl_api_one_get_map_request_itr_rlocs_t *mp;
17788   int ret;
17789
17790   if (!vam->json_output)
17791     {
17792       print (vam->ofp, "%=20s", "itr-rlocs:");
17793     }
17794
17795   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17796   /* send it... */
17797   S (mp);
17798   /* Wait for a reply... */
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17804
17805 static int
17806 api_af_packet_create (vat_main_t * vam)
17807 {
17808   unformat_input_t *i = vam->input;
17809   vl_api_af_packet_create_t *mp;
17810   u8 *host_if_name = 0;
17811   u8 hw_addr[6];
17812   u8 random_hw_addr = 1;
17813   int ret;
17814
17815   clib_memset (hw_addr, 0, sizeof (hw_addr));
17816
17817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (i, "name %s", &host_if_name))
17820         vec_add1 (host_if_name, 0);
17821       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17822         random_hw_addr = 0;
17823       else
17824         break;
17825     }
17826
17827   if (!vec_len (host_if_name))
17828     {
17829       errmsg ("host-interface name must be specified");
17830       return -99;
17831     }
17832
17833   if (vec_len (host_if_name) > 64)
17834     {
17835       errmsg ("host-interface name too long");
17836       return -99;
17837     }
17838
17839   M (AF_PACKET_CREATE, mp);
17840
17841   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17842   clib_memcpy (mp->hw_addr, hw_addr, 6);
17843   mp->use_random_hw_addr = random_hw_addr;
17844   vec_free (host_if_name);
17845
17846   S (mp);
17847
17848   /* *INDENT-OFF* */
17849   W2 (ret,
17850       ({
17851         if (ret == 0)
17852           fprintf (vam->ofp ? vam->ofp : stderr,
17853                    " new sw_if_index = %d\n", vam->sw_if_index);
17854       }));
17855   /* *INDENT-ON* */
17856   return ret;
17857 }
17858
17859 static int
17860 api_af_packet_delete (vat_main_t * vam)
17861 {
17862   unformat_input_t *i = vam->input;
17863   vl_api_af_packet_delete_t *mp;
17864   u8 *host_if_name = 0;
17865   int ret;
17866
17867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17868     {
17869       if (unformat (i, "name %s", &host_if_name))
17870         vec_add1 (host_if_name, 0);
17871       else
17872         break;
17873     }
17874
17875   if (!vec_len (host_if_name))
17876     {
17877       errmsg ("host-interface name must be specified");
17878       return -99;
17879     }
17880
17881   if (vec_len (host_if_name) > 64)
17882     {
17883       errmsg ("host-interface name too long");
17884       return -99;
17885     }
17886
17887   M (AF_PACKET_DELETE, mp);
17888
17889   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17890   vec_free (host_if_name);
17891
17892   S (mp);
17893   W (ret);
17894   return ret;
17895 }
17896
17897 static void vl_api_af_packet_details_t_handler
17898   (vl_api_af_packet_details_t * mp)
17899 {
17900   vat_main_t *vam = &vat_main;
17901
17902   print (vam->ofp, "%-16s %d",
17903          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17904 }
17905
17906 static void vl_api_af_packet_details_t_handler_json
17907   (vl_api_af_packet_details_t * mp)
17908 {
17909   vat_main_t *vam = &vat_main;
17910   vat_json_node_t *node = NULL;
17911
17912   if (VAT_JSON_ARRAY != vam->json_tree.type)
17913     {
17914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17915       vat_json_init_array (&vam->json_tree);
17916     }
17917   node = vat_json_array_add (&vam->json_tree);
17918
17919   vat_json_init_object (node);
17920   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17921   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17922 }
17923
17924 static int
17925 api_af_packet_dump (vat_main_t * vam)
17926 {
17927   vl_api_af_packet_dump_t *mp;
17928   vl_api_control_ping_t *mp_ping;
17929   int ret;
17930
17931   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17932   /* Get list of tap interfaces */
17933   M (AF_PACKET_DUMP, mp);
17934   S (mp);
17935
17936   /* Use a control ping for synchronization */
17937   MPING (CONTROL_PING, mp_ping);
17938   S (mp_ping);
17939
17940   W (ret);
17941   return ret;
17942 }
17943
17944 static int
17945 api_policer_add_del (vat_main_t * vam)
17946 {
17947   unformat_input_t *i = vam->input;
17948   vl_api_policer_add_del_t *mp;
17949   u8 is_add = 1;
17950   u8 *name = 0;
17951   u32 cir = 0;
17952   u32 eir = 0;
17953   u64 cb = 0;
17954   u64 eb = 0;
17955   u8 rate_type = 0;
17956   u8 round_type = 0;
17957   u8 type = 0;
17958   u8 color_aware = 0;
17959   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17960   int ret;
17961
17962   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17963   conform_action.dscp = 0;
17964   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17965   exceed_action.dscp = 0;
17966   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17967   violate_action.dscp = 0;
17968
17969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17970     {
17971       if (unformat (i, "del"))
17972         is_add = 0;
17973       else if (unformat (i, "name %s", &name))
17974         vec_add1 (name, 0);
17975       else if (unformat (i, "cir %u", &cir))
17976         ;
17977       else if (unformat (i, "eir %u", &eir))
17978         ;
17979       else if (unformat (i, "cb %u", &cb))
17980         ;
17981       else if (unformat (i, "eb %u", &eb))
17982         ;
17983       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17984                          &rate_type))
17985         ;
17986       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17987                          &round_type))
17988         ;
17989       else if (unformat (i, "type %U", unformat_policer_type, &type))
17990         ;
17991       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17992                          &conform_action))
17993         ;
17994       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17995                          &exceed_action))
17996         ;
17997       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17998                          &violate_action))
17999         ;
18000       else if (unformat (i, "color-aware"))
18001         color_aware = 1;
18002       else
18003         break;
18004     }
18005
18006   if (!vec_len (name))
18007     {
18008       errmsg ("policer name must be specified");
18009       return -99;
18010     }
18011
18012   if (vec_len (name) > 64)
18013     {
18014       errmsg ("policer name too long");
18015       return -99;
18016     }
18017
18018   M (POLICER_ADD_DEL, mp);
18019
18020   clib_memcpy (mp->name, name, vec_len (name));
18021   vec_free (name);
18022   mp->is_add = is_add;
18023   mp->cir = ntohl (cir);
18024   mp->eir = ntohl (eir);
18025   mp->cb = clib_net_to_host_u64 (cb);
18026   mp->eb = clib_net_to_host_u64 (eb);
18027   mp->rate_type = rate_type;
18028   mp->round_type = round_type;
18029   mp->type = type;
18030   mp->conform_action_type = conform_action.action_type;
18031   mp->conform_dscp = conform_action.dscp;
18032   mp->exceed_action_type = exceed_action.action_type;
18033   mp->exceed_dscp = exceed_action.dscp;
18034   mp->violate_action_type = violate_action.action_type;
18035   mp->violate_dscp = violate_action.dscp;
18036   mp->color_aware = color_aware;
18037
18038   S (mp);
18039   W (ret);
18040   return ret;
18041 }
18042
18043 static int
18044 api_policer_dump (vat_main_t * vam)
18045 {
18046   unformat_input_t *i = vam->input;
18047   vl_api_policer_dump_t *mp;
18048   vl_api_control_ping_t *mp_ping;
18049   u8 *match_name = 0;
18050   u8 match_name_valid = 0;
18051   int ret;
18052
18053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18054     {
18055       if (unformat (i, "name %s", &match_name))
18056         {
18057           vec_add1 (match_name, 0);
18058           match_name_valid = 1;
18059         }
18060       else
18061         break;
18062     }
18063
18064   M (POLICER_DUMP, mp);
18065   mp->match_name_valid = match_name_valid;
18066   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18067   vec_free (match_name);
18068   /* send it... */
18069   S (mp);
18070
18071   /* Use a control ping for synchronization */
18072   MPING (CONTROL_PING, mp_ping);
18073   S (mp_ping);
18074
18075   /* Wait for a reply... */
18076   W (ret);
18077   return ret;
18078 }
18079
18080 static int
18081 api_policer_classify_set_interface (vat_main_t * vam)
18082 {
18083   unformat_input_t *i = vam->input;
18084   vl_api_policer_classify_set_interface_t *mp;
18085   u32 sw_if_index;
18086   int sw_if_index_set;
18087   u32 ip4_table_index = ~0;
18088   u32 ip6_table_index = ~0;
18089   u32 l2_table_index = ~0;
18090   u8 is_add = 1;
18091   int ret;
18092
18093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18094     {
18095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18096         sw_if_index_set = 1;
18097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18098         sw_if_index_set = 1;
18099       else if (unformat (i, "del"))
18100         is_add = 0;
18101       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18102         ;
18103       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18104         ;
18105       else if (unformat (i, "l2-table %d", &l2_table_index))
18106         ;
18107       else
18108         {
18109           clib_warning ("parse error '%U'", format_unformat_error, i);
18110           return -99;
18111         }
18112     }
18113
18114   if (sw_if_index_set == 0)
18115     {
18116       errmsg ("missing interface name or sw_if_index");
18117       return -99;
18118     }
18119
18120   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18121
18122   mp->sw_if_index = ntohl (sw_if_index);
18123   mp->ip4_table_index = ntohl (ip4_table_index);
18124   mp->ip6_table_index = ntohl (ip6_table_index);
18125   mp->l2_table_index = ntohl (l2_table_index);
18126   mp->is_add = is_add;
18127
18128   S (mp);
18129   W (ret);
18130   return ret;
18131 }
18132
18133 static int
18134 api_policer_classify_dump (vat_main_t * vam)
18135 {
18136   unformat_input_t *i = vam->input;
18137   vl_api_policer_classify_dump_t *mp;
18138   vl_api_control_ping_t *mp_ping;
18139   u8 type = POLICER_CLASSIFY_N_TABLES;
18140   int ret;
18141
18142   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18143     ;
18144   else
18145     {
18146       errmsg ("classify table type must be specified");
18147       return -99;
18148     }
18149
18150   if (!vam->json_output)
18151     {
18152       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18153     }
18154
18155   M (POLICER_CLASSIFY_DUMP, mp);
18156   mp->type = type;
18157   /* send it... */
18158   S (mp);
18159
18160   /* Use a control ping for synchronization */
18161   MPING (CONTROL_PING, mp_ping);
18162   S (mp_ping);
18163
18164   /* Wait for a reply... */
18165   W (ret);
18166   return ret;
18167 }
18168
18169 static int
18170 api_netmap_create (vat_main_t * vam)
18171 {
18172   unformat_input_t *i = vam->input;
18173   vl_api_netmap_create_t *mp;
18174   u8 *if_name = 0;
18175   u8 hw_addr[6];
18176   u8 random_hw_addr = 1;
18177   u8 is_pipe = 0;
18178   u8 is_master = 0;
18179   int ret;
18180
18181   clib_memset (hw_addr, 0, sizeof (hw_addr));
18182
18183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18184     {
18185       if (unformat (i, "name %s", &if_name))
18186         vec_add1 (if_name, 0);
18187       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18188         random_hw_addr = 0;
18189       else if (unformat (i, "pipe"))
18190         is_pipe = 1;
18191       else if (unformat (i, "master"))
18192         is_master = 1;
18193       else if (unformat (i, "slave"))
18194         is_master = 0;
18195       else
18196         break;
18197     }
18198
18199   if (!vec_len (if_name))
18200     {
18201       errmsg ("interface name must be specified");
18202       return -99;
18203     }
18204
18205   if (vec_len (if_name) > 64)
18206     {
18207       errmsg ("interface name too long");
18208       return -99;
18209     }
18210
18211   M (NETMAP_CREATE, mp);
18212
18213   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18214   clib_memcpy (mp->hw_addr, hw_addr, 6);
18215   mp->use_random_hw_addr = random_hw_addr;
18216   mp->is_pipe = is_pipe;
18217   mp->is_master = is_master;
18218   vec_free (if_name);
18219
18220   S (mp);
18221   W (ret);
18222   return ret;
18223 }
18224
18225 static int
18226 api_netmap_delete (vat_main_t * vam)
18227 {
18228   unformat_input_t *i = vam->input;
18229   vl_api_netmap_delete_t *mp;
18230   u8 *if_name = 0;
18231   int ret;
18232
18233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18234     {
18235       if (unformat (i, "name %s", &if_name))
18236         vec_add1 (if_name, 0);
18237       else
18238         break;
18239     }
18240
18241   if (!vec_len (if_name))
18242     {
18243       errmsg ("interface name must be specified");
18244       return -99;
18245     }
18246
18247   if (vec_len (if_name) > 64)
18248     {
18249       errmsg ("interface name too long");
18250       return -99;
18251     }
18252
18253   M (NETMAP_DELETE, mp);
18254
18255   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18256   vec_free (if_name);
18257
18258   S (mp);
18259   W (ret);
18260   return ret;
18261 }
18262
18263 static u8 *
18264 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18265 {
18266   vl_api_fib_path_nh_proto_t proto =
18267     va_arg (*args, vl_api_fib_path_nh_proto_t);
18268
18269   switch (proto)
18270     {
18271     case FIB_API_PATH_NH_PROTO_IP4:
18272       s = format (s, "ip4");
18273       break;
18274     case FIB_API_PATH_NH_PROTO_IP6:
18275       s = format (s, "ip6");
18276       break;
18277     case FIB_API_PATH_NH_PROTO_MPLS:
18278       s = format (s, "mpls");
18279       break;
18280     case FIB_API_PATH_NH_PROTO_BIER:
18281       s = format (s, "bier");
18282       break;
18283     case FIB_API_PATH_NH_PROTO_ETHERNET:
18284       s = format (s, "ethernet");
18285       break;
18286     }
18287
18288   return (s);
18289 }
18290
18291 static u8 *
18292 format_vl_api_ip_address_union (u8 * s, va_list * args)
18293 {
18294   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18295   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18296
18297   switch (af)
18298     {
18299     case ADDRESS_IP4:
18300       s = format (s, "%U", format_ip4_address, u->ip4);
18301       break;
18302     case ADDRESS_IP6:
18303       s = format (s, "%U", format_ip6_address, u->ip6);
18304       break;
18305     }
18306   return (s);
18307 }
18308
18309 static u8 *
18310 format_vl_api_fib_path_type (u8 * s, va_list * args)
18311 {
18312   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18313
18314   switch (t)
18315     {
18316     case FIB_API_PATH_TYPE_NORMAL:
18317       s = format (s, "normal");
18318       break;
18319     case FIB_API_PATH_TYPE_LOCAL:
18320       s = format (s, "local");
18321       break;
18322     case FIB_API_PATH_TYPE_DROP:
18323       s = format (s, "drop");
18324       break;
18325     case FIB_API_PATH_TYPE_UDP_ENCAP:
18326       s = format (s, "udp-encap");
18327       break;
18328     case FIB_API_PATH_TYPE_BIER_IMP:
18329       s = format (s, "bier-imp");
18330       break;
18331     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18332       s = format (s, "unreach");
18333       break;
18334     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18335       s = format (s, "prohibit");
18336       break;
18337     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18338       s = format (s, "src-lookup");
18339       break;
18340     case FIB_API_PATH_TYPE_DVR:
18341       s = format (s, "dvr");
18342       break;
18343     case FIB_API_PATH_TYPE_INTERFACE_RX:
18344       s = format (s, "interface-rx");
18345       break;
18346     case FIB_API_PATH_TYPE_CLASSIFY:
18347       s = format (s, "classify");
18348       break;
18349     }
18350
18351   return (s);
18352 }
18353
18354 static void
18355 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18356 {
18357   print (vam->ofp,
18358          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18359          ntohl (fp->weight), ntohl (fp->sw_if_index),
18360          format_vl_api_fib_path_type, fp->type,
18361          format_fib_api_path_nh_proto, fp->proto,
18362          format_vl_api_ip_address_union, &fp->nh.address);
18363 }
18364
18365 static void
18366 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18367                                  vl_api_fib_path_t * fp)
18368 {
18369   struct in_addr ip4;
18370   struct in6_addr ip6;
18371
18372   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18373   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18374   vat_json_object_add_uint (node, "type", fp->type);
18375   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18376   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18377     {
18378       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18379       vat_json_object_add_ip4 (node, "next_hop", ip4);
18380     }
18381   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18382     {
18383       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18384       vat_json_object_add_ip6 (node, "next_hop", ip6);
18385     }
18386 }
18387
18388 static void
18389 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18390 {
18391   vat_main_t *vam = &vat_main;
18392   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18393   vl_api_fib_path_t *fp;
18394   i32 i;
18395
18396   print (vam->ofp, "sw_if_index %d via:",
18397          ntohl (mp->mt_tunnel.mt_sw_if_index));
18398   fp = mp->mt_tunnel.mt_paths;
18399   for (i = 0; i < count; i++)
18400     {
18401       vl_api_fib_path_print (vam, fp);
18402       fp++;
18403     }
18404
18405   print (vam->ofp, "");
18406 }
18407
18408 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18409 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18410
18411 static void
18412 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18413 {
18414   vat_main_t *vam = &vat_main;
18415   vat_json_node_t *node = NULL;
18416   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18417   vl_api_fib_path_t *fp;
18418   i32 i;
18419
18420   if (VAT_JSON_ARRAY != vam->json_tree.type)
18421     {
18422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18423       vat_json_init_array (&vam->json_tree);
18424     }
18425   node = vat_json_array_add (&vam->json_tree);
18426
18427   vat_json_init_object (node);
18428   vat_json_object_add_uint (node, "sw_if_index",
18429                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18430
18431   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18432
18433   fp = mp->mt_tunnel.mt_paths;
18434   for (i = 0; i < count; i++)
18435     {
18436       vl_api_mpls_fib_path_json_print (node, fp);
18437       fp++;
18438     }
18439 }
18440
18441 static int
18442 api_mpls_tunnel_dump (vat_main_t * vam)
18443 {
18444   vl_api_mpls_tunnel_dump_t *mp;
18445   vl_api_control_ping_t *mp_ping;
18446   int ret;
18447
18448   M (MPLS_TUNNEL_DUMP, mp);
18449
18450   S (mp);
18451
18452   /* Use a control ping for synchronization */
18453   MPING (CONTROL_PING, mp_ping);
18454   S (mp_ping);
18455
18456   W (ret);
18457   return ret;
18458 }
18459
18460 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18461 #define vl_api_mpls_table_details_t_print vl_noop_handler
18462
18463
18464 static void
18465 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18466 {
18467   vat_main_t *vam = &vat_main;
18468
18469   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18470 }
18471
18472 static void vl_api_mpls_table_details_t_handler_json
18473   (vl_api_mpls_table_details_t * mp)
18474 {
18475   vat_main_t *vam = &vat_main;
18476   vat_json_node_t *node = NULL;
18477
18478   if (VAT_JSON_ARRAY != vam->json_tree.type)
18479     {
18480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18481       vat_json_init_array (&vam->json_tree);
18482     }
18483   node = vat_json_array_add (&vam->json_tree);
18484
18485   vat_json_init_object (node);
18486   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18487 }
18488
18489 static int
18490 api_mpls_table_dump (vat_main_t * vam)
18491 {
18492   vl_api_mpls_table_dump_t *mp;
18493   vl_api_control_ping_t *mp_ping;
18494   int ret;
18495
18496   M (MPLS_TABLE_DUMP, mp);
18497   S (mp);
18498
18499   /* Use a control ping for synchronization */
18500   MPING (CONTROL_PING, mp_ping);
18501   S (mp_ping);
18502
18503   W (ret);
18504   return ret;
18505 }
18506
18507 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18508 #define vl_api_mpls_route_details_t_print vl_noop_handler
18509
18510 static void
18511 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18512 {
18513   vat_main_t *vam = &vat_main;
18514   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18515   vl_api_fib_path_t *fp;
18516   int i;
18517
18518   print (vam->ofp,
18519          "table-id %d, label %u, ess_bit %u",
18520          ntohl (mp->mr_route.mr_table_id),
18521          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18522   fp = mp->mr_route.mr_paths;
18523   for (i = 0; i < count; i++)
18524     {
18525       vl_api_fib_path_print (vam, fp);
18526       fp++;
18527     }
18528 }
18529
18530 static void vl_api_mpls_route_details_t_handler_json
18531   (vl_api_mpls_route_details_t * mp)
18532 {
18533   vat_main_t *vam = &vat_main;
18534   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18535   vat_json_node_t *node = NULL;
18536   vl_api_fib_path_t *fp;
18537   int i;
18538
18539   if (VAT_JSON_ARRAY != vam->json_tree.type)
18540     {
18541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18542       vat_json_init_array (&vam->json_tree);
18543     }
18544   node = vat_json_array_add (&vam->json_tree);
18545
18546   vat_json_init_object (node);
18547   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18548   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18549   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18550   vat_json_object_add_uint (node, "path_count", count);
18551   fp = mp->mr_route.mr_paths;
18552   for (i = 0; i < count; i++)
18553     {
18554       vl_api_mpls_fib_path_json_print (node, fp);
18555       fp++;
18556     }
18557 }
18558
18559 static int
18560 api_mpls_route_dump (vat_main_t * vam)
18561 {
18562   unformat_input_t *input = vam->input;
18563   vl_api_mpls_route_dump_t *mp;
18564   vl_api_control_ping_t *mp_ping;
18565   u32 table_id;
18566   int ret;
18567
18568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18569     {
18570       if (unformat (input, "table_id %d", &table_id))
18571         ;
18572       else
18573         break;
18574     }
18575   if (table_id == ~0)
18576     {
18577       errmsg ("missing table id");
18578       return -99;
18579     }
18580
18581   M (MPLS_ROUTE_DUMP, mp);
18582
18583   mp->table.mt_table_id = ntohl (table_id);
18584   S (mp);
18585
18586   /* Use a control ping for synchronization */
18587   MPING (CONTROL_PING, mp_ping);
18588   S (mp_ping);
18589
18590   W (ret);
18591   return ret;
18592 }
18593
18594 #define vl_api_ip_table_details_t_endian vl_noop_handler
18595 #define vl_api_ip_table_details_t_print vl_noop_handler
18596
18597 static void
18598 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18599 {
18600   vat_main_t *vam = &vat_main;
18601
18602   print (vam->ofp,
18603          "%s; table-id %d, prefix %U/%d",
18604          mp->table.name, ntohl (mp->table.table_id));
18605 }
18606
18607
18608 static void vl_api_ip_table_details_t_handler_json
18609   (vl_api_ip_table_details_t * mp)
18610 {
18611   vat_main_t *vam = &vat_main;
18612   vat_json_node_t *node = NULL;
18613
18614   if (VAT_JSON_ARRAY != vam->json_tree.type)
18615     {
18616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18617       vat_json_init_array (&vam->json_tree);
18618     }
18619   node = vat_json_array_add (&vam->json_tree);
18620
18621   vat_json_init_object (node);
18622   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18623 }
18624
18625 static int
18626 api_ip_table_dump (vat_main_t * vam)
18627 {
18628   vl_api_ip_table_dump_t *mp;
18629   vl_api_control_ping_t *mp_ping;
18630   int ret;
18631
18632   M (IP_TABLE_DUMP, mp);
18633   S (mp);
18634
18635   /* Use a control ping for synchronization */
18636   MPING (CONTROL_PING, mp_ping);
18637   S (mp_ping);
18638
18639   W (ret);
18640   return ret;
18641 }
18642
18643 static int
18644 api_ip_mtable_dump (vat_main_t * vam)
18645 {
18646   vl_api_ip_mtable_dump_t *mp;
18647   vl_api_control_ping_t *mp_ping;
18648   int ret;
18649
18650   M (IP_MTABLE_DUMP, mp);
18651   S (mp);
18652
18653   /* Use a control ping for synchronization */
18654   MPING (CONTROL_PING, mp_ping);
18655   S (mp_ping);
18656
18657   W (ret);
18658   return ret;
18659 }
18660
18661 static int
18662 api_ip_mroute_dump (vat_main_t * vam)
18663 {
18664   unformat_input_t *input = vam->input;
18665   vl_api_control_ping_t *mp_ping;
18666   vl_api_ip_mroute_dump_t *mp;
18667   int ret, is_ip6;
18668   u32 table_id;
18669
18670   is_ip6 = 0;
18671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18672     {
18673       if (unformat (input, "table_id %d", &table_id))
18674         ;
18675       else if (unformat (input, "ip6"))
18676         is_ip6 = 1;
18677       else if (unformat (input, "ip4"))
18678         is_ip6 = 0;
18679       else
18680         break;
18681     }
18682   if (table_id == ~0)
18683     {
18684       errmsg ("missing table id");
18685       return -99;
18686     }
18687
18688   M (IP_MROUTE_DUMP, mp);
18689   mp->table.table_id = table_id;
18690   mp->table.is_ip6 = is_ip6;
18691   S (mp);
18692
18693   /* Use a control ping for synchronization */
18694   MPING (CONTROL_PING, mp_ping);
18695   S (mp_ping);
18696
18697   W (ret);
18698   return ret;
18699 }
18700
18701 static void vl_api_ip_neighbor_details_t_handler
18702   (vl_api_ip_neighbor_details_t * mp)
18703 {
18704   vat_main_t *vam = &vat_main;
18705
18706   print (vam->ofp, "%c %U %U",
18707          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18708          format_vl_api_mac_address, &mp->neighbor.mac_address,
18709          format_vl_api_address, &mp->neighbor.ip_address);
18710 }
18711
18712 static void vl_api_ip_neighbor_details_t_handler_json
18713   (vl_api_ip_neighbor_details_t * mp)
18714 {
18715
18716   vat_main_t *vam = &vat_main;
18717   vat_json_node_t *node;
18718
18719   if (VAT_JSON_ARRAY != vam->json_tree.type)
18720     {
18721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18722       vat_json_init_array (&vam->json_tree);
18723     }
18724   node = vat_json_array_add (&vam->json_tree);
18725
18726   vat_json_init_object (node);
18727   vat_json_object_add_string_copy
18728     (node, "flag",
18729      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18730       (u8 *) "static" : (u8 *) "dynamic"));
18731
18732   vat_json_object_add_string_copy (node, "link_layer",
18733                                    format (0, "%U", format_vl_api_mac_address,
18734                                            &mp->neighbor.mac_address));
18735   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18736 }
18737
18738 static int
18739 api_ip_neighbor_dump (vat_main_t * vam)
18740 {
18741   unformat_input_t *i = vam->input;
18742   vl_api_ip_neighbor_dump_t *mp;
18743   vl_api_control_ping_t *mp_ping;
18744   u8 is_ipv6 = 0;
18745   u32 sw_if_index = ~0;
18746   int ret;
18747
18748   /* Parse args required to build the message */
18749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18750     {
18751       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18752         ;
18753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18754         ;
18755       else if (unformat (i, "ip6"))
18756         is_ipv6 = 1;
18757       else
18758         break;
18759     }
18760
18761   if (sw_if_index == ~0)
18762     {
18763       errmsg ("missing interface name or sw_if_index");
18764       return -99;
18765     }
18766
18767   M (IP_NEIGHBOR_DUMP, mp);
18768   mp->is_ipv6 = (u8) is_ipv6;
18769   mp->sw_if_index = ntohl (sw_if_index);
18770   S (mp);
18771
18772   /* Use a control ping for synchronization */
18773   MPING (CONTROL_PING, mp_ping);
18774   S (mp_ping);
18775
18776   W (ret);
18777   return ret;
18778 }
18779
18780 #define vl_api_ip_route_details_t_endian vl_noop_handler
18781 #define vl_api_ip_route_details_t_print vl_noop_handler
18782
18783 static void
18784 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18785 {
18786   vat_main_t *vam = &vat_main;
18787   u8 count = mp->route.n_paths;
18788   vl_api_fib_path_t *fp;
18789   int i;
18790
18791   print (vam->ofp,
18792          "table-id %d, prefix %U/%d",
18793          ntohl (mp->route.table_id),
18794          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18795   for (i = 0; i < count; i++)
18796     {
18797       fp = &mp->route.paths[i];
18798
18799       vl_api_fib_path_print (vam, fp);
18800       fp++;
18801     }
18802 }
18803
18804 static void vl_api_ip_route_details_t_handler_json
18805   (vl_api_ip_route_details_t * mp)
18806 {
18807   vat_main_t *vam = &vat_main;
18808   u8 count = mp->route.n_paths;
18809   vat_json_node_t *node = NULL;
18810   struct in_addr ip4;
18811   struct in6_addr ip6;
18812   vl_api_fib_path_t *fp;
18813   int i;
18814
18815   if (VAT_JSON_ARRAY != vam->json_tree.type)
18816     {
18817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18818       vat_json_init_array (&vam->json_tree);
18819     }
18820   node = vat_json_array_add (&vam->json_tree);
18821
18822   vat_json_init_object (node);
18823   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18824   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18825     {
18826       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18827       vat_json_object_add_ip6 (node, "prefix", ip6);
18828     }
18829   else
18830     {
18831       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18832       vat_json_object_add_ip4 (node, "prefix", ip4);
18833     }
18834   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18835   vat_json_object_add_uint (node, "path_count", count);
18836   for (i = 0; i < count; i++)
18837     {
18838       fp = &mp->route.paths[i];
18839       vl_api_mpls_fib_path_json_print (node, fp);
18840     }
18841 }
18842
18843 static int
18844 api_ip_route_dump (vat_main_t * vam)
18845 {
18846   unformat_input_t *input = vam->input;
18847   vl_api_ip_route_dump_t *mp;
18848   vl_api_control_ping_t *mp_ping;
18849   u32 table_id;
18850   u8 is_ip6;
18851   int ret;
18852
18853   is_ip6 = 0;
18854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18855     {
18856       if (unformat (input, "table_id %d", &table_id))
18857         ;
18858       else if (unformat (input, "ip6"))
18859         is_ip6 = 1;
18860       else if (unformat (input, "ip4"))
18861         is_ip6 = 0;
18862       else
18863         break;
18864     }
18865   if (table_id == ~0)
18866     {
18867       errmsg ("missing table id");
18868       return -99;
18869     }
18870
18871   M (IP_ROUTE_DUMP, mp);
18872
18873   mp->table.table_id = table_id;
18874   mp->table.is_ip6 = is_ip6;
18875
18876   S (mp);
18877
18878   /* Use a control ping for synchronization */
18879   MPING (CONTROL_PING, mp_ping);
18880   S (mp_ping);
18881
18882   W (ret);
18883   return ret;
18884 }
18885
18886 int
18887 api_classify_table_ids (vat_main_t * vam)
18888 {
18889   vl_api_classify_table_ids_t *mp;
18890   int ret;
18891
18892   /* Construct the API message */
18893   M (CLASSIFY_TABLE_IDS, mp);
18894   mp->context = 0;
18895
18896   S (mp);
18897   W (ret);
18898   return ret;
18899 }
18900
18901 int
18902 api_classify_table_by_interface (vat_main_t * vam)
18903 {
18904   unformat_input_t *input = vam->input;
18905   vl_api_classify_table_by_interface_t *mp;
18906
18907   u32 sw_if_index = ~0;
18908   int ret;
18909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18910     {
18911       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18912         ;
18913       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18914         ;
18915       else
18916         break;
18917     }
18918   if (sw_if_index == ~0)
18919     {
18920       errmsg ("missing interface name or sw_if_index");
18921       return -99;
18922     }
18923
18924   /* Construct the API message */
18925   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18926   mp->context = 0;
18927   mp->sw_if_index = ntohl (sw_if_index);
18928
18929   S (mp);
18930   W (ret);
18931   return ret;
18932 }
18933
18934 int
18935 api_classify_table_info (vat_main_t * vam)
18936 {
18937   unformat_input_t *input = vam->input;
18938   vl_api_classify_table_info_t *mp;
18939
18940   u32 table_id = ~0;
18941   int ret;
18942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18943     {
18944       if (unformat (input, "table_id %d", &table_id))
18945         ;
18946       else
18947         break;
18948     }
18949   if (table_id == ~0)
18950     {
18951       errmsg ("missing table id");
18952       return -99;
18953     }
18954
18955   /* Construct the API message */
18956   M (CLASSIFY_TABLE_INFO, mp);
18957   mp->context = 0;
18958   mp->table_id = ntohl (table_id);
18959
18960   S (mp);
18961   W (ret);
18962   return ret;
18963 }
18964
18965 int
18966 api_classify_session_dump (vat_main_t * vam)
18967 {
18968   unformat_input_t *input = vam->input;
18969   vl_api_classify_session_dump_t *mp;
18970   vl_api_control_ping_t *mp_ping;
18971
18972   u32 table_id = ~0;
18973   int ret;
18974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18975     {
18976       if (unformat (input, "table_id %d", &table_id))
18977         ;
18978       else
18979         break;
18980     }
18981   if (table_id == ~0)
18982     {
18983       errmsg ("missing table id");
18984       return -99;
18985     }
18986
18987   /* Construct the API message */
18988   M (CLASSIFY_SESSION_DUMP, mp);
18989   mp->context = 0;
18990   mp->table_id = ntohl (table_id);
18991   S (mp);
18992
18993   /* Use a control ping for synchronization */
18994   MPING (CONTROL_PING, mp_ping);
18995   S (mp_ping);
18996
18997   W (ret);
18998   return ret;
18999 }
19000
19001 static void
19002 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19003 {
19004   vat_main_t *vam = &vat_main;
19005
19006   print (vam->ofp, "collector_address %U, collector_port %d, "
19007          "src_address %U, vrf_id %d, path_mtu %u, "
19008          "template_interval %u, udp_checksum %d",
19009          format_ip4_address, mp->collector_address,
19010          ntohs (mp->collector_port),
19011          format_ip4_address, mp->src_address,
19012          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19013          ntohl (mp->template_interval), mp->udp_checksum);
19014
19015   vam->retval = 0;
19016   vam->result_ready = 1;
19017 }
19018
19019 static void
19020   vl_api_ipfix_exporter_details_t_handler_json
19021   (vl_api_ipfix_exporter_details_t * mp)
19022 {
19023   vat_main_t *vam = &vat_main;
19024   vat_json_node_t node;
19025   struct in_addr collector_address;
19026   struct in_addr src_address;
19027
19028   vat_json_init_object (&node);
19029   clib_memcpy (&collector_address, &mp->collector_address,
19030                sizeof (collector_address));
19031   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19032   vat_json_object_add_uint (&node, "collector_port",
19033                             ntohs (mp->collector_port));
19034   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19035   vat_json_object_add_ip4 (&node, "src_address", src_address);
19036   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19037   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19038   vat_json_object_add_uint (&node, "template_interval",
19039                             ntohl (mp->template_interval));
19040   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19041
19042   vat_json_print (vam->ofp, &node);
19043   vat_json_free (&node);
19044   vam->retval = 0;
19045   vam->result_ready = 1;
19046 }
19047
19048 int
19049 api_ipfix_exporter_dump (vat_main_t * vam)
19050 {
19051   vl_api_ipfix_exporter_dump_t *mp;
19052   int ret;
19053
19054   /* Construct the API message */
19055   M (IPFIX_EXPORTER_DUMP, mp);
19056   mp->context = 0;
19057
19058   S (mp);
19059   W (ret);
19060   return ret;
19061 }
19062
19063 static int
19064 api_ipfix_classify_stream_dump (vat_main_t * vam)
19065 {
19066   vl_api_ipfix_classify_stream_dump_t *mp;
19067   int ret;
19068
19069   /* Construct the API message */
19070   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19071   mp->context = 0;
19072
19073   S (mp);
19074   W (ret);
19075   return ret;
19076   /* NOTREACHED */
19077   return 0;
19078 }
19079
19080 static void
19081   vl_api_ipfix_classify_stream_details_t_handler
19082   (vl_api_ipfix_classify_stream_details_t * mp)
19083 {
19084   vat_main_t *vam = &vat_main;
19085   print (vam->ofp, "domain_id %d, src_port %d",
19086          ntohl (mp->domain_id), ntohs (mp->src_port));
19087   vam->retval = 0;
19088   vam->result_ready = 1;
19089 }
19090
19091 static void
19092   vl_api_ipfix_classify_stream_details_t_handler_json
19093   (vl_api_ipfix_classify_stream_details_t * mp)
19094 {
19095   vat_main_t *vam = &vat_main;
19096   vat_json_node_t node;
19097
19098   vat_json_init_object (&node);
19099   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19100   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19101
19102   vat_json_print (vam->ofp, &node);
19103   vat_json_free (&node);
19104   vam->retval = 0;
19105   vam->result_ready = 1;
19106 }
19107
19108 static int
19109 api_ipfix_classify_table_dump (vat_main_t * vam)
19110 {
19111   vl_api_ipfix_classify_table_dump_t *mp;
19112   vl_api_control_ping_t *mp_ping;
19113   int ret;
19114
19115   if (!vam->json_output)
19116     {
19117       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19118              "transport_protocol");
19119     }
19120
19121   /* Construct the API message */
19122   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19123
19124   /* send it... */
19125   S (mp);
19126
19127   /* Use a control ping for synchronization */
19128   MPING (CONTROL_PING, mp_ping);
19129   S (mp_ping);
19130
19131   W (ret);
19132   return ret;
19133 }
19134
19135 static void
19136   vl_api_ipfix_classify_table_details_t_handler
19137   (vl_api_ipfix_classify_table_details_t * mp)
19138 {
19139   vat_main_t *vam = &vat_main;
19140   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19141          mp->transport_protocol);
19142 }
19143
19144 static void
19145   vl_api_ipfix_classify_table_details_t_handler_json
19146   (vl_api_ipfix_classify_table_details_t * mp)
19147 {
19148   vat_json_node_t *node = NULL;
19149   vat_main_t *vam = &vat_main;
19150
19151   if (VAT_JSON_ARRAY != vam->json_tree.type)
19152     {
19153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19154       vat_json_init_array (&vam->json_tree);
19155     }
19156
19157   node = vat_json_array_add (&vam->json_tree);
19158   vat_json_init_object (node);
19159
19160   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19161   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19162   vat_json_object_add_uint (node, "transport_protocol",
19163                             mp->transport_protocol);
19164 }
19165
19166 static int
19167 api_sw_interface_span_enable_disable (vat_main_t * vam)
19168 {
19169   unformat_input_t *i = vam->input;
19170   vl_api_sw_interface_span_enable_disable_t *mp;
19171   u32 src_sw_if_index = ~0;
19172   u32 dst_sw_if_index = ~0;
19173   u8 state = 3;
19174   int ret;
19175   u8 is_l2 = 0;
19176
19177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19178     {
19179       if (unformat
19180           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19181         ;
19182       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19183         ;
19184       else
19185         if (unformat
19186             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19187         ;
19188       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19189         ;
19190       else if (unformat (i, "disable"))
19191         state = 0;
19192       else if (unformat (i, "rx"))
19193         state = 1;
19194       else if (unformat (i, "tx"))
19195         state = 2;
19196       else if (unformat (i, "both"))
19197         state = 3;
19198       else if (unformat (i, "l2"))
19199         is_l2 = 1;
19200       else
19201         break;
19202     }
19203
19204   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19205
19206   mp->sw_if_index_from = htonl (src_sw_if_index);
19207   mp->sw_if_index_to = htonl (dst_sw_if_index);
19208   mp->state = state;
19209   mp->is_l2 = is_l2;
19210
19211   S (mp);
19212   W (ret);
19213   return ret;
19214 }
19215
19216 static void
19217 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19218                                             * mp)
19219 {
19220   vat_main_t *vam = &vat_main;
19221   u8 *sw_if_from_name = 0;
19222   u8 *sw_if_to_name = 0;
19223   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19224   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19225   char *states[] = { "none", "rx", "tx", "both" };
19226   hash_pair_t *p;
19227
19228   /* *INDENT-OFF* */
19229   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19230   ({
19231     if ((u32) p->value[0] == sw_if_index_from)
19232       {
19233         sw_if_from_name = (u8 *)(p->key);
19234         if (sw_if_to_name)
19235           break;
19236       }
19237     if ((u32) p->value[0] == sw_if_index_to)
19238       {
19239         sw_if_to_name = (u8 *)(p->key);
19240         if (sw_if_from_name)
19241           break;
19242       }
19243   }));
19244   /* *INDENT-ON* */
19245   print (vam->ofp, "%20s => %20s (%s) %s",
19246          sw_if_from_name, sw_if_to_name, states[mp->state],
19247          mp->is_l2 ? "l2" : "device");
19248 }
19249
19250 static void
19251   vl_api_sw_interface_span_details_t_handler_json
19252   (vl_api_sw_interface_span_details_t * mp)
19253 {
19254   vat_main_t *vam = &vat_main;
19255   vat_json_node_t *node = NULL;
19256   u8 *sw_if_from_name = 0;
19257   u8 *sw_if_to_name = 0;
19258   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19259   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19260   hash_pair_t *p;
19261
19262   /* *INDENT-OFF* */
19263   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19264   ({
19265     if ((u32) p->value[0] == sw_if_index_from)
19266       {
19267         sw_if_from_name = (u8 *)(p->key);
19268         if (sw_if_to_name)
19269           break;
19270       }
19271     if ((u32) p->value[0] == sw_if_index_to)
19272       {
19273         sw_if_to_name = (u8 *)(p->key);
19274         if (sw_if_from_name)
19275           break;
19276       }
19277   }));
19278   /* *INDENT-ON* */
19279
19280   if (VAT_JSON_ARRAY != vam->json_tree.type)
19281     {
19282       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19283       vat_json_init_array (&vam->json_tree);
19284     }
19285   node = vat_json_array_add (&vam->json_tree);
19286
19287   vat_json_init_object (node);
19288   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19289   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19290   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19291   if (0 != sw_if_to_name)
19292     {
19293       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19294     }
19295   vat_json_object_add_uint (node, "state", mp->state);
19296   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19297 }
19298
19299 static int
19300 api_sw_interface_span_dump (vat_main_t * vam)
19301 {
19302   unformat_input_t *input = vam->input;
19303   vl_api_sw_interface_span_dump_t *mp;
19304   vl_api_control_ping_t *mp_ping;
19305   u8 is_l2 = 0;
19306   int ret;
19307
19308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19309     {
19310       if (unformat (input, "l2"))
19311         is_l2 = 1;
19312       else
19313         break;
19314     }
19315
19316   M (SW_INTERFACE_SPAN_DUMP, mp);
19317   mp->is_l2 = is_l2;
19318   S (mp);
19319
19320   /* Use a control ping for synchronization */
19321   MPING (CONTROL_PING, mp_ping);
19322   S (mp_ping);
19323
19324   W (ret);
19325   return ret;
19326 }
19327
19328 int
19329 api_pg_create_interface (vat_main_t * vam)
19330 {
19331   unformat_input_t *input = vam->input;
19332   vl_api_pg_create_interface_t *mp;
19333
19334   u32 if_id = ~0, gso_size = 0;
19335   u8 gso_enabled = 0;
19336   int ret;
19337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19338     {
19339       if (unformat (input, "if_id %d", &if_id))
19340         ;
19341       else if (unformat (input, "gso-enabled"))
19342         {
19343           gso_enabled = 1;
19344           if (unformat (input, "gso-size %u", &gso_size))
19345             ;
19346           else
19347             {
19348               errmsg ("missing gso-size");
19349               return -99;
19350             }
19351         }
19352       else
19353         break;
19354     }
19355   if (if_id == ~0)
19356     {
19357       errmsg ("missing pg interface index");
19358       return -99;
19359     }
19360
19361   /* Construct the API message */
19362   M (PG_CREATE_INTERFACE, mp);
19363   mp->context = 0;
19364   mp->interface_id = ntohl (if_id);
19365   mp->gso_enabled = gso_enabled;
19366
19367   S (mp);
19368   W (ret);
19369   return ret;
19370 }
19371
19372 int
19373 api_pg_capture (vat_main_t * vam)
19374 {
19375   unformat_input_t *input = vam->input;
19376   vl_api_pg_capture_t *mp;
19377
19378   u32 if_id = ~0;
19379   u8 enable = 1;
19380   u32 count = 1;
19381   u8 pcap_file_set = 0;
19382   u8 *pcap_file = 0;
19383   int ret;
19384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19385     {
19386       if (unformat (input, "if_id %d", &if_id))
19387         ;
19388       else if (unformat (input, "pcap %s", &pcap_file))
19389         pcap_file_set = 1;
19390       else if (unformat (input, "count %d", &count))
19391         ;
19392       else if (unformat (input, "disable"))
19393         enable = 0;
19394       else
19395         break;
19396     }
19397   if (if_id == ~0)
19398     {
19399       errmsg ("missing pg interface index");
19400       return -99;
19401     }
19402   if (pcap_file_set > 0)
19403     {
19404       if (vec_len (pcap_file) > 255)
19405         {
19406           errmsg ("pcap file name is too long");
19407           return -99;
19408         }
19409     }
19410
19411   u32 name_len = vec_len (pcap_file);
19412   /* Construct the API message */
19413   M (PG_CAPTURE, mp);
19414   mp->context = 0;
19415   mp->interface_id = ntohl (if_id);
19416   mp->is_enabled = enable;
19417   mp->count = ntohl (count);
19418   mp->pcap_name_length = ntohl (name_len);
19419   if (pcap_file_set != 0)
19420     {
19421       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19422     }
19423   vec_free (pcap_file);
19424
19425   S (mp);
19426   W (ret);
19427   return ret;
19428 }
19429
19430 int
19431 api_pg_enable_disable (vat_main_t * vam)
19432 {
19433   unformat_input_t *input = vam->input;
19434   vl_api_pg_enable_disable_t *mp;
19435
19436   u8 enable = 1;
19437   u8 stream_name_set = 0;
19438   u8 *stream_name = 0;
19439   int ret;
19440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19441     {
19442       if (unformat (input, "stream %s", &stream_name))
19443         stream_name_set = 1;
19444       else if (unformat (input, "disable"))
19445         enable = 0;
19446       else
19447         break;
19448     }
19449
19450   if (stream_name_set > 0)
19451     {
19452       if (vec_len (stream_name) > 255)
19453         {
19454           errmsg ("stream name too long");
19455           return -99;
19456         }
19457     }
19458
19459   u32 name_len = vec_len (stream_name);
19460   /* Construct the API message */
19461   M (PG_ENABLE_DISABLE, mp);
19462   mp->context = 0;
19463   mp->is_enabled = enable;
19464   if (stream_name_set != 0)
19465     {
19466       mp->stream_name_length = ntohl (name_len);
19467       clib_memcpy (mp->stream_name, stream_name, name_len);
19468     }
19469   vec_free (stream_name);
19470
19471   S (mp);
19472   W (ret);
19473   return ret;
19474 }
19475
19476 int
19477 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19478 {
19479   unformat_input_t *input = vam->input;
19480   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19481
19482   u16 *low_ports = 0;
19483   u16 *high_ports = 0;
19484   u16 this_low;
19485   u16 this_hi;
19486   vl_api_prefix_t prefix;
19487   u32 tmp, tmp2;
19488   u8 prefix_set = 0;
19489   u32 vrf_id = ~0;
19490   u8 is_add = 1;
19491   int ret;
19492
19493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19494     {
19495       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19496         prefix_set = 1;
19497       else if (unformat (input, "vrf %d", &vrf_id))
19498         ;
19499       else if (unformat (input, "del"))
19500         is_add = 0;
19501       else if (unformat (input, "port %d", &tmp))
19502         {
19503           if (tmp == 0 || tmp > 65535)
19504             {
19505               errmsg ("port %d out of range", tmp);
19506               return -99;
19507             }
19508           this_low = tmp;
19509           this_hi = this_low + 1;
19510           vec_add1 (low_ports, this_low);
19511           vec_add1 (high_ports, this_hi);
19512         }
19513       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19514         {
19515           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19516             {
19517               errmsg ("incorrect range parameters");
19518               return -99;
19519             }
19520           this_low = tmp;
19521           /* Note: in debug CLI +1 is added to high before
19522              passing to real fn that does "the work"
19523              (ip_source_and_port_range_check_add_del).
19524              This fn is a wrapper around the binary API fn a
19525              control plane will call, which expects this increment
19526              to have occurred. Hence letting the binary API control
19527              plane fn do the increment for consistency between VAT
19528              and other control planes.
19529            */
19530           this_hi = tmp2;
19531           vec_add1 (low_ports, this_low);
19532           vec_add1 (high_ports, this_hi);
19533         }
19534       else
19535         break;
19536     }
19537
19538   if (prefix_set == 0)
19539     {
19540       errmsg ("<address>/<mask> not specified");
19541       return -99;
19542     }
19543
19544   if (vrf_id == ~0)
19545     {
19546       errmsg ("VRF ID required, not specified");
19547       return -99;
19548     }
19549
19550   if (vrf_id == 0)
19551     {
19552       errmsg
19553         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19554       return -99;
19555     }
19556
19557   if (vec_len (low_ports) == 0)
19558     {
19559       errmsg ("At least one port or port range required");
19560       return -99;
19561     }
19562
19563   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19564
19565   mp->is_add = is_add;
19566
19567   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19568
19569   mp->number_of_ranges = vec_len (low_ports);
19570
19571   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19572   vec_free (low_ports);
19573
19574   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19575   vec_free (high_ports);
19576
19577   mp->vrf_id = ntohl (vrf_id);
19578
19579   S (mp);
19580   W (ret);
19581   return ret;
19582 }
19583
19584 int
19585 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19586 {
19587   unformat_input_t *input = vam->input;
19588   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19589   u32 sw_if_index = ~0;
19590   int vrf_set = 0;
19591   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19592   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19593   u8 is_add = 1;
19594   int ret;
19595
19596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19597     {
19598       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19599         ;
19600       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19601         ;
19602       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19603         vrf_set = 1;
19604       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19605         vrf_set = 1;
19606       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19607         vrf_set = 1;
19608       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19609         vrf_set = 1;
19610       else if (unformat (input, "del"))
19611         is_add = 0;
19612       else
19613         break;
19614     }
19615
19616   if (sw_if_index == ~0)
19617     {
19618       errmsg ("Interface required but not specified");
19619       return -99;
19620     }
19621
19622   if (vrf_set == 0)
19623     {
19624       errmsg ("VRF ID required but not specified");
19625       return -99;
19626     }
19627
19628   if (tcp_out_vrf_id == 0
19629       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19630     {
19631       errmsg
19632         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19633       return -99;
19634     }
19635
19636   /* Construct the API message */
19637   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19638
19639   mp->sw_if_index = ntohl (sw_if_index);
19640   mp->is_add = is_add;
19641   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19642   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19643   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19644   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19645
19646   /* send it... */
19647   S (mp);
19648
19649   /* Wait for a reply... */
19650   W (ret);
19651   return ret;
19652 }
19653
19654 static int
19655 api_set_punt (vat_main_t * vam)
19656 {
19657   unformat_input_t *i = vam->input;
19658   vl_api_address_family_t af;
19659   vl_api_set_punt_t *mp;
19660   u32 protocol = ~0;
19661   u32 port = ~0;
19662   int is_add = 1;
19663   int ret;
19664
19665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19666     {
19667       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19668         ;
19669       else if (unformat (i, "protocol %d", &protocol))
19670         ;
19671       else if (unformat (i, "port %d", &port))
19672         ;
19673       else if (unformat (i, "del"))
19674         is_add = 0;
19675       else
19676         {
19677           clib_warning ("parse error '%U'", format_unformat_error, i);
19678           return -99;
19679         }
19680     }
19681
19682   M (SET_PUNT, mp);
19683
19684   mp->is_add = (u8) is_add;
19685   mp->punt.type = PUNT_API_TYPE_L4;
19686   mp->punt.punt.l4.af = af;
19687   mp->punt.punt.l4.protocol = (u8) protocol;
19688   mp->punt.punt.l4.port = htons ((u16) port);
19689
19690   S (mp);
19691   W (ret);
19692   return ret;
19693 }
19694
19695 static int
19696 api_delete_subif (vat_main_t * vam)
19697 {
19698   unformat_input_t *i = vam->input;
19699   vl_api_delete_subif_t *mp;
19700   u32 sw_if_index = ~0;
19701   int ret;
19702
19703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19704     {
19705       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19706         ;
19707       if (unformat (i, "sw_if_index %d", &sw_if_index))
19708         ;
19709       else
19710         break;
19711     }
19712
19713   if (sw_if_index == ~0)
19714     {
19715       errmsg ("missing sw_if_index");
19716       return -99;
19717     }
19718
19719   /* Construct the API message */
19720   M (DELETE_SUBIF, mp);
19721   mp->sw_if_index = ntohl (sw_if_index);
19722
19723   S (mp);
19724   W (ret);
19725   return ret;
19726 }
19727
19728 #define foreach_pbb_vtr_op      \
19729 _("disable",  L2_VTR_DISABLED)  \
19730 _("pop",  L2_VTR_POP_2)         \
19731 _("push",  L2_VTR_PUSH_2)
19732
19733 static int
19734 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19735 {
19736   unformat_input_t *i = vam->input;
19737   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19738   u32 sw_if_index = ~0, vtr_op = ~0;
19739   u16 outer_tag = ~0;
19740   u8 dmac[6], smac[6];
19741   u8 dmac_set = 0, smac_set = 0;
19742   u16 vlanid = 0;
19743   u32 sid = ~0;
19744   u32 tmp;
19745   int ret;
19746
19747   /* Shut up coverity */
19748   clib_memset (dmac, 0, sizeof (dmac));
19749   clib_memset (smac, 0, sizeof (smac));
19750
19751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19752     {
19753       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19754         ;
19755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19756         ;
19757       else if (unformat (i, "vtr_op %d", &vtr_op))
19758         ;
19759 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19760       foreach_pbb_vtr_op
19761 #undef _
19762         else if (unformat (i, "translate_pbb_stag"))
19763         {
19764           if (unformat (i, "%d", &tmp))
19765             {
19766               vtr_op = L2_VTR_TRANSLATE_2_1;
19767               outer_tag = tmp;
19768             }
19769           else
19770             {
19771               errmsg
19772                 ("translate_pbb_stag operation requires outer tag definition");
19773               return -99;
19774             }
19775         }
19776       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19777         dmac_set++;
19778       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19779         smac_set++;
19780       else if (unformat (i, "sid %d", &sid))
19781         ;
19782       else if (unformat (i, "vlanid %d", &tmp))
19783         vlanid = tmp;
19784       else
19785         {
19786           clib_warning ("parse error '%U'", format_unformat_error, i);
19787           return -99;
19788         }
19789     }
19790
19791   if ((sw_if_index == ~0) || (vtr_op == ~0))
19792     {
19793       errmsg ("missing sw_if_index or vtr operation");
19794       return -99;
19795     }
19796   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19797       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19798     {
19799       errmsg
19800         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19801       return -99;
19802     }
19803
19804   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19805   mp->sw_if_index = ntohl (sw_if_index);
19806   mp->vtr_op = ntohl (vtr_op);
19807   mp->outer_tag = ntohs (outer_tag);
19808   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19809   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19810   mp->b_vlanid = ntohs (vlanid);
19811   mp->i_sid = ntohl (sid);
19812
19813   S (mp);
19814   W (ret);
19815   return ret;
19816 }
19817
19818 static int
19819 api_flow_classify_set_interface (vat_main_t * vam)
19820 {
19821   unformat_input_t *i = vam->input;
19822   vl_api_flow_classify_set_interface_t *mp;
19823   u32 sw_if_index;
19824   int sw_if_index_set;
19825   u32 ip4_table_index = ~0;
19826   u32 ip6_table_index = ~0;
19827   u8 is_add = 1;
19828   int ret;
19829
19830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19831     {
19832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19833         sw_if_index_set = 1;
19834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19835         sw_if_index_set = 1;
19836       else if (unformat (i, "del"))
19837         is_add = 0;
19838       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19839         ;
19840       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19841         ;
19842       else
19843         {
19844           clib_warning ("parse error '%U'", format_unformat_error, i);
19845           return -99;
19846         }
19847     }
19848
19849   if (sw_if_index_set == 0)
19850     {
19851       errmsg ("missing interface name or sw_if_index");
19852       return -99;
19853     }
19854
19855   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19856
19857   mp->sw_if_index = ntohl (sw_if_index);
19858   mp->ip4_table_index = ntohl (ip4_table_index);
19859   mp->ip6_table_index = ntohl (ip6_table_index);
19860   mp->is_add = is_add;
19861
19862   S (mp);
19863   W (ret);
19864   return ret;
19865 }
19866
19867 static int
19868 api_flow_classify_dump (vat_main_t * vam)
19869 {
19870   unformat_input_t *i = vam->input;
19871   vl_api_flow_classify_dump_t *mp;
19872   vl_api_control_ping_t *mp_ping;
19873   u8 type = FLOW_CLASSIFY_N_TABLES;
19874   int ret;
19875
19876   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19877     ;
19878   else
19879     {
19880       errmsg ("classify table type must be specified");
19881       return -99;
19882     }
19883
19884   if (!vam->json_output)
19885     {
19886       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19887     }
19888
19889   M (FLOW_CLASSIFY_DUMP, mp);
19890   mp->type = type;
19891   /* send it... */
19892   S (mp);
19893
19894   /* Use a control ping for synchronization */
19895   MPING (CONTROL_PING, mp_ping);
19896   S (mp_ping);
19897
19898   /* Wait for a reply... */
19899   W (ret);
19900   return ret;
19901 }
19902
19903 static int
19904 api_feature_enable_disable (vat_main_t * vam)
19905 {
19906   unformat_input_t *i = vam->input;
19907   vl_api_feature_enable_disable_t *mp;
19908   u8 *arc_name = 0;
19909   u8 *feature_name = 0;
19910   u32 sw_if_index = ~0;
19911   u8 enable = 1;
19912   int ret;
19913
19914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19915     {
19916       if (unformat (i, "arc_name %s", &arc_name))
19917         ;
19918       else if (unformat (i, "feature_name %s", &feature_name))
19919         ;
19920       else
19921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19922         ;
19923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19924         ;
19925       else if (unformat (i, "disable"))
19926         enable = 0;
19927       else
19928         break;
19929     }
19930
19931   if (arc_name == 0)
19932     {
19933       errmsg ("missing arc name");
19934       return -99;
19935     }
19936   if (vec_len (arc_name) > 63)
19937     {
19938       errmsg ("arc name too long");
19939     }
19940
19941   if (feature_name == 0)
19942     {
19943       errmsg ("missing feature name");
19944       return -99;
19945     }
19946   if (vec_len (feature_name) > 63)
19947     {
19948       errmsg ("feature name too long");
19949     }
19950
19951   if (sw_if_index == ~0)
19952     {
19953       errmsg ("missing interface name or sw_if_index");
19954       return -99;
19955     }
19956
19957   /* Construct the API message */
19958   M (FEATURE_ENABLE_DISABLE, mp);
19959   mp->sw_if_index = ntohl (sw_if_index);
19960   mp->enable = enable;
19961   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19962   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19963   vec_free (arc_name);
19964   vec_free (feature_name);
19965
19966   S (mp);
19967   W (ret);
19968   return ret;
19969 }
19970
19971 static int
19972 api_feature_gso_enable_disable (vat_main_t * vam)
19973 {
19974   unformat_input_t *i = vam->input;
19975   vl_api_feature_gso_enable_disable_t *mp;
19976   u32 sw_if_index = ~0;
19977   u8 enable = 1;
19978   int ret;
19979
19980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19981     {
19982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19983         ;
19984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19985         ;
19986       else if (unformat (i, "enable"))
19987         enable = 1;
19988       else if (unformat (i, "disable"))
19989         enable = 0;
19990       else
19991         break;
19992     }
19993
19994   if (sw_if_index == ~0)
19995     {
19996       errmsg ("missing interface name or sw_if_index");
19997       return -99;
19998     }
19999
20000   /* Construct the API message */
20001   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20002   mp->sw_if_index = ntohl (sw_if_index);
20003   mp->enable_disable = enable;
20004
20005   S (mp);
20006   W (ret);
20007   return ret;
20008 }
20009
20010 static int
20011 api_sw_interface_tag_add_del (vat_main_t * vam)
20012 {
20013   unformat_input_t *i = vam->input;
20014   vl_api_sw_interface_tag_add_del_t *mp;
20015   u32 sw_if_index = ~0;
20016   u8 *tag = 0;
20017   u8 enable = 1;
20018   int ret;
20019
20020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20021     {
20022       if (unformat (i, "tag %s", &tag))
20023         ;
20024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20025         ;
20026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20027         ;
20028       else if (unformat (i, "del"))
20029         enable = 0;
20030       else
20031         break;
20032     }
20033
20034   if (sw_if_index == ~0)
20035     {
20036       errmsg ("missing interface name or sw_if_index");
20037       return -99;
20038     }
20039
20040   if (enable && (tag == 0))
20041     {
20042       errmsg ("no tag specified");
20043       return -99;
20044     }
20045
20046   /* Construct the API message */
20047   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20048   mp->sw_if_index = ntohl (sw_if_index);
20049   mp->is_add = enable;
20050   if (enable)
20051     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20052   vec_free (tag);
20053
20054   S (mp);
20055   W (ret);
20056   return ret;
20057 }
20058
20059 static int
20060 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20061 {
20062   unformat_input_t *i = vam->input;
20063   vl_api_mac_address_t mac = { 0 };
20064   vl_api_sw_interface_add_del_mac_address_t *mp;
20065   u32 sw_if_index = ~0;
20066   u8 is_add = 1;
20067   u8 mac_set = 0;
20068   int ret;
20069
20070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20071     {
20072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20073         ;
20074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20075         ;
20076       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20077         mac_set++;
20078       else if (unformat (i, "del"))
20079         is_add = 0;
20080       else
20081         break;
20082     }
20083
20084   if (sw_if_index == ~0)
20085     {
20086       errmsg ("missing interface name or sw_if_index");
20087       return -99;
20088     }
20089
20090   if (!mac_set)
20091     {
20092       errmsg ("missing MAC address");
20093       return -99;
20094     }
20095
20096   /* Construct the API message */
20097   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20098   mp->sw_if_index = ntohl (sw_if_index);
20099   mp->is_add = is_add;
20100   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20101
20102   S (mp);
20103   W (ret);
20104   return ret;
20105 }
20106
20107 static void vl_api_l2_xconnect_details_t_handler
20108   (vl_api_l2_xconnect_details_t * mp)
20109 {
20110   vat_main_t *vam = &vat_main;
20111
20112   print (vam->ofp, "%15d%15d",
20113          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20114 }
20115
20116 static void vl_api_l2_xconnect_details_t_handler_json
20117   (vl_api_l2_xconnect_details_t * mp)
20118 {
20119   vat_main_t *vam = &vat_main;
20120   vat_json_node_t *node = NULL;
20121
20122   if (VAT_JSON_ARRAY != vam->json_tree.type)
20123     {
20124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20125       vat_json_init_array (&vam->json_tree);
20126     }
20127   node = vat_json_array_add (&vam->json_tree);
20128
20129   vat_json_init_object (node);
20130   vat_json_object_add_uint (node, "rx_sw_if_index",
20131                             ntohl (mp->rx_sw_if_index));
20132   vat_json_object_add_uint (node, "tx_sw_if_index",
20133                             ntohl (mp->tx_sw_if_index));
20134 }
20135
20136 static int
20137 api_l2_xconnect_dump (vat_main_t * vam)
20138 {
20139   vl_api_l2_xconnect_dump_t *mp;
20140   vl_api_control_ping_t *mp_ping;
20141   int ret;
20142
20143   if (!vam->json_output)
20144     {
20145       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20146     }
20147
20148   M (L2_XCONNECT_DUMP, mp);
20149
20150   S (mp);
20151
20152   /* Use a control ping for synchronization */
20153   MPING (CONTROL_PING, mp_ping);
20154   S (mp_ping);
20155
20156   W (ret);
20157   return ret;
20158 }
20159
20160 static int
20161 api_hw_interface_set_mtu (vat_main_t * vam)
20162 {
20163   unformat_input_t *i = vam->input;
20164   vl_api_hw_interface_set_mtu_t *mp;
20165   u32 sw_if_index = ~0;
20166   u32 mtu = 0;
20167   int ret;
20168
20169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20170     {
20171       if (unformat (i, "mtu %d", &mtu))
20172         ;
20173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20174         ;
20175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20176         ;
20177       else
20178         break;
20179     }
20180
20181   if (sw_if_index == ~0)
20182     {
20183       errmsg ("missing interface name or sw_if_index");
20184       return -99;
20185     }
20186
20187   if (mtu == 0)
20188     {
20189       errmsg ("no mtu specified");
20190       return -99;
20191     }
20192
20193   /* Construct the API message */
20194   M (HW_INTERFACE_SET_MTU, mp);
20195   mp->sw_if_index = ntohl (sw_if_index);
20196   mp->mtu = ntohs ((u16) mtu);
20197
20198   S (mp);
20199   W (ret);
20200   return ret;
20201 }
20202
20203 static int
20204 api_p2p_ethernet_add (vat_main_t * vam)
20205 {
20206   unformat_input_t *i = vam->input;
20207   vl_api_p2p_ethernet_add_t *mp;
20208   u32 parent_if_index = ~0;
20209   u32 sub_id = ~0;
20210   u8 remote_mac[6];
20211   u8 mac_set = 0;
20212   int ret;
20213
20214   clib_memset (remote_mac, 0, sizeof (remote_mac));
20215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20216     {
20217       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20218         ;
20219       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20220         ;
20221       else
20222         if (unformat
20223             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20224         mac_set++;
20225       else if (unformat (i, "sub_id %d", &sub_id))
20226         ;
20227       else
20228         {
20229           clib_warning ("parse error '%U'", format_unformat_error, i);
20230           return -99;
20231         }
20232     }
20233
20234   if (parent_if_index == ~0)
20235     {
20236       errmsg ("missing interface name or sw_if_index");
20237       return -99;
20238     }
20239   if (mac_set == 0)
20240     {
20241       errmsg ("missing remote mac address");
20242       return -99;
20243     }
20244   if (sub_id == ~0)
20245     {
20246       errmsg ("missing sub-interface id");
20247       return -99;
20248     }
20249
20250   M (P2P_ETHERNET_ADD, mp);
20251   mp->parent_if_index = ntohl (parent_if_index);
20252   mp->subif_id = ntohl (sub_id);
20253   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20254
20255   S (mp);
20256   W (ret);
20257   return ret;
20258 }
20259
20260 static int
20261 api_p2p_ethernet_del (vat_main_t * vam)
20262 {
20263   unformat_input_t *i = vam->input;
20264   vl_api_p2p_ethernet_del_t *mp;
20265   u32 parent_if_index = ~0;
20266   u8 remote_mac[6];
20267   u8 mac_set = 0;
20268   int ret;
20269
20270   clib_memset (remote_mac, 0, sizeof (remote_mac));
20271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20272     {
20273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20274         ;
20275       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20276         ;
20277       else
20278         if (unformat
20279             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20280         mac_set++;
20281       else
20282         {
20283           clib_warning ("parse error '%U'", format_unformat_error, i);
20284           return -99;
20285         }
20286     }
20287
20288   if (parent_if_index == ~0)
20289     {
20290       errmsg ("missing interface name or sw_if_index");
20291       return -99;
20292     }
20293   if (mac_set == 0)
20294     {
20295       errmsg ("missing remote mac address");
20296       return -99;
20297     }
20298
20299   M (P2P_ETHERNET_DEL, mp);
20300   mp->parent_if_index = ntohl (parent_if_index);
20301   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20302
20303   S (mp);
20304   W (ret);
20305   return ret;
20306 }
20307
20308 static int
20309 api_lldp_config (vat_main_t * vam)
20310 {
20311   unformat_input_t *i = vam->input;
20312   vl_api_lldp_config_t *mp;
20313   int tx_hold = 0;
20314   int tx_interval = 0;
20315   u8 *sys_name = NULL;
20316   int ret;
20317
20318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20319     {
20320       if (unformat (i, "system-name %s", &sys_name))
20321         ;
20322       else if (unformat (i, "tx-hold %d", &tx_hold))
20323         ;
20324       else if (unformat (i, "tx-interval %d", &tx_interval))
20325         ;
20326       else
20327         {
20328           clib_warning ("parse error '%U'", format_unformat_error, i);
20329           return -99;
20330         }
20331     }
20332
20333   vec_add1 (sys_name, 0);
20334
20335   M (LLDP_CONFIG, mp);
20336   mp->tx_hold = htonl (tx_hold);
20337   mp->tx_interval = htonl (tx_interval);
20338   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20339   vec_free (sys_name);
20340
20341   S (mp);
20342   W (ret);
20343   return ret;
20344 }
20345
20346 static int
20347 api_sw_interface_set_lldp (vat_main_t * vam)
20348 {
20349   unformat_input_t *i = vam->input;
20350   vl_api_sw_interface_set_lldp_t *mp;
20351   u32 sw_if_index = ~0;
20352   u32 enable = 1;
20353   u8 *port_desc = NULL, *mgmt_oid = NULL;
20354   ip4_address_t ip4_addr;
20355   ip6_address_t ip6_addr;
20356   int ret;
20357
20358   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20359   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20360
20361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20362     {
20363       if (unformat (i, "disable"))
20364         enable = 0;
20365       else
20366         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20367         ;
20368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20369         ;
20370       else if (unformat (i, "port-desc %s", &port_desc))
20371         ;
20372       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20373         ;
20374       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20375         ;
20376       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20377         ;
20378       else
20379         break;
20380     }
20381
20382   if (sw_if_index == ~0)
20383     {
20384       errmsg ("missing interface name or sw_if_index");
20385       return -99;
20386     }
20387
20388   /* Construct the API message */
20389   vec_add1 (port_desc, 0);
20390   vec_add1 (mgmt_oid, 0);
20391   M (SW_INTERFACE_SET_LLDP, mp);
20392   mp->sw_if_index = ntohl (sw_if_index);
20393   mp->enable = enable;
20394   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20395   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20396   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20397   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20398   vec_free (port_desc);
20399   vec_free (mgmt_oid);
20400
20401   S (mp);
20402   W (ret);
20403   return ret;
20404 }
20405
20406 static int
20407 api_tcp_configure_src_addresses (vat_main_t * vam)
20408 {
20409   vl_api_tcp_configure_src_addresses_t *mp;
20410   unformat_input_t *i = vam->input;
20411   ip4_address_t v4first, v4last;
20412   ip6_address_t v6first, v6last;
20413   u8 range_set = 0;
20414   u32 vrf_id = 0;
20415   int ret;
20416
20417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20418     {
20419       if (unformat (i, "%U - %U",
20420                     unformat_ip4_address, &v4first,
20421                     unformat_ip4_address, &v4last))
20422         {
20423           if (range_set)
20424             {
20425               errmsg ("one range per message (range already set)");
20426               return -99;
20427             }
20428           range_set = 1;
20429         }
20430       else if (unformat (i, "%U - %U",
20431                          unformat_ip6_address, &v6first,
20432                          unformat_ip6_address, &v6last))
20433         {
20434           if (range_set)
20435             {
20436               errmsg ("one range per message (range already set)");
20437               return -99;
20438             }
20439           range_set = 2;
20440         }
20441       else if (unformat (i, "vrf %d", &vrf_id))
20442         ;
20443       else
20444         break;
20445     }
20446
20447   if (range_set == 0)
20448     {
20449       errmsg ("address range not set");
20450       return -99;
20451     }
20452
20453   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20454   mp->vrf_id = ntohl (vrf_id);
20455   /* ipv6? */
20456   if (range_set == 2)
20457     {
20458       mp->is_ipv6 = 1;
20459       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20460       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20461     }
20462   else
20463     {
20464       mp->is_ipv6 = 0;
20465       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20466       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20467     }
20468   S (mp);
20469   W (ret);
20470   return ret;
20471 }
20472
20473 static void vl_api_app_namespace_add_del_reply_t_handler
20474   (vl_api_app_namespace_add_del_reply_t * mp)
20475 {
20476   vat_main_t *vam = &vat_main;
20477   i32 retval = ntohl (mp->retval);
20478   if (vam->async_mode)
20479     {
20480       vam->async_errors += (retval < 0);
20481     }
20482   else
20483     {
20484       vam->retval = retval;
20485       if (retval == 0)
20486         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20487       vam->result_ready = 1;
20488     }
20489 }
20490
20491 static void vl_api_app_namespace_add_del_reply_t_handler_json
20492   (vl_api_app_namespace_add_del_reply_t * mp)
20493 {
20494   vat_main_t *vam = &vat_main;
20495   vat_json_node_t node;
20496
20497   vat_json_init_object (&node);
20498   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20499   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20500
20501   vat_json_print (vam->ofp, &node);
20502   vat_json_free (&node);
20503
20504   vam->retval = ntohl (mp->retval);
20505   vam->result_ready = 1;
20506 }
20507
20508 static int
20509 api_app_namespace_add_del (vat_main_t * vam)
20510 {
20511   vl_api_app_namespace_add_del_t *mp;
20512   unformat_input_t *i = vam->input;
20513   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20514   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20515   u64 secret;
20516   int ret;
20517
20518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20519     {
20520       if (unformat (i, "id %_%v%_", &ns_id))
20521         ;
20522       else if (unformat (i, "secret %lu", &secret))
20523         secret_set = 1;
20524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20525         sw_if_index_set = 1;
20526       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20527         ;
20528       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20529         ;
20530       else
20531         break;
20532     }
20533   if (!ns_id || !secret_set || !sw_if_index_set)
20534     {
20535       errmsg ("namespace id, secret and sw_if_index must be set");
20536       return -99;
20537     }
20538   if (vec_len (ns_id) > 64)
20539     {
20540       errmsg ("namespace id too long");
20541       return -99;
20542     }
20543   M (APP_NAMESPACE_ADD_DEL, mp);
20544
20545   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20546   mp->namespace_id_len = vec_len (ns_id);
20547   mp->secret = clib_host_to_net_u64 (secret);
20548   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20549   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20550   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20551   vec_free (ns_id);
20552   S (mp);
20553   W (ret);
20554   return ret;
20555 }
20556
20557 static int
20558 api_sock_init_shm (vat_main_t * vam)
20559 {
20560 #if VPP_API_TEST_BUILTIN == 0
20561   unformat_input_t *i = vam->input;
20562   vl_api_shm_elem_config_t *config = 0;
20563   u64 size = 64 << 20;
20564   int rv;
20565
20566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20567     {
20568       if (unformat (i, "size %U", unformat_memory_size, &size))
20569         ;
20570       else
20571         break;
20572     }
20573
20574   /*
20575    * Canned custom ring allocator config.
20576    * Should probably parse all of this
20577    */
20578   vec_validate (config, 6);
20579   config[0].type = VL_API_VLIB_RING;
20580   config[0].size = 256;
20581   config[0].count = 32;
20582
20583   config[1].type = VL_API_VLIB_RING;
20584   config[1].size = 1024;
20585   config[1].count = 16;
20586
20587   config[2].type = VL_API_VLIB_RING;
20588   config[2].size = 4096;
20589   config[2].count = 2;
20590
20591   config[3].type = VL_API_CLIENT_RING;
20592   config[3].size = 256;
20593   config[3].count = 32;
20594
20595   config[4].type = VL_API_CLIENT_RING;
20596   config[4].size = 1024;
20597   config[4].count = 16;
20598
20599   config[5].type = VL_API_CLIENT_RING;
20600   config[5].size = 4096;
20601   config[5].count = 2;
20602
20603   config[6].type = VL_API_QUEUE;
20604   config[6].count = 128;
20605   config[6].size = sizeof (uword);
20606
20607   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20608   if (!rv)
20609     vam->client_index_invalid = 1;
20610   return rv;
20611 #else
20612   return -99;
20613 #endif
20614 }
20615
20616 static void
20617 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20618 {
20619   vat_main_t *vam = &vat_main;
20620
20621   if (mp->is_ip4)
20622     {
20623       print (vam->ofp,
20624              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20625              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20626              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20627              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20628              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20629              clib_net_to_host_u32 (mp->action_index), mp->tag);
20630     }
20631   else
20632     {
20633       print (vam->ofp,
20634              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20635              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20636              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20637              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20638              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20639              clib_net_to_host_u32 (mp->action_index), mp->tag);
20640     }
20641 }
20642
20643 static void
20644 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20645                                              mp)
20646 {
20647   vat_main_t *vam = &vat_main;
20648   vat_json_node_t *node = NULL;
20649   struct in6_addr ip6;
20650   struct in_addr ip4;
20651
20652   if (VAT_JSON_ARRAY != vam->json_tree.type)
20653     {
20654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20655       vat_json_init_array (&vam->json_tree);
20656     }
20657   node = vat_json_array_add (&vam->json_tree);
20658   vat_json_init_object (node);
20659
20660   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20661   vat_json_object_add_uint (node, "appns_index",
20662                             clib_net_to_host_u32 (mp->appns_index));
20663   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20664   vat_json_object_add_uint (node, "scope", mp->scope);
20665   vat_json_object_add_uint (node, "action_index",
20666                             clib_net_to_host_u32 (mp->action_index));
20667   vat_json_object_add_uint (node, "lcl_port",
20668                             clib_net_to_host_u16 (mp->lcl_port));
20669   vat_json_object_add_uint (node, "rmt_port",
20670                             clib_net_to_host_u16 (mp->rmt_port));
20671   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20672   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20673   vat_json_object_add_string_copy (node, "tag", mp->tag);
20674   if (mp->is_ip4)
20675     {
20676       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20677       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20678       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20679       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20680     }
20681   else
20682     {
20683       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20684       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20685       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20686       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20687     }
20688 }
20689
20690 static int
20691 api_session_rule_add_del (vat_main_t * vam)
20692 {
20693   vl_api_session_rule_add_del_t *mp;
20694   unformat_input_t *i = vam->input;
20695   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20696   u32 appns_index = 0, scope = 0;
20697   ip4_address_t lcl_ip4, rmt_ip4;
20698   ip6_address_t lcl_ip6, rmt_ip6;
20699   u8 is_ip4 = 1, conn_set = 0;
20700   u8 is_add = 1, *tag = 0;
20701   int ret;
20702
20703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20704     {
20705       if (unformat (i, "del"))
20706         is_add = 0;
20707       else if (unformat (i, "add"))
20708         ;
20709       else if (unformat (i, "proto tcp"))
20710         proto = 0;
20711       else if (unformat (i, "proto udp"))
20712         proto = 1;
20713       else if (unformat (i, "appns %d", &appns_index))
20714         ;
20715       else if (unformat (i, "scope %d", &scope))
20716         ;
20717       else if (unformat (i, "tag %_%v%_", &tag))
20718         ;
20719       else
20720         if (unformat
20721             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20722              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20723              &rmt_port))
20724         {
20725           is_ip4 = 1;
20726           conn_set = 1;
20727         }
20728       else
20729         if (unformat
20730             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20731              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20732              &rmt_port))
20733         {
20734           is_ip4 = 0;
20735           conn_set = 1;
20736         }
20737       else if (unformat (i, "action %d", &action))
20738         ;
20739       else
20740         break;
20741     }
20742   if (proto == ~0 || !conn_set || action == ~0)
20743     {
20744       errmsg ("transport proto, connection and action must be set");
20745       return -99;
20746     }
20747
20748   if (scope > 3)
20749     {
20750       errmsg ("scope should be 0-3");
20751       return -99;
20752     }
20753
20754   M (SESSION_RULE_ADD_DEL, mp);
20755
20756   mp->is_ip4 = is_ip4;
20757   mp->transport_proto = proto;
20758   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20759   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20760   mp->lcl_plen = lcl_plen;
20761   mp->rmt_plen = rmt_plen;
20762   mp->action_index = clib_host_to_net_u32 (action);
20763   mp->appns_index = clib_host_to_net_u32 (appns_index);
20764   mp->scope = scope;
20765   mp->is_add = is_add;
20766   if (is_ip4)
20767     {
20768       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20769       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20770     }
20771   else
20772     {
20773       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20774       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20775     }
20776   if (tag)
20777     {
20778       clib_memcpy (mp->tag, tag, vec_len (tag));
20779       vec_free (tag);
20780     }
20781
20782   S (mp);
20783   W (ret);
20784   return ret;
20785 }
20786
20787 static int
20788 api_session_rules_dump (vat_main_t * vam)
20789 {
20790   vl_api_session_rules_dump_t *mp;
20791   vl_api_control_ping_t *mp_ping;
20792   int ret;
20793
20794   if (!vam->json_output)
20795     {
20796       print (vam->ofp, "%=20s", "Session Rules");
20797     }
20798
20799   M (SESSION_RULES_DUMP, mp);
20800   /* send it... */
20801   S (mp);
20802
20803   /* Use a control ping for synchronization */
20804   MPING (CONTROL_PING, mp_ping);
20805   S (mp_ping);
20806
20807   /* Wait for a reply... */
20808   W (ret);
20809   return ret;
20810 }
20811
20812 static int
20813 api_ip_container_proxy_add_del (vat_main_t * vam)
20814 {
20815   vl_api_ip_container_proxy_add_del_t *mp;
20816   unformat_input_t *i = vam->input;
20817   u32 sw_if_index = ~0;
20818   vl_api_prefix_t pfx = { };
20819   u8 is_add = 1;
20820   int ret;
20821
20822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20823     {
20824       if (unformat (i, "del"))
20825         is_add = 0;
20826       else if (unformat (i, "add"))
20827         ;
20828       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20829         ;
20830       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20831         ;
20832       else
20833         break;
20834     }
20835   if (sw_if_index == ~0 || pfx.len == 0)
20836     {
20837       errmsg ("address and sw_if_index must be set");
20838       return -99;
20839     }
20840
20841   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20842
20843   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20844   mp->is_add = is_add;
20845   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20846
20847   S (mp);
20848   W (ret);
20849   return ret;
20850 }
20851
20852 static int
20853 api_qos_record_enable_disable (vat_main_t * vam)
20854 {
20855   unformat_input_t *i = vam->input;
20856   vl_api_qos_record_enable_disable_t *mp;
20857   u32 sw_if_index, qs = 0xff;
20858   u8 sw_if_index_set = 0;
20859   u8 enable = 1;
20860   int ret;
20861
20862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20863     {
20864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20865         sw_if_index_set = 1;
20866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20867         sw_if_index_set = 1;
20868       else if (unformat (i, "%U", unformat_qos_source, &qs))
20869         ;
20870       else if (unformat (i, "disable"))
20871         enable = 0;
20872       else
20873         {
20874           clib_warning ("parse error '%U'", format_unformat_error, i);
20875           return -99;
20876         }
20877     }
20878
20879   if (sw_if_index_set == 0)
20880     {
20881       errmsg ("missing interface name or sw_if_index");
20882       return -99;
20883     }
20884   if (qs == 0xff)
20885     {
20886       errmsg ("input location must be specified");
20887       return -99;
20888     }
20889
20890   M (QOS_RECORD_ENABLE_DISABLE, mp);
20891
20892   mp->record.sw_if_index = ntohl (sw_if_index);
20893   mp->record.input_source = qs;
20894   mp->enable = enable;
20895
20896   S (mp);
20897   W (ret);
20898   return ret;
20899 }
20900
20901
20902 static int
20903 q_or_quit (vat_main_t * vam)
20904 {
20905 #if VPP_API_TEST_BUILTIN == 0
20906   longjmp (vam->jump_buf, 1);
20907 #endif
20908   return 0;                     /* not so much */
20909 }
20910
20911 static int
20912 q (vat_main_t * vam)
20913 {
20914   return q_or_quit (vam);
20915 }
20916
20917 static int
20918 quit (vat_main_t * vam)
20919 {
20920   return q_or_quit (vam);
20921 }
20922
20923 static int
20924 comment (vat_main_t * vam)
20925 {
20926   return 0;
20927 }
20928
20929 static int
20930 elog_save (vat_main_t * vam)
20931 {
20932 #if VPP_API_TEST_BUILTIN == 0
20933   elog_main_t *em = &vam->elog_main;
20934   unformat_input_t *i = vam->input;
20935   char *file, *chroot_file;
20936   clib_error_t *error;
20937
20938   if (!unformat (i, "%s", &file))
20939     {
20940       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20941       return 0;
20942     }
20943
20944   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20945   if (strstr (file, "..") || index (file, '/'))
20946     {
20947       errmsg ("illegal characters in filename '%s'", file);
20948       return 0;
20949     }
20950
20951   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20952
20953   vec_free (file);
20954
20955   errmsg ("Saving %wd of %wd events to %s",
20956           elog_n_events_in_buffer (em),
20957           elog_buffer_capacity (em), chroot_file);
20958
20959   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20960   vec_free (chroot_file);
20961
20962   if (error)
20963     clib_error_report (error);
20964 #else
20965   errmsg ("Use the vpp event loger...");
20966 #endif
20967
20968   return 0;
20969 }
20970
20971 static int
20972 elog_setup (vat_main_t * vam)
20973 {
20974 #if VPP_API_TEST_BUILTIN == 0
20975   elog_main_t *em = &vam->elog_main;
20976   unformat_input_t *i = vam->input;
20977   u32 nevents = 128 << 10;
20978
20979   (void) unformat (i, "nevents %d", &nevents);
20980
20981   elog_init (em, nevents);
20982   vl_api_set_elog_main (em);
20983   vl_api_set_elog_trace_api_messages (1);
20984   errmsg ("Event logger initialized with %u events", nevents);
20985 #else
20986   errmsg ("Use the vpp event loger...");
20987 #endif
20988   return 0;
20989 }
20990
20991 static int
20992 elog_enable (vat_main_t * vam)
20993 {
20994 #if VPP_API_TEST_BUILTIN == 0
20995   elog_main_t *em = &vam->elog_main;
20996
20997   elog_enable_disable (em, 1 /* enable */ );
20998   vl_api_set_elog_trace_api_messages (1);
20999   errmsg ("Event logger enabled...");
21000 #else
21001   errmsg ("Use the vpp event loger...");
21002 #endif
21003   return 0;
21004 }
21005
21006 static int
21007 elog_disable (vat_main_t * vam)
21008 {
21009 #if VPP_API_TEST_BUILTIN == 0
21010   elog_main_t *em = &vam->elog_main;
21011
21012   elog_enable_disable (em, 0 /* enable */ );
21013   vl_api_set_elog_trace_api_messages (1);
21014   errmsg ("Event logger disabled...");
21015 #else
21016   errmsg ("Use the vpp event loger...");
21017 #endif
21018   return 0;
21019 }
21020
21021 static int
21022 statseg (vat_main_t * vam)
21023 {
21024   ssvm_private_t *ssvmp = &vam->stat_segment;
21025   ssvm_shared_header_t *shared_header = ssvmp->sh;
21026   vlib_counter_t **counters;
21027   u64 thread0_index1_packets;
21028   u64 thread0_index1_bytes;
21029   f64 vector_rate, input_rate;
21030   uword *p;
21031
21032   uword *counter_vector_by_name;
21033   if (vam->stat_segment_lockp == 0)
21034     {
21035       errmsg ("Stat segment not mapped...");
21036       return -99;
21037     }
21038
21039   /* look up "/if/rx for sw_if_index 1 as a test */
21040
21041   clib_spinlock_lock (vam->stat_segment_lockp);
21042
21043   counter_vector_by_name = (uword *) shared_header->opaque[1];
21044
21045   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21046   if (p == 0)
21047     {
21048       clib_spinlock_unlock (vam->stat_segment_lockp);
21049       errmsg ("/if/tx not found?");
21050       return -99;
21051     }
21052
21053   /* Fish per-thread vector of combined counters from shared memory */
21054   counters = (vlib_counter_t **) p[0];
21055
21056   if (vec_len (counters[0]) < 2)
21057     {
21058       clib_spinlock_unlock (vam->stat_segment_lockp);
21059       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21060       return -99;
21061     }
21062
21063   /* Read thread 0 sw_if_index 1 counter */
21064   thread0_index1_packets = counters[0][1].packets;
21065   thread0_index1_bytes = counters[0][1].bytes;
21066
21067   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21068   if (p == 0)
21069     {
21070       clib_spinlock_unlock (vam->stat_segment_lockp);
21071       errmsg ("vector_rate not found?");
21072       return -99;
21073     }
21074
21075   vector_rate = *(f64 *) (p[0]);
21076   p = hash_get_mem (counter_vector_by_name, "input_rate");
21077   if (p == 0)
21078     {
21079       clib_spinlock_unlock (vam->stat_segment_lockp);
21080       errmsg ("input_rate not found?");
21081       return -99;
21082     }
21083   input_rate = *(f64 *) (p[0]);
21084
21085   clib_spinlock_unlock (vam->stat_segment_lockp);
21086
21087   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21088          vector_rate, input_rate);
21089   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21090          thread0_index1_packets, thread0_index1_bytes);
21091
21092   return 0;
21093 }
21094
21095 static int
21096 cmd_cmp (void *a1, void *a2)
21097 {
21098   u8 **c1 = a1;
21099   u8 **c2 = a2;
21100
21101   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21102 }
21103
21104 static int
21105 help (vat_main_t * vam)
21106 {
21107   u8 **cmds = 0;
21108   u8 *name = 0;
21109   hash_pair_t *p;
21110   unformat_input_t *i = vam->input;
21111   int j;
21112
21113   if (unformat (i, "%s", &name))
21114     {
21115       uword *hs;
21116
21117       vec_add1 (name, 0);
21118
21119       hs = hash_get_mem (vam->help_by_name, name);
21120       if (hs)
21121         print (vam->ofp, "usage: %s %s", name, hs[0]);
21122       else
21123         print (vam->ofp, "No such msg / command '%s'", name);
21124       vec_free (name);
21125       return 0;
21126     }
21127
21128   print (vam->ofp, "Help is available for the following:");
21129
21130     /* *INDENT-OFF* */
21131     hash_foreach_pair (p, vam->function_by_name,
21132     ({
21133       vec_add1 (cmds, (u8 *)(p->key));
21134     }));
21135     /* *INDENT-ON* */
21136
21137   vec_sort_with_function (cmds, cmd_cmp);
21138
21139   for (j = 0; j < vec_len (cmds); j++)
21140     print (vam->ofp, "%s", cmds[j]);
21141
21142   vec_free (cmds);
21143   return 0;
21144 }
21145
21146 static int
21147 set (vat_main_t * vam)
21148 {
21149   u8 *name = 0, *value = 0;
21150   unformat_input_t *i = vam->input;
21151
21152   if (unformat (i, "%s", &name))
21153     {
21154       /* The input buffer is a vector, not a string. */
21155       value = vec_dup (i->buffer);
21156       vec_delete (value, i->index, 0);
21157       /* Almost certainly has a trailing newline */
21158       if (value[vec_len (value) - 1] == '\n')
21159         value[vec_len (value) - 1] = 0;
21160       /* Make sure it's a proper string, one way or the other */
21161       vec_add1 (value, 0);
21162       (void) clib_macro_set_value (&vam->macro_main,
21163                                    (char *) name, (char *) value);
21164     }
21165   else
21166     errmsg ("usage: set <name> <value>");
21167
21168   vec_free (name);
21169   vec_free (value);
21170   return 0;
21171 }
21172
21173 static int
21174 unset (vat_main_t * vam)
21175 {
21176   u8 *name = 0;
21177
21178   if (unformat (vam->input, "%s", &name))
21179     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21180       errmsg ("unset: %s wasn't set", name);
21181   vec_free (name);
21182   return 0;
21183 }
21184
21185 typedef struct
21186 {
21187   u8 *name;
21188   u8 *value;
21189 } macro_sort_t;
21190
21191
21192 static int
21193 macro_sort_cmp (void *a1, void *a2)
21194 {
21195   macro_sort_t *s1 = a1;
21196   macro_sort_t *s2 = a2;
21197
21198   return strcmp ((char *) (s1->name), (char *) (s2->name));
21199 }
21200
21201 static int
21202 dump_macro_table (vat_main_t * vam)
21203 {
21204   macro_sort_t *sort_me = 0, *sm;
21205   int i;
21206   hash_pair_t *p;
21207
21208     /* *INDENT-OFF* */
21209     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21210     ({
21211       vec_add2 (sort_me, sm, 1);
21212       sm->name = (u8 *)(p->key);
21213       sm->value = (u8 *) (p->value[0]);
21214     }));
21215     /* *INDENT-ON* */
21216
21217   vec_sort_with_function (sort_me, macro_sort_cmp);
21218
21219   if (vec_len (sort_me))
21220     print (vam->ofp, "%-15s%s", "Name", "Value");
21221   else
21222     print (vam->ofp, "The macro table is empty...");
21223
21224   for (i = 0; i < vec_len (sort_me); i++)
21225     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21226   return 0;
21227 }
21228
21229 static int
21230 dump_node_table (vat_main_t * vam)
21231 {
21232   int i, j;
21233   vlib_node_t *node, *next_node;
21234
21235   if (vec_len (vam->graph_nodes) == 0)
21236     {
21237       print (vam->ofp, "Node table empty, issue get_node_graph...");
21238       return 0;
21239     }
21240
21241   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21242     {
21243       node = vam->graph_nodes[0][i];
21244       print (vam->ofp, "[%d] %s", i, node->name);
21245       for (j = 0; j < vec_len (node->next_nodes); j++)
21246         {
21247           if (node->next_nodes[j] != ~0)
21248             {
21249               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21250               print (vam->ofp, "  [%d] %s", j, next_node->name);
21251             }
21252         }
21253     }
21254   return 0;
21255 }
21256
21257 static int
21258 value_sort_cmp (void *a1, void *a2)
21259 {
21260   name_sort_t *n1 = a1;
21261   name_sort_t *n2 = a2;
21262
21263   if (n1->value < n2->value)
21264     return -1;
21265   if (n1->value > n2->value)
21266     return 1;
21267   return 0;
21268 }
21269
21270
21271 static int
21272 dump_msg_api_table (vat_main_t * vam)
21273 {
21274   api_main_t *am = &api_main;
21275   name_sort_t *nses = 0, *ns;
21276   hash_pair_t *hp;
21277   int i;
21278
21279   /* *INDENT-OFF* */
21280   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21281   ({
21282     vec_add2 (nses, ns, 1);
21283     ns->name = (u8 *)(hp->key);
21284     ns->value = (u32) hp->value[0];
21285   }));
21286   /* *INDENT-ON* */
21287
21288   vec_sort_with_function (nses, value_sort_cmp);
21289
21290   for (i = 0; i < vec_len (nses); i++)
21291     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21292   vec_free (nses);
21293   return 0;
21294 }
21295
21296 static int
21297 get_msg_id (vat_main_t * vam)
21298 {
21299   u8 *name_and_crc;
21300   u32 message_index;
21301
21302   if (unformat (vam->input, "%s", &name_and_crc))
21303     {
21304       message_index = vl_msg_api_get_msg_index (name_and_crc);
21305       if (message_index == ~0)
21306         {
21307           print (vam->ofp, " '%s' not found", name_and_crc);
21308           return 0;
21309         }
21310       print (vam->ofp, " '%s' has message index %d",
21311              name_and_crc, message_index);
21312       return 0;
21313     }
21314   errmsg ("name_and_crc required...");
21315   return 0;
21316 }
21317
21318 static int
21319 search_node_table (vat_main_t * vam)
21320 {
21321   unformat_input_t *line_input = vam->input;
21322   u8 *node_to_find;
21323   int j;
21324   vlib_node_t *node, *next_node;
21325   uword *p;
21326
21327   if (vam->graph_node_index_by_name == 0)
21328     {
21329       print (vam->ofp, "Node table empty, issue get_node_graph...");
21330       return 0;
21331     }
21332
21333   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21334     {
21335       if (unformat (line_input, "%s", &node_to_find))
21336         {
21337           vec_add1 (node_to_find, 0);
21338           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21339           if (p == 0)
21340             {
21341               print (vam->ofp, "%s not found...", node_to_find);
21342               goto out;
21343             }
21344           node = vam->graph_nodes[0][p[0]];
21345           print (vam->ofp, "[%d] %s", p[0], node->name);
21346           for (j = 0; j < vec_len (node->next_nodes); j++)
21347             {
21348               if (node->next_nodes[j] != ~0)
21349                 {
21350                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21351                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21352                 }
21353             }
21354         }
21355
21356       else
21357         {
21358           clib_warning ("parse error '%U'", format_unformat_error,
21359                         line_input);
21360           return -99;
21361         }
21362
21363     out:
21364       vec_free (node_to_find);
21365
21366     }
21367
21368   return 0;
21369 }
21370
21371
21372 static int
21373 script (vat_main_t * vam)
21374 {
21375 #if (VPP_API_TEST_BUILTIN==0)
21376   u8 *s = 0;
21377   char *save_current_file;
21378   unformat_input_t save_input;
21379   jmp_buf save_jump_buf;
21380   u32 save_line_number;
21381
21382   FILE *new_fp, *save_ifp;
21383
21384   if (unformat (vam->input, "%s", &s))
21385     {
21386       new_fp = fopen ((char *) s, "r");
21387       if (new_fp == 0)
21388         {
21389           errmsg ("Couldn't open script file %s", s);
21390           vec_free (s);
21391           return -99;
21392         }
21393     }
21394   else
21395     {
21396       errmsg ("Missing script name");
21397       return -99;
21398     }
21399
21400   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21401   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21402   save_ifp = vam->ifp;
21403   save_line_number = vam->input_line_number;
21404   save_current_file = (char *) vam->current_file;
21405
21406   vam->input_line_number = 0;
21407   vam->ifp = new_fp;
21408   vam->current_file = s;
21409   do_one_file (vam);
21410
21411   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21412   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21413   vam->ifp = save_ifp;
21414   vam->input_line_number = save_line_number;
21415   vam->current_file = (u8 *) save_current_file;
21416   vec_free (s);
21417
21418   return 0;
21419 #else
21420   clib_warning ("use the exec command...");
21421   return -99;
21422 #endif
21423 }
21424
21425 static int
21426 echo (vat_main_t * vam)
21427 {
21428   print (vam->ofp, "%v", vam->input->buffer);
21429   return 0;
21430 }
21431
21432 /* List of API message constructors, CLI names map to api_xxx */
21433 #define foreach_vpe_api_msg                                             \
21434 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21435 _(sw_interface_dump,"")                                                 \
21436 _(sw_interface_set_flags,                                               \
21437   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21438 _(sw_interface_add_del_address,                                         \
21439   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21440 _(sw_interface_set_rx_mode,                                             \
21441   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21442 _(sw_interface_set_rx_placement,                                        \
21443   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21444 _(sw_interface_rx_placement_dump,                                       \
21445   "[<intfc> | sw_if_index <id>]")                                         \
21446 _(sw_interface_set_table,                                               \
21447   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21448 _(sw_interface_set_mpls_enable,                                         \
21449   "<intfc> | sw_if_index [disable | dis]")                              \
21450 _(sw_interface_set_vpath,                                               \
21451   "<intfc> | sw_if_index <id> enable | disable")                        \
21452 _(sw_interface_set_vxlan_bypass,                                        \
21453   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21454 _(sw_interface_set_geneve_bypass,                                       \
21455   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21456 _(sw_interface_set_l2_xconnect,                                         \
21457   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21458   "enable | disable")                                                   \
21459 _(sw_interface_set_l2_bridge,                                           \
21460   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21461   "[shg <split-horizon-group>] [bvi]\n"                                 \
21462   "enable | disable")                                                   \
21463 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21464 _(bridge_domain_add_del,                                                \
21465   "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") \
21466 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21467 _(l2fib_add_del,                                                        \
21468   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21469 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21470 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21471 _(l2_flags,                                                             \
21472   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21473 _(bridge_flags,                                                         \
21474   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21475 _(tap_create_v2,                                                        \
21476   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21477 _(tap_delete_v2,                                                        \
21478   "<vpp-if-name> | sw_if_index <id>")                                   \
21479 _(sw_interface_tap_v2_dump, "")                                         \
21480 _(virtio_pci_create,                                                    \
21481   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21482 _(virtio_pci_delete,                                                    \
21483   "<vpp-if-name> | sw_if_index <id>")                                   \
21484 _(sw_interface_virtio_pci_dump, "")                                     \
21485 _(bond_create,                                                          \
21486   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21487   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21488   "[id <if-id>]")                                                       \
21489 _(bond_delete,                                                          \
21490   "<vpp-if-name> | sw_if_index <id>")                                   \
21491 _(bond_enslave,                                                         \
21492   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21493 _(bond_detach_slave,                                                    \
21494   "sw_if_index <n>")                                                    \
21495  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21496 _(sw_interface_bond_dump, "")                                           \
21497 _(sw_interface_slave_dump,                                              \
21498   "<vpp-if-name> | sw_if_index <id>")                                   \
21499 _(ip_table_add_del,                                                     \
21500   "table <n> [ipv6] [add | del]\n")                                     \
21501 _(ip_route_add_del,                                                     \
21502   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21503   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21504   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21505   "[multipath] [count <n>] [del]")                                      \
21506 _(ip_mroute_add_del,                                                    \
21507   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21508   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21509 _(mpls_table_add_del,                                                   \
21510   "table <n> [add | del]\n")                                            \
21511 _(mpls_route_add_del,                                                   \
21512   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21513   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21514   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21515   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21516   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21517   "[count <n>] [del]")                                                  \
21518 _(mpls_ip_bind_unbind,                                                  \
21519   "<label> <addr/len>")                                                 \
21520 _(mpls_tunnel_add_del,                                                  \
21521   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21522   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21523   "[l2-only]  [out-label <n>]")                                         \
21524 _(sr_mpls_policy_add,                                                   \
21525   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21526 _(sr_mpls_policy_del,                                                   \
21527   "bsid <id>")                                                          \
21528 _(bier_table_add_del,                                                   \
21529   "<label> <sub-domain> <set> <bsl> [del]")                             \
21530 _(bier_route_add_del,                                                   \
21531   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21532   "[<intfc> | sw_if_index <id>]"                                        \
21533   "[weight <n>] [del] [multipath]")                                     \
21534 _(proxy_arp_add_del,                                                    \
21535   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21536 _(proxy_arp_intfc_enable_disable,                                       \
21537   "<intfc> | sw_if_index <id> enable | disable")                        \
21538 _(sw_interface_set_unnumbered,                                          \
21539   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21540 _(ip_neighbor_add_del,                                                  \
21541   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21542   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21543 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21544 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21545   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21546   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21547   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21548 _(reset_fib, "vrf <n> [ipv6]")                                          \
21549 _(set_ip_flow_hash,                                                     \
21550   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21551 _(sw_interface_ip6_enable_disable,                                      \
21552   "<intfc> | sw_if_index <id> enable | disable")                        \
21553 _(ip6nd_proxy_add_del,                                                  \
21554   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21555 _(ip6nd_proxy_dump, "")                                                 \
21556 _(sw_interface_ip6nd_ra_prefix,                                         \
21557   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21558   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21559   "[nolink] [isno]")                                                    \
21560 _(sw_interface_ip6nd_ra_config,                                         \
21561   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21562   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21563   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21564 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21565 _(l2_patch_add_del,                                                     \
21566   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21567   "enable | disable")                                                   \
21568 _(sr_localsid_add_del,                                                  \
21569   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21570   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21571 _(classify_add_del_table,                                               \
21572   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21573   " [del] [del-chain] mask <mask-value>\n"                              \
21574   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21575   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21576 _(classify_add_del_session,                                             \
21577   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21578   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21579   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21580   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21581 _(classify_set_interface_ip_table,                                      \
21582   "<intfc> | sw_if_index <nn> table <nn>")                              \
21583 _(classify_set_interface_l2_tables,                                     \
21584   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21585   "  [other-table <nn>]")                                               \
21586 _(get_node_index, "node <node-name")                                    \
21587 _(add_node_next, "node <node-name> next <next-node-name>")              \
21588 _(l2tpv3_create_tunnel,                                                 \
21589   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21590   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21591   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21592 _(l2tpv3_set_tunnel_cookies,                                            \
21593   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21594   "[new_remote_cookie <nn>]\n")                                         \
21595 _(l2tpv3_interface_enable_disable,                                      \
21596   "<intfc> | sw_if_index <nn> enable | disable")                        \
21597 _(l2tpv3_set_lookup_key,                                                \
21598   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21599 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21600 _(vxlan_offload_rx,                                                     \
21601   "hw { <interface name> | hw_if_index <nn>} "                          \
21602   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21603 _(vxlan_add_del_tunnel,                                                 \
21604   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21605   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21606   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21607 _(geneve_add_del_tunnel,                                                \
21608   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21609   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21610   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21611 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21612 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21613 _(gre_tunnel_add_del,                                                   \
21614   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21615   "[teb | erspan <session-id>] [del]")                                  \
21616 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21617 _(l2_fib_clear_table, "")                                               \
21618 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21619 _(l2_interface_vlan_tag_rewrite,                                        \
21620   "<intfc> | sw_if_index <nn> \n"                                       \
21621   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21622   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21623 _(create_vhost_user_if,                                                 \
21624         "socket <filename> [server] [renumber <dev_instance>] "         \
21625         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21626         "[mac <mac_address>]")                                          \
21627 _(modify_vhost_user_if,                                                 \
21628         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21629         "[server] [renumber <dev_instance>] [gso]")                     \
21630 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21631 _(sw_interface_vhost_user_dump, "")                                     \
21632 _(show_version, "")                                                     \
21633 _(show_threads, "")                                                     \
21634 _(vxlan_gpe_add_del_tunnel,                                             \
21635   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21636   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21637   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21638   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21639 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21640 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21641 _(interface_name_renumber,                                              \
21642   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21643 _(input_acl_set_interface,                                              \
21644   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21645   "  [l2-table <nn>] [del]")                                            \
21646 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21647 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21648   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21649 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21650 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21651 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21652 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21653 _(ip_dump, "ipv4 | ipv6")                                               \
21654 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21655 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21656   "  spid_id <n> ")                                                     \
21657 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21658   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21659   "  integ_alg <alg> integ_key <hex>")                                  \
21660 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21661   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21662   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21663   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21664 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21665   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21666   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21667   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21668   "  [instance <n>]")     \
21669 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21670 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21671 _(delete_loopback,"sw_if_index <nn>")                                   \
21672 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21673 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21674 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21675 _(want_interface_events,  "enable|disable")                             \
21676 _(get_first_msg_id, "client <name>")                                    \
21677 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21678 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21679   "fib-id <nn> [ip4][ip6][default]")                                    \
21680 _(get_node_graph, " ")                                                  \
21681 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21682 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21683 _(ioam_disable, "")                                                     \
21684 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21685                             " sw_if_index <sw_if_index> p <priority> "  \
21686                             "w <weight>] [del]")                        \
21687 _(one_add_del_locator, "locator-set <locator_name> "                    \
21688                         "iface <intf> | sw_if_index <sw_if_index> "     \
21689                         "p <priority> w <weight> [del]")                \
21690 _(one_add_del_local_eid,"vni <vni> eid "                                \
21691                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21692                          "locator-set <locator_name> [del]"             \
21693                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21694 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21695 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21696 _(one_enable_disable, "enable|disable")                                 \
21697 _(one_map_register_enable_disable, "enable|disable")                    \
21698 _(one_map_register_fallback_threshold, "<value>")                       \
21699 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21700 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21701                                "[seid <seid>] "                         \
21702                                "rloc <locator> p <prio> "               \
21703                                "w <weight> [rloc <loc> ... ] "          \
21704                                "action <action> [del-all]")             \
21705 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21706                           "<local-eid>")                                \
21707 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21708 _(one_use_petr, "ip-address> | disable")                                \
21709 _(one_map_request_mode, "src-dst|dst-only")                             \
21710 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21711 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21712 _(one_locator_set_dump, "[local | remote]")                             \
21713 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21714 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21715                        "[local] | [remote]")                            \
21716 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21717 _(one_ndp_bd_get, "")                                                   \
21718 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21719 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21720 _(one_l2_arp_bd_get, "")                                                \
21721 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21722 _(one_stats_enable_disable, "enable|disable")                           \
21723 _(show_one_stats_enable_disable, "")                                    \
21724 _(one_eid_table_vni_dump, "")                                           \
21725 _(one_eid_table_map_dump, "l2|l3")                                      \
21726 _(one_map_resolver_dump, "")                                            \
21727 _(one_map_server_dump, "")                                              \
21728 _(one_adjacencies_get, "vni <vni>")                                     \
21729 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21730 _(show_one_rloc_probe_state, "")                                        \
21731 _(show_one_map_register_state, "")                                      \
21732 _(show_one_status, "")                                                  \
21733 _(one_stats_dump, "")                                                   \
21734 _(one_stats_flush, "")                                                  \
21735 _(one_get_map_request_itr_rlocs, "")                                    \
21736 _(one_map_register_set_ttl, "<ttl>")                                    \
21737 _(one_set_transport_protocol, "udp|api")                                \
21738 _(one_get_transport_protocol, "")                                       \
21739 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21740 _(one_show_xtr_mode, "")                                                \
21741 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21742 _(one_show_pitr_mode, "")                                               \
21743 _(one_enable_disable_petr_mode, "enable|disable")                       \
21744 _(one_show_petr_mode, "")                                               \
21745 _(show_one_nsh_mapping, "")                                             \
21746 _(show_one_pitr, "")                                                    \
21747 _(show_one_use_petr, "")                                                \
21748 _(show_one_map_request_mode, "")                                        \
21749 _(show_one_map_register_ttl, "")                                        \
21750 _(show_one_map_register_fallback_threshold, "")                         \
21751 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21752                             " sw_if_index <sw_if_index> p <priority> "  \
21753                             "w <weight>] [del]")                        \
21754 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21755                         "iface <intf> | sw_if_index <sw_if_index> "     \
21756                         "p <priority> w <weight> [del]")                \
21757 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21758                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21759                          "locator-set <locator_name> [del]"             \
21760                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21761 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21762 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21763 _(lisp_enable_disable, "enable|disable")                                \
21764 _(lisp_map_register_enable_disable, "enable|disable")                   \
21765 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21766 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21767                                "[seid <seid>] "                         \
21768                                "rloc <locator> p <prio> "               \
21769                                "w <weight> [rloc <loc> ... ] "          \
21770                                "action <action> [del-all]")             \
21771 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21772                           "<local-eid>")                                \
21773 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21774 _(lisp_use_petr, "<ip-address> | disable")                              \
21775 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21776 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21777 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21778 _(lisp_locator_set_dump, "[local | remote]")                            \
21779 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21780 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21781                        "[local] | [remote]")                            \
21782 _(lisp_eid_table_vni_dump, "")                                          \
21783 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21784 _(lisp_map_resolver_dump, "")                                           \
21785 _(lisp_map_server_dump, "")                                             \
21786 _(lisp_adjacencies_get, "vni <vni>")                                    \
21787 _(gpe_fwd_entry_vnis_get, "")                                           \
21788 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21789 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21790                                 "[table <table-id>]")                   \
21791 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21792 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21793 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21794 _(gpe_get_encap_mode, "")                                               \
21795 _(lisp_gpe_add_del_iface, "up|down")                                    \
21796 _(lisp_gpe_enable_disable, "enable|disable")                            \
21797 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21798   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21799 _(show_lisp_rloc_probe_state, "")                                       \
21800 _(show_lisp_map_register_state, "")                                     \
21801 _(show_lisp_status, "")                                                 \
21802 _(lisp_get_map_request_itr_rlocs, "")                                   \
21803 _(show_lisp_pitr, "")                                                   \
21804 _(show_lisp_use_petr, "")                                               \
21805 _(show_lisp_map_request_mode, "")                                       \
21806 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21807 _(af_packet_delete, "name <host interface name>")                       \
21808 _(af_packet_dump, "")                                                   \
21809 _(policer_add_del, "name <policer name> <params> [del]")                \
21810 _(policer_dump, "[name <policer name>]")                                \
21811 _(policer_classify_set_interface,                                       \
21812   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21813   "  [l2-table <nn>] [del]")                                            \
21814 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21815 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21816     "[master|slave]")                                                   \
21817 _(netmap_delete, "name <interface name>")                               \
21818 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21819 _(mpls_table_dump, "")                                                  \
21820 _(mpls_route_dump, "table-id <ID>")                                     \
21821 _(classify_table_ids, "")                                               \
21822 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21823 _(classify_table_info, "table_id <nn>")                                 \
21824 _(classify_session_dump, "table_id <nn>")                               \
21825 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21826     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21827     "[template_interval <nn>] [udp_checksum]")                          \
21828 _(ipfix_exporter_dump, "")                                              \
21829 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21830 _(ipfix_classify_stream_dump, "")                                       \
21831 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21832 _(ipfix_classify_table_dump, "")                                        \
21833 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21834 _(sw_interface_span_dump, "[l2]")                                           \
21835 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21836 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21837 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21838 _(pg_enable_disable, "[stream <id>] disable")                           \
21839 _(ip_source_and_port_range_check_add_del,                               \
21840   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21841 _(ip_source_and_port_range_check_interface_add_del,                     \
21842   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21843   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21844 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21845 _(l2_interface_pbb_tag_rewrite,                                         \
21846   "<intfc> | sw_if_index <nn> \n"                                       \
21847   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21848   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21849 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21850 _(flow_classify_set_interface,                                          \
21851   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21852 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21853 _(ip_table_dump, "")                                                    \
21854 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21855 _(ip_mtable_dump, "")                                                   \
21856 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21857 _(feature_enable_disable, "arc_name <arc_name> "                        \
21858   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21859 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21860   "[enable | disable] ")                                                \
21861 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21862 "[disable]")                                                            \
21863 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21864   "mac <mac-address> [del]")                                            \
21865 _(l2_xconnect_dump, "")                                                 \
21866 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21867 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21868 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21869 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21870 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21871 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21872 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21873   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21874 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21875 _(sock_init_shm, "size <nnn>")                                          \
21876 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21877 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21878   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21879 _(session_rules_dump, "")                                               \
21880 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21881 _(output_acl_set_interface,                                             \
21882   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21883   "  [l2-table <nn>] [del]")                                            \
21884 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21885
21886 /* List of command functions, CLI names map directly to functions */
21887 #define foreach_cli_function                                    \
21888 _(comment, "usage: comment <ignore-rest-of-line>")              \
21889 _(dump_interface_table, "usage: dump_interface_table")          \
21890 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21891 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21892 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21893 _(dump_macro_table, "usage: dump_macro_table ")                 \
21894 _(dump_node_table, "usage: dump_node_table")                    \
21895 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21896 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21897 _(elog_disable, "usage: elog_disable")                          \
21898 _(elog_enable, "usage: elog_enable")                            \
21899 _(elog_save, "usage: elog_save <filename>")                     \
21900 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21901 _(echo, "usage: echo <message>")                                \
21902 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21903 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21904 _(help, "usage: help")                                          \
21905 _(q, "usage: quit")                                             \
21906 _(quit, "usage: quit")                                          \
21907 _(search_node_table, "usage: search_node_table <name>...")      \
21908 _(set, "usage: set <variable-name> <value>")                    \
21909 _(script, "usage: script <file-name>")                          \
21910 _(statseg, "usage: statseg")                                    \
21911 _(unset, "usage: unset <variable-name>")
21912
21913 #define _(N,n)                                  \
21914     static void vl_api_##n##_t_handler_uni      \
21915     (vl_api_##n##_t * mp)                       \
21916     {                                           \
21917         vat_main_t * vam = &vat_main;           \
21918         if (vam->json_output) {                 \
21919             vl_api_##n##_t_handler_json(mp);    \
21920         } else {                                \
21921             vl_api_##n##_t_handler(mp);         \
21922         }                                       \
21923     }
21924 foreach_vpe_api_reply_msg;
21925 #if VPP_API_TEST_BUILTIN == 0
21926 foreach_standalone_reply_msg;
21927 #endif
21928 #undef _
21929
21930 void
21931 vat_api_hookup (vat_main_t * vam)
21932 {
21933 #define _(N,n)                                                  \
21934     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21935                            vl_api_##n##_t_handler_uni,          \
21936                            vl_noop_handler,                     \
21937                            vl_api_##n##_t_endian,               \
21938                            vl_api_##n##_t_print,                \
21939                            sizeof(vl_api_##n##_t), 1);
21940   foreach_vpe_api_reply_msg;
21941 #if VPP_API_TEST_BUILTIN == 0
21942   foreach_standalone_reply_msg;
21943 #endif
21944 #undef _
21945
21946 #if (VPP_API_TEST_BUILTIN==0)
21947   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21948
21949   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21950
21951   vam->function_by_name = hash_create_string (0, sizeof (uword));
21952
21953   vam->help_by_name = hash_create_string (0, sizeof (uword));
21954 #endif
21955
21956   /* API messages we can send */
21957 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21958   foreach_vpe_api_msg;
21959 #undef _
21960
21961   /* Help strings */
21962 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21963   foreach_vpe_api_msg;
21964 #undef _
21965
21966   /* CLI functions */
21967 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21968   foreach_cli_function;
21969 #undef _
21970
21971   /* Help strings */
21972 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21973   foreach_cli_function;
21974 #undef _
21975 }
21976
21977 #if VPP_API_TEST_BUILTIN
21978 static clib_error_t *
21979 vat_api_hookup_shim (vlib_main_t * vm)
21980 {
21981   vat_api_hookup (&vat_main);
21982   return 0;
21983 }
21984
21985 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21986 #endif
21987
21988 /*
21989  * fd.io coding-style-patch-verification: ON
21990  *
21991  * Local Variables:
21992  * eval: (c-set-style "gnu")
21993  * End:
21994  */