geneve: 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 _(sw_interface_tag_add_del_reply)                       \
5178 _(sw_interface_add_del_mac_address_reply)               \
5179 _(hw_interface_set_mtu_reply)                           \
5180 _(p2p_ethernet_add_reply)                               \
5181 _(p2p_ethernet_del_reply)                               \
5182 _(lldp_config_reply)                                    \
5183 _(sw_interface_set_lldp_reply)                          \
5184 _(tcp_configure_src_addresses_reply)                    \
5185 _(session_rule_add_del_reply)                           \
5186 _(ip_container_proxy_add_del_reply)                     \
5187 _(output_acl_set_interface_reply)                       \
5188 _(qos_record_enable_disable_reply)
5189
5190 #define _(n)                                    \
5191     static void vl_api_##n##_t_handler          \
5192     (vl_api_##n##_t * mp)                       \
5193     {                                           \
5194         vat_main_t * vam = &vat_main;           \
5195         i32 retval = ntohl(mp->retval);         \
5196         if (vam->async_mode) {                  \
5197             vam->async_errors += (retval < 0);  \
5198         } else {                                \
5199             vam->retval = retval;               \
5200             vam->result_ready = 1;              \
5201         }                                       \
5202     }
5203 foreach_standard_reply_retval_handler;
5204 #undef _
5205
5206 #define _(n)                                    \
5207     static void vl_api_##n##_t_handler_json     \
5208     (vl_api_##n##_t * mp)                       \
5209     {                                           \
5210         vat_main_t * vam = &vat_main;           \
5211         vat_json_node_t node;                   \
5212         vat_json_init_object(&node);            \
5213         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5214         vat_json_print(vam->ofp, &node);        \
5215         vam->retval = ntohl(mp->retval);        \
5216         vam->result_ready = 1;                  \
5217     }
5218 foreach_standard_reply_retval_handler;
5219 #undef _
5220
5221 /*
5222  * Table of message reply handlers, must include boilerplate handlers
5223  * we just generated
5224  */
5225
5226 #define foreach_vpe_api_reply_msg                                       \
5227 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5228 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5229 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5230 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5231 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5232 _(CLI_REPLY, cli_reply)                                                 \
5233 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5234 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5235   sw_interface_add_del_address_reply)                                   \
5236 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5237 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5238 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5239 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5240 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5241 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5242 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5243 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5244 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5245 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5246   sw_interface_set_l2_xconnect_reply)                                   \
5247 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5248   sw_interface_set_l2_bridge_reply)                                     \
5249 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5250 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5251 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5252 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5253 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5254 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5255 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5256 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5257 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5258 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5259 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5260 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5261 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5262 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5263 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5264 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5265 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5266 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5267 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5268 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5269 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5270 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5271 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5272 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5273 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5274 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5275 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5276 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5277 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5278 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5279 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5280   proxy_arp_intfc_enable_disable_reply)                                 \
5281 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5282 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5283   sw_interface_set_unnumbered_reply)                                    \
5284 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5285 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5286 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5287 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5288 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5289 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5290   sw_interface_ip6_enable_disable_reply)                                \
5291 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5292 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5293 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5294   sw_interface_ip6nd_ra_prefix_reply)                                   \
5295 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5296   sw_interface_ip6nd_ra_config_reply)                                   \
5297 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5298 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5299 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5300 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5301 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5302 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5303 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5304 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5305 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5306 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5307 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5308 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5309 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5310 classify_set_interface_ip_table_reply)                                  \
5311 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5312   classify_set_interface_l2_tables_reply)                               \
5313 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5314 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5315 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5316 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5317 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5318   l2tpv3_interface_enable_disable_reply)                                \
5319 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5320 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5321 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5322 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5323 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5324 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5325 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5326 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5327 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5328 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5329 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5330 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5331 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5332 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5333 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5334 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5335 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5336 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5337 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5338 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5339 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5340 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5341 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5342 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5343 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5344 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5345 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5346 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5347 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5348 _(L2_MACS_EVENT, l2_macs_event)                                         \
5349 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5350 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5351 _(IP_DETAILS, ip_details)                                               \
5352 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5353 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5354 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5355 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5356 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5357 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5358 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5359 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5360 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5361 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5362 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5363 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5364 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5365 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5366 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5367 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5368 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5369 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5370 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5371 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5372 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5373 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5374 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5375 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5376 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5377 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5378 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5379 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5380   one_map_register_enable_disable_reply)                                \
5381 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5382 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5383 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5384 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5385   one_map_register_fallback_threshold_reply)                            \
5386 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5387   one_rloc_probe_enable_disable_reply)                                  \
5388 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5389 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5390 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5391 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5392 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5393 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5394 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5395 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5396 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5397 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5398 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5399 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5400 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5401 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5402 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5403 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5404   show_one_stats_enable_disable_reply)                                  \
5405 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5406 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5407 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5408 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5409 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5410 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5411 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5412 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5413   one_enable_disable_pitr_mode_reply)                                   \
5414 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5415   one_enable_disable_petr_mode_reply)                                   \
5416 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5417 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5418 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5419 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5420 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5421 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5422 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5423 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5424 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5425 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5426 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5427 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5428   gpe_add_del_native_fwd_rpath_reply)                                   \
5429 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5430   gpe_fwd_entry_path_details)                                           \
5431 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5432 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5433   one_add_del_map_request_itr_rlocs_reply)                              \
5434 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5435   one_get_map_request_itr_rlocs_reply)                                  \
5436 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5437 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5438 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5439 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5440 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5442   show_one_map_register_state_reply)                                    \
5443 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5444 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5445   show_one_map_register_fallback_threshold_reply)                       \
5446 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5447 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5448 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5449 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5450 _(POLICER_DETAILS, policer_details)                                     \
5451 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5452 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5453 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5454 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5455 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5456 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5457 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5458 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5459 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5460 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5461 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5462 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5463 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5464 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5465 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5466 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5467 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5468 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5469 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5470 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5471 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5472 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5473 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5474 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5475 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5476 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5477  ip_source_and_port_range_check_add_del_reply)                          \
5478 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5479  ip_source_and_port_range_check_interface_add_del_reply)                \
5480 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5481 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5482 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5483 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5484 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5485 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5486 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5487 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5488 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5489 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5490 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5491 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5492 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5493 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5494 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5495 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5496 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5497 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5498 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5499 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5500 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5501 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5502 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5503
5504 #define foreach_standalone_reply_msg                                    \
5505 _(SW_INTERFACE_EVENT, sw_interface_event)
5506
5507 typedef struct
5508 {
5509   u8 *name;
5510   u32 value;
5511 } name_sort_t;
5512
5513 #define STR_VTR_OP_CASE(op)     \
5514     case L2_VTR_ ## op:         \
5515         return "" # op;
5516
5517 static const char *
5518 str_vtr_op (u32 vtr_op)
5519 {
5520   switch (vtr_op)
5521     {
5522       STR_VTR_OP_CASE (DISABLED);
5523       STR_VTR_OP_CASE (PUSH_1);
5524       STR_VTR_OP_CASE (PUSH_2);
5525       STR_VTR_OP_CASE (POP_1);
5526       STR_VTR_OP_CASE (POP_2);
5527       STR_VTR_OP_CASE (TRANSLATE_1_1);
5528       STR_VTR_OP_CASE (TRANSLATE_1_2);
5529       STR_VTR_OP_CASE (TRANSLATE_2_1);
5530       STR_VTR_OP_CASE (TRANSLATE_2_2);
5531     }
5532
5533   return "UNKNOWN";
5534 }
5535
5536 static int
5537 dump_sub_interface_table (vat_main_t * vam)
5538 {
5539   const sw_interface_subif_t *sub = NULL;
5540
5541   if (vam->json_output)
5542     {
5543       clib_warning
5544         ("JSON output supported only for VPE API calls and dump_stats_table");
5545       return -99;
5546     }
5547
5548   print (vam->ofp,
5549          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5550          "Interface", "sw_if_index",
5551          "sub id", "dot1ad", "tags", "outer id",
5552          "inner id", "exact", "default", "outer any", "inner any");
5553
5554   vec_foreach (sub, vam->sw_if_subif_table)
5555   {
5556     print (vam->ofp,
5557            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5558            sub->interface_name,
5559            sub->sw_if_index,
5560            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5561            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5562            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5563            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5564     if (sub->vtr_op != L2_VTR_DISABLED)
5565       {
5566         print (vam->ofp,
5567                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5568                "tag1: %d tag2: %d ]",
5569                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5570                sub->vtr_tag1, sub->vtr_tag2);
5571       }
5572   }
5573
5574   return 0;
5575 }
5576
5577 static int
5578 name_sort_cmp (void *a1, void *a2)
5579 {
5580   name_sort_t *n1 = a1;
5581   name_sort_t *n2 = a2;
5582
5583   return strcmp ((char *) n1->name, (char *) n2->name);
5584 }
5585
5586 static int
5587 dump_interface_table (vat_main_t * vam)
5588 {
5589   hash_pair_t *p;
5590   name_sort_t *nses = 0, *ns;
5591
5592   if (vam->json_output)
5593     {
5594       clib_warning
5595         ("JSON output supported only for VPE API calls and dump_stats_table");
5596       return -99;
5597     }
5598
5599   /* *INDENT-OFF* */
5600   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5601   ({
5602     vec_add2 (nses, ns, 1);
5603     ns->name = (u8 *)(p->key);
5604     ns->value = (u32) p->value[0];
5605   }));
5606   /* *INDENT-ON* */
5607
5608   vec_sort_with_function (nses, name_sort_cmp);
5609
5610   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5611   vec_foreach (ns, nses)
5612   {
5613     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5614   }
5615   vec_free (nses);
5616   return 0;
5617 }
5618
5619 static int
5620 dump_ip_table (vat_main_t * vam, int is_ipv6)
5621 {
5622   const ip_details_t *det = NULL;
5623   const ip_address_details_t *address = NULL;
5624   u32 i = ~0;
5625
5626   print (vam->ofp, "%-12s", "sw_if_index");
5627
5628   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5629   {
5630     i++;
5631     if (!det->present)
5632       {
5633         continue;
5634       }
5635     print (vam->ofp, "%-12d", i);
5636     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5637     if (!det->addr)
5638       {
5639         continue;
5640       }
5641     vec_foreach (address, det->addr)
5642     {
5643       print (vam->ofp,
5644              "            %-30U%-13d",
5645              is_ipv6 ? format_ip6_address : format_ip4_address,
5646              address->ip, address->prefix_length);
5647     }
5648   }
5649
5650   return 0;
5651 }
5652
5653 static int
5654 dump_ipv4_table (vat_main_t * vam)
5655 {
5656   if (vam->json_output)
5657     {
5658       clib_warning
5659         ("JSON output supported only for VPE API calls and dump_stats_table");
5660       return -99;
5661     }
5662
5663   return dump_ip_table (vam, 0);
5664 }
5665
5666 static int
5667 dump_ipv6_table (vat_main_t * vam)
5668 {
5669   if (vam->json_output)
5670     {
5671       clib_warning
5672         ("JSON output supported only for VPE API calls and dump_stats_table");
5673       return -99;
5674     }
5675
5676   return dump_ip_table (vam, 1);
5677 }
5678
5679 /*
5680  * Pass CLI buffers directly in the CLI_INBAND API message,
5681  * instead of an additional shared memory area.
5682  */
5683 static int
5684 exec_inband (vat_main_t * vam)
5685 {
5686   vl_api_cli_inband_t *mp;
5687   unformat_input_t *i = vam->input;
5688   int ret;
5689
5690   if (vec_len (i->buffer) == 0)
5691     return -1;
5692
5693   if (vam->exec_mode == 0 && unformat (i, "mode"))
5694     {
5695       vam->exec_mode = 1;
5696       return 0;
5697     }
5698   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5699     {
5700       vam->exec_mode = 0;
5701       return 0;
5702     }
5703
5704   /*
5705    * In order for the CLI command to work, it
5706    * must be a vector ending in \n, not a C-string ending
5707    * in \n\0.
5708    */
5709   u32 len = vec_len (vam->input->buffer);
5710   M2 (CLI_INBAND, mp, len);
5711   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5712
5713   S (mp);
5714   W (ret);
5715   /* json responses may or may not include a useful reply... */
5716   if (vec_len (vam->cmd_reply))
5717     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5718   return ret;
5719 }
5720
5721 int
5722 exec (vat_main_t * vam)
5723 {
5724   return exec_inband (vam);
5725 }
5726
5727 static int
5728 api_create_loopback (vat_main_t * vam)
5729 {
5730   unformat_input_t *i = vam->input;
5731   vl_api_create_loopback_t *mp;
5732   vl_api_create_loopback_instance_t *mp_lbi;
5733   u8 mac_address[6];
5734   u8 mac_set = 0;
5735   u8 is_specified = 0;
5736   u32 user_instance = 0;
5737   int ret;
5738
5739   clib_memset (mac_address, 0, sizeof (mac_address));
5740
5741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5742     {
5743       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5744         mac_set = 1;
5745       if (unformat (i, "instance %d", &user_instance))
5746         is_specified = 1;
5747       else
5748         break;
5749     }
5750
5751   if (is_specified)
5752     {
5753       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5754       mp_lbi->is_specified = is_specified;
5755       if (is_specified)
5756         mp_lbi->user_instance = htonl (user_instance);
5757       if (mac_set)
5758         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5759       S (mp_lbi);
5760     }
5761   else
5762     {
5763       /* Construct the API message */
5764       M (CREATE_LOOPBACK, mp);
5765       if (mac_set)
5766         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5767       S (mp);
5768     }
5769
5770   W (ret);
5771   return ret;
5772 }
5773
5774 static int
5775 api_delete_loopback (vat_main_t * vam)
5776 {
5777   unformat_input_t *i = vam->input;
5778   vl_api_delete_loopback_t *mp;
5779   u32 sw_if_index = ~0;
5780   int ret;
5781
5782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5783     {
5784       if (unformat (i, "sw_if_index %d", &sw_if_index))
5785         ;
5786       else
5787         break;
5788     }
5789
5790   if (sw_if_index == ~0)
5791     {
5792       errmsg ("missing sw_if_index");
5793       return -99;
5794     }
5795
5796   /* Construct the API message */
5797   M (DELETE_LOOPBACK, mp);
5798   mp->sw_if_index = ntohl (sw_if_index);
5799
5800   S (mp);
5801   W (ret);
5802   return ret;
5803 }
5804
5805 static int
5806 api_want_interface_events (vat_main_t * vam)
5807 {
5808   unformat_input_t *i = vam->input;
5809   vl_api_want_interface_events_t *mp;
5810   int enable = -1;
5811   int ret;
5812
5813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5814     {
5815       if (unformat (i, "enable"))
5816         enable = 1;
5817       else if (unformat (i, "disable"))
5818         enable = 0;
5819       else
5820         break;
5821     }
5822
5823   if (enable == -1)
5824     {
5825       errmsg ("missing enable|disable");
5826       return -99;
5827     }
5828
5829   M (WANT_INTERFACE_EVENTS, mp);
5830   mp->enable_disable = enable;
5831
5832   vam->interface_event_display = enable;
5833
5834   S (mp);
5835   W (ret);
5836   return ret;
5837 }
5838
5839
5840 /* Note: non-static, called once to set up the initial intfc table */
5841 int
5842 api_sw_interface_dump (vat_main_t * vam)
5843 {
5844   vl_api_sw_interface_dump_t *mp;
5845   vl_api_control_ping_t *mp_ping;
5846   hash_pair_t *p;
5847   name_sort_t *nses = 0, *ns;
5848   sw_interface_subif_t *sub = NULL;
5849   int ret;
5850
5851   /* Toss the old name table */
5852   /* *INDENT-OFF* */
5853   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5854   ({
5855     vec_add2 (nses, ns, 1);
5856     ns->name = (u8 *)(p->key);
5857     ns->value = (u32) p->value[0];
5858   }));
5859   /* *INDENT-ON* */
5860
5861   hash_free (vam->sw_if_index_by_interface_name);
5862
5863   vec_foreach (ns, nses) vec_free (ns->name);
5864
5865   vec_free (nses);
5866
5867   vec_foreach (sub, vam->sw_if_subif_table)
5868   {
5869     vec_free (sub->interface_name);
5870   }
5871   vec_free (vam->sw_if_subif_table);
5872
5873   /* recreate the interface name hash table */
5874   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5875
5876   /*
5877    * Ask for all interface names. Otherwise, the epic catalog of
5878    * name filters becomes ridiculously long, and vat ends up needing
5879    * to be taught about new interface types.
5880    */
5881   M (SW_INTERFACE_DUMP, mp);
5882   S (mp);
5883
5884   /* Use a control ping for synchronization */
5885   MPING (CONTROL_PING, mp_ping);
5886   S (mp_ping);
5887
5888   W (ret);
5889   return ret;
5890 }
5891
5892 static int
5893 api_sw_interface_set_flags (vat_main_t * vam)
5894 {
5895   unformat_input_t *i = vam->input;
5896   vl_api_sw_interface_set_flags_t *mp;
5897   u32 sw_if_index;
5898   u8 sw_if_index_set = 0;
5899   u8 admin_up = 0;
5900   int ret;
5901
5902   /* Parse args required to build the message */
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "admin-up"))
5906         admin_up = 1;
5907       else if (unformat (i, "admin-down"))
5908         admin_up = 0;
5909       else
5910         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5911         sw_if_index_set = 1;
5912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5913         sw_if_index_set = 1;
5914       else
5915         break;
5916     }
5917
5918   if (sw_if_index_set == 0)
5919     {
5920       errmsg ("missing interface name or sw_if_index");
5921       return -99;
5922     }
5923
5924   /* Construct the API message */
5925   M (SW_INTERFACE_SET_FLAGS, mp);
5926   mp->sw_if_index = ntohl (sw_if_index);
5927   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5928
5929   /* send it... */
5930   S (mp);
5931
5932   /* Wait for a reply, return the good/bad news... */
5933   W (ret);
5934   return ret;
5935 }
5936
5937 static int
5938 api_sw_interface_set_rx_mode (vat_main_t * vam)
5939 {
5940   unformat_input_t *i = vam->input;
5941   vl_api_sw_interface_set_rx_mode_t *mp;
5942   u32 sw_if_index;
5943   u8 sw_if_index_set = 0;
5944   int ret;
5945   u8 queue_id_valid = 0;
5946   u32 queue_id;
5947   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5948
5949   /* Parse args required to build the message */
5950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5951     {
5952       if (unformat (i, "queue %d", &queue_id))
5953         queue_id_valid = 1;
5954       else if (unformat (i, "polling"))
5955         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5956       else if (unformat (i, "interrupt"))
5957         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5958       else if (unformat (i, "adaptive"))
5959         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5960       else
5961         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5962         sw_if_index_set = 1;
5963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5964         sw_if_index_set = 1;
5965       else
5966         break;
5967     }
5968
5969   if (sw_if_index_set == 0)
5970     {
5971       errmsg ("missing interface name or sw_if_index");
5972       return -99;
5973     }
5974   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5975     {
5976       errmsg ("missing rx-mode");
5977       return -99;
5978     }
5979
5980   /* Construct the API message */
5981   M (SW_INTERFACE_SET_RX_MODE, mp);
5982   mp->sw_if_index = ntohl (sw_if_index);
5983   mp->mode = (vl_api_rx_mode_t) mode;
5984   mp->queue_id_valid = queue_id_valid;
5985   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5986
5987   /* send it... */
5988   S (mp);
5989
5990   /* Wait for a reply, return the good/bad news... */
5991   W (ret);
5992   return ret;
5993 }
5994
5995 static int
5996 api_sw_interface_set_rx_placement (vat_main_t * vam)
5997 {
5998   unformat_input_t *i = vam->input;
5999   vl_api_sw_interface_set_rx_placement_t *mp;
6000   u32 sw_if_index;
6001   u8 sw_if_index_set = 0;
6002   int ret;
6003   u8 is_main = 0;
6004   u32 queue_id, thread_index;
6005
6006   /* Parse args required to build the message */
6007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6008     {
6009       if (unformat (i, "queue %d", &queue_id))
6010         ;
6011       else if (unformat (i, "main"))
6012         is_main = 1;
6013       else if (unformat (i, "worker %d", &thread_index))
6014         ;
6015       else
6016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6017         sw_if_index_set = 1;
6018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6019         sw_if_index_set = 1;
6020       else
6021         break;
6022     }
6023
6024   if (sw_if_index_set == 0)
6025     {
6026       errmsg ("missing interface name or sw_if_index");
6027       return -99;
6028     }
6029
6030   if (is_main)
6031     thread_index = 0;
6032   /* Construct the API message */
6033   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6034   mp->sw_if_index = ntohl (sw_if_index);
6035   mp->worker_id = ntohl (thread_index);
6036   mp->queue_id = ntohl (queue_id);
6037   mp->is_main = is_main;
6038
6039   /* send it... */
6040   S (mp);
6041   /* Wait for a reply, return the good/bad news... */
6042   W (ret);
6043   return ret;
6044 }
6045
6046 static void vl_api_sw_interface_rx_placement_details_t_handler
6047   (vl_api_sw_interface_rx_placement_details_t * mp)
6048 {
6049   vat_main_t *vam = &vat_main;
6050   u32 worker_id = ntohl (mp->worker_id);
6051
6052   print (vam->ofp,
6053          "\n%-11d %-11s %-6d %-5d %-9s",
6054          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6055          worker_id, ntohl (mp->queue_id),
6056          (mp->mode ==
6057           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6058 }
6059
6060 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6061   (vl_api_sw_interface_rx_placement_details_t * mp)
6062 {
6063   vat_main_t *vam = &vat_main;
6064   vat_json_node_t *node = NULL;
6065
6066   if (VAT_JSON_ARRAY != vam->json_tree.type)
6067     {
6068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6069       vat_json_init_array (&vam->json_tree);
6070     }
6071   node = vat_json_array_add (&vam->json_tree);
6072
6073   vat_json_init_object (node);
6074   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6075   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6076   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6077   vat_json_object_add_uint (node, "mode", mp->mode);
6078 }
6079
6080 static int
6081 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6082 {
6083   unformat_input_t *i = vam->input;
6084   vl_api_sw_interface_rx_placement_dump_t *mp;
6085   vl_api_control_ping_t *mp_ping;
6086   int ret;
6087   u32 sw_if_index;
6088   u8 sw_if_index_set = 0;
6089
6090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6091     {
6092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093         sw_if_index_set++;
6094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6095         sw_if_index_set++;
6096       else
6097         break;
6098     }
6099
6100   print (vam->ofp,
6101          "\n%-11s %-11s %-6s %-5s %-4s",
6102          "sw_if_index", "main/worker", "thread", "queue", "mode");
6103
6104   /* Dump Interface rx placement */
6105   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6106
6107   if (sw_if_index_set)
6108     mp->sw_if_index = htonl (sw_if_index);
6109   else
6110     mp->sw_if_index = ~0;
6111
6112   S (mp);
6113
6114   /* Use a control ping for synchronization */
6115   MPING (CONTROL_PING, mp_ping);
6116   S (mp_ping);
6117
6118   W (ret);
6119   return ret;
6120 }
6121
6122 static int
6123 api_sw_interface_clear_stats (vat_main_t * vam)
6124 {
6125   unformat_input_t *i = vam->input;
6126   vl_api_sw_interface_clear_stats_t *mp;
6127   u32 sw_if_index;
6128   u8 sw_if_index_set = 0;
6129   int ret;
6130
6131   /* Parse args required to build the message */
6132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6133     {
6134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6137         sw_if_index_set = 1;
6138       else
6139         break;
6140     }
6141
6142   /* Construct the API message */
6143   M (SW_INTERFACE_CLEAR_STATS, mp);
6144
6145   if (sw_if_index_set == 1)
6146     mp->sw_if_index = ntohl (sw_if_index);
6147   else
6148     mp->sw_if_index = ~0;
6149
6150   /* send it... */
6151   S (mp);
6152
6153   /* Wait for a reply, return the good/bad news... */
6154   W (ret);
6155   return ret;
6156 }
6157
6158 static int
6159 api_sw_interface_add_del_address (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_sw_interface_add_del_address_t *mp;
6163   u32 sw_if_index;
6164   u8 sw_if_index_set = 0;
6165   u8 is_add = 1, del_all = 0;
6166   u32 address_length = 0;
6167   u8 v4_address_set = 0;
6168   u8 v6_address_set = 0;
6169   ip4_address_t v4address;
6170   ip6_address_t v6address;
6171   int ret;
6172
6173   /* Parse args required to build the message */
6174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6175     {
6176       if (unformat (i, "del-all"))
6177         del_all = 1;
6178       else if (unformat (i, "del"))
6179         is_add = 0;
6180       else
6181         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6182         sw_if_index_set = 1;
6183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6184         sw_if_index_set = 1;
6185       else if (unformat (i, "%U/%d",
6186                          unformat_ip4_address, &v4address, &address_length))
6187         v4_address_set = 1;
6188       else if (unformat (i, "%U/%d",
6189                          unformat_ip6_address, &v6address, &address_length))
6190         v6_address_set = 1;
6191       else
6192         break;
6193     }
6194
6195   if (sw_if_index_set == 0)
6196     {
6197       errmsg ("missing interface name or sw_if_index");
6198       return -99;
6199     }
6200   if (v4_address_set && v6_address_set)
6201     {
6202       errmsg ("both v4 and v6 addresses set");
6203       return -99;
6204     }
6205   if (!v4_address_set && !v6_address_set && !del_all)
6206     {
6207       errmsg ("no addresses set");
6208       return -99;
6209     }
6210
6211   /* Construct the API message */
6212   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6213
6214   mp->sw_if_index = ntohl (sw_if_index);
6215   mp->is_add = is_add;
6216   mp->del_all = del_all;
6217   if (v6_address_set)
6218     {
6219       mp->prefix.address.af = ADDRESS_IP6;
6220       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6221     }
6222   else
6223     {
6224       mp->prefix.address.af = ADDRESS_IP4;
6225       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6226     }
6227   mp->prefix.len = address_length;
6228
6229   /* send it... */
6230   S (mp);
6231
6232   /* Wait for a reply, return good/bad news  */
6233   W (ret);
6234   return ret;
6235 }
6236
6237 static int
6238 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_sw_interface_set_mpls_enable_t *mp;
6242   u32 sw_if_index;
6243   u8 sw_if_index_set = 0;
6244   u8 enable = 1;
6245   int ret;
6246
6247   /* Parse args required to build the message */
6248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6249     {
6250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6251         sw_if_index_set = 1;
6252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "disable"))
6255         enable = 0;
6256       else if (unformat (i, "dis"))
6257         enable = 0;
6258       else
6259         break;
6260     }
6261
6262   if (sw_if_index_set == 0)
6263     {
6264       errmsg ("missing interface name or sw_if_index");
6265       return -99;
6266     }
6267
6268   /* Construct the API message */
6269   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6270
6271   mp->sw_if_index = ntohl (sw_if_index);
6272   mp->enable = enable;
6273
6274   /* send it... */
6275   S (mp);
6276
6277   /* Wait for a reply... */
6278   W (ret);
6279   return ret;
6280 }
6281
6282 static int
6283 api_sw_interface_set_table (vat_main_t * vam)
6284 {
6285   unformat_input_t *i = vam->input;
6286   vl_api_sw_interface_set_table_t *mp;
6287   u32 sw_if_index, vrf_id = 0;
6288   u8 sw_if_index_set = 0;
6289   u8 is_ipv6 = 0;
6290   int ret;
6291
6292   /* Parse args required to build the message */
6293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6294     {
6295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6296         sw_if_index_set = 1;
6297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "vrf %d", &vrf_id))
6300         ;
6301       else if (unformat (i, "ipv6"))
6302         is_ipv6 = 1;
6303       else
6304         break;
6305     }
6306
6307   if (sw_if_index_set == 0)
6308     {
6309       errmsg ("missing interface name or sw_if_index");
6310       return -99;
6311     }
6312
6313   /* Construct the API message */
6314   M (SW_INTERFACE_SET_TABLE, mp);
6315
6316   mp->sw_if_index = ntohl (sw_if_index);
6317   mp->is_ipv6 = is_ipv6;
6318   mp->vrf_id = ntohl (vrf_id);
6319
6320   /* send it... */
6321   S (mp);
6322
6323   /* Wait for a reply... */
6324   W (ret);
6325   return ret;
6326 }
6327
6328 static void vl_api_sw_interface_get_table_reply_t_handler
6329   (vl_api_sw_interface_get_table_reply_t * mp)
6330 {
6331   vat_main_t *vam = &vat_main;
6332
6333   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6334
6335   vam->retval = ntohl (mp->retval);
6336   vam->result_ready = 1;
6337
6338 }
6339
6340 static void vl_api_sw_interface_get_table_reply_t_handler_json
6341   (vl_api_sw_interface_get_table_reply_t * mp)
6342 {
6343   vat_main_t *vam = &vat_main;
6344   vat_json_node_t node;
6345
6346   vat_json_init_object (&node);
6347   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6348   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6349
6350   vat_json_print (vam->ofp, &node);
6351   vat_json_free (&node);
6352
6353   vam->retval = ntohl (mp->retval);
6354   vam->result_ready = 1;
6355 }
6356
6357 static int
6358 api_sw_interface_get_table (vat_main_t * vam)
6359 {
6360   unformat_input_t *i = vam->input;
6361   vl_api_sw_interface_get_table_t *mp;
6362   u32 sw_if_index;
6363   u8 sw_if_index_set = 0;
6364   u8 is_ipv6 = 0;
6365   int ret;
6366
6367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6368     {
6369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "ipv6"))
6374         is_ipv6 = 1;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index_set == 0)
6380     {
6381       errmsg ("missing interface name or sw_if_index");
6382       return -99;
6383     }
6384
6385   M (SW_INTERFACE_GET_TABLE, mp);
6386   mp->sw_if_index = htonl (sw_if_index);
6387   mp->is_ipv6 = is_ipv6;
6388
6389   S (mp);
6390   W (ret);
6391   return ret;
6392 }
6393
6394 static int
6395 api_sw_interface_set_vpath (vat_main_t * vam)
6396 {
6397   unformat_input_t *i = vam->input;
6398   vl_api_sw_interface_set_vpath_t *mp;
6399   u32 sw_if_index = 0;
6400   u8 sw_if_index_set = 0;
6401   u8 is_enable = 0;
6402   int ret;
6403
6404   /* Parse args required to build the message */
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "enable"))
6412         is_enable = 1;
6413       else if (unformat (i, "disable"))
6414         is_enable = 0;
6415       else
6416         break;
6417     }
6418
6419   if (sw_if_index_set == 0)
6420     {
6421       errmsg ("missing interface name or sw_if_index");
6422       return -99;
6423     }
6424
6425   /* Construct the API message */
6426   M (SW_INTERFACE_SET_VPATH, mp);
6427
6428   mp->sw_if_index = ntohl (sw_if_index);
6429   mp->enable = is_enable;
6430
6431   /* send it... */
6432   S (mp);
6433
6434   /* Wait for a reply... */
6435   W (ret);
6436   return ret;
6437 }
6438
6439 static int
6440 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6441 {
6442   unformat_input_t *i = vam->input;
6443   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6444   u32 sw_if_index = 0;
6445   u8 sw_if_index_set = 0;
6446   u8 is_enable = 1;
6447   u8 is_ipv6 = 0;
6448   int ret;
6449
6450   /* Parse args required to build the message */
6451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6452     {
6453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6454         sw_if_index_set = 1;
6455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "enable"))
6458         is_enable = 1;
6459       else if (unformat (i, "disable"))
6460         is_enable = 0;
6461       else if (unformat (i, "ip4"))
6462         is_ipv6 = 0;
6463       else if (unformat (i, "ip6"))
6464         is_ipv6 = 1;
6465       else
6466         break;
6467     }
6468
6469   if (sw_if_index_set == 0)
6470     {
6471       errmsg ("missing interface name or sw_if_index");
6472       return -99;
6473     }
6474
6475   /* Construct the API message */
6476   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6477
6478   mp->sw_if_index = ntohl (sw_if_index);
6479   mp->enable = is_enable;
6480   mp->is_ipv6 = is_ipv6;
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static int
6491 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6492 {
6493   unformat_input_t *i = vam->input;
6494   vl_api_sw_interface_set_geneve_bypass_t *mp;
6495   u32 sw_if_index = 0;
6496   u8 sw_if_index_set = 0;
6497   u8 is_enable = 1;
6498   u8 is_ipv6 = 0;
6499   int ret;
6500
6501   /* Parse args required to build the message */
6502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6503     {
6504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6505         sw_if_index_set = 1;
6506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6507         sw_if_index_set = 1;
6508       else if (unformat (i, "enable"))
6509         is_enable = 1;
6510       else if (unformat (i, "disable"))
6511         is_enable = 0;
6512       else if (unformat (i, "ip4"))
6513         is_ipv6 = 0;
6514       else if (unformat (i, "ip6"))
6515         is_ipv6 = 1;
6516       else
6517         break;
6518     }
6519
6520   if (sw_if_index_set == 0)
6521     {
6522       errmsg ("missing interface name or sw_if_index");
6523       return -99;
6524     }
6525
6526   /* Construct the API message */
6527   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6528
6529   mp->sw_if_index = ntohl (sw_if_index);
6530   mp->enable = is_enable;
6531   mp->is_ipv6 = is_ipv6;
6532
6533   /* send it... */
6534   S (mp);
6535
6536   /* Wait for a reply... */
6537   W (ret);
6538   return ret;
6539 }
6540
6541 static int
6542 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6543 {
6544   unformat_input_t *i = vam->input;
6545   vl_api_sw_interface_set_l2_xconnect_t *mp;
6546   u32 rx_sw_if_index;
6547   u8 rx_sw_if_index_set = 0;
6548   u32 tx_sw_if_index;
6549   u8 tx_sw_if_index_set = 0;
6550   u8 enable = 1;
6551   int ret;
6552
6553   /* Parse args required to build the message */
6554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6555     {
6556       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6557         rx_sw_if_index_set = 1;
6558       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6559         tx_sw_if_index_set = 1;
6560       else if (unformat (i, "rx"))
6561         {
6562           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6563             {
6564               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6565                             &rx_sw_if_index))
6566                 rx_sw_if_index_set = 1;
6567             }
6568           else
6569             break;
6570         }
6571       else if (unformat (i, "tx"))
6572         {
6573           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574             {
6575               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6576                             &tx_sw_if_index))
6577                 tx_sw_if_index_set = 1;
6578             }
6579           else
6580             break;
6581         }
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or rx_sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (tx_sw_if_index_set == 0))
6597     {
6598       errmsg ("missing tx interface name or tx_sw_if_index");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6606   mp->enable = enable;
6607
6608   S (mp);
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_set_l2_bridge_t *mp;
6618   vl_api_l2_port_type_t port_type;
6619   u32 rx_sw_if_index;
6620   u8 rx_sw_if_index_set = 0;
6621   u32 bd_id;
6622   u8 bd_id_set = 0;
6623   u32 shg = 0;
6624   u8 enable = 1;
6625   int ret;
6626
6627   port_type = L2_API_PORT_TYPE_NORMAL;
6628
6629   /* Parse args required to build the message */
6630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6631     {
6632       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6633         rx_sw_if_index_set = 1;
6634       else if (unformat (i, "bd_id %d", &bd_id))
6635         bd_id_set = 1;
6636       else
6637         if (unformat
6638             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6639         rx_sw_if_index_set = 1;
6640       else if (unformat (i, "shg %d", &shg))
6641         ;
6642       else if (unformat (i, "bvi"))
6643         port_type = L2_API_PORT_TYPE_BVI;
6644       else if (unformat (i, "uu-fwd"))
6645         port_type = L2_API_PORT_TYPE_UU_FWD;
6646       else if (unformat (i, "enable"))
6647         enable = 1;
6648       else if (unformat (i, "disable"))
6649         enable = 0;
6650       else
6651         break;
6652     }
6653
6654   if (rx_sw_if_index_set == 0)
6655     {
6656       errmsg ("missing rx interface name or sw_if_index");
6657       return -99;
6658     }
6659
6660   if (enable && (bd_id_set == 0))
6661     {
6662       errmsg ("missing bridge domain");
6663       return -99;
6664     }
6665
6666   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6667
6668   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6669   mp->bd_id = ntohl (bd_id);
6670   mp->shg = (u8) shg;
6671   mp->port_type = ntohl (port_type);
6672   mp->enable = enable;
6673
6674   S (mp);
6675   W (ret);
6676   return ret;
6677 }
6678
6679 static int
6680 api_bridge_domain_dump (vat_main_t * vam)
6681 {
6682   unformat_input_t *i = vam->input;
6683   vl_api_bridge_domain_dump_t *mp;
6684   vl_api_control_ping_t *mp_ping;
6685   u32 bd_id = ~0;
6686   int ret;
6687
6688   /* Parse args required to build the message */
6689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6690     {
6691       if (unformat (i, "bd_id %d", &bd_id))
6692         ;
6693       else
6694         break;
6695     }
6696
6697   M (BRIDGE_DOMAIN_DUMP, mp);
6698   mp->bd_id = ntohl (bd_id);
6699   S (mp);
6700
6701   /* Use a control ping for synchronization */
6702   MPING (CONTROL_PING, mp_ping);
6703   S (mp_ping);
6704
6705   W (ret);
6706   return ret;
6707 }
6708
6709 static int
6710 api_bridge_domain_add_del (vat_main_t * vam)
6711 {
6712   unformat_input_t *i = vam->input;
6713   vl_api_bridge_domain_add_del_t *mp;
6714   u32 bd_id = ~0;
6715   u8 is_add = 1;
6716   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6717   u8 *bd_tag = NULL;
6718   u32 mac_age = 0;
6719   int ret;
6720
6721   /* Parse args required to build the message */
6722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6723     {
6724       if (unformat (i, "bd_id %d", &bd_id))
6725         ;
6726       else if (unformat (i, "flood %d", &flood))
6727         ;
6728       else if (unformat (i, "uu-flood %d", &uu_flood))
6729         ;
6730       else if (unformat (i, "forward %d", &forward))
6731         ;
6732       else if (unformat (i, "learn %d", &learn))
6733         ;
6734       else if (unformat (i, "arp-term %d", &arp_term))
6735         ;
6736       else if (unformat (i, "mac-age %d", &mac_age))
6737         ;
6738       else if (unformat (i, "bd-tag %s", &bd_tag))
6739         ;
6740       else if (unformat (i, "del"))
6741         {
6742           is_add = 0;
6743           flood = uu_flood = forward = learn = 0;
6744         }
6745       else
6746         break;
6747     }
6748
6749   if (bd_id == ~0)
6750     {
6751       errmsg ("missing bridge domain");
6752       ret = -99;
6753       goto done;
6754     }
6755
6756   if (mac_age > 255)
6757     {
6758       errmsg ("mac age must be less than 256 ");
6759       ret = -99;
6760       goto done;
6761     }
6762
6763   if ((bd_tag) && (vec_len (bd_tag) > 63))
6764     {
6765       errmsg ("bd-tag cannot be longer than 63");
6766       ret = -99;
6767       goto done;
6768     }
6769
6770   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6771
6772   mp->bd_id = ntohl (bd_id);
6773   mp->flood = flood;
6774   mp->uu_flood = uu_flood;
6775   mp->forward = forward;
6776   mp->learn = learn;
6777   mp->arp_term = arp_term;
6778   mp->is_add = is_add;
6779   mp->mac_age = (u8) mac_age;
6780   if (bd_tag)
6781     {
6782       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6783       mp->bd_tag[vec_len (bd_tag)] = 0;
6784     }
6785   S (mp);
6786   W (ret);
6787
6788 done:
6789   vec_free (bd_tag);
6790   return ret;
6791 }
6792
6793 static int
6794 api_l2fib_flush_bd (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_l2fib_flush_bd_t *mp;
6798   u32 bd_id = ~0;
6799   int ret;
6800
6801   /* Parse args required to build the message */
6802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6803     {
6804       if (unformat (i, "bd_id %d", &bd_id));
6805       else
6806         break;
6807     }
6808
6809   if (bd_id == ~0)
6810     {
6811       errmsg ("missing bridge domain");
6812       return -99;
6813     }
6814
6815   M (L2FIB_FLUSH_BD, mp);
6816
6817   mp->bd_id = htonl (bd_id);
6818
6819   S (mp);
6820   W (ret);
6821   return ret;
6822 }
6823
6824 static int
6825 api_l2fib_flush_int (vat_main_t * vam)
6826 {
6827   unformat_input_t *i = vam->input;
6828   vl_api_l2fib_flush_int_t *mp;
6829   u32 sw_if_index = ~0;
6830   int ret;
6831
6832   /* Parse args required to build the message */
6833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6834     {
6835       if (unformat (i, "sw_if_index %d", &sw_if_index));
6836       else
6837         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6838       else
6839         break;
6840     }
6841
6842   if (sw_if_index == ~0)
6843     {
6844       errmsg ("missing interface name or sw_if_index");
6845       return -99;
6846     }
6847
6848   M (L2FIB_FLUSH_INT, mp);
6849
6850   mp->sw_if_index = ntohl (sw_if_index);
6851
6852   S (mp);
6853   W (ret);
6854   return ret;
6855 }
6856
6857 static int
6858 api_l2fib_add_del (vat_main_t * vam)
6859 {
6860   unformat_input_t *i = vam->input;
6861   vl_api_l2fib_add_del_t *mp;
6862   f64 timeout;
6863   u8 mac[6] = { 0 };
6864   u8 mac_set = 0;
6865   u32 bd_id;
6866   u8 bd_id_set = 0;
6867   u32 sw_if_index = 0;
6868   u8 sw_if_index_set = 0;
6869   u8 is_add = 1;
6870   u8 static_mac = 0;
6871   u8 filter_mac = 0;
6872   u8 bvi_mac = 0;
6873   int count = 1;
6874   f64 before = 0;
6875   int j;
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6881         mac_set = 1;
6882       else if (unformat (i, "bd_id %d", &bd_id))
6883         bd_id_set = 1;
6884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6885         sw_if_index_set = 1;
6886       else if (unformat (i, "sw_if"))
6887         {
6888           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6889             {
6890               if (unformat
6891                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6892                 sw_if_index_set = 1;
6893             }
6894           else
6895             break;
6896         }
6897       else if (unformat (i, "static"))
6898         static_mac = 1;
6899       else if (unformat (i, "filter"))
6900         {
6901           filter_mac = 1;
6902           static_mac = 1;
6903         }
6904       else if (unformat (i, "bvi"))
6905         {
6906           bvi_mac = 1;
6907           static_mac = 1;
6908         }
6909       else if (unformat (i, "del"))
6910         is_add = 0;
6911       else if (unformat (i, "count %d", &count))
6912         ;
6913       else
6914         break;
6915     }
6916
6917   if (mac_set == 0)
6918     {
6919       errmsg ("missing mac address");
6920       return -99;
6921     }
6922
6923   if (bd_id_set == 0)
6924     {
6925       errmsg ("missing bridge domain");
6926       return -99;
6927     }
6928
6929   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6930     {
6931       errmsg ("missing interface name or sw_if_index");
6932       return -99;
6933     }
6934
6935   if (count > 1)
6936     {
6937       /* Turn on async mode */
6938       vam->async_mode = 1;
6939       vam->async_errors = 0;
6940       before = vat_time_now (vam);
6941     }
6942
6943   for (j = 0; j < count; j++)
6944     {
6945       M (L2FIB_ADD_DEL, mp);
6946
6947       clib_memcpy (mp->mac, mac, 6);
6948       mp->bd_id = ntohl (bd_id);
6949       mp->is_add = is_add;
6950       mp->sw_if_index = ntohl (sw_if_index);
6951
6952       if (is_add)
6953         {
6954           mp->static_mac = static_mac;
6955           mp->filter_mac = filter_mac;
6956           mp->bvi_mac = bvi_mac;
6957         }
6958       increment_mac_address (mac);
6959       /* send it... */
6960       S (mp);
6961     }
6962
6963   if (count > 1)
6964     {
6965       vl_api_control_ping_t *mp_ping;
6966       f64 after;
6967
6968       /* Shut off async mode */
6969       vam->async_mode = 0;
6970
6971       MPING (CONTROL_PING, mp_ping);
6972       S (mp_ping);
6973
6974       timeout = vat_time_now (vam) + 1.0;
6975       while (vat_time_now (vam) < timeout)
6976         if (vam->result_ready == 1)
6977           goto out;
6978       vam->retval = -99;
6979
6980     out:
6981       if (vam->retval == -99)
6982         errmsg ("timeout");
6983
6984       if (vam->async_errors > 0)
6985         {
6986           errmsg ("%d asynchronous errors", vam->async_errors);
6987           vam->retval = -98;
6988         }
6989       vam->async_errors = 0;
6990       after = vat_time_now (vam);
6991
6992       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6993              count, after - before, count / (after - before));
6994     }
6995   else
6996     {
6997       int ret;
6998
6999       /* Wait for a reply... */
7000       W (ret);
7001       return ret;
7002     }
7003   /* Return the good/bad news */
7004   return (vam->retval);
7005 }
7006
7007 static int
7008 api_bridge_domain_set_mac_age (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_bridge_domain_set_mac_age_t *mp;
7012   u32 bd_id = ~0;
7013   u32 mac_age = 0;
7014   int ret;
7015
7016   /* Parse args required to build the message */
7017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018     {
7019       if (unformat (i, "bd_id %d", &bd_id));
7020       else if (unformat (i, "mac-age %d", &mac_age));
7021       else
7022         break;
7023     }
7024
7025   if (bd_id == ~0)
7026     {
7027       errmsg ("missing bridge domain");
7028       return -99;
7029     }
7030
7031   if (mac_age > 255)
7032     {
7033       errmsg ("mac age must be less than 256 ");
7034       return -99;
7035     }
7036
7037   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7038
7039   mp->bd_id = htonl (bd_id);
7040   mp->mac_age = (u8) mac_age;
7041
7042   S (mp);
7043   W (ret);
7044   return ret;
7045 }
7046
7047 static int
7048 api_l2_flags (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_l2_flags_t *mp;
7052   u32 sw_if_index;
7053   u32 flags = 0;
7054   u8 sw_if_index_set = 0;
7055   u8 is_set = 0;
7056   int ret;
7057
7058   /* Parse args required to build the message */
7059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7060     {
7061       if (unformat (i, "sw_if_index %d", &sw_if_index))
7062         sw_if_index_set = 1;
7063       else if (unformat (i, "sw_if"))
7064         {
7065           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7066             {
7067               if (unformat
7068                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7069                 sw_if_index_set = 1;
7070             }
7071           else
7072             break;
7073         }
7074       else if (unformat (i, "learn"))
7075         flags |= L2_LEARN;
7076       else if (unformat (i, "forward"))
7077         flags |= L2_FWD;
7078       else if (unformat (i, "flood"))
7079         flags |= L2_FLOOD;
7080       else if (unformat (i, "uu-flood"))
7081         flags |= L2_UU_FLOOD;
7082       else if (unformat (i, "arp-term"))
7083         flags |= L2_ARP_TERM;
7084       else if (unformat (i, "off"))
7085         is_set = 0;
7086       else if (unformat (i, "disable"))
7087         is_set = 0;
7088       else
7089         break;
7090     }
7091
7092   if (sw_if_index_set == 0)
7093     {
7094       errmsg ("missing interface name or sw_if_index");
7095       return -99;
7096     }
7097
7098   M (L2_FLAGS, mp);
7099
7100   mp->sw_if_index = ntohl (sw_if_index);
7101   mp->feature_bitmap = ntohl (flags);
7102   mp->is_set = is_set;
7103
7104   S (mp);
7105   W (ret);
7106   return ret;
7107 }
7108
7109 static int
7110 api_bridge_flags (vat_main_t * vam)
7111 {
7112   unformat_input_t *i = vam->input;
7113   vl_api_bridge_flags_t *mp;
7114   u32 bd_id;
7115   u8 bd_id_set = 0;
7116   u8 is_set = 1;
7117   bd_flags_t flags = 0;
7118   int ret;
7119
7120   /* Parse args required to build the message */
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "bd_id %d", &bd_id))
7124         bd_id_set = 1;
7125       else if (unformat (i, "learn"))
7126         flags |= BRIDGE_API_FLAG_LEARN;
7127       else if (unformat (i, "forward"))
7128         flags |= BRIDGE_API_FLAG_FWD;
7129       else if (unformat (i, "flood"))
7130         flags |= BRIDGE_API_FLAG_FLOOD;
7131       else if (unformat (i, "uu-flood"))
7132         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7133       else if (unformat (i, "arp-term"))
7134         flags |= BRIDGE_API_FLAG_ARP_TERM;
7135       else if (unformat (i, "off"))
7136         is_set = 0;
7137       else if (unformat (i, "disable"))
7138         is_set = 0;
7139       else
7140         break;
7141     }
7142
7143   if (bd_id_set == 0)
7144     {
7145       errmsg ("missing bridge domain");
7146       return -99;
7147     }
7148
7149   M (BRIDGE_FLAGS, mp);
7150
7151   mp->bd_id = ntohl (bd_id);
7152   mp->flags = ntohl (flags);
7153   mp->is_set = is_set;
7154
7155   S (mp);
7156   W (ret);
7157   return ret;
7158 }
7159
7160 static int
7161 api_bd_ip_mac_add_del (vat_main_t * vam)
7162 {
7163   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7164   vl_api_mac_address_t mac = { 0 };
7165   unformat_input_t *i = vam->input;
7166   vl_api_bd_ip_mac_add_del_t *mp;
7167   u32 bd_id;
7168   u8 is_add = 1;
7169   u8 bd_id_set = 0;
7170   u8 ip_set = 0;
7171   u8 mac_set = 0;
7172   int ret;
7173
7174
7175   /* Parse args required to build the message */
7176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7177     {
7178       if (unformat (i, "bd_id %d", &bd_id))
7179         {
7180           bd_id_set++;
7181         }
7182       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7183         {
7184           ip_set++;
7185         }
7186       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7187         {
7188           mac_set++;
7189         }
7190       else if (unformat (i, "del"))
7191         is_add = 0;
7192       else
7193         break;
7194     }
7195
7196   if (bd_id_set == 0)
7197     {
7198       errmsg ("missing bridge domain");
7199       return -99;
7200     }
7201   else if (ip_set == 0)
7202     {
7203       errmsg ("missing IP address");
7204       return -99;
7205     }
7206   else if (mac_set == 0)
7207     {
7208       errmsg ("missing MAC address");
7209       return -99;
7210     }
7211
7212   M (BD_IP_MAC_ADD_DEL, mp);
7213
7214   mp->entry.bd_id = ntohl (bd_id);
7215   mp->is_add = is_add;
7216
7217   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7218   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7219
7220   S (mp);
7221   W (ret);
7222   return ret;
7223 }
7224
7225 static int
7226 api_bd_ip_mac_flush (vat_main_t * vam)
7227 {
7228   unformat_input_t *i = vam->input;
7229   vl_api_bd_ip_mac_flush_t *mp;
7230   u32 bd_id;
7231   u8 bd_id_set = 0;
7232   int ret;
7233
7234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7235     {
7236       if (unformat (i, "bd_id %d", &bd_id))
7237         {
7238           bd_id_set++;
7239         }
7240       else
7241         break;
7242     }
7243
7244   if (bd_id_set == 0)
7245     {
7246       errmsg ("missing bridge domain");
7247       return -99;
7248     }
7249
7250   M (BD_IP_MAC_FLUSH, mp);
7251
7252   mp->bd_id = ntohl (bd_id);
7253
7254   S (mp);
7255   W (ret);
7256   return ret;
7257 }
7258
7259 static void vl_api_bd_ip_mac_details_t_handler
7260   (vl_api_bd_ip_mac_details_t * mp)
7261 {
7262   vat_main_t *vam = &vat_main;
7263
7264   print (vam->ofp,
7265          "\n%-5d %U %U",
7266          ntohl (mp->entry.bd_id),
7267          format_vl_api_mac_address, mp->entry.mac,
7268          format_vl_api_address, &mp->entry.ip);
7269 }
7270
7271 static void vl_api_bd_ip_mac_details_t_handler_json
7272   (vl_api_bd_ip_mac_details_t * mp)
7273 {
7274   vat_main_t *vam = &vat_main;
7275   vat_json_node_t *node = NULL;
7276
7277   if (VAT_JSON_ARRAY != vam->json_tree.type)
7278     {
7279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7280       vat_json_init_array (&vam->json_tree);
7281     }
7282   node = vat_json_array_add (&vam->json_tree);
7283
7284   vat_json_init_object (node);
7285   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7286   vat_json_object_add_string_copy (node, "mac_address",
7287                                    format (0, "%U", format_vl_api_mac_address,
7288                                            &mp->entry.mac));
7289   u8 *ip = 0;
7290
7291   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7292   vat_json_object_add_string_copy (node, "ip_address", ip);
7293   vec_free (ip);
7294 }
7295
7296 static int
7297 api_bd_ip_mac_dump (vat_main_t * vam)
7298 {
7299   unformat_input_t *i = vam->input;
7300   vl_api_bd_ip_mac_dump_t *mp;
7301   vl_api_control_ping_t *mp_ping;
7302   int ret;
7303   u32 bd_id;
7304   u8 bd_id_set = 0;
7305
7306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7307     {
7308       if (unformat (i, "bd_id %d", &bd_id))
7309         {
7310           bd_id_set++;
7311         }
7312       else
7313         break;
7314     }
7315
7316   print (vam->ofp,
7317          "\n%-5s %-7s %-20s %-30s",
7318          "bd_id", "is_ipv6", "mac_address", "ip_address");
7319
7320   /* Dump Bridge Domain Ip to Mac entries */
7321   M (BD_IP_MAC_DUMP, mp);
7322
7323   if (bd_id_set)
7324     mp->bd_id = htonl (bd_id);
7325   else
7326     mp->bd_id = ~0;
7327
7328   S (mp);
7329
7330   /* Use a control ping for synchronization */
7331   MPING (CONTROL_PING, mp_ping);
7332   S (mp_ping);
7333
7334   W (ret);
7335   return ret;
7336 }
7337
7338 static int
7339 api_tap_create_v2 (vat_main_t * vam)
7340 {
7341   unformat_input_t *i = vam->input;
7342   vl_api_tap_create_v2_t *mp;
7343 #define TAP_FLAG_GSO (1 << 0)
7344   u8 mac_address[6];
7345   u8 random_mac = 1;
7346   u32 id = ~0;
7347   u8 *host_if_name = 0;
7348   u8 *host_ns = 0;
7349   u8 host_mac_addr[6];
7350   u8 host_mac_addr_set = 0;
7351   u8 *host_bridge = 0;
7352   ip4_address_t host_ip4_addr;
7353   ip4_address_t host_ip4_gw;
7354   u8 host_ip4_gw_set = 0;
7355   u32 host_ip4_prefix_len = 0;
7356   ip6_address_t host_ip6_addr;
7357   ip6_address_t host_ip6_gw;
7358   u8 host_ip6_gw_set = 0;
7359   u32 host_ip6_prefix_len = 0;
7360   u8 host_mtu_set = 0;
7361   u32 host_mtu_size = 0;
7362   u32 tap_flags = 0;
7363   int ret;
7364   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7365
7366   clib_memset (mac_address, 0, sizeof (mac_address));
7367
7368   /* Parse args required to build the message */
7369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7370     {
7371       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7372         {
7373           random_mac = 0;
7374         }
7375       else if (unformat (i, "id %u", &id))
7376         ;
7377       else if (unformat (i, "host-if-name %s", &host_if_name))
7378         ;
7379       else if (unformat (i, "host-ns %s", &host_ns))
7380         ;
7381       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7382                          host_mac_addr))
7383         host_mac_addr_set = 1;
7384       else if (unformat (i, "host-bridge %s", &host_bridge))
7385         ;
7386       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7387                          &host_ip4_addr, &host_ip4_prefix_len))
7388         ;
7389       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7390                          &host_ip6_addr, &host_ip6_prefix_len))
7391         ;
7392       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7393                          &host_ip4_gw))
7394         host_ip4_gw_set = 1;
7395       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7396                          &host_ip6_gw))
7397         host_ip6_gw_set = 1;
7398       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7399         ;
7400       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7401         ;
7402       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7403         host_mtu_set = 1;
7404       else if (unformat (i, "no-gso"))
7405         tap_flags &= ~TAP_FLAG_GSO;
7406       else if (unformat (i, "gso"))
7407         tap_flags |= TAP_FLAG_GSO;
7408       else
7409         break;
7410     }
7411
7412   if (vec_len (host_if_name) > 63)
7413     {
7414       errmsg ("tap name too long. ");
7415       return -99;
7416     }
7417   if (vec_len (host_ns) > 63)
7418     {
7419       errmsg ("host name space too long. ");
7420       return -99;
7421     }
7422   if (vec_len (host_bridge) > 63)
7423     {
7424       errmsg ("host bridge name too long. ");
7425       return -99;
7426     }
7427   if (host_ip4_prefix_len > 32)
7428     {
7429       errmsg ("host ip4 prefix length not valid. ");
7430       return -99;
7431     }
7432   if (host_ip6_prefix_len > 128)
7433     {
7434       errmsg ("host ip6 prefix length not valid. ");
7435       return -99;
7436     }
7437   if (!is_pow2 (rx_ring_sz))
7438     {
7439       errmsg ("rx ring size must be power of 2. ");
7440       return -99;
7441     }
7442   if (rx_ring_sz > 32768)
7443     {
7444       errmsg ("rx ring size must be 32768 or lower. ");
7445       return -99;
7446     }
7447   if (!is_pow2 (tx_ring_sz))
7448     {
7449       errmsg ("tx ring size must be power of 2. ");
7450       return -99;
7451     }
7452   if (tx_ring_sz > 32768)
7453     {
7454       errmsg ("tx ring size must be 32768 or lower. ");
7455       return -99;
7456     }
7457   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7458     {
7459       errmsg ("host MTU size must be in between 64 and 65355. ");
7460       return -99;
7461     }
7462
7463   /* Construct the API message */
7464   M (TAP_CREATE_V2, mp);
7465
7466   mp->use_random_mac = random_mac;
7467
7468   mp->id = ntohl (id);
7469   mp->host_namespace_set = host_ns != 0;
7470   mp->host_bridge_set = host_bridge != 0;
7471   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7472   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7473   mp->rx_ring_sz = ntohs (rx_ring_sz);
7474   mp->tx_ring_sz = ntohs (tx_ring_sz);
7475   mp->host_mtu_set = host_mtu_set;
7476   mp->host_mtu_size = ntohl (host_mtu_size);
7477   mp->tap_flags = ntohl (tap_flags);
7478
7479   if (random_mac == 0)
7480     clib_memcpy (mp->mac_address, mac_address, 6);
7481   if (host_mac_addr_set)
7482     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7483   if (host_if_name)
7484     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7485   if (host_ns)
7486     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7487   if (host_bridge)
7488     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7489   if (host_ip4_prefix_len)
7490     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7491   if (host_ip6_prefix_len)
7492     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7493   if (host_ip4_gw_set)
7494     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7495   if (host_ip6_gw_set)
7496     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7497
7498   vec_free (host_ns);
7499   vec_free (host_if_name);
7500   vec_free (host_bridge);
7501
7502   /* send it... */
7503   S (mp);
7504
7505   /* Wait for a reply... */
7506   W (ret);
7507   return ret;
7508 }
7509
7510 static int
7511 api_tap_delete_v2 (vat_main_t * vam)
7512 {
7513   unformat_input_t *i = vam->input;
7514   vl_api_tap_delete_v2_t *mp;
7515   u32 sw_if_index = ~0;
7516   u8 sw_if_index_set = 0;
7517   int ret;
7518
7519   /* Parse args required to build the message */
7520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7521     {
7522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7523         sw_if_index_set = 1;
7524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7525         sw_if_index_set = 1;
7526       else
7527         break;
7528     }
7529
7530   if (sw_if_index_set == 0)
7531     {
7532       errmsg ("missing vpp interface name. ");
7533       return -99;
7534     }
7535
7536   /* Construct the API message */
7537   M (TAP_DELETE_V2, mp);
7538
7539   mp->sw_if_index = ntohl (sw_if_index);
7540
7541   /* send it... */
7542   S (mp);
7543
7544   /* Wait for a reply... */
7545   W (ret);
7546   return ret;
7547 }
7548
7549 uword
7550 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7551 {
7552   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7553   u32 x[4];
7554
7555   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7556     return 0;
7557
7558   addr->domain = x[0];
7559   addr->bus = x[1];
7560   addr->slot = x[2];
7561   addr->function = x[3];
7562
7563   return 1;
7564 }
7565
7566 static int
7567 api_virtio_pci_create (vat_main_t * vam)
7568 {
7569   unformat_input_t *i = vam->input;
7570   vl_api_virtio_pci_create_t *mp;
7571   u8 mac_address[6];
7572   u8 random_mac = 1;
7573   u8 gso_enabled = 0;
7574   u32 pci_addr = 0;
7575   u64 features = (u64) ~ (0ULL);
7576   int ret;
7577
7578   clib_memset (mac_address, 0, sizeof (mac_address));
7579
7580   /* Parse args required to build the message */
7581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7582     {
7583       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7584         {
7585           random_mac = 0;
7586         }
7587       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7588         ;
7589       else if (unformat (i, "features 0x%llx", &features))
7590         ;
7591       else if (unformat (i, "gso-enabled"))
7592         gso_enabled = 1;
7593       else
7594         break;
7595     }
7596
7597   if (pci_addr == 0)
7598     {
7599       errmsg ("pci address must be non zero. ");
7600       return -99;
7601     }
7602
7603   /* Construct the API message */
7604   M (VIRTIO_PCI_CREATE, mp);
7605
7606   mp->use_random_mac = random_mac;
7607
7608   mp->pci_addr = htonl (pci_addr);
7609   mp->features = clib_host_to_net_u64 (features);
7610   mp->gso_enabled = gso_enabled;
7611
7612   if (random_mac == 0)
7613     clib_memcpy (mp->mac_address, mac_address, 6);
7614
7615   /* send it... */
7616   S (mp);
7617
7618   /* Wait for a reply... */
7619   W (ret);
7620   return ret;
7621 }
7622
7623 static int
7624 api_virtio_pci_delete (vat_main_t * vam)
7625 {
7626   unformat_input_t *i = vam->input;
7627   vl_api_virtio_pci_delete_t *mp;
7628   u32 sw_if_index = ~0;
7629   u8 sw_if_index_set = 0;
7630   int ret;
7631
7632   /* Parse args required to build the message */
7633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7634     {
7635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7636         sw_if_index_set = 1;
7637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7638         sw_if_index_set = 1;
7639       else
7640         break;
7641     }
7642
7643   if (sw_if_index_set == 0)
7644     {
7645       errmsg ("missing vpp interface name. ");
7646       return -99;
7647     }
7648
7649   /* Construct the API message */
7650   M (VIRTIO_PCI_DELETE, mp);
7651
7652   mp->sw_if_index = htonl (sw_if_index);
7653
7654   /* send it... */
7655   S (mp);
7656
7657   /* Wait for a reply... */
7658   W (ret);
7659   return ret;
7660 }
7661
7662 static int
7663 api_bond_create (vat_main_t * vam)
7664 {
7665   unformat_input_t *i = vam->input;
7666   vl_api_bond_create_t *mp;
7667   u8 mac_address[6];
7668   u8 custom_mac = 0;
7669   int ret;
7670   u8 mode;
7671   u8 lb;
7672   u8 mode_is_set = 0;
7673   u32 id = ~0;
7674   u8 numa_only = 0;
7675
7676   clib_memset (mac_address, 0, sizeof (mac_address));
7677   lb = BOND_LB_L2;
7678
7679   /* Parse args required to build the message */
7680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7681     {
7682       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7683         mode_is_set = 1;
7684       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7685                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7686         ;
7687       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7688                          mac_address))
7689         custom_mac = 1;
7690       else if (unformat (i, "numa-only"))
7691         numa_only = 1;
7692       else if (unformat (i, "id %u", &id))
7693         ;
7694       else
7695         break;
7696     }
7697
7698   if (mode_is_set == 0)
7699     {
7700       errmsg ("Missing bond mode. ");
7701       return -99;
7702     }
7703
7704   /* Construct the API message */
7705   M (BOND_CREATE, mp);
7706
7707   mp->use_custom_mac = custom_mac;
7708
7709   mp->mode = htonl (mode);
7710   mp->lb = htonl (lb);
7711   mp->id = htonl (id);
7712   mp->numa_only = numa_only;
7713
7714   if (custom_mac)
7715     clib_memcpy (mp->mac_address, mac_address, 6);
7716
7717   /* send it... */
7718   S (mp);
7719
7720   /* Wait for a reply... */
7721   W (ret);
7722   return ret;
7723 }
7724
7725 static int
7726 api_bond_delete (vat_main_t * vam)
7727 {
7728   unformat_input_t *i = vam->input;
7729   vl_api_bond_delete_t *mp;
7730   u32 sw_if_index = ~0;
7731   u8 sw_if_index_set = 0;
7732   int ret;
7733
7734   /* Parse args required to build the message */
7735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7736     {
7737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7738         sw_if_index_set = 1;
7739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7740         sw_if_index_set = 1;
7741       else
7742         break;
7743     }
7744
7745   if (sw_if_index_set == 0)
7746     {
7747       errmsg ("missing vpp interface name. ");
7748       return -99;
7749     }
7750
7751   /* Construct the API message */
7752   M (BOND_DELETE, mp);
7753
7754   mp->sw_if_index = ntohl (sw_if_index);
7755
7756   /* send it... */
7757   S (mp);
7758
7759   /* Wait for a reply... */
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_bond_enslave (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_bond_enslave_t *mp;
7769   u32 bond_sw_if_index;
7770   int ret;
7771   u8 is_passive;
7772   u8 is_long_timeout;
7773   u32 bond_sw_if_index_is_set = 0;
7774   u32 sw_if_index;
7775   u8 sw_if_index_is_set = 0;
7776
7777   /* Parse args required to build the message */
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "sw_if_index %d", &sw_if_index))
7781         sw_if_index_is_set = 1;
7782       else if (unformat (i, "bond %u", &bond_sw_if_index))
7783         bond_sw_if_index_is_set = 1;
7784       else if (unformat (i, "passive %d", &is_passive))
7785         ;
7786       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7787         ;
7788       else
7789         break;
7790     }
7791
7792   if (bond_sw_if_index_is_set == 0)
7793     {
7794       errmsg ("Missing bond sw_if_index. ");
7795       return -99;
7796     }
7797   if (sw_if_index_is_set == 0)
7798     {
7799       errmsg ("Missing slave sw_if_index. ");
7800       return -99;
7801     }
7802
7803   /* Construct the API message */
7804   M (BOND_ENSLAVE, mp);
7805
7806   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7807   mp->sw_if_index = ntohl (sw_if_index);
7808   mp->is_long_timeout = is_long_timeout;
7809   mp->is_passive = is_passive;
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply... */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_bond_detach_slave (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_bond_detach_slave_t *mp;
7824   u32 sw_if_index = ~0;
7825   u8 sw_if_index_set = 0;
7826   int ret;
7827
7828   /* Parse args required to build the message */
7829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7832         sw_if_index_set = 1;
7833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7834         sw_if_index_set = 1;
7835       else
7836         break;
7837     }
7838
7839   if (sw_if_index_set == 0)
7840     {
7841       errmsg ("missing vpp interface name. ");
7842       return -99;
7843     }
7844
7845   /* Construct the API message */
7846   M (BOND_DETACH_SLAVE, mp);
7847
7848   mp->sw_if_index = ntohl (sw_if_index);
7849
7850   /* send it... */
7851   S (mp);
7852
7853   /* Wait for a reply... */
7854   W (ret);
7855   return ret;
7856 }
7857
7858 static int
7859 api_ip_table_add_del (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_ip_table_add_del_t *mp;
7863   u32 table_id = ~0;
7864   u8 is_ipv6 = 0;
7865   u8 is_add = 1;
7866   int ret = 0;
7867
7868   /* Parse args required to build the message */
7869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7870     {
7871       if (unformat (i, "ipv6"))
7872         is_ipv6 = 1;
7873       else if (unformat (i, "del"))
7874         is_add = 0;
7875       else if (unformat (i, "add"))
7876         is_add = 1;
7877       else if (unformat (i, "table %d", &table_id))
7878         ;
7879       else
7880         {
7881           clib_warning ("parse error '%U'", format_unformat_error, i);
7882           return -99;
7883         }
7884     }
7885
7886   if (~0 == table_id)
7887     {
7888       errmsg ("missing table-ID");
7889       return -99;
7890     }
7891
7892   /* Construct the API message */
7893   M (IP_TABLE_ADD_DEL, mp);
7894
7895   mp->table.table_id = ntohl (table_id);
7896   mp->table.is_ip6 = is_ipv6;
7897   mp->is_add = is_add;
7898
7899   /* send it... */
7900   S (mp);
7901
7902   /* Wait for a reply... */
7903   W (ret);
7904
7905   return ret;
7906 }
7907
7908 uword
7909 unformat_fib_path (unformat_input_t * input, va_list * args)
7910 {
7911   vat_main_t *vam = va_arg (*args, vat_main_t *);
7912   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7913   u32 weight, preference;
7914   mpls_label_t out_label;
7915
7916   clib_memset (path, 0, sizeof (*path));
7917   path->weight = 1;
7918   path->sw_if_index = ~0;
7919   path->rpf_id = ~0;
7920   path->n_labels = 0;
7921
7922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7923     {
7924       if (unformat (input, "%U %U",
7925                     unformat_vl_api_ip4_address,
7926                     &path->nh.address.ip4,
7927                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7928         {
7929           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7930         }
7931       else if (unformat (input, "%U %U",
7932                          unformat_vl_api_ip6_address,
7933                          &path->nh.address.ip6,
7934                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7935         {
7936           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7937         }
7938       else if (unformat (input, "weight %u", &weight))
7939         {
7940           path->weight = weight;
7941         }
7942       else if (unformat (input, "preference %u", &preference))
7943         {
7944           path->preference = preference;
7945         }
7946       else if (unformat (input, "%U next-hop-table %d",
7947                          unformat_vl_api_ip4_address,
7948                          &path->nh.address.ip4, &path->table_id))
7949         {
7950           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7951         }
7952       else if (unformat (input, "%U next-hop-table %d",
7953                          unformat_vl_api_ip6_address,
7954                          &path->nh.address.ip6, &path->table_id))
7955         {
7956           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7957         }
7958       else if (unformat (input, "%U",
7959                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7960         {
7961           /*
7962            * the recursive next-hops are by default in the default table
7963            */
7964           path->table_id = 0;
7965           path->sw_if_index = ~0;
7966           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7967         }
7968       else if (unformat (input, "%U",
7969                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7970         {
7971           /*
7972            * the recursive next-hops are by default in the default table
7973            */
7974           path->table_id = 0;
7975           path->sw_if_index = ~0;
7976           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7977         }
7978       else if (unformat (input, "resolve-via-host"))
7979         {
7980           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7981         }
7982       else if (unformat (input, "resolve-via-attached"))
7983         {
7984           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7985         }
7986       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7987         {
7988           path->type = FIB_API_PATH_TYPE_LOCAL;
7989           path->sw_if_index = ~0;
7990           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7991         }
7992       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7993         {
7994           path->type = FIB_API_PATH_TYPE_LOCAL;
7995           path->sw_if_index = ~0;
7996           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7997         }
7998       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7999         ;
8000       else if (unformat (input, "via-label %d", &path->nh.via_label))
8001         {
8002           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8003           path->sw_if_index = ~0;
8004         }
8005       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8006         {
8007           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8008           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8009         }
8010       else if (unformat (input, "local"))
8011         {
8012           path->type = FIB_API_PATH_TYPE_LOCAL;
8013         }
8014       else if (unformat (input, "out-labels"))
8015         {
8016           while (unformat (input, "%d", &out_label))
8017             {
8018               path->label_stack[path->n_labels].label = out_label;
8019               path->label_stack[path->n_labels].is_uniform = 0;
8020               path->label_stack[path->n_labels].ttl = 64;
8021               path->n_labels++;
8022             }
8023         }
8024       else if (unformat (input, "via"))
8025         {
8026           /* new path, back up and return */
8027           unformat_put_input (input);
8028           unformat_put_input (input);
8029           unformat_put_input (input);
8030           unformat_put_input (input);
8031           break;
8032         }
8033       else
8034         {
8035           return (0);
8036         }
8037     }
8038
8039   path->proto = ntohl (path->proto);
8040   path->type = ntohl (path->type);
8041   path->flags = ntohl (path->flags);
8042   path->table_id = ntohl (path->table_id);
8043   path->sw_if_index = ntohl (path->sw_if_index);
8044
8045   return (1);
8046 }
8047
8048 static int
8049 api_ip_route_add_del (vat_main_t * vam)
8050 {
8051   unformat_input_t *i = vam->input;
8052   vl_api_ip_route_add_del_t *mp;
8053   u32 vrf_id = 0;
8054   u8 is_add = 1;
8055   u8 is_multipath = 0;
8056   u8 prefix_set = 0;
8057   u8 path_count = 0;
8058   vl_api_prefix_t pfx = { };
8059   vl_api_fib_path_t paths[8];
8060   int count = 1;
8061   int j;
8062   f64 before = 0;
8063   u32 random_add_del = 0;
8064   u32 *random_vector = 0;
8065   u32 random_seed = 0xdeaddabe;
8066
8067   /* Parse args required to build the message */
8068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8069     {
8070       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8071         prefix_set = 1;
8072       else if (unformat (i, "del"))
8073         is_add = 0;
8074       else if (unformat (i, "add"))
8075         is_add = 1;
8076       else if (unformat (i, "vrf %d", &vrf_id))
8077         ;
8078       else if (unformat (i, "count %d", &count))
8079         ;
8080       else if (unformat (i, "random"))
8081         random_add_del = 1;
8082       else if (unformat (i, "multipath"))
8083         is_multipath = 1;
8084       else if (unformat (i, "seed %d", &random_seed))
8085         ;
8086       else
8087         if (unformat
8088             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8089         {
8090           path_count++;
8091           if (8 == path_count)
8092             {
8093               errmsg ("max 8 paths");
8094               return -99;
8095             }
8096         }
8097       else
8098         {
8099           clib_warning ("parse error '%U'", format_unformat_error, i);
8100           return -99;
8101         }
8102     }
8103
8104   if (!path_count)
8105     {
8106       errmsg ("specify a path; via ...");
8107       return -99;
8108     }
8109   if (prefix_set == 0)
8110     {
8111       errmsg ("missing prefix");
8112       return -99;
8113     }
8114
8115   /* Generate a pile of unique, random routes */
8116   if (random_add_del)
8117     {
8118       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8119       u32 this_random_address;
8120       uword *random_hash;
8121
8122       random_hash = hash_create (count, sizeof (uword));
8123
8124       hash_set (random_hash, i->as_u32, 1);
8125       for (j = 0; j <= count; j++)
8126         {
8127           do
8128             {
8129               this_random_address = random_u32 (&random_seed);
8130               this_random_address =
8131                 clib_host_to_net_u32 (this_random_address);
8132             }
8133           while (hash_get (random_hash, this_random_address));
8134           vec_add1 (random_vector, this_random_address);
8135           hash_set (random_hash, this_random_address, 1);
8136         }
8137       hash_free (random_hash);
8138       set_ip4_address (&pfx.address, random_vector[0]);
8139     }
8140
8141   if (count > 1)
8142     {
8143       /* Turn on async mode */
8144       vam->async_mode = 1;
8145       vam->async_errors = 0;
8146       before = vat_time_now (vam);
8147     }
8148
8149   for (j = 0; j < count; j++)
8150     {
8151       /* Construct the API message */
8152       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8153
8154       mp->is_add = is_add;
8155       mp->is_multipath = is_multipath;
8156
8157       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8158       mp->route.table_id = ntohl (vrf_id);
8159       mp->route.n_paths = path_count;
8160
8161       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8162
8163       if (random_add_del)
8164         set_ip4_address (&pfx.address, random_vector[j + 1]);
8165       else
8166         increment_address (&pfx.address);
8167       /* send it... */
8168       S (mp);
8169       /* If we receive SIGTERM, stop now... */
8170       if (vam->do_exit)
8171         break;
8172     }
8173
8174   /* When testing multiple add/del ops, use a control-ping to sync */
8175   if (count > 1)
8176     {
8177       vl_api_control_ping_t *mp_ping;
8178       f64 after;
8179       f64 timeout;
8180
8181       /* Shut off async mode */
8182       vam->async_mode = 0;
8183
8184       MPING (CONTROL_PING, mp_ping);
8185       S (mp_ping);
8186
8187       timeout = vat_time_now (vam) + 1.0;
8188       while (vat_time_now (vam) < timeout)
8189         if (vam->result_ready == 1)
8190           goto out;
8191       vam->retval = -99;
8192
8193     out:
8194       if (vam->retval == -99)
8195         errmsg ("timeout");
8196
8197       if (vam->async_errors > 0)
8198         {
8199           errmsg ("%d asynchronous errors", vam->async_errors);
8200           vam->retval = -98;
8201         }
8202       vam->async_errors = 0;
8203       after = vat_time_now (vam);
8204
8205       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8206       if (j > 0)
8207         count = j;
8208
8209       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8210              count, after - before, count / (after - before));
8211     }
8212   else
8213     {
8214       int ret;
8215
8216       /* Wait for a reply... */
8217       W (ret);
8218       return ret;
8219     }
8220
8221   /* Return the good/bad news */
8222   return (vam->retval);
8223 }
8224
8225 static int
8226 api_ip_mroute_add_del (vat_main_t * vam)
8227 {
8228   unformat_input_t *i = vam->input;
8229   u8 path_set = 0, prefix_set = 0, is_add = 1;
8230   vl_api_ip_mroute_add_del_t *mp;
8231   mfib_entry_flags_t eflags = 0;
8232   vl_api_mfib_path_t path;
8233   vl_api_mprefix_t pfx = { };
8234   u32 vrf_id = 0;
8235   int ret;
8236
8237   /* Parse args required to build the message */
8238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8239     {
8240       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8241         {
8242           prefix_set = 1;
8243           pfx.grp_address_length = htons (pfx.grp_address_length);
8244         }
8245       else if (unformat (i, "del"))
8246         is_add = 0;
8247       else if (unformat (i, "add"))
8248         is_add = 1;
8249       else if (unformat (i, "vrf %d", &vrf_id))
8250         ;
8251       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8252         path.itf_flags = htonl (path.itf_flags);
8253       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8254         ;
8255       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8256         path_set = 1;
8257       else
8258         {
8259           clib_warning ("parse error '%U'", format_unformat_error, i);
8260           return -99;
8261         }
8262     }
8263
8264   if (prefix_set == 0)
8265     {
8266       errmsg ("missing addresses\n");
8267       return -99;
8268     }
8269   if (path_set == 0)
8270     {
8271       errmsg ("missing path\n");
8272       return -99;
8273     }
8274
8275   /* Construct the API message */
8276   M (IP_MROUTE_ADD_DEL, mp);
8277
8278   mp->is_add = is_add;
8279   mp->is_multipath = 1;
8280
8281   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8282   mp->route.table_id = htonl (vrf_id);
8283   mp->route.n_paths = 1;
8284   mp->route.entry_flags = htonl (eflags);
8285
8286   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8287
8288   /* send it... */
8289   S (mp);
8290   /* Wait for a reply... */
8291   W (ret);
8292   return ret;
8293 }
8294
8295 static int
8296 api_mpls_table_add_del (vat_main_t * vam)
8297 {
8298   unformat_input_t *i = vam->input;
8299   vl_api_mpls_table_add_del_t *mp;
8300   u32 table_id = ~0;
8301   u8 is_add = 1;
8302   int ret = 0;
8303
8304   /* Parse args required to build the message */
8305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8306     {
8307       if (unformat (i, "table %d", &table_id))
8308         ;
8309       else if (unformat (i, "del"))
8310         is_add = 0;
8311       else if (unformat (i, "add"))
8312         is_add = 1;
8313       else
8314         {
8315           clib_warning ("parse error '%U'", format_unformat_error, i);
8316           return -99;
8317         }
8318     }
8319
8320   if (~0 == table_id)
8321     {
8322       errmsg ("missing table-ID");
8323       return -99;
8324     }
8325
8326   /* Construct the API message */
8327   M (MPLS_TABLE_ADD_DEL, mp);
8328
8329   mp->mt_table.mt_table_id = ntohl (table_id);
8330   mp->mt_is_add = is_add;
8331
8332   /* send it... */
8333   S (mp);
8334
8335   /* Wait for a reply... */
8336   W (ret);
8337
8338   return ret;
8339 }
8340
8341 static int
8342 api_mpls_route_add_del (vat_main_t * vam)
8343 {
8344   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8345   mpls_label_t local_label = MPLS_LABEL_INVALID;
8346   unformat_input_t *i = vam->input;
8347   vl_api_mpls_route_add_del_t *mp;
8348   vl_api_fib_path_t paths[8];
8349   int count = 1, j;
8350   f64 before = 0;
8351
8352   /* Parse args required to build the message */
8353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8354     {
8355       if (unformat (i, "%d", &local_label))
8356         ;
8357       else if (unformat (i, "eos"))
8358         is_eos = 1;
8359       else if (unformat (i, "non-eos"))
8360         is_eos = 0;
8361       else if (unformat (i, "del"))
8362         is_add = 0;
8363       else if (unformat (i, "add"))
8364         is_add = 1;
8365       else if (unformat (i, "multipath"))
8366         is_multipath = 1;
8367       else if (unformat (i, "count %d", &count))
8368         ;
8369       else
8370         if (unformat
8371             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8372         {
8373           path_count++;
8374           if (8 == path_count)
8375             {
8376               errmsg ("max 8 paths");
8377               return -99;
8378             }
8379         }
8380       else
8381         {
8382           clib_warning ("parse error '%U'", format_unformat_error, i);
8383           return -99;
8384         }
8385     }
8386
8387   if (!path_count)
8388     {
8389       errmsg ("specify a path; via ...");
8390       return -99;
8391     }
8392
8393   if (MPLS_LABEL_INVALID == local_label)
8394     {
8395       errmsg ("missing label");
8396       return -99;
8397     }
8398
8399   if (count > 1)
8400     {
8401       /* Turn on async mode */
8402       vam->async_mode = 1;
8403       vam->async_errors = 0;
8404       before = vat_time_now (vam);
8405     }
8406
8407   for (j = 0; j < count; j++)
8408     {
8409       /* Construct the API message */
8410       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8411
8412       mp->mr_is_add = is_add;
8413       mp->mr_is_multipath = is_multipath;
8414
8415       mp->mr_route.mr_label = local_label;
8416       mp->mr_route.mr_eos = is_eos;
8417       mp->mr_route.mr_table_id = 0;
8418       mp->mr_route.mr_n_paths = path_count;
8419
8420       clib_memcpy (&mp->mr_route.mr_paths, paths,
8421                    sizeof (paths[0]) * path_count);
8422
8423       local_label++;
8424
8425       /* send it... */
8426       S (mp);
8427       /* If we receive SIGTERM, stop now... */
8428       if (vam->do_exit)
8429         break;
8430     }
8431
8432   /* When testing multiple add/del ops, use a control-ping to sync */
8433   if (count > 1)
8434     {
8435       vl_api_control_ping_t *mp_ping;
8436       f64 after;
8437       f64 timeout;
8438
8439       /* Shut off async mode */
8440       vam->async_mode = 0;
8441
8442       MPING (CONTROL_PING, mp_ping);
8443       S (mp_ping);
8444
8445       timeout = vat_time_now (vam) + 1.0;
8446       while (vat_time_now (vam) < timeout)
8447         if (vam->result_ready == 1)
8448           goto out;
8449       vam->retval = -99;
8450
8451     out:
8452       if (vam->retval == -99)
8453         errmsg ("timeout");
8454
8455       if (vam->async_errors > 0)
8456         {
8457           errmsg ("%d asynchronous errors", vam->async_errors);
8458           vam->retval = -98;
8459         }
8460       vam->async_errors = 0;
8461       after = vat_time_now (vam);
8462
8463       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8464       if (j > 0)
8465         count = j;
8466
8467       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8468              count, after - before, count / (after - before));
8469     }
8470   else
8471     {
8472       int ret;
8473
8474       /* Wait for a reply... */
8475       W (ret);
8476       return ret;
8477     }
8478
8479   /* Return the good/bad news */
8480   return (vam->retval);
8481   return (0);
8482 }
8483
8484 static int
8485 api_mpls_ip_bind_unbind (vat_main_t * vam)
8486 {
8487   unformat_input_t *i = vam->input;
8488   vl_api_mpls_ip_bind_unbind_t *mp;
8489   u32 ip_table_id = 0;
8490   u8 is_bind = 1;
8491   vl_api_prefix_t pfx;
8492   u8 prefix_set = 0;
8493   mpls_label_t local_label = MPLS_LABEL_INVALID;
8494   int ret;
8495
8496   /* Parse args required to build the message */
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8500         prefix_set = 1;
8501       else if (unformat (i, "%d", &local_label))
8502         ;
8503       else if (unformat (i, "table-id %d", &ip_table_id))
8504         ;
8505       else if (unformat (i, "unbind"))
8506         is_bind = 0;
8507       else if (unformat (i, "bind"))
8508         is_bind = 1;
8509       else
8510         {
8511           clib_warning ("parse error '%U'", format_unformat_error, i);
8512           return -99;
8513         }
8514     }
8515
8516   if (!prefix_set)
8517     {
8518       errmsg ("IP prefix not set");
8519       return -99;
8520     }
8521
8522   if (MPLS_LABEL_INVALID == local_label)
8523     {
8524       errmsg ("missing label");
8525       return -99;
8526     }
8527
8528   /* Construct the API message */
8529   M (MPLS_IP_BIND_UNBIND, mp);
8530
8531   mp->mb_is_bind = is_bind;
8532   mp->mb_ip_table_id = ntohl (ip_table_id);
8533   mp->mb_mpls_table_id = 0;
8534   mp->mb_label = ntohl (local_label);
8535   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8536
8537   /* send it... */
8538   S (mp);
8539
8540   /* Wait for a reply... */
8541   W (ret);
8542   return ret;
8543   return (0);
8544 }
8545
8546 static int
8547 api_sr_mpls_policy_add (vat_main_t * vam)
8548 {
8549   unformat_input_t *i = vam->input;
8550   vl_api_sr_mpls_policy_add_t *mp;
8551   u32 bsid = 0;
8552   u32 weight = 1;
8553   u8 type = 0;
8554   u8 n_segments = 0;
8555   u32 sid;
8556   u32 *segments = NULL;
8557   int ret;
8558
8559   /* Parse args required to build the message */
8560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8561     {
8562       if (unformat (i, "bsid %d", &bsid))
8563         ;
8564       else if (unformat (i, "weight %d", &weight))
8565         ;
8566       else if (unformat (i, "spray"))
8567         type = 1;
8568       else if (unformat (i, "next %d", &sid))
8569         {
8570           n_segments += 1;
8571           vec_add1 (segments, htonl (sid));
8572         }
8573       else
8574         {
8575           clib_warning ("parse error '%U'", format_unformat_error, i);
8576           return -99;
8577         }
8578     }
8579
8580   if (bsid == 0)
8581     {
8582       errmsg ("bsid not set");
8583       return -99;
8584     }
8585
8586   if (n_segments == 0)
8587     {
8588       errmsg ("no sid in segment stack");
8589       return -99;
8590     }
8591
8592   /* Construct the API message */
8593   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8594
8595   mp->bsid = htonl (bsid);
8596   mp->weight = htonl (weight);
8597   mp->type = type;
8598   mp->n_segments = n_segments;
8599   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8600   vec_free (segments);
8601
8602   /* send it... */
8603   S (mp);
8604
8605   /* Wait for a reply... */
8606   W (ret);
8607   return ret;
8608 }
8609
8610 static int
8611 api_sr_mpls_policy_del (vat_main_t * vam)
8612 {
8613   unformat_input_t *i = vam->input;
8614   vl_api_sr_mpls_policy_del_t *mp;
8615   u32 bsid = 0;
8616   int ret;
8617
8618   /* Parse args required to build the message */
8619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8620     {
8621       if (unformat (i, "bsid %d", &bsid))
8622         ;
8623       else
8624         {
8625           clib_warning ("parse error '%U'", format_unformat_error, i);
8626           return -99;
8627         }
8628     }
8629
8630   if (bsid == 0)
8631     {
8632       errmsg ("bsid not set");
8633       return -99;
8634     }
8635
8636   /* Construct the API message */
8637   M (SR_MPLS_POLICY_DEL, mp);
8638
8639   mp->bsid = htonl (bsid);
8640
8641   /* send it... */
8642   S (mp);
8643
8644   /* Wait for a reply... */
8645   W (ret);
8646   return ret;
8647 }
8648
8649 static int
8650 api_bier_table_add_del (vat_main_t * vam)
8651 {
8652   unformat_input_t *i = vam->input;
8653   vl_api_bier_table_add_del_t *mp;
8654   u8 is_add = 1;
8655   u32 set = 0, sub_domain = 0, hdr_len = 3;
8656   mpls_label_t local_label = MPLS_LABEL_INVALID;
8657   int ret;
8658
8659   /* Parse args required to build the message */
8660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8661     {
8662       if (unformat (i, "sub-domain %d", &sub_domain))
8663         ;
8664       else if (unformat (i, "set %d", &set))
8665         ;
8666       else if (unformat (i, "label %d", &local_label))
8667         ;
8668       else if (unformat (i, "hdr-len %d", &hdr_len))
8669         ;
8670       else if (unformat (i, "add"))
8671         is_add = 1;
8672       else if (unformat (i, "del"))
8673         is_add = 0;
8674       else
8675         {
8676           clib_warning ("parse error '%U'", format_unformat_error, i);
8677           return -99;
8678         }
8679     }
8680
8681   if (MPLS_LABEL_INVALID == local_label)
8682     {
8683       errmsg ("missing label\n");
8684       return -99;
8685     }
8686
8687   /* Construct the API message */
8688   M (BIER_TABLE_ADD_DEL, mp);
8689
8690   mp->bt_is_add = is_add;
8691   mp->bt_label = ntohl (local_label);
8692   mp->bt_tbl_id.bt_set = set;
8693   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8694   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8695
8696   /* send it... */
8697   S (mp);
8698
8699   /* Wait for a reply... */
8700   W (ret);
8701
8702   return (ret);
8703 }
8704
8705 static int
8706 api_bier_route_add_del (vat_main_t * vam)
8707 {
8708   unformat_input_t *i = vam->input;
8709   vl_api_bier_route_add_del_t *mp;
8710   u8 is_add = 1;
8711   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8712   ip4_address_t v4_next_hop_address;
8713   ip6_address_t v6_next_hop_address;
8714   u8 next_hop_set = 0;
8715   u8 next_hop_proto_is_ip4 = 1;
8716   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8717   int ret;
8718
8719   /* Parse args required to build the message */
8720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8721     {
8722       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8723         {
8724           next_hop_proto_is_ip4 = 1;
8725           next_hop_set = 1;
8726         }
8727       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8728         {
8729           next_hop_proto_is_ip4 = 0;
8730           next_hop_set = 1;
8731         }
8732       if (unformat (i, "sub-domain %d", &sub_domain))
8733         ;
8734       else if (unformat (i, "set %d", &set))
8735         ;
8736       else if (unformat (i, "hdr-len %d", &hdr_len))
8737         ;
8738       else if (unformat (i, "bp %d", &bp))
8739         ;
8740       else if (unformat (i, "add"))
8741         is_add = 1;
8742       else if (unformat (i, "del"))
8743         is_add = 0;
8744       else if (unformat (i, "out-label %d", &next_hop_out_label))
8745         ;
8746       else
8747         {
8748           clib_warning ("parse error '%U'", format_unformat_error, i);
8749           return -99;
8750         }
8751     }
8752
8753   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8754     {
8755       errmsg ("next hop / label set\n");
8756       return -99;
8757     }
8758   if (0 == bp)
8759     {
8760       errmsg ("bit=position not set\n");
8761       return -99;
8762     }
8763
8764   /* Construct the API message */
8765   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8766
8767   mp->br_is_add = is_add;
8768   mp->br_route.br_tbl_id.bt_set = set;
8769   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8770   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8771   mp->br_route.br_bp = ntohs (bp);
8772   mp->br_route.br_n_paths = 1;
8773   mp->br_route.br_paths[0].n_labels = 1;
8774   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8775   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8776                                     FIB_API_PATH_NH_PROTO_IP4 :
8777                                     FIB_API_PATH_NH_PROTO_IP6);
8778
8779   if (next_hop_proto_is_ip4)
8780     {
8781       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8782                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8783     }
8784   else
8785     {
8786       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8787                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8788     }
8789
8790   /* send it... */
8791   S (mp);
8792
8793   /* Wait for a reply... */
8794   W (ret);
8795
8796   return (ret);
8797 }
8798
8799 static int
8800 api_proxy_arp_add_del (vat_main_t * vam)
8801 {
8802   unformat_input_t *i = vam->input;
8803   vl_api_proxy_arp_add_del_t *mp;
8804   u32 vrf_id = 0;
8805   u8 is_add = 1;
8806   vl_api_ip4_address_t lo, hi;
8807   u8 range_set = 0;
8808   int ret;
8809
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "vrf %d", &vrf_id))
8813         ;
8814       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8815                          unformat_vl_api_ip4_address, &hi))
8816         range_set = 1;
8817       else if (unformat (i, "del"))
8818         is_add = 0;
8819       else
8820         {
8821           clib_warning ("parse error '%U'", format_unformat_error, i);
8822           return -99;
8823         }
8824     }
8825
8826   if (range_set == 0)
8827     {
8828       errmsg ("address range not set");
8829       return -99;
8830     }
8831
8832   M (PROXY_ARP_ADD_DEL, mp);
8833
8834   mp->proxy.table_id = ntohl (vrf_id);
8835   mp->is_add = is_add;
8836   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8837   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8838
8839   S (mp);
8840   W (ret);
8841   return ret;
8842 }
8843
8844 static int
8845 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8846 {
8847   unformat_input_t *i = vam->input;
8848   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8849   u32 sw_if_index;
8850   u8 enable = 1;
8851   u8 sw_if_index_set = 0;
8852   int ret;
8853
8854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8855     {
8856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8857         sw_if_index_set = 1;
8858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8859         sw_if_index_set = 1;
8860       else if (unformat (i, "enable"))
8861         enable = 1;
8862       else if (unformat (i, "disable"))
8863         enable = 0;
8864       else
8865         {
8866           clib_warning ("parse error '%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (sw_if_index_set == 0)
8872     {
8873       errmsg ("missing interface name or sw_if_index");
8874       return -99;
8875     }
8876
8877   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8878
8879   mp->sw_if_index = ntohl (sw_if_index);
8880   mp->enable_disable = enable;
8881
8882   S (mp);
8883   W (ret);
8884   return ret;
8885 }
8886
8887 static int
8888 api_mpls_tunnel_add_del (vat_main_t * vam)
8889 {
8890   unformat_input_t *i = vam->input;
8891   vl_api_mpls_tunnel_add_del_t *mp;
8892
8893   vl_api_fib_path_t paths[8];
8894   u32 sw_if_index = ~0;
8895   u8 path_count = 0;
8896   u8 l2_only = 0;
8897   u8 is_add = 1;
8898   int ret;
8899
8900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8901     {
8902       if (unformat (i, "add"))
8903         is_add = 1;
8904       else
8905         if (unformat
8906             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8907         is_add = 0;
8908       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8909         is_add = 0;
8910       else if (unformat (i, "l2-only"))
8911         l2_only = 1;
8912       else
8913         if (unformat
8914             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8915         {
8916           path_count++;
8917           if (8 == path_count)
8918             {
8919               errmsg ("max 8 paths");
8920               return -99;
8921             }
8922         }
8923       else
8924         {
8925           clib_warning ("parse error '%U'", format_unformat_error, i);
8926           return -99;
8927         }
8928     }
8929
8930   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8931
8932   mp->mt_is_add = is_add;
8933   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8934   mp->mt_tunnel.mt_l2_only = l2_only;
8935   mp->mt_tunnel.mt_is_multicast = 0;
8936   mp->mt_tunnel.mt_n_paths = path_count;
8937
8938   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8939                sizeof (paths[0]) * path_count);
8940
8941   S (mp);
8942   W (ret);
8943   return ret;
8944 }
8945
8946 static int
8947 api_sw_interface_set_unnumbered (vat_main_t * vam)
8948 {
8949   unformat_input_t *i = vam->input;
8950   vl_api_sw_interface_set_unnumbered_t *mp;
8951   u32 sw_if_index;
8952   u32 unnum_sw_index = ~0;
8953   u8 is_add = 1;
8954   u8 sw_if_index_set = 0;
8955   int ret;
8956
8957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8958     {
8959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8960         sw_if_index_set = 1;
8961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8962         sw_if_index_set = 1;
8963       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8964         ;
8965       else if (unformat (i, "del"))
8966         is_add = 0;
8967       else
8968         {
8969           clib_warning ("parse error '%U'", format_unformat_error, i);
8970           return -99;
8971         }
8972     }
8973
8974   if (sw_if_index_set == 0)
8975     {
8976       errmsg ("missing interface name or sw_if_index");
8977       return -99;
8978     }
8979
8980   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8981
8982   mp->sw_if_index = ntohl (sw_if_index);
8983   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8984   mp->is_add = is_add;
8985
8986   S (mp);
8987   W (ret);
8988   return ret;
8989 }
8990
8991 static int
8992 api_ip_neighbor_add_del (vat_main_t * vam)
8993 {
8994   vl_api_mac_address_t mac_address;
8995   unformat_input_t *i = vam->input;
8996   vl_api_ip_neighbor_add_del_t *mp;
8997   vl_api_address_t ip_address;
8998   u32 sw_if_index;
8999   u8 sw_if_index_set = 0;
9000   u8 is_add = 1;
9001   u8 mac_set = 0;
9002   u8 address_set = 0;
9003   int ret;
9004   ip_neighbor_flags_t flags;
9005
9006   flags = IP_NEIGHBOR_FLAG_NONE;
9007   clib_memset (&ip_address, 0, sizeof (ip_address));
9008   clib_memset (&mac_address, 0, sizeof (mac_address));
9009
9010   /* Parse args required to build the message */
9011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9012     {
9013       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9014         {
9015           mac_set = 1;
9016         }
9017       else if (unformat (i, "del"))
9018         is_add = 0;
9019       else
9020         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9021         sw_if_index_set = 1;
9022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9023         sw_if_index_set = 1;
9024       else if (unformat (i, "static"))
9025         flags |= IP_NEIGHBOR_FLAG_STATIC;
9026       else if (unformat (i, "no-fib-entry"))
9027         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9028       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9029         address_set = 1;
9030       else
9031         {
9032           clib_warning ("parse error '%U'", format_unformat_error, i);
9033           return -99;
9034         }
9035     }
9036
9037   if (sw_if_index_set == 0)
9038     {
9039       errmsg ("missing interface name or sw_if_index");
9040       return -99;
9041     }
9042   if (!address_set)
9043     {
9044       errmsg ("no address set");
9045       return -99;
9046     }
9047
9048   /* Construct the API message */
9049   M (IP_NEIGHBOR_ADD_DEL, mp);
9050
9051   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9052   mp->is_add = is_add;
9053   mp->neighbor.flags = htonl (flags);
9054   if (mac_set)
9055     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9056                  sizeof (mac_address));
9057   if (address_set)
9058     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9059
9060   /* send it... */
9061   S (mp);
9062
9063   /* Wait for a reply, return good/bad news  */
9064   W (ret);
9065   return ret;
9066 }
9067
9068 static int
9069 api_create_vlan_subif (vat_main_t * vam)
9070 {
9071   unformat_input_t *i = vam->input;
9072   vl_api_create_vlan_subif_t *mp;
9073   u32 sw_if_index;
9074   u8 sw_if_index_set = 0;
9075   u32 vlan_id;
9076   u8 vlan_id_set = 0;
9077   int ret;
9078
9079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9080     {
9081       if (unformat (i, "sw_if_index %d", &sw_if_index))
9082         sw_if_index_set = 1;
9083       else
9084         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9085         sw_if_index_set = 1;
9086       else if (unformat (i, "vlan %d", &vlan_id))
9087         vlan_id_set = 1;
9088       else
9089         {
9090           clib_warning ("parse error '%U'", format_unformat_error, i);
9091           return -99;
9092         }
9093     }
9094
9095   if (sw_if_index_set == 0)
9096     {
9097       errmsg ("missing interface name or sw_if_index");
9098       return -99;
9099     }
9100
9101   if (vlan_id_set == 0)
9102     {
9103       errmsg ("missing vlan_id");
9104       return -99;
9105     }
9106   M (CREATE_VLAN_SUBIF, mp);
9107
9108   mp->sw_if_index = ntohl (sw_if_index);
9109   mp->vlan_id = ntohl (vlan_id);
9110
9111   S (mp);
9112   W (ret);
9113   return ret;
9114 }
9115
9116 #define foreach_create_subif_bit                \
9117 _(no_tags)                                      \
9118 _(one_tag)                                      \
9119 _(two_tags)                                     \
9120 _(dot1ad)                                       \
9121 _(exact_match)                                  \
9122 _(default_sub)                                  \
9123 _(outer_vlan_id_any)                            \
9124 _(inner_vlan_id_any)
9125
9126 #define foreach_create_subif_flag               \
9127 _(0, "no_tags")                                 \
9128 _(1, "one_tag")                                 \
9129 _(2, "two_tags")                                \
9130 _(3, "dot1ad")                                  \
9131 _(4, "exact_match")                             \
9132 _(5, "default_sub")                             \
9133 _(6, "outer_vlan_id_any")                       \
9134 _(7, "inner_vlan_id_any")
9135
9136 static int
9137 api_create_subif (vat_main_t * vam)
9138 {
9139   unformat_input_t *i = vam->input;
9140   vl_api_create_subif_t *mp;
9141   u32 sw_if_index;
9142   u8 sw_if_index_set = 0;
9143   u32 sub_id;
9144   u8 sub_id_set = 0;
9145   u32 __attribute__ ((unused)) no_tags = 0;
9146   u32 __attribute__ ((unused)) one_tag = 0;
9147   u32 __attribute__ ((unused)) two_tags = 0;
9148   u32 __attribute__ ((unused)) dot1ad = 0;
9149   u32 __attribute__ ((unused)) exact_match = 0;
9150   u32 __attribute__ ((unused)) default_sub = 0;
9151   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9152   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9153   u32 tmp;
9154   u16 outer_vlan_id = 0;
9155   u16 inner_vlan_id = 0;
9156   int ret;
9157
9158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9159     {
9160       if (unformat (i, "sw_if_index %d", &sw_if_index))
9161         sw_if_index_set = 1;
9162       else
9163         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9164         sw_if_index_set = 1;
9165       else if (unformat (i, "sub_id %d", &sub_id))
9166         sub_id_set = 1;
9167       else if (unformat (i, "outer_vlan_id %d", &tmp))
9168         outer_vlan_id = tmp;
9169       else if (unformat (i, "inner_vlan_id %d", &tmp))
9170         inner_vlan_id = tmp;
9171
9172 #define _(a) else if (unformat (i, #a)) a = 1 ;
9173       foreach_create_subif_bit
9174 #undef _
9175         else
9176         {
9177           clib_warning ("parse error '%U'", format_unformat_error, i);
9178           return -99;
9179         }
9180     }
9181
9182   if (sw_if_index_set == 0)
9183     {
9184       errmsg ("missing interface name or sw_if_index");
9185       return -99;
9186     }
9187
9188   if (sub_id_set == 0)
9189     {
9190       errmsg ("missing sub_id");
9191       return -99;
9192     }
9193   M (CREATE_SUBIF, mp);
9194
9195   mp->sw_if_index = ntohl (sw_if_index);
9196   mp->sub_id = ntohl (sub_id);
9197
9198 #define _(a,b) mp->sub_if_flags |= (1 << a);
9199   foreach_create_subif_flag;
9200 #undef _
9201
9202   mp->outer_vlan_id = ntohs (outer_vlan_id);
9203   mp->inner_vlan_id = ntohs (inner_vlan_id);
9204
9205   S (mp);
9206   W (ret);
9207   return ret;
9208 }
9209
9210 static int
9211 api_reset_fib (vat_main_t * vam)
9212 {
9213   unformat_input_t *i = vam->input;
9214   vl_api_reset_fib_t *mp;
9215   u32 vrf_id = 0;
9216   u8 is_ipv6 = 0;
9217   u8 vrf_id_set = 0;
9218
9219   int ret;
9220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9221     {
9222       if (unformat (i, "vrf %d", &vrf_id))
9223         vrf_id_set = 1;
9224       else if (unformat (i, "ipv6"))
9225         is_ipv6 = 1;
9226       else
9227         {
9228           clib_warning ("parse error '%U'", format_unformat_error, i);
9229           return -99;
9230         }
9231     }
9232
9233   if (vrf_id_set == 0)
9234     {
9235       errmsg ("missing vrf id");
9236       return -99;
9237     }
9238
9239   M (RESET_FIB, mp);
9240
9241   mp->vrf_id = ntohl (vrf_id);
9242   mp->is_ipv6 = is_ipv6;
9243
9244   S (mp);
9245   W (ret);
9246   return ret;
9247 }
9248
9249 static int
9250 api_set_ip_flow_hash (vat_main_t * vam)
9251 {
9252   unformat_input_t *i = vam->input;
9253   vl_api_set_ip_flow_hash_t *mp;
9254   u32 vrf_id = 0;
9255   u8 is_ipv6 = 0;
9256   u8 vrf_id_set = 0;
9257   u8 src = 0;
9258   u8 dst = 0;
9259   u8 sport = 0;
9260   u8 dport = 0;
9261   u8 proto = 0;
9262   u8 reverse = 0;
9263   int ret;
9264
9265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9266     {
9267       if (unformat (i, "vrf %d", &vrf_id))
9268         vrf_id_set = 1;
9269       else if (unformat (i, "ipv6"))
9270         is_ipv6 = 1;
9271       else if (unformat (i, "src"))
9272         src = 1;
9273       else if (unformat (i, "dst"))
9274         dst = 1;
9275       else if (unformat (i, "sport"))
9276         sport = 1;
9277       else if (unformat (i, "dport"))
9278         dport = 1;
9279       else if (unformat (i, "proto"))
9280         proto = 1;
9281       else if (unformat (i, "reverse"))
9282         reverse = 1;
9283
9284       else
9285         {
9286           clib_warning ("parse error '%U'", format_unformat_error, i);
9287           return -99;
9288         }
9289     }
9290
9291   if (vrf_id_set == 0)
9292     {
9293       errmsg ("missing vrf id");
9294       return -99;
9295     }
9296
9297   M (SET_IP_FLOW_HASH, mp);
9298   mp->src = src;
9299   mp->dst = dst;
9300   mp->sport = sport;
9301   mp->dport = dport;
9302   mp->proto = proto;
9303   mp->reverse = reverse;
9304   mp->vrf_id = ntohl (vrf_id);
9305   mp->is_ipv6 = is_ipv6;
9306
9307   S (mp);
9308   W (ret);
9309   return ret;
9310 }
9311
9312 static int
9313 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9314 {
9315   unformat_input_t *i = vam->input;
9316   vl_api_sw_interface_ip6_enable_disable_t *mp;
9317   u32 sw_if_index;
9318   u8 sw_if_index_set = 0;
9319   u8 enable = 0;
9320   int ret;
9321
9322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "enable"))
9329         enable = 1;
9330       else if (unformat (i, "disable"))
9331         enable = 0;
9332       else
9333         {
9334           clib_warning ("parse error '%U'", format_unformat_error, i);
9335           return -99;
9336         }
9337     }
9338
9339   if (sw_if_index_set == 0)
9340     {
9341       errmsg ("missing interface name or sw_if_index");
9342       return -99;
9343     }
9344
9345   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9346
9347   mp->sw_if_index = ntohl (sw_if_index);
9348   mp->enable = enable;
9349
9350   S (mp);
9351   W (ret);
9352   return ret;
9353 }
9354
9355 static int
9356 api_ip6nd_proxy_add_del (vat_main_t * vam)
9357 {
9358   unformat_input_t *i = vam->input;
9359   vl_api_ip6nd_proxy_add_del_t *mp;
9360   u32 sw_if_index = ~0;
9361   u8 v6_address_set = 0;
9362   vl_api_ip6_address_t v6address;
9363   u8 is_del = 0;
9364   int ret;
9365
9366   /* Parse args required to build the message */
9367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9368     {
9369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9370         ;
9371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9372         ;
9373       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9374         v6_address_set = 1;
9375       if (unformat (i, "del"))
9376         is_del = 1;
9377       else
9378         {
9379           clib_warning ("parse error '%U'", format_unformat_error, i);
9380           return -99;
9381         }
9382     }
9383
9384   if (sw_if_index == ~0)
9385     {
9386       errmsg ("missing interface name or sw_if_index");
9387       return -99;
9388     }
9389   if (!v6_address_set)
9390     {
9391       errmsg ("no address set");
9392       return -99;
9393     }
9394
9395   /* Construct the API message */
9396   M (IP6ND_PROXY_ADD_DEL, mp);
9397
9398   mp->is_del = is_del;
9399   mp->sw_if_index = ntohl (sw_if_index);
9400   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9401
9402   /* send it... */
9403   S (mp);
9404
9405   /* Wait for a reply, return good/bad news  */
9406   W (ret);
9407   return ret;
9408 }
9409
9410 static int
9411 api_ip6nd_proxy_dump (vat_main_t * vam)
9412 {
9413   vl_api_ip6nd_proxy_dump_t *mp;
9414   vl_api_control_ping_t *mp_ping;
9415   int ret;
9416
9417   M (IP6ND_PROXY_DUMP, mp);
9418
9419   S (mp);
9420
9421   /* Use a control ping for synchronization */
9422   MPING (CONTROL_PING, mp_ping);
9423   S (mp_ping);
9424
9425   W (ret);
9426   return ret;
9427 }
9428
9429 static void vl_api_ip6nd_proxy_details_t_handler
9430   (vl_api_ip6nd_proxy_details_t * mp)
9431 {
9432   vat_main_t *vam = &vat_main;
9433
9434   print (vam->ofp, "host %U sw_if_index %d",
9435          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9436 }
9437
9438 static void vl_api_ip6nd_proxy_details_t_handler_json
9439   (vl_api_ip6nd_proxy_details_t * mp)
9440 {
9441   vat_main_t *vam = &vat_main;
9442   struct in6_addr ip6;
9443   vat_json_node_t *node = NULL;
9444
9445   if (VAT_JSON_ARRAY != vam->json_tree.type)
9446     {
9447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9448       vat_json_init_array (&vam->json_tree);
9449     }
9450   node = vat_json_array_add (&vam->json_tree);
9451
9452   vat_json_init_object (node);
9453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9454
9455   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9456   vat_json_object_add_ip6 (node, "host", ip6);
9457 }
9458
9459 static int
9460 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9461 {
9462   unformat_input_t *i = vam->input;
9463   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9464   u32 sw_if_index;
9465   u8 sw_if_index_set = 0;
9466   u8 v6_address_set = 0;
9467   vl_api_prefix_t pfx;
9468   u8 use_default = 0;
9469   u8 no_advertise = 0;
9470   u8 off_link = 0;
9471   u8 no_autoconfig = 0;
9472   u8 no_onlink = 0;
9473   u8 is_no = 0;
9474   u32 val_lifetime = 0;
9475   u32 pref_lifetime = 0;
9476   int ret;
9477
9478   /* Parse args required to build the message */
9479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9480     {
9481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9482         sw_if_index_set = 1;
9483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9484         sw_if_index_set = 1;
9485       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9486         v6_address_set = 1;
9487       else if (unformat (i, "val_life %d", &val_lifetime))
9488         ;
9489       else if (unformat (i, "pref_life %d", &pref_lifetime))
9490         ;
9491       else if (unformat (i, "def"))
9492         use_default = 1;
9493       else if (unformat (i, "noadv"))
9494         no_advertise = 1;
9495       else if (unformat (i, "offl"))
9496         off_link = 1;
9497       else if (unformat (i, "noauto"))
9498         no_autoconfig = 1;
9499       else if (unformat (i, "nolink"))
9500         no_onlink = 1;
9501       else if (unformat (i, "isno"))
9502         is_no = 1;
9503       else
9504         {
9505           clib_warning ("parse error '%U'", format_unformat_error, i);
9506           return -99;
9507         }
9508     }
9509
9510   if (sw_if_index_set == 0)
9511     {
9512       errmsg ("missing interface name or sw_if_index");
9513       return -99;
9514     }
9515   if (!v6_address_set)
9516     {
9517       errmsg ("no address set");
9518       return -99;
9519     }
9520
9521   /* Construct the API message */
9522   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9523
9524   mp->sw_if_index = ntohl (sw_if_index);
9525   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9526   mp->use_default = use_default;
9527   mp->no_advertise = no_advertise;
9528   mp->off_link = off_link;
9529   mp->no_autoconfig = no_autoconfig;
9530   mp->no_onlink = no_onlink;
9531   mp->is_no = is_no;
9532   mp->val_lifetime = ntohl (val_lifetime);
9533   mp->pref_lifetime = ntohl (pref_lifetime);
9534
9535   /* send it... */
9536   S (mp);
9537
9538   /* Wait for a reply, return good/bad news  */
9539   W (ret);
9540   return ret;
9541 }
9542
9543 static int
9544 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9545 {
9546   unformat_input_t *i = vam->input;
9547   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9548   u32 sw_if_index;
9549   u8 sw_if_index_set = 0;
9550   u8 suppress = 0;
9551   u8 managed = 0;
9552   u8 other = 0;
9553   u8 ll_option = 0;
9554   u8 send_unicast = 0;
9555   u8 cease = 0;
9556   u8 is_no = 0;
9557   u8 default_router = 0;
9558   u32 max_interval = 0;
9559   u32 min_interval = 0;
9560   u32 lifetime = 0;
9561   u32 initial_count = 0;
9562   u32 initial_interval = 0;
9563   int ret;
9564
9565
9566   /* Parse args required to build the message */
9567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9568     {
9569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9570         sw_if_index_set = 1;
9571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9572         sw_if_index_set = 1;
9573       else if (unformat (i, "maxint %d", &max_interval))
9574         ;
9575       else if (unformat (i, "minint %d", &min_interval))
9576         ;
9577       else if (unformat (i, "life %d", &lifetime))
9578         ;
9579       else if (unformat (i, "count %d", &initial_count))
9580         ;
9581       else if (unformat (i, "interval %d", &initial_interval))
9582         ;
9583       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9584         suppress = 1;
9585       else if (unformat (i, "managed"))
9586         managed = 1;
9587       else if (unformat (i, "other"))
9588         other = 1;
9589       else if (unformat (i, "ll"))
9590         ll_option = 1;
9591       else if (unformat (i, "send"))
9592         send_unicast = 1;
9593       else if (unformat (i, "cease"))
9594         cease = 1;
9595       else if (unformat (i, "isno"))
9596         is_no = 1;
9597       else if (unformat (i, "def"))
9598         default_router = 1;
9599       else
9600         {
9601           clib_warning ("parse error '%U'", format_unformat_error, i);
9602           return -99;
9603         }
9604     }
9605
9606   if (sw_if_index_set == 0)
9607     {
9608       errmsg ("missing interface name or sw_if_index");
9609       return -99;
9610     }
9611
9612   /* Construct the API message */
9613   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9614
9615   mp->sw_if_index = ntohl (sw_if_index);
9616   mp->max_interval = ntohl (max_interval);
9617   mp->min_interval = ntohl (min_interval);
9618   mp->lifetime = ntohl (lifetime);
9619   mp->initial_count = ntohl (initial_count);
9620   mp->initial_interval = ntohl (initial_interval);
9621   mp->suppress = suppress;
9622   mp->managed = managed;
9623   mp->other = other;
9624   mp->ll_option = ll_option;
9625   mp->send_unicast = send_unicast;
9626   mp->cease = cease;
9627   mp->is_no = is_no;
9628   mp->default_router = default_router;
9629
9630   /* send it... */
9631   S (mp);
9632
9633   /* Wait for a reply, return good/bad news  */
9634   W (ret);
9635   return ret;
9636 }
9637
9638 static int
9639 api_set_arp_neighbor_limit (vat_main_t * vam)
9640 {
9641   unformat_input_t *i = vam->input;
9642   vl_api_set_arp_neighbor_limit_t *mp;
9643   u32 arp_nbr_limit;
9644   u8 limit_set = 0;
9645   u8 is_ipv6 = 0;
9646   int ret;
9647
9648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9651         limit_set = 1;
9652       else if (unformat (i, "ipv6"))
9653         is_ipv6 = 1;
9654       else
9655         {
9656           clib_warning ("parse error '%U'", format_unformat_error, i);
9657           return -99;
9658         }
9659     }
9660
9661   if (limit_set == 0)
9662     {
9663       errmsg ("missing limit value");
9664       return -99;
9665     }
9666
9667   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9668
9669   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9670   mp->is_ipv6 = is_ipv6;
9671
9672   S (mp);
9673   W (ret);
9674   return ret;
9675 }
9676
9677 static int
9678 api_l2_patch_add_del (vat_main_t * vam)
9679 {
9680   unformat_input_t *i = vam->input;
9681   vl_api_l2_patch_add_del_t *mp;
9682   u32 rx_sw_if_index;
9683   u8 rx_sw_if_index_set = 0;
9684   u32 tx_sw_if_index;
9685   u8 tx_sw_if_index_set = 0;
9686   u8 is_add = 1;
9687   int ret;
9688
9689   /* Parse args required to build the message */
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9693         rx_sw_if_index_set = 1;
9694       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9695         tx_sw_if_index_set = 1;
9696       else if (unformat (i, "rx"))
9697         {
9698           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9699             {
9700               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9701                             &rx_sw_if_index))
9702                 rx_sw_if_index_set = 1;
9703             }
9704           else
9705             break;
9706         }
9707       else if (unformat (i, "tx"))
9708         {
9709           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9710             {
9711               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9712                             &tx_sw_if_index))
9713                 tx_sw_if_index_set = 1;
9714             }
9715           else
9716             break;
9717         }
9718       else if (unformat (i, "del"))
9719         is_add = 0;
9720       else
9721         break;
9722     }
9723
9724   if (rx_sw_if_index_set == 0)
9725     {
9726       errmsg ("missing rx interface name or rx_sw_if_index");
9727       return -99;
9728     }
9729
9730   if (tx_sw_if_index_set == 0)
9731     {
9732       errmsg ("missing tx interface name or tx_sw_if_index");
9733       return -99;
9734     }
9735
9736   M (L2_PATCH_ADD_DEL, mp);
9737
9738   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9739   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9740   mp->is_add = is_add;
9741
9742   S (mp);
9743   W (ret);
9744   return ret;
9745 }
9746
9747 u8 is_del;
9748 u8 localsid_addr[16];
9749 u8 end_psp;
9750 u8 behavior;
9751 u32 sw_if_index;
9752 u32 vlan_index;
9753 u32 fib_table;
9754 u8 nh_addr[16];
9755
9756 static int
9757 api_sr_localsid_add_del (vat_main_t * vam)
9758 {
9759   unformat_input_t *i = vam->input;
9760   vl_api_sr_localsid_add_del_t *mp;
9761
9762   u8 is_del;
9763   ip6_address_t localsid;
9764   u8 end_psp = 0;
9765   u8 behavior = ~0;
9766   u32 sw_if_index;
9767   u32 fib_table = ~(u32) 0;
9768   ip6_address_t nh_addr6;
9769   ip4_address_t nh_addr4;
9770   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9771   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9772
9773   bool nexthop_set = 0;
9774
9775   int ret;
9776
9777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9778     {
9779       if (unformat (i, "del"))
9780         is_del = 1;
9781       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9782       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9783         nexthop_set = 1;
9784       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9785         nexthop_set = 1;
9786       else if (unformat (i, "behavior %u", &behavior));
9787       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9788       else if (unformat (i, "fib-table %u", &fib_table));
9789       else if (unformat (i, "end.psp %u", &behavior));
9790       else
9791         break;
9792     }
9793
9794   M (SR_LOCALSID_ADD_DEL, mp);
9795
9796   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9797   if (nexthop_set)
9798     {
9799       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9800       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9801     }
9802   mp->behavior = behavior;
9803   mp->sw_if_index = ntohl (sw_if_index);
9804   mp->fib_table = ntohl (fib_table);
9805   mp->end_psp = end_psp;
9806   mp->is_del = is_del;
9807
9808   S (mp);
9809   W (ret);
9810   return ret;
9811 }
9812
9813 static int
9814 api_ioam_enable (vat_main_t * vam)
9815 {
9816   unformat_input_t *input = vam->input;
9817   vl_api_ioam_enable_t *mp;
9818   u32 id = 0;
9819   int has_trace_option = 0;
9820   int has_pot_option = 0;
9821   int has_seqno_option = 0;
9822   int has_analyse_option = 0;
9823   int ret;
9824
9825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (input, "trace"))
9828         has_trace_option = 1;
9829       else if (unformat (input, "pot"))
9830         has_pot_option = 1;
9831       else if (unformat (input, "seqno"))
9832         has_seqno_option = 1;
9833       else if (unformat (input, "analyse"))
9834         has_analyse_option = 1;
9835       else
9836         break;
9837     }
9838   M (IOAM_ENABLE, mp);
9839   mp->id = htons (id);
9840   mp->seqno = has_seqno_option;
9841   mp->analyse = has_analyse_option;
9842   mp->pot_enable = has_pot_option;
9843   mp->trace_enable = has_trace_option;
9844
9845   S (mp);
9846   W (ret);
9847   return ret;
9848 }
9849
9850
9851 static int
9852 api_ioam_disable (vat_main_t * vam)
9853 {
9854   vl_api_ioam_disable_t *mp;
9855   int ret;
9856
9857   M (IOAM_DISABLE, mp);
9858   S (mp);
9859   W (ret);
9860   return ret;
9861 }
9862
9863 #define foreach_tcp_proto_field                 \
9864 _(src_port)                                     \
9865 _(dst_port)
9866
9867 #define foreach_udp_proto_field                 \
9868 _(src_port)                                     \
9869 _(dst_port)
9870
9871 #define foreach_ip4_proto_field                 \
9872 _(src_address)                                  \
9873 _(dst_address)                                  \
9874 _(tos)                                          \
9875 _(length)                                       \
9876 _(fragment_id)                                  \
9877 _(ttl)                                          \
9878 _(protocol)                                     \
9879 _(checksum)
9880
9881 typedef struct
9882 {
9883   u16 src_port, dst_port;
9884 } tcpudp_header_t;
9885
9886 #if VPP_API_TEST_BUILTIN == 0
9887 uword
9888 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9889 {
9890   u8 **maskp = va_arg (*args, u8 **);
9891   u8 *mask = 0;
9892   u8 found_something = 0;
9893   tcp_header_t *tcp;
9894
9895 #define _(a) u8 a=0;
9896   foreach_tcp_proto_field;
9897 #undef _
9898
9899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9900     {
9901       if (0);
9902 #define _(a) else if (unformat (input, #a)) a=1;
9903       foreach_tcp_proto_field
9904 #undef _
9905         else
9906         break;
9907     }
9908
9909 #define _(a) found_something += a;
9910   foreach_tcp_proto_field;
9911 #undef _
9912
9913   if (found_something == 0)
9914     return 0;
9915
9916   vec_validate (mask, sizeof (*tcp) - 1);
9917
9918   tcp = (tcp_header_t *) mask;
9919
9920 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9921   foreach_tcp_proto_field;
9922 #undef _
9923
9924   *maskp = mask;
9925   return 1;
9926 }
9927
9928 uword
9929 unformat_udp_mask (unformat_input_t * input, va_list * args)
9930 {
9931   u8 **maskp = va_arg (*args, u8 **);
9932   u8 *mask = 0;
9933   u8 found_something = 0;
9934   udp_header_t *udp;
9935
9936 #define _(a) u8 a=0;
9937   foreach_udp_proto_field;
9938 #undef _
9939
9940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9941     {
9942       if (0);
9943 #define _(a) else if (unformat (input, #a)) a=1;
9944       foreach_udp_proto_field
9945 #undef _
9946         else
9947         break;
9948     }
9949
9950 #define _(a) found_something += a;
9951   foreach_udp_proto_field;
9952 #undef _
9953
9954   if (found_something == 0)
9955     return 0;
9956
9957   vec_validate (mask, sizeof (*udp) - 1);
9958
9959   udp = (udp_header_t *) mask;
9960
9961 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9962   foreach_udp_proto_field;
9963 #undef _
9964
9965   *maskp = mask;
9966   return 1;
9967 }
9968
9969 uword
9970 unformat_l4_mask (unformat_input_t * input, va_list * args)
9971 {
9972   u8 **maskp = va_arg (*args, u8 **);
9973   u16 src_port = 0, dst_port = 0;
9974   tcpudp_header_t *tcpudp;
9975
9976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9977     {
9978       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9979         return 1;
9980       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9981         return 1;
9982       else if (unformat (input, "src_port"))
9983         src_port = 0xFFFF;
9984       else if (unformat (input, "dst_port"))
9985         dst_port = 0xFFFF;
9986       else
9987         return 0;
9988     }
9989
9990   if (!src_port && !dst_port)
9991     return 0;
9992
9993   u8 *mask = 0;
9994   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9995
9996   tcpudp = (tcpudp_header_t *) mask;
9997   tcpudp->src_port = src_port;
9998   tcpudp->dst_port = dst_port;
9999
10000   *maskp = mask;
10001
10002   return 1;
10003 }
10004
10005 uword
10006 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10007 {
10008   u8 **maskp = va_arg (*args, u8 **);
10009   u8 *mask = 0;
10010   u8 found_something = 0;
10011   ip4_header_t *ip;
10012
10013 #define _(a) u8 a=0;
10014   foreach_ip4_proto_field;
10015 #undef _
10016   u8 version = 0;
10017   u8 hdr_length = 0;
10018
10019
10020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10021     {
10022       if (unformat (input, "version"))
10023         version = 1;
10024       else if (unformat (input, "hdr_length"))
10025         hdr_length = 1;
10026       else if (unformat (input, "src"))
10027         src_address = 1;
10028       else if (unformat (input, "dst"))
10029         dst_address = 1;
10030       else if (unformat (input, "proto"))
10031         protocol = 1;
10032
10033 #define _(a) else if (unformat (input, #a)) a=1;
10034       foreach_ip4_proto_field
10035 #undef _
10036         else
10037         break;
10038     }
10039
10040 #define _(a) found_something += a;
10041   foreach_ip4_proto_field;
10042 #undef _
10043
10044   if (found_something == 0)
10045     return 0;
10046
10047   vec_validate (mask, sizeof (*ip) - 1);
10048
10049   ip = (ip4_header_t *) mask;
10050
10051 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10052   foreach_ip4_proto_field;
10053 #undef _
10054
10055   ip->ip_version_and_header_length = 0;
10056
10057   if (version)
10058     ip->ip_version_and_header_length |= 0xF0;
10059
10060   if (hdr_length)
10061     ip->ip_version_and_header_length |= 0x0F;
10062
10063   *maskp = mask;
10064   return 1;
10065 }
10066
10067 #define foreach_ip6_proto_field                 \
10068 _(src_address)                                  \
10069 _(dst_address)                                  \
10070 _(payload_length)                               \
10071 _(hop_limit)                                    \
10072 _(protocol)
10073
10074 uword
10075 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10076 {
10077   u8 **maskp = va_arg (*args, u8 **);
10078   u8 *mask = 0;
10079   u8 found_something = 0;
10080   ip6_header_t *ip;
10081   u32 ip_version_traffic_class_and_flow_label;
10082
10083 #define _(a) u8 a=0;
10084   foreach_ip6_proto_field;
10085 #undef _
10086   u8 version = 0;
10087   u8 traffic_class = 0;
10088   u8 flow_label = 0;
10089
10090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (input, "version"))
10093         version = 1;
10094       else if (unformat (input, "traffic-class"))
10095         traffic_class = 1;
10096       else if (unformat (input, "flow-label"))
10097         flow_label = 1;
10098       else if (unformat (input, "src"))
10099         src_address = 1;
10100       else if (unformat (input, "dst"))
10101         dst_address = 1;
10102       else if (unformat (input, "proto"))
10103         protocol = 1;
10104
10105 #define _(a) else if (unformat (input, #a)) a=1;
10106       foreach_ip6_proto_field
10107 #undef _
10108         else
10109         break;
10110     }
10111
10112 #define _(a) found_something += a;
10113   foreach_ip6_proto_field;
10114 #undef _
10115
10116   if (found_something == 0)
10117     return 0;
10118
10119   vec_validate (mask, sizeof (*ip) - 1);
10120
10121   ip = (ip6_header_t *) mask;
10122
10123 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10124   foreach_ip6_proto_field;
10125 #undef _
10126
10127   ip_version_traffic_class_and_flow_label = 0;
10128
10129   if (version)
10130     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10131
10132   if (traffic_class)
10133     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10134
10135   if (flow_label)
10136     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10137
10138   ip->ip_version_traffic_class_and_flow_label =
10139     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10140
10141   *maskp = mask;
10142   return 1;
10143 }
10144
10145 uword
10146 unformat_l3_mask (unformat_input_t * input, va_list * args)
10147 {
10148   u8 **maskp = va_arg (*args, u8 **);
10149
10150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10151     {
10152       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10153         return 1;
10154       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10155         return 1;
10156       else
10157         break;
10158     }
10159   return 0;
10160 }
10161
10162 uword
10163 unformat_l2_mask (unformat_input_t * input, va_list * args)
10164 {
10165   u8 **maskp = va_arg (*args, u8 **);
10166   u8 *mask = 0;
10167   u8 src = 0;
10168   u8 dst = 0;
10169   u8 proto = 0;
10170   u8 tag1 = 0;
10171   u8 tag2 = 0;
10172   u8 ignore_tag1 = 0;
10173   u8 ignore_tag2 = 0;
10174   u8 cos1 = 0;
10175   u8 cos2 = 0;
10176   u8 dot1q = 0;
10177   u8 dot1ad = 0;
10178   int len = 14;
10179
10180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10181     {
10182       if (unformat (input, "src"))
10183         src = 1;
10184       else if (unformat (input, "dst"))
10185         dst = 1;
10186       else if (unformat (input, "proto"))
10187         proto = 1;
10188       else if (unformat (input, "tag1"))
10189         tag1 = 1;
10190       else if (unformat (input, "tag2"))
10191         tag2 = 1;
10192       else if (unformat (input, "ignore-tag1"))
10193         ignore_tag1 = 1;
10194       else if (unformat (input, "ignore-tag2"))
10195         ignore_tag2 = 1;
10196       else if (unformat (input, "cos1"))
10197         cos1 = 1;
10198       else if (unformat (input, "cos2"))
10199         cos2 = 1;
10200       else if (unformat (input, "dot1q"))
10201         dot1q = 1;
10202       else if (unformat (input, "dot1ad"))
10203         dot1ad = 1;
10204       else
10205         break;
10206     }
10207   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10208        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10209     return 0;
10210
10211   if (tag1 || ignore_tag1 || cos1 || dot1q)
10212     len = 18;
10213   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10214     len = 22;
10215
10216   vec_validate (mask, len - 1);
10217
10218   if (dst)
10219     clib_memset (mask, 0xff, 6);
10220
10221   if (src)
10222     clib_memset (mask + 6, 0xff, 6);
10223
10224   if (tag2 || dot1ad)
10225     {
10226       /* inner vlan tag */
10227       if (tag2)
10228         {
10229           mask[19] = 0xff;
10230           mask[18] = 0x0f;
10231         }
10232       if (cos2)
10233         mask[18] |= 0xe0;
10234       if (proto)
10235         mask[21] = mask[20] = 0xff;
10236       if (tag1)
10237         {
10238           mask[15] = 0xff;
10239           mask[14] = 0x0f;
10240         }
10241       if (cos1)
10242         mask[14] |= 0xe0;
10243       *maskp = mask;
10244       return 1;
10245     }
10246   if (tag1 | dot1q)
10247     {
10248       if (tag1)
10249         {
10250           mask[15] = 0xff;
10251           mask[14] = 0x0f;
10252         }
10253       if (cos1)
10254         mask[14] |= 0xe0;
10255       if (proto)
10256         mask[16] = mask[17] = 0xff;
10257
10258       *maskp = mask;
10259       return 1;
10260     }
10261   if (cos2)
10262     mask[18] |= 0xe0;
10263   if (cos1)
10264     mask[14] |= 0xe0;
10265   if (proto)
10266     mask[12] = mask[13] = 0xff;
10267
10268   *maskp = mask;
10269   return 1;
10270 }
10271
10272 uword
10273 unformat_classify_mask (unformat_input_t * input, va_list * args)
10274 {
10275   u8 **maskp = va_arg (*args, u8 **);
10276   u32 *skipp = va_arg (*args, u32 *);
10277   u32 *matchp = va_arg (*args, u32 *);
10278   u32 match;
10279   u8 *mask = 0;
10280   u8 *l2 = 0;
10281   u8 *l3 = 0;
10282   u8 *l4 = 0;
10283   int i;
10284
10285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10286     {
10287       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10288         ;
10289       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10290         ;
10291       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10292         ;
10293       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10294         ;
10295       else
10296         break;
10297     }
10298
10299   if (l4 && !l3)
10300     {
10301       vec_free (mask);
10302       vec_free (l2);
10303       vec_free (l4);
10304       return 0;
10305     }
10306
10307   if (mask || l2 || l3 || l4)
10308     {
10309       if (l2 || l3 || l4)
10310         {
10311           /* "With a free Ethernet header in every package" */
10312           if (l2 == 0)
10313             vec_validate (l2, 13);
10314           mask = l2;
10315           if (vec_len (l3))
10316             {
10317               vec_append (mask, l3);
10318               vec_free (l3);
10319             }
10320           if (vec_len (l4))
10321             {
10322               vec_append (mask, l4);
10323               vec_free (l4);
10324             }
10325         }
10326
10327       /* Scan forward looking for the first significant mask octet */
10328       for (i = 0; i < vec_len (mask); i++)
10329         if (mask[i])
10330           break;
10331
10332       /* compute (skip, match) params */
10333       *skipp = i / sizeof (u32x4);
10334       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10335
10336       /* Pad mask to an even multiple of the vector size */
10337       while (vec_len (mask) % sizeof (u32x4))
10338         vec_add1 (mask, 0);
10339
10340       match = vec_len (mask) / sizeof (u32x4);
10341
10342       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10343         {
10344           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10345           if (*tmp || *(tmp + 1))
10346             break;
10347           match--;
10348         }
10349       if (match == 0)
10350         clib_warning ("BUG: match 0");
10351
10352       _vec_len (mask) = match * sizeof (u32x4);
10353
10354       *matchp = match;
10355       *maskp = mask;
10356
10357       return 1;
10358     }
10359
10360   return 0;
10361 }
10362 #endif /* VPP_API_TEST_BUILTIN */
10363
10364 #define foreach_l2_next                         \
10365 _(drop, DROP)                                   \
10366 _(ethernet, ETHERNET_INPUT)                     \
10367 _(ip4, IP4_INPUT)                               \
10368 _(ip6, IP6_INPUT)
10369
10370 uword
10371 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10372 {
10373   u32 *miss_next_indexp = va_arg (*args, u32 *);
10374   u32 next_index = 0;
10375   u32 tmp;
10376
10377 #define _(n,N) \
10378   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10379   foreach_l2_next;
10380 #undef _
10381
10382   if (unformat (input, "%d", &tmp))
10383     {
10384       next_index = tmp;
10385       goto out;
10386     }
10387
10388   return 0;
10389
10390 out:
10391   *miss_next_indexp = next_index;
10392   return 1;
10393 }
10394
10395 #define foreach_ip_next                         \
10396 _(drop, DROP)                                   \
10397 _(local, LOCAL)                                 \
10398 _(rewrite, REWRITE)
10399
10400 uword
10401 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10402 {
10403   u32 *miss_next_indexp = va_arg (*args, u32 *);
10404   u32 next_index = 0;
10405   u32 tmp;
10406
10407 #define _(n,N) \
10408   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10409   foreach_ip_next;
10410 #undef _
10411
10412   if (unformat (input, "%d", &tmp))
10413     {
10414       next_index = tmp;
10415       goto out;
10416     }
10417
10418   return 0;
10419
10420 out:
10421   *miss_next_indexp = next_index;
10422   return 1;
10423 }
10424
10425 #define foreach_acl_next                        \
10426 _(deny, DENY)
10427
10428 uword
10429 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10430 {
10431   u32 *miss_next_indexp = va_arg (*args, u32 *);
10432   u32 next_index = 0;
10433   u32 tmp;
10434
10435 #define _(n,N) \
10436   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10437   foreach_acl_next;
10438 #undef _
10439
10440   if (unformat (input, "permit"))
10441     {
10442       next_index = ~0;
10443       goto out;
10444     }
10445   else if (unformat (input, "%d", &tmp))
10446     {
10447       next_index = tmp;
10448       goto out;
10449     }
10450
10451   return 0;
10452
10453 out:
10454   *miss_next_indexp = next_index;
10455   return 1;
10456 }
10457
10458 uword
10459 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10460 {
10461   u32 *r = va_arg (*args, u32 *);
10462
10463   if (unformat (input, "conform-color"))
10464     *r = POLICE_CONFORM;
10465   else if (unformat (input, "exceed-color"))
10466     *r = POLICE_EXCEED;
10467   else
10468     return 0;
10469
10470   return 1;
10471 }
10472
10473 static int
10474 api_classify_add_del_table (vat_main_t * vam)
10475 {
10476   unformat_input_t *i = vam->input;
10477   vl_api_classify_add_del_table_t *mp;
10478
10479   u32 nbuckets = 2;
10480   u32 skip = ~0;
10481   u32 match = ~0;
10482   int is_add = 1;
10483   int del_chain = 0;
10484   u32 table_index = ~0;
10485   u32 next_table_index = ~0;
10486   u32 miss_next_index = ~0;
10487   u32 memory_size = 32 << 20;
10488   u8 *mask = 0;
10489   u32 current_data_flag = 0;
10490   int current_data_offset = 0;
10491   int ret;
10492
10493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (i, "del"))
10496         is_add = 0;
10497       else if (unformat (i, "del-chain"))
10498         {
10499           is_add = 0;
10500           del_chain = 1;
10501         }
10502       else if (unformat (i, "buckets %d", &nbuckets))
10503         ;
10504       else if (unformat (i, "memory_size %d", &memory_size))
10505         ;
10506       else if (unformat (i, "skip %d", &skip))
10507         ;
10508       else if (unformat (i, "match %d", &match))
10509         ;
10510       else if (unformat (i, "table %d", &table_index))
10511         ;
10512       else if (unformat (i, "mask %U", unformat_classify_mask,
10513                          &mask, &skip, &match))
10514         ;
10515       else if (unformat (i, "next-table %d", &next_table_index))
10516         ;
10517       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10518                          &miss_next_index))
10519         ;
10520       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10521                          &miss_next_index))
10522         ;
10523       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10524                          &miss_next_index))
10525         ;
10526       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10527         ;
10528       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10529         ;
10530       else
10531         break;
10532     }
10533
10534   if (is_add && mask == 0)
10535     {
10536       errmsg ("Mask required");
10537       return -99;
10538     }
10539
10540   if (is_add && skip == ~0)
10541     {
10542       errmsg ("skip count required");
10543       return -99;
10544     }
10545
10546   if (is_add && match == ~0)
10547     {
10548       errmsg ("match count required");
10549       return -99;
10550     }
10551
10552   if (!is_add && table_index == ~0)
10553     {
10554       errmsg ("table index required for delete");
10555       return -99;
10556     }
10557
10558   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10559
10560   mp->is_add = is_add;
10561   mp->del_chain = del_chain;
10562   mp->table_index = ntohl (table_index);
10563   mp->nbuckets = ntohl (nbuckets);
10564   mp->memory_size = ntohl (memory_size);
10565   mp->skip_n_vectors = ntohl (skip);
10566   mp->match_n_vectors = ntohl (match);
10567   mp->next_table_index = ntohl (next_table_index);
10568   mp->miss_next_index = ntohl (miss_next_index);
10569   mp->current_data_flag = ntohl (current_data_flag);
10570   mp->current_data_offset = ntohl (current_data_offset);
10571   mp->mask_len = ntohl (vec_len (mask));
10572   clib_memcpy (mp->mask, mask, vec_len (mask));
10573
10574   vec_free (mask);
10575
10576   S (mp);
10577   W (ret);
10578   return ret;
10579 }
10580
10581 #if VPP_API_TEST_BUILTIN == 0
10582 uword
10583 unformat_l4_match (unformat_input_t * input, va_list * args)
10584 {
10585   u8 **matchp = va_arg (*args, u8 **);
10586
10587   u8 *proto_header = 0;
10588   int src_port = 0;
10589   int dst_port = 0;
10590
10591   tcpudp_header_t h;
10592
10593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10594     {
10595       if (unformat (input, "src_port %d", &src_port))
10596         ;
10597       else if (unformat (input, "dst_port %d", &dst_port))
10598         ;
10599       else
10600         return 0;
10601     }
10602
10603   h.src_port = clib_host_to_net_u16 (src_port);
10604   h.dst_port = clib_host_to_net_u16 (dst_port);
10605   vec_validate (proto_header, sizeof (h) - 1);
10606   memcpy (proto_header, &h, sizeof (h));
10607
10608   *matchp = proto_header;
10609
10610   return 1;
10611 }
10612
10613 uword
10614 unformat_ip4_match (unformat_input_t * input, va_list * args)
10615 {
10616   u8 **matchp = va_arg (*args, u8 **);
10617   u8 *match = 0;
10618   ip4_header_t *ip;
10619   int version = 0;
10620   u32 version_val;
10621   int hdr_length = 0;
10622   u32 hdr_length_val;
10623   int src = 0, dst = 0;
10624   ip4_address_t src_val, dst_val;
10625   int proto = 0;
10626   u32 proto_val;
10627   int tos = 0;
10628   u32 tos_val;
10629   int length = 0;
10630   u32 length_val;
10631   int fragment_id = 0;
10632   u32 fragment_id_val;
10633   int ttl = 0;
10634   int ttl_val;
10635   int checksum = 0;
10636   u32 checksum_val;
10637
10638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10639     {
10640       if (unformat (input, "version %d", &version_val))
10641         version = 1;
10642       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10643         hdr_length = 1;
10644       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10645         src = 1;
10646       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10647         dst = 1;
10648       else if (unformat (input, "proto %d", &proto_val))
10649         proto = 1;
10650       else if (unformat (input, "tos %d", &tos_val))
10651         tos = 1;
10652       else if (unformat (input, "length %d", &length_val))
10653         length = 1;
10654       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10655         fragment_id = 1;
10656       else if (unformat (input, "ttl %d", &ttl_val))
10657         ttl = 1;
10658       else if (unformat (input, "checksum %d", &checksum_val))
10659         checksum = 1;
10660       else
10661         break;
10662     }
10663
10664   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10665       + ttl + checksum == 0)
10666     return 0;
10667
10668   /*
10669    * Aligned because we use the real comparison functions
10670    */
10671   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10672
10673   ip = (ip4_header_t *) match;
10674
10675   /* These are realistically matched in practice */
10676   if (src)
10677     ip->src_address.as_u32 = src_val.as_u32;
10678
10679   if (dst)
10680     ip->dst_address.as_u32 = dst_val.as_u32;
10681
10682   if (proto)
10683     ip->protocol = proto_val;
10684
10685
10686   /* These are not, but they're included for completeness */
10687   if (version)
10688     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10689
10690   if (hdr_length)
10691     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10692
10693   if (tos)
10694     ip->tos = tos_val;
10695
10696   if (length)
10697     ip->length = clib_host_to_net_u16 (length_val);
10698
10699   if (ttl)
10700     ip->ttl = ttl_val;
10701
10702   if (checksum)
10703     ip->checksum = clib_host_to_net_u16 (checksum_val);
10704
10705   *matchp = match;
10706   return 1;
10707 }
10708
10709 uword
10710 unformat_ip6_match (unformat_input_t * input, va_list * args)
10711 {
10712   u8 **matchp = va_arg (*args, u8 **);
10713   u8 *match = 0;
10714   ip6_header_t *ip;
10715   int version = 0;
10716   u32 version_val;
10717   u8 traffic_class = 0;
10718   u32 traffic_class_val = 0;
10719   u8 flow_label = 0;
10720   u8 flow_label_val;
10721   int src = 0, dst = 0;
10722   ip6_address_t src_val, dst_val;
10723   int proto = 0;
10724   u32 proto_val;
10725   int payload_length = 0;
10726   u32 payload_length_val;
10727   int hop_limit = 0;
10728   int hop_limit_val;
10729   u32 ip_version_traffic_class_and_flow_label;
10730
10731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10732     {
10733       if (unformat (input, "version %d", &version_val))
10734         version = 1;
10735       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10736         traffic_class = 1;
10737       else if (unformat (input, "flow_label %d", &flow_label_val))
10738         flow_label = 1;
10739       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10740         src = 1;
10741       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10742         dst = 1;
10743       else if (unformat (input, "proto %d", &proto_val))
10744         proto = 1;
10745       else if (unformat (input, "payload_length %d", &payload_length_val))
10746         payload_length = 1;
10747       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10748         hop_limit = 1;
10749       else
10750         break;
10751     }
10752
10753   if (version + traffic_class + flow_label + src + dst + proto +
10754       payload_length + hop_limit == 0)
10755     return 0;
10756
10757   /*
10758    * Aligned because we use the real comparison functions
10759    */
10760   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10761
10762   ip = (ip6_header_t *) match;
10763
10764   if (src)
10765     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10766
10767   if (dst)
10768     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10769
10770   if (proto)
10771     ip->protocol = proto_val;
10772
10773   ip_version_traffic_class_and_flow_label = 0;
10774
10775   if (version)
10776     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10777
10778   if (traffic_class)
10779     ip_version_traffic_class_and_flow_label |=
10780       (traffic_class_val & 0xFF) << 20;
10781
10782   if (flow_label)
10783     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10784
10785   ip->ip_version_traffic_class_and_flow_label =
10786     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10787
10788   if (payload_length)
10789     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10790
10791   if (hop_limit)
10792     ip->hop_limit = hop_limit_val;
10793
10794   *matchp = match;
10795   return 1;
10796 }
10797
10798 uword
10799 unformat_l3_match (unformat_input_t * input, va_list * args)
10800 {
10801   u8 **matchp = va_arg (*args, u8 **);
10802
10803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10804     {
10805       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10806         return 1;
10807       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10808         return 1;
10809       else
10810         break;
10811     }
10812   return 0;
10813 }
10814
10815 uword
10816 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10817 {
10818   u8 *tagp = va_arg (*args, u8 *);
10819   u32 tag;
10820
10821   if (unformat (input, "%d", &tag))
10822     {
10823       tagp[0] = (tag >> 8) & 0x0F;
10824       tagp[1] = tag & 0xFF;
10825       return 1;
10826     }
10827
10828   return 0;
10829 }
10830
10831 uword
10832 unformat_l2_match (unformat_input_t * input, va_list * args)
10833 {
10834   u8 **matchp = va_arg (*args, u8 **);
10835   u8 *match = 0;
10836   u8 src = 0;
10837   u8 src_val[6];
10838   u8 dst = 0;
10839   u8 dst_val[6];
10840   u8 proto = 0;
10841   u16 proto_val;
10842   u8 tag1 = 0;
10843   u8 tag1_val[2];
10844   u8 tag2 = 0;
10845   u8 tag2_val[2];
10846   int len = 14;
10847   u8 ignore_tag1 = 0;
10848   u8 ignore_tag2 = 0;
10849   u8 cos1 = 0;
10850   u8 cos2 = 0;
10851   u32 cos1_val = 0;
10852   u32 cos2_val = 0;
10853
10854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10855     {
10856       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10857         src = 1;
10858       else
10859         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10860         dst = 1;
10861       else if (unformat (input, "proto %U",
10862                          unformat_ethernet_type_host_byte_order, &proto_val))
10863         proto = 1;
10864       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10865         tag1 = 1;
10866       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10867         tag2 = 1;
10868       else if (unformat (input, "ignore-tag1"))
10869         ignore_tag1 = 1;
10870       else if (unformat (input, "ignore-tag2"))
10871         ignore_tag2 = 1;
10872       else if (unformat (input, "cos1 %d", &cos1_val))
10873         cos1 = 1;
10874       else if (unformat (input, "cos2 %d", &cos2_val))
10875         cos2 = 1;
10876       else
10877         break;
10878     }
10879   if ((src + dst + proto + tag1 + tag2 +
10880        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10881     return 0;
10882
10883   if (tag1 || ignore_tag1 || cos1)
10884     len = 18;
10885   if (tag2 || ignore_tag2 || cos2)
10886     len = 22;
10887
10888   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10889
10890   if (dst)
10891     clib_memcpy (match, dst_val, 6);
10892
10893   if (src)
10894     clib_memcpy (match + 6, src_val, 6);
10895
10896   if (tag2)
10897     {
10898       /* inner vlan tag */
10899       match[19] = tag2_val[1];
10900       match[18] = tag2_val[0];
10901       if (cos2)
10902         match[18] |= (cos2_val & 0x7) << 5;
10903       if (proto)
10904         {
10905           match[21] = proto_val & 0xff;
10906           match[20] = proto_val >> 8;
10907         }
10908       if (tag1)
10909         {
10910           match[15] = tag1_val[1];
10911           match[14] = tag1_val[0];
10912         }
10913       if (cos1)
10914         match[14] |= (cos1_val & 0x7) << 5;
10915       *matchp = match;
10916       return 1;
10917     }
10918   if (tag1)
10919     {
10920       match[15] = tag1_val[1];
10921       match[14] = tag1_val[0];
10922       if (proto)
10923         {
10924           match[17] = proto_val & 0xff;
10925           match[16] = proto_val >> 8;
10926         }
10927       if (cos1)
10928         match[14] |= (cos1_val & 0x7) << 5;
10929
10930       *matchp = match;
10931       return 1;
10932     }
10933   if (cos2)
10934     match[18] |= (cos2_val & 0x7) << 5;
10935   if (cos1)
10936     match[14] |= (cos1_val & 0x7) << 5;
10937   if (proto)
10938     {
10939       match[13] = proto_val & 0xff;
10940       match[12] = proto_val >> 8;
10941     }
10942
10943   *matchp = match;
10944   return 1;
10945 }
10946
10947 uword
10948 unformat_qos_source (unformat_input_t * input, va_list * args)
10949 {
10950   int *qs = va_arg (*args, int *);
10951
10952   if (unformat (input, "ip"))
10953     *qs = QOS_SOURCE_IP;
10954   else if (unformat (input, "mpls"))
10955     *qs = QOS_SOURCE_MPLS;
10956   else if (unformat (input, "ext"))
10957     *qs = QOS_SOURCE_EXT;
10958   else if (unformat (input, "vlan"))
10959     *qs = QOS_SOURCE_VLAN;
10960   else
10961     return 0;
10962
10963   return 1;
10964 }
10965 #endif
10966
10967 uword
10968 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10969 {
10970   u8 **matchp = va_arg (*args, u8 **);
10971   u32 skip_n_vectors = va_arg (*args, u32);
10972   u32 match_n_vectors = va_arg (*args, u32);
10973
10974   u8 *match = 0;
10975   u8 *l2 = 0;
10976   u8 *l3 = 0;
10977   u8 *l4 = 0;
10978
10979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10980     {
10981       if (unformat (input, "hex %U", unformat_hex_string, &match))
10982         ;
10983       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10984         ;
10985       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10986         ;
10987       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10988         ;
10989       else
10990         break;
10991     }
10992
10993   if (l4 && !l3)
10994     {
10995       vec_free (match);
10996       vec_free (l2);
10997       vec_free (l4);
10998       return 0;
10999     }
11000
11001   if (match || l2 || l3 || l4)
11002     {
11003       if (l2 || l3 || l4)
11004         {
11005           /* "Win a free Ethernet header in every packet" */
11006           if (l2 == 0)
11007             vec_validate_aligned (l2, 13, sizeof (u32x4));
11008           match = l2;
11009           if (vec_len (l3))
11010             {
11011               vec_append_aligned (match, l3, sizeof (u32x4));
11012               vec_free (l3);
11013             }
11014           if (vec_len (l4))
11015             {
11016               vec_append_aligned (match, l4, sizeof (u32x4));
11017               vec_free (l4);
11018             }
11019         }
11020
11021       /* Make sure the vector is big enough even if key is all 0's */
11022       vec_validate_aligned
11023         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11024          sizeof (u32x4));
11025
11026       /* Set size, include skipped vectors */
11027       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11028
11029       *matchp = match;
11030
11031       return 1;
11032     }
11033
11034   return 0;
11035 }
11036
11037 static int
11038 api_classify_add_del_session (vat_main_t * vam)
11039 {
11040   unformat_input_t *i = vam->input;
11041   vl_api_classify_add_del_session_t *mp;
11042   int is_add = 1;
11043   u32 table_index = ~0;
11044   u32 hit_next_index = ~0;
11045   u32 opaque_index = ~0;
11046   u8 *match = 0;
11047   i32 advance = 0;
11048   u32 skip_n_vectors = 0;
11049   u32 match_n_vectors = 0;
11050   u32 action = 0;
11051   u32 metadata = 0;
11052   int ret;
11053
11054   /*
11055    * Warning: you have to supply skip_n and match_n
11056    * because the API client cant simply look at the classify
11057    * table object.
11058    */
11059
11060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11061     {
11062       if (unformat (i, "del"))
11063         is_add = 0;
11064       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11065                          &hit_next_index))
11066         ;
11067       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11068                          &hit_next_index))
11069         ;
11070       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11071                          &hit_next_index))
11072         ;
11073       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11074         ;
11075       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11076         ;
11077       else if (unformat (i, "opaque-index %d", &opaque_index))
11078         ;
11079       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11080         ;
11081       else if (unformat (i, "match_n %d", &match_n_vectors))
11082         ;
11083       else if (unformat (i, "match %U", api_unformat_classify_match,
11084                          &match, skip_n_vectors, match_n_vectors))
11085         ;
11086       else if (unformat (i, "advance %d", &advance))
11087         ;
11088       else if (unformat (i, "table-index %d", &table_index))
11089         ;
11090       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11091         action = 1;
11092       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11093         action = 2;
11094       else if (unformat (i, "action %d", &action))
11095         ;
11096       else if (unformat (i, "metadata %d", &metadata))
11097         ;
11098       else
11099         break;
11100     }
11101
11102   if (table_index == ~0)
11103     {
11104       errmsg ("Table index required");
11105       return -99;
11106     }
11107
11108   if (is_add && match == 0)
11109     {
11110       errmsg ("Match value required");
11111       return -99;
11112     }
11113
11114   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11115
11116   mp->is_add = is_add;
11117   mp->table_index = ntohl (table_index);
11118   mp->hit_next_index = ntohl (hit_next_index);
11119   mp->opaque_index = ntohl (opaque_index);
11120   mp->advance = ntohl (advance);
11121   mp->action = action;
11122   mp->metadata = ntohl (metadata);
11123   mp->match_len = ntohl (vec_len (match));
11124   clib_memcpy (mp->match, match, vec_len (match));
11125   vec_free (match);
11126
11127   S (mp);
11128   W (ret);
11129   return ret;
11130 }
11131
11132 static int
11133 api_classify_set_interface_ip_table (vat_main_t * vam)
11134 {
11135   unformat_input_t *i = vam->input;
11136   vl_api_classify_set_interface_ip_table_t *mp;
11137   u32 sw_if_index;
11138   int sw_if_index_set;
11139   u32 table_index = ~0;
11140   u8 is_ipv6 = 0;
11141   int ret;
11142
11143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11144     {
11145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11146         sw_if_index_set = 1;
11147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11148         sw_if_index_set = 1;
11149       else if (unformat (i, "table %d", &table_index))
11150         ;
11151       else
11152         {
11153           clib_warning ("parse error '%U'", format_unformat_error, i);
11154           return -99;
11155         }
11156     }
11157
11158   if (sw_if_index_set == 0)
11159     {
11160       errmsg ("missing interface name or sw_if_index");
11161       return -99;
11162     }
11163
11164
11165   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11166
11167   mp->sw_if_index = ntohl (sw_if_index);
11168   mp->table_index = ntohl (table_index);
11169   mp->is_ipv6 = is_ipv6;
11170
11171   S (mp);
11172   W (ret);
11173   return ret;
11174 }
11175
11176 static int
11177 api_classify_set_interface_l2_tables (vat_main_t * vam)
11178 {
11179   unformat_input_t *i = vam->input;
11180   vl_api_classify_set_interface_l2_tables_t *mp;
11181   u32 sw_if_index;
11182   int sw_if_index_set;
11183   u32 ip4_table_index = ~0;
11184   u32 ip6_table_index = ~0;
11185   u32 other_table_index = ~0;
11186   u32 is_input = 1;
11187   int ret;
11188
11189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11190     {
11191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11192         sw_if_index_set = 1;
11193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11196         ;
11197       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11198         ;
11199       else if (unformat (i, "other-table %d", &other_table_index))
11200         ;
11201       else if (unformat (i, "is-input %d", &is_input))
11202         ;
11203       else
11204         {
11205           clib_warning ("parse error '%U'", format_unformat_error, i);
11206           return -99;
11207         }
11208     }
11209
11210   if (sw_if_index_set == 0)
11211     {
11212       errmsg ("missing interface name or sw_if_index");
11213       return -99;
11214     }
11215
11216
11217   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11218
11219   mp->sw_if_index = ntohl (sw_if_index);
11220   mp->ip4_table_index = ntohl (ip4_table_index);
11221   mp->ip6_table_index = ntohl (ip6_table_index);
11222   mp->other_table_index = ntohl (other_table_index);
11223   mp->is_input = (u8) is_input;
11224
11225   S (mp);
11226   W (ret);
11227   return ret;
11228 }
11229
11230 static int
11231 api_set_ipfix_exporter (vat_main_t * vam)
11232 {
11233   unformat_input_t *i = vam->input;
11234   vl_api_set_ipfix_exporter_t *mp;
11235   ip4_address_t collector_address;
11236   u8 collector_address_set = 0;
11237   u32 collector_port = ~0;
11238   ip4_address_t src_address;
11239   u8 src_address_set = 0;
11240   u32 vrf_id = ~0;
11241   u32 path_mtu = ~0;
11242   u32 template_interval = ~0;
11243   u8 udp_checksum = 0;
11244   int ret;
11245
11246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (i, "collector_address %U", unformat_ip4_address,
11249                     &collector_address))
11250         collector_address_set = 1;
11251       else if (unformat (i, "collector_port %d", &collector_port))
11252         ;
11253       else if (unformat (i, "src_address %U", unformat_ip4_address,
11254                          &src_address))
11255         src_address_set = 1;
11256       else if (unformat (i, "vrf_id %d", &vrf_id))
11257         ;
11258       else if (unformat (i, "path_mtu %d", &path_mtu))
11259         ;
11260       else if (unformat (i, "template_interval %d", &template_interval))
11261         ;
11262       else if (unformat (i, "udp_checksum"))
11263         udp_checksum = 1;
11264       else
11265         break;
11266     }
11267
11268   if (collector_address_set == 0)
11269     {
11270       errmsg ("collector_address required");
11271       return -99;
11272     }
11273
11274   if (src_address_set == 0)
11275     {
11276       errmsg ("src_address required");
11277       return -99;
11278     }
11279
11280   M (SET_IPFIX_EXPORTER, mp);
11281
11282   memcpy (mp->collector_address, collector_address.data,
11283           sizeof (collector_address.data));
11284   mp->collector_port = htons ((u16) collector_port);
11285   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11286   mp->vrf_id = htonl (vrf_id);
11287   mp->path_mtu = htonl (path_mtu);
11288   mp->template_interval = htonl (template_interval);
11289   mp->udp_checksum = udp_checksum;
11290
11291   S (mp);
11292   W (ret);
11293   return ret;
11294 }
11295
11296 static int
11297 api_set_ipfix_classify_stream (vat_main_t * vam)
11298 {
11299   unformat_input_t *i = vam->input;
11300   vl_api_set_ipfix_classify_stream_t *mp;
11301   u32 domain_id = 0;
11302   u32 src_port = UDP_DST_PORT_ipfix;
11303   int ret;
11304
11305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (i, "domain %d", &domain_id))
11308         ;
11309       else if (unformat (i, "src_port %d", &src_port))
11310         ;
11311       else
11312         {
11313           errmsg ("unknown input `%U'", format_unformat_error, i);
11314           return -99;
11315         }
11316     }
11317
11318   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11319
11320   mp->domain_id = htonl (domain_id);
11321   mp->src_port = htons ((u16) src_port);
11322
11323   S (mp);
11324   W (ret);
11325   return ret;
11326 }
11327
11328 static int
11329 api_ipfix_classify_table_add_del (vat_main_t * vam)
11330 {
11331   unformat_input_t *i = vam->input;
11332   vl_api_ipfix_classify_table_add_del_t *mp;
11333   int is_add = -1;
11334   u32 classify_table_index = ~0;
11335   u8 ip_version = 0;
11336   u8 transport_protocol = 255;
11337   int ret;
11338
11339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11340     {
11341       if (unformat (i, "add"))
11342         is_add = 1;
11343       else if (unformat (i, "del"))
11344         is_add = 0;
11345       else if (unformat (i, "table %d", &classify_table_index))
11346         ;
11347       else if (unformat (i, "ip4"))
11348         ip_version = 4;
11349       else if (unformat (i, "ip6"))
11350         ip_version = 6;
11351       else if (unformat (i, "tcp"))
11352         transport_protocol = 6;
11353       else if (unformat (i, "udp"))
11354         transport_protocol = 17;
11355       else
11356         {
11357           errmsg ("unknown input `%U'", format_unformat_error, i);
11358           return -99;
11359         }
11360     }
11361
11362   if (is_add == -1)
11363     {
11364       errmsg ("expecting: add|del");
11365       return -99;
11366     }
11367   if (classify_table_index == ~0)
11368     {
11369       errmsg ("classifier table not specified");
11370       return -99;
11371     }
11372   if (ip_version == 0)
11373     {
11374       errmsg ("IP version not specified");
11375       return -99;
11376     }
11377
11378   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11379
11380   mp->is_add = is_add;
11381   mp->table_id = htonl (classify_table_index);
11382   mp->ip_version = ip_version;
11383   mp->transport_protocol = transport_protocol;
11384
11385   S (mp);
11386   W (ret);
11387   return ret;
11388 }
11389
11390 static int
11391 api_get_node_index (vat_main_t * vam)
11392 {
11393   unformat_input_t *i = vam->input;
11394   vl_api_get_node_index_t *mp;
11395   u8 *name = 0;
11396   int ret;
11397
11398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11399     {
11400       if (unformat (i, "node %s", &name))
11401         ;
11402       else
11403         break;
11404     }
11405   if (name == 0)
11406     {
11407       errmsg ("node name required");
11408       return -99;
11409     }
11410   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11411     {
11412       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11413       return -99;
11414     }
11415
11416   M (GET_NODE_INDEX, mp);
11417   clib_memcpy (mp->node_name, name, vec_len (name));
11418   vec_free (name);
11419
11420   S (mp);
11421   W (ret);
11422   return ret;
11423 }
11424
11425 static int
11426 api_get_next_index (vat_main_t * vam)
11427 {
11428   unformat_input_t *i = vam->input;
11429   vl_api_get_next_index_t *mp;
11430   u8 *node_name = 0, *next_node_name = 0;
11431   int ret;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "node-name %s", &node_name))
11436         ;
11437       else if (unformat (i, "next-node-name %s", &next_node_name))
11438         break;
11439     }
11440
11441   if (node_name == 0)
11442     {
11443       errmsg ("node name required");
11444       return -99;
11445     }
11446   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11447     {
11448       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11449       return -99;
11450     }
11451
11452   if (next_node_name == 0)
11453     {
11454       errmsg ("next node name required");
11455       return -99;
11456     }
11457   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11458     {
11459       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11460       return -99;
11461     }
11462
11463   M (GET_NEXT_INDEX, mp);
11464   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11465   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11466   vec_free (node_name);
11467   vec_free (next_node_name);
11468
11469   S (mp);
11470   W (ret);
11471   return ret;
11472 }
11473
11474 static int
11475 api_add_node_next (vat_main_t * vam)
11476 {
11477   unformat_input_t *i = vam->input;
11478   vl_api_add_node_next_t *mp;
11479   u8 *name = 0;
11480   u8 *next = 0;
11481   int ret;
11482
11483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (i, "node %s", &name))
11486         ;
11487       else if (unformat (i, "next %s", &next))
11488         ;
11489       else
11490         break;
11491     }
11492   if (name == 0)
11493     {
11494       errmsg ("node name required");
11495       return -99;
11496     }
11497   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11498     {
11499       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11500       return -99;
11501     }
11502   if (next == 0)
11503     {
11504       errmsg ("next node required");
11505       return -99;
11506     }
11507   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11508     {
11509       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11510       return -99;
11511     }
11512
11513   M (ADD_NODE_NEXT, mp);
11514   clib_memcpy (mp->node_name, name, vec_len (name));
11515   clib_memcpy (mp->next_name, next, vec_len (next));
11516   vec_free (name);
11517   vec_free (next);
11518
11519   S (mp);
11520   W (ret);
11521   return ret;
11522 }
11523
11524 static int
11525 api_l2tpv3_create_tunnel (vat_main_t * vam)
11526 {
11527   unformat_input_t *i = vam->input;
11528   ip6_address_t client_address, our_address;
11529   int client_address_set = 0;
11530   int our_address_set = 0;
11531   u32 local_session_id = 0;
11532   u32 remote_session_id = 0;
11533   u64 local_cookie = 0;
11534   u64 remote_cookie = 0;
11535   u8 l2_sublayer_present = 0;
11536   vl_api_l2tpv3_create_tunnel_t *mp;
11537   int ret;
11538
11539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11540     {
11541       if (unformat (i, "client_address %U", unformat_ip6_address,
11542                     &client_address))
11543         client_address_set = 1;
11544       else if (unformat (i, "our_address %U", unformat_ip6_address,
11545                          &our_address))
11546         our_address_set = 1;
11547       else if (unformat (i, "local_session_id %d", &local_session_id))
11548         ;
11549       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11550         ;
11551       else if (unformat (i, "local_cookie %lld", &local_cookie))
11552         ;
11553       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11554         ;
11555       else if (unformat (i, "l2-sublayer-present"))
11556         l2_sublayer_present = 1;
11557       else
11558         break;
11559     }
11560
11561   if (client_address_set == 0)
11562     {
11563       errmsg ("client_address required");
11564       return -99;
11565     }
11566
11567   if (our_address_set == 0)
11568     {
11569       errmsg ("our_address required");
11570       return -99;
11571     }
11572
11573   M (L2TPV3_CREATE_TUNNEL, mp);
11574
11575   clib_memcpy (mp->client_address, client_address.as_u8,
11576                sizeof (mp->client_address));
11577
11578   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11579
11580   mp->local_session_id = ntohl (local_session_id);
11581   mp->remote_session_id = ntohl (remote_session_id);
11582   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11583   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11584   mp->l2_sublayer_present = l2_sublayer_present;
11585   mp->is_ipv6 = 1;
11586
11587   S (mp);
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static int
11593 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   u32 sw_if_index;
11597   u8 sw_if_index_set = 0;
11598   u64 new_local_cookie = 0;
11599   u64 new_remote_cookie = 0;
11600   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11601   int ret;
11602
11603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11604     {
11605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11606         sw_if_index_set = 1;
11607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11608         sw_if_index_set = 1;
11609       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11610         ;
11611       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11612         ;
11613       else
11614         break;
11615     }
11616
11617   if (sw_if_index_set == 0)
11618     {
11619       errmsg ("missing interface name or sw_if_index");
11620       return -99;
11621     }
11622
11623   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11624
11625   mp->sw_if_index = ntohl (sw_if_index);
11626   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11627   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11628
11629   S (mp);
11630   W (ret);
11631   return ret;
11632 }
11633
11634 static int
11635 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11636 {
11637   unformat_input_t *i = vam->input;
11638   vl_api_l2tpv3_interface_enable_disable_t *mp;
11639   u32 sw_if_index;
11640   u8 sw_if_index_set = 0;
11641   u8 enable_disable = 1;
11642   int ret;
11643
11644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11645     {
11646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11647         sw_if_index_set = 1;
11648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11649         sw_if_index_set = 1;
11650       else if (unformat (i, "enable"))
11651         enable_disable = 1;
11652       else if (unformat (i, "disable"))
11653         enable_disable = 0;
11654       else
11655         break;
11656     }
11657
11658   if (sw_if_index_set == 0)
11659     {
11660       errmsg ("missing interface name or sw_if_index");
11661       return -99;
11662     }
11663
11664   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11665
11666   mp->sw_if_index = ntohl (sw_if_index);
11667   mp->enable_disable = enable_disable;
11668
11669   S (mp);
11670   W (ret);
11671   return ret;
11672 }
11673
11674 static int
11675 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11676 {
11677   unformat_input_t *i = vam->input;
11678   vl_api_l2tpv3_set_lookup_key_t *mp;
11679   u8 key = ~0;
11680   int ret;
11681
11682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11683     {
11684       if (unformat (i, "lookup_v6_src"))
11685         key = L2T_LOOKUP_SRC_ADDRESS;
11686       else if (unformat (i, "lookup_v6_dst"))
11687         key = L2T_LOOKUP_DST_ADDRESS;
11688       else if (unformat (i, "lookup_session_id"))
11689         key = L2T_LOOKUP_SESSION_ID;
11690       else
11691         break;
11692     }
11693
11694   if (key == (u8) ~ 0)
11695     {
11696       errmsg ("l2tp session lookup key unset");
11697       return -99;
11698     }
11699
11700   M (L2TPV3_SET_LOOKUP_KEY, mp);
11701
11702   mp->key = key;
11703
11704   S (mp);
11705   W (ret);
11706   return ret;
11707 }
11708
11709 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11710   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11711 {
11712   vat_main_t *vam = &vat_main;
11713
11714   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11715          format_ip6_address, mp->our_address,
11716          format_ip6_address, mp->client_address,
11717          clib_net_to_host_u32 (mp->sw_if_index));
11718
11719   print (vam->ofp,
11720          "   local cookies %016llx %016llx remote cookie %016llx",
11721          clib_net_to_host_u64 (mp->local_cookie[0]),
11722          clib_net_to_host_u64 (mp->local_cookie[1]),
11723          clib_net_to_host_u64 (mp->remote_cookie));
11724
11725   print (vam->ofp, "   local session-id %d remote session-id %d",
11726          clib_net_to_host_u32 (mp->local_session_id),
11727          clib_net_to_host_u32 (mp->remote_session_id));
11728
11729   print (vam->ofp, "   l2 specific sublayer %s\n",
11730          mp->l2_sublayer_present ? "preset" : "absent");
11731
11732 }
11733
11734 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11735   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11736 {
11737   vat_main_t *vam = &vat_main;
11738   vat_json_node_t *node = NULL;
11739   struct in6_addr addr;
11740
11741   if (VAT_JSON_ARRAY != vam->json_tree.type)
11742     {
11743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11744       vat_json_init_array (&vam->json_tree);
11745     }
11746   node = vat_json_array_add (&vam->json_tree);
11747
11748   vat_json_init_object (node);
11749
11750   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11751   vat_json_object_add_ip6 (node, "our_address", addr);
11752   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11753   vat_json_object_add_ip6 (node, "client_address", addr);
11754
11755   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11756   vat_json_init_array (lc);
11757   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11758   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11759   vat_json_object_add_uint (node, "remote_cookie",
11760                             clib_net_to_host_u64 (mp->remote_cookie));
11761
11762   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11763   vat_json_object_add_uint (node, "local_session_id",
11764                             clib_net_to_host_u32 (mp->local_session_id));
11765   vat_json_object_add_uint (node, "remote_session_id",
11766                             clib_net_to_host_u32 (mp->remote_session_id));
11767   vat_json_object_add_string_copy (node, "l2_sublayer",
11768                                    mp->l2_sublayer_present ? (u8 *) "present"
11769                                    : (u8 *) "absent");
11770 }
11771
11772 static int
11773 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11774 {
11775   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11776   vl_api_control_ping_t *mp_ping;
11777   int ret;
11778
11779   /* Get list of l2tpv3-tunnel interfaces */
11780   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11781   S (mp);
11782
11783   /* Use a control ping for synchronization */
11784   MPING (CONTROL_PING, mp_ping);
11785   S (mp_ping);
11786
11787   W (ret);
11788   return ret;
11789 }
11790
11791
11792 static void vl_api_sw_interface_tap_v2_details_t_handler
11793   (vl_api_sw_interface_tap_v2_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796
11797   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11798                     mp->host_ip4_prefix_len);
11799   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11800                     mp->host_ip6_prefix_len);
11801
11802   print (vam->ofp,
11803          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11804          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11805          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11806          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11807          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11808
11809   vec_free (ip4);
11810   vec_free (ip6);
11811 }
11812
11813 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11814   (vl_api_sw_interface_tap_v2_details_t * mp)
11815 {
11816   vat_main_t *vam = &vat_main;
11817   vat_json_node_t *node = NULL;
11818
11819   if (VAT_JSON_ARRAY != vam->json_tree.type)
11820     {
11821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11822       vat_json_init_array (&vam->json_tree);
11823     }
11824   node = vat_json_array_add (&vam->json_tree);
11825
11826   vat_json_init_object (node);
11827   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11828   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11829   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11830   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11831   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11832   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11833   vat_json_object_add_string_copy (node, "host_mac_addr",
11834                                    format (0, "%U", format_ethernet_address,
11835                                            &mp->host_mac_addr));
11836   vat_json_object_add_string_copy (node, "host_namespace",
11837                                    mp->host_namespace);
11838   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11839   vat_json_object_add_string_copy (node, "host_ip4_addr",
11840                                    format (0, "%U/%d", format_ip4_address,
11841                                            mp->host_ip4_addr,
11842                                            mp->host_ip4_prefix_len));
11843   vat_json_object_add_string_copy (node, "host_ip6_addr",
11844                                    format (0, "%U/%d", format_ip6_address,
11845                                            mp->host_ip6_addr,
11846                                            mp->host_ip6_prefix_len));
11847
11848 }
11849
11850 static int
11851 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11852 {
11853   vl_api_sw_interface_tap_v2_dump_t *mp;
11854   vl_api_control_ping_t *mp_ping;
11855   int ret;
11856
11857   print (vam->ofp,
11858          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11859          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11860          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11861          "host_ip6_addr");
11862
11863   /* Get list of tap interfaces */
11864   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11865   S (mp);
11866
11867   /* Use a control ping for synchronization */
11868   MPING (CONTROL_PING, mp_ping);
11869   S (mp_ping);
11870
11871   W (ret);
11872   return ret;
11873 }
11874
11875 static void vl_api_sw_interface_virtio_pci_details_t_handler
11876   (vl_api_sw_interface_virtio_pci_details_t * mp)
11877 {
11878   vat_main_t *vam = &vat_main;
11879
11880   typedef union
11881   {
11882     struct
11883     {
11884       u16 domain;
11885       u8 bus;
11886       u8 slot:5;
11887       u8 function:3;
11888     };
11889     u32 as_u32;
11890   } pci_addr_t;
11891   pci_addr_t addr;
11892   addr.as_u32 = ntohl (mp->pci_addr);
11893   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11894                          addr.slot, addr.function);
11895
11896   print (vam->ofp,
11897          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11898          pci_addr, ntohl (mp->sw_if_index),
11899          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11900          format_ethernet_address, mp->mac_addr,
11901          clib_net_to_host_u64 (mp->features));
11902   vec_free (pci_addr);
11903 }
11904
11905 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11906   (vl_api_sw_interface_virtio_pci_details_t * mp)
11907 {
11908   vat_main_t *vam = &vat_main;
11909   vat_json_node_t *node = NULL;
11910
11911   if (VAT_JSON_ARRAY != vam->json_tree.type)
11912     {
11913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11914       vat_json_init_array (&vam->json_tree);
11915     }
11916   node = vat_json_array_add (&vam->json_tree);
11917
11918   vat_json_init_object (node);
11919   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11920   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11921   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11922   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11923   vat_json_object_add_uint (node, "features",
11924                             clib_net_to_host_u64 (mp->features));
11925   vat_json_object_add_string_copy (node, "mac_addr",
11926                                    format (0, "%U", format_ethernet_address,
11927                                            &mp->mac_addr));
11928 }
11929
11930 static int
11931 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11932 {
11933   vl_api_sw_interface_virtio_pci_dump_t *mp;
11934   vl_api_control_ping_t *mp_ping;
11935   int ret;
11936
11937   print (vam->ofp,
11938          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11939          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11940          "mac_addr", "features");
11941
11942   /* Get list of tap interfaces */
11943   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11944   S (mp);
11945
11946   /* Use a control ping for synchronization */
11947   MPING (CONTROL_PING, mp_ping);
11948   S (mp_ping);
11949
11950   W (ret);
11951   return ret;
11952 }
11953
11954 static int
11955 api_vxlan_offload_rx (vat_main_t * vam)
11956 {
11957   unformat_input_t *line_input = vam->input;
11958   vl_api_vxlan_offload_rx_t *mp;
11959   u32 hw_if_index = ~0, rx_if_index = ~0;
11960   u8 is_add = 1;
11961   int ret;
11962
11963   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11964     {
11965       if (unformat (line_input, "del"))
11966         is_add = 0;
11967       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11968                          &hw_if_index))
11969         ;
11970       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11971         ;
11972       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11973                          &rx_if_index))
11974         ;
11975       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11976         ;
11977       else
11978         {
11979           errmsg ("parse error '%U'", format_unformat_error, line_input);
11980           return -99;
11981         }
11982     }
11983
11984   if (hw_if_index == ~0)
11985     {
11986       errmsg ("no hw interface");
11987       return -99;
11988     }
11989
11990   if (rx_if_index == ~0)
11991     {
11992       errmsg ("no rx tunnel");
11993       return -99;
11994     }
11995
11996   M (VXLAN_OFFLOAD_RX, mp);
11997
11998   mp->hw_if_index = ntohl (hw_if_index);
11999   mp->sw_if_index = ntohl (rx_if_index);
12000   mp->enable = is_add;
12001
12002   S (mp);
12003   W (ret);
12004   return ret;
12005 }
12006
12007 static uword unformat_vxlan_decap_next
12008   (unformat_input_t * input, va_list * args)
12009 {
12010   u32 *result = va_arg (*args, u32 *);
12011   u32 tmp;
12012
12013   if (unformat (input, "l2"))
12014     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12015   else if (unformat (input, "%d", &tmp))
12016     *result = tmp;
12017   else
12018     return 0;
12019   return 1;
12020 }
12021
12022 static int
12023 api_vxlan_add_del_tunnel (vat_main_t * vam)
12024 {
12025   unformat_input_t *line_input = vam->input;
12026   vl_api_vxlan_add_del_tunnel_t *mp;
12027   ip46_address_t src, dst;
12028   u8 is_add = 1;
12029   u8 ipv4_set = 0, ipv6_set = 0;
12030   u8 src_set = 0;
12031   u8 dst_set = 0;
12032   u8 grp_set = 0;
12033   u32 instance = ~0;
12034   u32 mcast_sw_if_index = ~0;
12035   u32 encap_vrf_id = 0;
12036   u32 decap_next_index = ~0;
12037   u32 vni = 0;
12038   int ret;
12039
12040   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12041   clib_memset (&src, 0, sizeof src);
12042   clib_memset (&dst, 0, sizeof dst);
12043
12044   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12045     {
12046       if (unformat (line_input, "del"))
12047         is_add = 0;
12048       else if (unformat (line_input, "instance %d", &instance))
12049         ;
12050       else
12051         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12052         {
12053           ipv4_set = 1;
12054           src_set = 1;
12055         }
12056       else
12057         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12058         {
12059           ipv4_set = 1;
12060           dst_set = 1;
12061         }
12062       else
12063         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12064         {
12065           ipv6_set = 1;
12066           src_set = 1;
12067         }
12068       else
12069         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12070         {
12071           ipv6_set = 1;
12072           dst_set = 1;
12073         }
12074       else if (unformat (line_input, "group %U %U",
12075                          unformat_ip4_address, &dst.ip4,
12076                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12077         {
12078           grp_set = dst_set = 1;
12079           ipv4_set = 1;
12080         }
12081       else if (unformat (line_input, "group %U",
12082                          unformat_ip4_address, &dst.ip4))
12083         {
12084           grp_set = dst_set = 1;
12085           ipv4_set = 1;
12086         }
12087       else if (unformat (line_input, "group %U %U",
12088                          unformat_ip6_address, &dst.ip6,
12089                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12090         {
12091           grp_set = dst_set = 1;
12092           ipv6_set = 1;
12093         }
12094       else if (unformat (line_input, "group %U",
12095                          unformat_ip6_address, &dst.ip6))
12096         {
12097           grp_set = dst_set = 1;
12098           ipv6_set = 1;
12099         }
12100       else
12101         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12102         ;
12103       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12104         ;
12105       else if (unformat (line_input, "decap-next %U",
12106                          unformat_vxlan_decap_next, &decap_next_index))
12107         ;
12108       else if (unformat (line_input, "vni %d", &vni))
12109         ;
12110       else
12111         {
12112           errmsg ("parse error '%U'", format_unformat_error, line_input);
12113           return -99;
12114         }
12115     }
12116
12117   if (src_set == 0)
12118     {
12119       errmsg ("tunnel src address not specified");
12120       return -99;
12121     }
12122   if (dst_set == 0)
12123     {
12124       errmsg ("tunnel dst address not specified");
12125       return -99;
12126     }
12127
12128   if (grp_set && !ip46_address_is_multicast (&dst))
12129     {
12130       errmsg ("tunnel group address not multicast");
12131       return -99;
12132     }
12133   if (grp_set && mcast_sw_if_index == ~0)
12134     {
12135       errmsg ("tunnel nonexistent multicast device");
12136       return -99;
12137     }
12138   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12139     {
12140       errmsg ("tunnel dst address must be unicast");
12141       return -99;
12142     }
12143
12144
12145   if (ipv4_set && ipv6_set)
12146     {
12147       errmsg ("both IPv4 and IPv6 addresses specified");
12148       return -99;
12149     }
12150
12151   if ((vni == 0) || (vni >> 24))
12152     {
12153       errmsg ("vni not specified or out of range");
12154       return -99;
12155     }
12156
12157   M (VXLAN_ADD_DEL_TUNNEL, mp);
12158
12159   if (ipv6_set)
12160     {
12161       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12162       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12163     }
12164   else
12165     {
12166       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12167       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12168     }
12169
12170   mp->instance = htonl (instance);
12171   mp->encap_vrf_id = ntohl (encap_vrf_id);
12172   mp->decap_next_index = ntohl (decap_next_index);
12173   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12174   mp->vni = ntohl (vni);
12175   mp->is_add = is_add;
12176   mp->is_ipv6 = ipv6_set;
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static void vl_api_vxlan_tunnel_details_t_handler
12184   (vl_api_vxlan_tunnel_details_t * mp)
12185 {
12186   vat_main_t *vam = &vat_main;
12187   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12188   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12189
12190   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12191          ntohl (mp->sw_if_index),
12192          ntohl (mp->instance),
12193          format_ip46_address, &src, IP46_TYPE_ANY,
12194          format_ip46_address, &dst, IP46_TYPE_ANY,
12195          ntohl (mp->encap_vrf_id),
12196          ntohl (mp->decap_next_index), ntohl (mp->vni),
12197          ntohl (mp->mcast_sw_if_index));
12198 }
12199
12200 static void vl_api_vxlan_tunnel_details_t_handler_json
12201   (vl_api_vxlan_tunnel_details_t * mp)
12202 {
12203   vat_main_t *vam = &vat_main;
12204   vat_json_node_t *node = NULL;
12205
12206   if (VAT_JSON_ARRAY != vam->json_tree.type)
12207     {
12208       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12209       vat_json_init_array (&vam->json_tree);
12210     }
12211   node = vat_json_array_add (&vam->json_tree);
12212
12213   vat_json_init_object (node);
12214   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12215
12216   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12217
12218   if (mp->is_ipv6)
12219     {
12220       struct in6_addr ip6;
12221
12222       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12223       vat_json_object_add_ip6 (node, "src_address", ip6);
12224       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12225       vat_json_object_add_ip6 (node, "dst_address", ip6);
12226     }
12227   else
12228     {
12229       struct in_addr ip4;
12230
12231       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12232       vat_json_object_add_ip4 (node, "src_address", ip4);
12233       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12234       vat_json_object_add_ip4 (node, "dst_address", ip4);
12235     }
12236   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12237   vat_json_object_add_uint (node, "decap_next_index",
12238                             ntohl (mp->decap_next_index));
12239   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12240   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12241   vat_json_object_add_uint (node, "mcast_sw_if_index",
12242                             ntohl (mp->mcast_sw_if_index));
12243 }
12244
12245 static int
12246 api_vxlan_tunnel_dump (vat_main_t * vam)
12247 {
12248   unformat_input_t *i = vam->input;
12249   vl_api_vxlan_tunnel_dump_t *mp;
12250   vl_api_control_ping_t *mp_ping;
12251   u32 sw_if_index;
12252   u8 sw_if_index_set = 0;
12253   int ret;
12254
12255   /* Parse args required to build the message */
12256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12257     {
12258       if (unformat (i, "sw_if_index %d", &sw_if_index))
12259         sw_if_index_set = 1;
12260       else
12261         break;
12262     }
12263
12264   if (sw_if_index_set == 0)
12265     {
12266       sw_if_index = ~0;
12267     }
12268
12269   if (!vam->json_output)
12270     {
12271       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12272              "sw_if_index", "instance", "src_address", "dst_address",
12273              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12274     }
12275
12276   /* Get list of vxlan-tunnel interfaces */
12277   M (VXLAN_TUNNEL_DUMP, mp);
12278
12279   mp->sw_if_index = htonl (sw_if_index);
12280
12281   S (mp);
12282
12283   /* Use a control ping for synchronization */
12284   MPING (CONTROL_PING, mp_ping);
12285   S (mp_ping);
12286
12287   W (ret);
12288   return ret;
12289 }
12290
12291 static uword unformat_geneve_decap_next
12292   (unformat_input_t * input, va_list * args)
12293 {
12294   u32 *result = va_arg (*args, u32 *);
12295   u32 tmp;
12296
12297   if (unformat (input, "l2"))
12298     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12299   else if (unformat (input, "%d", &tmp))
12300     *result = tmp;
12301   else
12302     return 0;
12303   return 1;
12304 }
12305
12306 static int
12307 api_geneve_add_del_tunnel (vat_main_t * vam)
12308 {
12309   unformat_input_t *line_input = vam->input;
12310   vl_api_geneve_add_del_tunnel_t *mp;
12311   ip46_address_t src, dst;
12312   u8 is_add = 1;
12313   u8 ipv4_set = 0, ipv6_set = 0;
12314   u8 src_set = 0;
12315   u8 dst_set = 0;
12316   u8 grp_set = 0;
12317   u32 mcast_sw_if_index = ~0;
12318   u32 encap_vrf_id = 0;
12319   u32 decap_next_index = ~0;
12320   u32 vni = 0;
12321   int ret;
12322
12323   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12324   clib_memset (&src, 0, sizeof src);
12325   clib_memset (&dst, 0, sizeof dst);
12326
12327   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12328     {
12329       if (unformat (line_input, "del"))
12330         is_add = 0;
12331       else
12332         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12333         {
12334           ipv4_set = 1;
12335           src_set = 1;
12336         }
12337       else
12338         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12339         {
12340           ipv4_set = 1;
12341           dst_set = 1;
12342         }
12343       else
12344         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12345         {
12346           ipv6_set = 1;
12347           src_set = 1;
12348         }
12349       else
12350         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12351         {
12352           ipv6_set = 1;
12353           dst_set = 1;
12354         }
12355       else if (unformat (line_input, "group %U %U",
12356                          unformat_ip4_address, &dst.ip4,
12357                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12358         {
12359           grp_set = dst_set = 1;
12360           ipv4_set = 1;
12361         }
12362       else if (unformat (line_input, "group %U",
12363                          unformat_ip4_address, &dst.ip4))
12364         {
12365           grp_set = dst_set = 1;
12366           ipv4_set = 1;
12367         }
12368       else if (unformat (line_input, "group %U %U",
12369                          unformat_ip6_address, &dst.ip6,
12370                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12371         {
12372           grp_set = dst_set = 1;
12373           ipv6_set = 1;
12374         }
12375       else if (unformat (line_input, "group %U",
12376                          unformat_ip6_address, &dst.ip6))
12377         {
12378           grp_set = dst_set = 1;
12379           ipv6_set = 1;
12380         }
12381       else
12382         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12383         ;
12384       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12385         ;
12386       else if (unformat (line_input, "decap-next %U",
12387                          unformat_geneve_decap_next, &decap_next_index))
12388         ;
12389       else if (unformat (line_input, "vni %d", &vni))
12390         ;
12391       else
12392         {
12393           errmsg ("parse error '%U'", format_unformat_error, line_input);
12394           return -99;
12395         }
12396     }
12397
12398   if (src_set == 0)
12399     {
12400       errmsg ("tunnel src address not specified");
12401       return -99;
12402     }
12403   if (dst_set == 0)
12404     {
12405       errmsg ("tunnel dst address not specified");
12406       return -99;
12407     }
12408
12409   if (grp_set && !ip46_address_is_multicast (&dst))
12410     {
12411       errmsg ("tunnel group address not multicast");
12412       return -99;
12413     }
12414   if (grp_set && mcast_sw_if_index == ~0)
12415     {
12416       errmsg ("tunnel nonexistent multicast device");
12417       return -99;
12418     }
12419   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12420     {
12421       errmsg ("tunnel dst address must be unicast");
12422       return -99;
12423     }
12424
12425
12426   if (ipv4_set && ipv6_set)
12427     {
12428       errmsg ("both IPv4 and IPv6 addresses specified");
12429       return -99;
12430     }
12431
12432   if ((vni == 0) || (vni >> 24))
12433     {
12434       errmsg ("vni not specified or out of range");
12435       return -99;
12436     }
12437
12438   M (GENEVE_ADD_DEL_TUNNEL, mp);
12439
12440   if (ipv6_set)
12441     {
12442       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12443       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12444     }
12445   else
12446     {
12447       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12448       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12449     }
12450   mp->encap_vrf_id = ntohl (encap_vrf_id);
12451   mp->decap_next_index = ntohl (decap_next_index);
12452   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12453   mp->vni = ntohl (vni);
12454   mp->is_add = is_add;
12455
12456   S (mp);
12457   W (ret);
12458   return ret;
12459 }
12460
12461 static void vl_api_geneve_tunnel_details_t_handler
12462   (vl_api_geneve_tunnel_details_t * mp)
12463 {
12464   vat_main_t *vam = &vat_main;
12465   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12466   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12467
12468   if (mp->src_address.af == ADDRESS_IP6)
12469     {
12470       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12471       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12472     }
12473   else
12474     {
12475       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12476       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12477     }
12478
12479   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12480          ntohl (mp->sw_if_index),
12481          format_ip46_address, &src, IP46_TYPE_ANY,
12482          format_ip46_address, &dst, IP46_TYPE_ANY,
12483          ntohl (mp->encap_vrf_id),
12484          ntohl (mp->decap_next_index), ntohl (mp->vni),
12485          ntohl (mp->mcast_sw_if_index));
12486 }
12487
12488 static void vl_api_geneve_tunnel_details_t_handler_json
12489   (vl_api_geneve_tunnel_details_t * mp)
12490 {
12491   vat_main_t *vam = &vat_main;
12492   vat_json_node_t *node = NULL;
12493   bool is_ipv6;
12494
12495   if (VAT_JSON_ARRAY != vam->json_tree.type)
12496     {
12497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12498       vat_json_init_array (&vam->json_tree);
12499     }
12500   node = vat_json_array_add (&vam->json_tree);
12501
12502   vat_json_init_object (node);
12503   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12504   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12505   if (is_ipv6)
12506     {
12507       struct in6_addr ip6;
12508
12509       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12510       vat_json_object_add_ip6 (node, "src_address", ip6);
12511       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12512       vat_json_object_add_ip6 (node, "dst_address", ip6);
12513     }
12514   else
12515     {
12516       struct in_addr ip4;
12517
12518       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12519       vat_json_object_add_ip4 (node, "src_address", ip4);
12520       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12521       vat_json_object_add_ip4 (node, "dst_address", ip4);
12522     }
12523   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12524   vat_json_object_add_uint (node, "decap_next_index",
12525                             ntohl (mp->decap_next_index));
12526   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12527   vat_json_object_add_uint (node, "mcast_sw_if_index",
12528                             ntohl (mp->mcast_sw_if_index));
12529 }
12530
12531 static int
12532 api_geneve_tunnel_dump (vat_main_t * vam)
12533 {
12534   unformat_input_t *i = vam->input;
12535   vl_api_geneve_tunnel_dump_t *mp;
12536   vl_api_control_ping_t *mp_ping;
12537   u32 sw_if_index;
12538   u8 sw_if_index_set = 0;
12539   int ret;
12540
12541   /* Parse args required to build the message */
12542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12543     {
12544       if (unformat (i, "sw_if_index %d", &sw_if_index))
12545         sw_if_index_set = 1;
12546       else
12547         break;
12548     }
12549
12550   if (sw_if_index_set == 0)
12551     {
12552       sw_if_index = ~0;
12553     }
12554
12555   if (!vam->json_output)
12556     {
12557       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12558              "sw_if_index", "local_address", "remote_address",
12559              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12560     }
12561
12562   /* Get list of geneve-tunnel interfaces */
12563   M (GENEVE_TUNNEL_DUMP, mp);
12564
12565   mp->sw_if_index = htonl (sw_if_index);
12566
12567   S (mp);
12568
12569   /* Use a control ping for synchronization */
12570   M (CONTROL_PING, mp_ping);
12571   S (mp_ping);
12572
12573   W (ret);
12574   return ret;
12575 }
12576
12577 static int
12578 api_gre_tunnel_add_del (vat_main_t * vam)
12579 {
12580   unformat_input_t *line_input = vam->input;
12581   vl_api_address_t src = { }, dst =
12582   {
12583   };
12584   vl_api_gre_tunnel_add_del_t *mp;
12585   vl_api_gre_tunnel_type_t t_type;
12586   u8 is_add = 1;
12587   u8 src_set = 0;
12588   u8 dst_set = 0;
12589   u32 outer_fib_id = 0;
12590   u32 session_id = 0;
12591   u32 instance = ~0;
12592   int ret;
12593
12594   t_type = GRE_API_TUNNEL_TYPE_L3;
12595
12596   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12597     {
12598       if (unformat (line_input, "del"))
12599         is_add = 0;
12600       else if (unformat (line_input, "instance %d", &instance))
12601         ;
12602       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12603         {
12604           src_set = 1;
12605         }
12606       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12607         {
12608           dst_set = 1;
12609         }
12610       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12611         ;
12612       else if (unformat (line_input, "teb"))
12613         t_type = GRE_API_TUNNEL_TYPE_TEB;
12614       else if (unformat (line_input, "erspan %d", &session_id))
12615         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12616       else
12617         {
12618           errmsg ("parse error '%U'", format_unformat_error, line_input);
12619           return -99;
12620         }
12621     }
12622
12623   if (src_set == 0)
12624     {
12625       errmsg ("tunnel src address not specified");
12626       return -99;
12627     }
12628   if (dst_set == 0)
12629     {
12630       errmsg ("tunnel dst address not specified");
12631       return -99;
12632     }
12633
12634   M (GRE_TUNNEL_ADD_DEL, mp);
12635
12636   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12637   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12638
12639   mp->tunnel.instance = htonl (instance);
12640   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12641   mp->is_add = is_add;
12642   mp->tunnel.session_id = htons ((u16) session_id);
12643   mp->tunnel.type = htonl (t_type);
12644
12645   S (mp);
12646   W (ret);
12647   return ret;
12648 }
12649
12650 static void vl_api_gre_tunnel_details_t_handler
12651   (vl_api_gre_tunnel_details_t * mp)
12652 {
12653   vat_main_t *vam = &vat_main;
12654
12655   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12656          ntohl (mp->tunnel.sw_if_index),
12657          ntohl (mp->tunnel.instance),
12658          format_vl_api_address, &mp->tunnel.src,
12659          format_vl_api_address, &mp->tunnel.dst,
12660          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12661          ntohl (mp->tunnel.session_id));
12662 }
12663
12664 static void vl_api_gre_tunnel_details_t_handler_json
12665   (vl_api_gre_tunnel_details_t * mp)
12666 {
12667   vat_main_t *vam = &vat_main;
12668   vat_json_node_t *node = NULL;
12669
12670   if (VAT_JSON_ARRAY != vam->json_tree.type)
12671     {
12672       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12673       vat_json_init_array (&vam->json_tree);
12674     }
12675   node = vat_json_array_add (&vam->json_tree);
12676
12677   vat_json_init_object (node);
12678   vat_json_object_add_uint (node, "sw_if_index",
12679                             ntohl (mp->tunnel.sw_if_index));
12680   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12681
12682   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12683   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12684   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12685   vat_json_object_add_uint (node, "outer_fib_id",
12686                             ntohl (mp->tunnel.outer_fib_id));
12687   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12688 }
12689
12690 static int
12691 api_gre_tunnel_dump (vat_main_t * vam)
12692 {
12693   unformat_input_t *i = vam->input;
12694   vl_api_gre_tunnel_dump_t *mp;
12695   vl_api_control_ping_t *mp_ping;
12696   u32 sw_if_index;
12697   u8 sw_if_index_set = 0;
12698   int ret;
12699
12700   /* Parse args required to build the message */
12701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12702     {
12703       if (unformat (i, "sw_if_index %d", &sw_if_index))
12704         sw_if_index_set = 1;
12705       else
12706         break;
12707     }
12708
12709   if (sw_if_index_set == 0)
12710     {
12711       sw_if_index = ~0;
12712     }
12713
12714   if (!vam->json_output)
12715     {
12716       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12717              "sw_if_index", "instance", "src_address", "dst_address",
12718              "tunnel_type", "outer_fib_id", "session_id");
12719     }
12720
12721   /* Get list of gre-tunnel interfaces */
12722   M (GRE_TUNNEL_DUMP, mp);
12723
12724   mp->sw_if_index = htonl (sw_if_index);
12725
12726   S (mp);
12727
12728   /* Use a control ping for synchronization */
12729   MPING (CONTROL_PING, mp_ping);
12730   S (mp_ping);
12731
12732   W (ret);
12733   return ret;
12734 }
12735
12736 static int
12737 api_l2_fib_clear_table (vat_main_t * vam)
12738 {
12739 //  unformat_input_t * i = vam->input;
12740   vl_api_l2_fib_clear_table_t *mp;
12741   int ret;
12742
12743   M (L2_FIB_CLEAR_TABLE, mp);
12744
12745   S (mp);
12746   W (ret);
12747   return ret;
12748 }
12749
12750 static int
12751 api_l2_interface_efp_filter (vat_main_t * vam)
12752 {
12753   unformat_input_t *i = vam->input;
12754   vl_api_l2_interface_efp_filter_t *mp;
12755   u32 sw_if_index;
12756   u8 enable = 1;
12757   u8 sw_if_index_set = 0;
12758   int ret;
12759
12760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12761     {
12762       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12763         sw_if_index_set = 1;
12764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12765         sw_if_index_set = 1;
12766       else if (unformat (i, "enable"))
12767         enable = 1;
12768       else if (unformat (i, "disable"))
12769         enable = 0;
12770       else
12771         {
12772           clib_warning ("parse error '%U'", format_unformat_error, i);
12773           return -99;
12774         }
12775     }
12776
12777   if (sw_if_index_set == 0)
12778     {
12779       errmsg ("missing sw_if_index");
12780       return -99;
12781     }
12782
12783   M (L2_INTERFACE_EFP_FILTER, mp);
12784
12785   mp->sw_if_index = ntohl (sw_if_index);
12786   mp->enable_disable = enable;
12787
12788   S (mp);
12789   W (ret);
12790   return ret;
12791 }
12792
12793 #define foreach_vtr_op                          \
12794 _("disable",  L2_VTR_DISABLED)                  \
12795 _("push-1",  L2_VTR_PUSH_1)                     \
12796 _("push-2",  L2_VTR_PUSH_2)                     \
12797 _("pop-1",  L2_VTR_POP_1)                       \
12798 _("pop-2",  L2_VTR_POP_2)                       \
12799 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12800 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12801 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12802 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12803
12804 static int
12805 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12806 {
12807   unformat_input_t *i = vam->input;
12808   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12809   u32 sw_if_index;
12810   u8 sw_if_index_set = 0;
12811   u8 vtr_op_set = 0;
12812   u32 vtr_op = 0;
12813   u32 push_dot1q = 1;
12814   u32 tag1 = ~0;
12815   u32 tag2 = ~0;
12816   int ret;
12817
12818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819     {
12820       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12821         sw_if_index_set = 1;
12822       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12823         sw_if_index_set = 1;
12824       else if (unformat (i, "vtr_op %d", &vtr_op))
12825         vtr_op_set = 1;
12826 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12827       foreach_vtr_op
12828 #undef _
12829         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12830         ;
12831       else if (unformat (i, "tag1 %d", &tag1))
12832         ;
12833       else if (unformat (i, "tag2 %d", &tag2))
12834         ;
12835       else
12836         {
12837           clib_warning ("parse error '%U'", format_unformat_error, i);
12838           return -99;
12839         }
12840     }
12841
12842   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12843     {
12844       errmsg ("missing vtr operation or sw_if_index");
12845       return -99;
12846     }
12847
12848   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12849   mp->sw_if_index = ntohl (sw_if_index);
12850   mp->vtr_op = ntohl (vtr_op);
12851   mp->push_dot1q = ntohl (push_dot1q);
12852   mp->tag1 = ntohl (tag1);
12853   mp->tag2 = ntohl (tag2);
12854
12855   S (mp);
12856   W (ret);
12857   return ret;
12858 }
12859
12860 static int
12861 api_create_vhost_user_if (vat_main_t * vam)
12862 {
12863   unformat_input_t *i = vam->input;
12864   vl_api_create_vhost_user_if_t *mp;
12865   u8 *file_name;
12866   u8 is_server = 0;
12867   u8 file_name_set = 0;
12868   u32 custom_dev_instance = ~0;
12869   u8 hwaddr[6];
12870   u8 use_custom_mac = 0;
12871   u8 disable_mrg_rxbuf = 0;
12872   u8 disable_indirect_desc = 0;
12873   u8 *tag = 0;
12874   u8 enable_gso = 0;
12875   int ret;
12876
12877   /* Shut up coverity */
12878   clib_memset (hwaddr, 0, sizeof (hwaddr));
12879
12880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12881     {
12882       if (unformat (i, "socket %s", &file_name))
12883         {
12884           file_name_set = 1;
12885         }
12886       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12887         ;
12888       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12889         use_custom_mac = 1;
12890       else if (unformat (i, "server"))
12891         is_server = 1;
12892       else if (unformat (i, "disable_mrg_rxbuf"))
12893         disable_mrg_rxbuf = 1;
12894       else if (unformat (i, "disable_indirect_desc"))
12895         disable_indirect_desc = 1;
12896       else if (unformat (i, "gso"))
12897         enable_gso = 1;
12898       else if (unformat (i, "tag %s", &tag))
12899         ;
12900       else
12901         break;
12902     }
12903
12904   if (file_name_set == 0)
12905     {
12906       errmsg ("missing socket file name");
12907       return -99;
12908     }
12909
12910   if (vec_len (file_name) > 255)
12911     {
12912       errmsg ("socket file name too long");
12913       return -99;
12914     }
12915   vec_add1 (file_name, 0);
12916
12917   M (CREATE_VHOST_USER_IF, mp);
12918
12919   mp->is_server = is_server;
12920   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12921   mp->disable_indirect_desc = disable_indirect_desc;
12922   mp->enable_gso = enable_gso;
12923   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12924   vec_free (file_name);
12925   if (custom_dev_instance != ~0)
12926     {
12927       mp->renumber = 1;
12928       mp->custom_dev_instance = ntohl (custom_dev_instance);
12929     }
12930
12931   mp->use_custom_mac = use_custom_mac;
12932   clib_memcpy (mp->mac_address, hwaddr, 6);
12933   if (tag)
12934     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12935   vec_free (tag);
12936
12937   S (mp);
12938   W (ret);
12939   return ret;
12940 }
12941
12942 static int
12943 api_modify_vhost_user_if (vat_main_t * vam)
12944 {
12945   unformat_input_t *i = vam->input;
12946   vl_api_modify_vhost_user_if_t *mp;
12947   u8 *file_name;
12948   u8 is_server = 0;
12949   u8 file_name_set = 0;
12950   u32 custom_dev_instance = ~0;
12951   u8 sw_if_index_set = 0;
12952   u32 sw_if_index = (u32) ~ 0;
12953   u8 enable_gso = 0;
12954   int ret;
12955
12956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12957     {
12958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12959         sw_if_index_set = 1;
12960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12961         sw_if_index_set = 1;
12962       else if (unformat (i, "socket %s", &file_name))
12963         {
12964           file_name_set = 1;
12965         }
12966       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12967         ;
12968       else if (unformat (i, "server"))
12969         is_server = 1;
12970       else if (unformat (i, "gso"))
12971         enable_gso = 1;
12972       else
12973         break;
12974     }
12975
12976   if (sw_if_index_set == 0)
12977     {
12978       errmsg ("missing sw_if_index or interface name");
12979       return -99;
12980     }
12981
12982   if (file_name_set == 0)
12983     {
12984       errmsg ("missing socket file name");
12985       return -99;
12986     }
12987
12988   if (vec_len (file_name) > 255)
12989     {
12990       errmsg ("socket file name too long");
12991       return -99;
12992     }
12993   vec_add1 (file_name, 0);
12994
12995   M (MODIFY_VHOST_USER_IF, mp);
12996
12997   mp->sw_if_index = ntohl (sw_if_index);
12998   mp->is_server = is_server;
12999   mp->enable_gso = enable_gso;
13000   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13001   vec_free (file_name);
13002   if (custom_dev_instance != ~0)
13003     {
13004       mp->renumber = 1;
13005       mp->custom_dev_instance = ntohl (custom_dev_instance);
13006     }
13007
13008   S (mp);
13009   W (ret);
13010   return ret;
13011 }
13012
13013 static int
13014 api_delete_vhost_user_if (vat_main_t * vam)
13015 {
13016   unformat_input_t *i = vam->input;
13017   vl_api_delete_vhost_user_if_t *mp;
13018   u32 sw_if_index = ~0;
13019   u8 sw_if_index_set = 0;
13020   int ret;
13021
13022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13023     {
13024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13025         sw_if_index_set = 1;
13026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13027         sw_if_index_set = 1;
13028       else
13029         break;
13030     }
13031
13032   if (sw_if_index_set == 0)
13033     {
13034       errmsg ("missing sw_if_index or interface name");
13035       return -99;
13036     }
13037
13038
13039   M (DELETE_VHOST_USER_IF, mp);
13040
13041   mp->sw_if_index = ntohl (sw_if_index);
13042
13043   S (mp);
13044   W (ret);
13045   return ret;
13046 }
13047
13048 static void vl_api_sw_interface_vhost_user_details_t_handler
13049   (vl_api_sw_interface_vhost_user_details_t * mp)
13050 {
13051   vat_main_t *vam = &vat_main;
13052
13053   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13054          (char *) mp->interface_name,
13055          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13056          clib_net_to_host_u64 (mp->features), mp->is_server,
13057          ntohl (mp->num_regions), (char *) mp->sock_filename);
13058   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13059 }
13060
13061 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13062   (vl_api_sw_interface_vhost_user_details_t * mp)
13063 {
13064   vat_main_t *vam = &vat_main;
13065   vat_json_node_t *node = NULL;
13066
13067   if (VAT_JSON_ARRAY != vam->json_tree.type)
13068     {
13069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13070       vat_json_init_array (&vam->json_tree);
13071     }
13072   node = vat_json_array_add (&vam->json_tree);
13073
13074   vat_json_init_object (node);
13075   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13076   vat_json_object_add_string_copy (node, "interface_name",
13077                                    mp->interface_name);
13078   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13079                             ntohl (mp->virtio_net_hdr_sz));
13080   vat_json_object_add_uint (node, "features",
13081                             clib_net_to_host_u64 (mp->features));
13082   vat_json_object_add_uint (node, "is_server", mp->is_server);
13083   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13084   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13085   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13086 }
13087
13088 static int
13089 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13090 {
13091   vl_api_sw_interface_vhost_user_dump_t *mp;
13092   vl_api_control_ping_t *mp_ping;
13093   int ret;
13094   print (vam->ofp,
13095          "Interface name            idx hdr_sz features server regions filename");
13096
13097   /* Get list of vhost-user interfaces */
13098   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13099   S (mp);
13100
13101   /* Use a control ping for synchronization */
13102   MPING (CONTROL_PING, mp_ping);
13103   S (mp_ping);
13104
13105   W (ret);
13106   return ret;
13107 }
13108
13109 static int
13110 api_show_version (vat_main_t * vam)
13111 {
13112   vl_api_show_version_t *mp;
13113   int ret;
13114
13115   M (SHOW_VERSION, mp);
13116
13117   S (mp);
13118   W (ret);
13119   return ret;
13120 }
13121
13122
13123 static int
13124 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13125 {
13126   unformat_input_t *line_input = vam->input;
13127   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13128   ip4_address_t local4, remote4;
13129   ip6_address_t local6, remote6;
13130   u8 is_add = 1;
13131   u8 ipv4_set = 0, ipv6_set = 0;
13132   u8 local_set = 0;
13133   u8 remote_set = 0;
13134   u8 grp_set = 0;
13135   u32 mcast_sw_if_index = ~0;
13136   u32 encap_vrf_id = 0;
13137   u32 decap_vrf_id = 0;
13138   u8 protocol = ~0;
13139   u32 vni;
13140   u8 vni_set = 0;
13141   int ret;
13142
13143   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13144   clib_memset (&local4, 0, sizeof local4);
13145   clib_memset (&remote4, 0, sizeof remote4);
13146   clib_memset (&local6, 0, sizeof local6);
13147   clib_memset (&remote6, 0, sizeof remote6);
13148
13149   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13150     {
13151       if (unformat (line_input, "del"))
13152         is_add = 0;
13153       else if (unformat (line_input, "local %U",
13154                          unformat_ip4_address, &local4))
13155         {
13156           local_set = 1;
13157           ipv4_set = 1;
13158         }
13159       else if (unformat (line_input, "remote %U",
13160                          unformat_ip4_address, &remote4))
13161         {
13162           remote_set = 1;
13163           ipv4_set = 1;
13164         }
13165       else if (unformat (line_input, "local %U",
13166                          unformat_ip6_address, &local6))
13167         {
13168           local_set = 1;
13169           ipv6_set = 1;
13170         }
13171       else if (unformat (line_input, "remote %U",
13172                          unformat_ip6_address, &remote6))
13173         {
13174           remote_set = 1;
13175           ipv6_set = 1;
13176         }
13177       else if (unformat (line_input, "group %U %U",
13178                          unformat_ip4_address, &remote4,
13179                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13180         {
13181           grp_set = remote_set = 1;
13182           ipv4_set = 1;
13183         }
13184       else if (unformat (line_input, "group %U",
13185                          unformat_ip4_address, &remote4))
13186         {
13187           grp_set = remote_set = 1;
13188           ipv4_set = 1;
13189         }
13190       else if (unformat (line_input, "group %U %U",
13191                          unformat_ip6_address, &remote6,
13192                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13193         {
13194           grp_set = remote_set = 1;
13195           ipv6_set = 1;
13196         }
13197       else if (unformat (line_input, "group %U",
13198                          unformat_ip6_address, &remote6))
13199         {
13200           grp_set = remote_set = 1;
13201           ipv6_set = 1;
13202         }
13203       else
13204         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13205         ;
13206       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13207         ;
13208       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13209         ;
13210       else if (unformat (line_input, "vni %d", &vni))
13211         vni_set = 1;
13212       else if (unformat (line_input, "next-ip4"))
13213         protocol = 1;
13214       else if (unformat (line_input, "next-ip6"))
13215         protocol = 2;
13216       else if (unformat (line_input, "next-ethernet"))
13217         protocol = 3;
13218       else if (unformat (line_input, "next-nsh"))
13219         protocol = 4;
13220       else
13221         {
13222           errmsg ("parse error '%U'", format_unformat_error, line_input);
13223           return -99;
13224         }
13225     }
13226
13227   if (local_set == 0)
13228     {
13229       errmsg ("tunnel local address not specified");
13230       return -99;
13231     }
13232   if (remote_set == 0)
13233     {
13234       errmsg ("tunnel remote address not specified");
13235       return -99;
13236     }
13237   if (grp_set && mcast_sw_if_index == ~0)
13238     {
13239       errmsg ("tunnel nonexistent multicast device");
13240       return -99;
13241     }
13242   if (ipv4_set && ipv6_set)
13243     {
13244       errmsg ("both IPv4 and IPv6 addresses specified");
13245       return -99;
13246     }
13247
13248   if (vni_set == 0)
13249     {
13250       errmsg ("vni not specified");
13251       return -99;
13252     }
13253
13254   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13255
13256
13257   if (ipv6_set)
13258     {
13259       clib_memcpy (&mp->local, &local6, sizeof (local6));
13260       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13261     }
13262   else
13263     {
13264       clib_memcpy (&mp->local, &local4, sizeof (local4));
13265       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13266     }
13267
13268   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13269   mp->encap_vrf_id = ntohl (encap_vrf_id);
13270   mp->decap_vrf_id = ntohl (decap_vrf_id);
13271   mp->protocol = protocol;
13272   mp->vni = ntohl (vni);
13273   mp->is_add = is_add;
13274   mp->is_ipv6 = ipv6_set;
13275
13276   S (mp);
13277   W (ret);
13278   return ret;
13279 }
13280
13281 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13282   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13283 {
13284   vat_main_t *vam = &vat_main;
13285   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13286   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13287
13288   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13289          ntohl (mp->sw_if_index),
13290          format_ip46_address, &local, IP46_TYPE_ANY,
13291          format_ip46_address, &remote, IP46_TYPE_ANY,
13292          ntohl (mp->vni), mp->protocol,
13293          ntohl (mp->mcast_sw_if_index),
13294          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13295 }
13296
13297
13298 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13299   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13300 {
13301   vat_main_t *vam = &vat_main;
13302   vat_json_node_t *node = NULL;
13303   struct in_addr ip4;
13304   struct in6_addr ip6;
13305
13306   if (VAT_JSON_ARRAY != vam->json_tree.type)
13307     {
13308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13309       vat_json_init_array (&vam->json_tree);
13310     }
13311   node = vat_json_array_add (&vam->json_tree);
13312
13313   vat_json_init_object (node);
13314   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13315   if (mp->is_ipv6)
13316     {
13317       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13318       vat_json_object_add_ip6 (node, "local", ip6);
13319       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13320       vat_json_object_add_ip6 (node, "remote", ip6);
13321     }
13322   else
13323     {
13324       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13325       vat_json_object_add_ip4 (node, "local", ip4);
13326       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13327       vat_json_object_add_ip4 (node, "remote", ip4);
13328     }
13329   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13330   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13331   vat_json_object_add_uint (node, "mcast_sw_if_index",
13332                             ntohl (mp->mcast_sw_if_index));
13333   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13334   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13335   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13336 }
13337
13338 static int
13339 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13340 {
13341   unformat_input_t *i = vam->input;
13342   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13343   vl_api_control_ping_t *mp_ping;
13344   u32 sw_if_index;
13345   u8 sw_if_index_set = 0;
13346   int ret;
13347
13348   /* Parse args required to build the message */
13349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13350     {
13351       if (unformat (i, "sw_if_index %d", &sw_if_index))
13352         sw_if_index_set = 1;
13353       else
13354         break;
13355     }
13356
13357   if (sw_if_index_set == 0)
13358     {
13359       sw_if_index = ~0;
13360     }
13361
13362   if (!vam->json_output)
13363     {
13364       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13365              "sw_if_index", "local", "remote", "vni",
13366              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13367     }
13368
13369   /* Get list of vxlan-tunnel interfaces */
13370   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13371
13372   mp->sw_if_index = htonl (sw_if_index);
13373
13374   S (mp);
13375
13376   /* Use a control ping for synchronization */
13377   MPING (CONTROL_PING, mp_ping);
13378   S (mp_ping);
13379
13380   W (ret);
13381   return ret;
13382 }
13383
13384 static void vl_api_l2_fib_table_details_t_handler
13385   (vl_api_l2_fib_table_details_t * mp)
13386 {
13387   vat_main_t *vam = &vat_main;
13388
13389   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13390          "       %d       %d     %d",
13391          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13392          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13393          mp->bvi_mac);
13394 }
13395
13396 static void vl_api_l2_fib_table_details_t_handler_json
13397   (vl_api_l2_fib_table_details_t * mp)
13398 {
13399   vat_main_t *vam = &vat_main;
13400   vat_json_node_t *node = NULL;
13401
13402   if (VAT_JSON_ARRAY != vam->json_tree.type)
13403     {
13404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13405       vat_json_init_array (&vam->json_tree);
13406     }
13407   node = vat_json_array_add (&vam->json_tree);
13408
13409   vat_json_init_object (node);
13410   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13411   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13412   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13413   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13414   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13415   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13416 }
13417
13418 static int
13419 api_l2_fib_table_dump (vat_main_t * vam)
13420 {
13421   unformat_input_t *i = vam->input;
13422   vl_api_l2_fib_table_dump_t *mp;
13423   vl_api_control_ping_t *mp_ping;
13424   u32 bd_id;
13425   u8 bd_id_set = 0;
13426   int ret;
13427
13428   /* Parse args required to build the message */
13429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13430     {
13431       if (unformat (i, "bd_id %d", &bd_id))
13432         bd_id_set = 1;
13433       else
13434         break;
13435     }
13436
13437   if (bd_id_set == 0)
13438     {
13439       errmsg ("missing bridge domain");
13440       return -99;
13441     }
13442
13443   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13444
13445   /* Get list of l2 fib entries */
13446   M (L2_FIB_TABLE_DUMP, mp);
13447
13448   mp->bd_id = ntohl (bd_id);
13449   S (mp);
13450
13451   /* Use a control ping for synchronization */
13452   MPING (CONTROL_PING, mp_ping);
13453   S (mp_ping);
13454
13455   W (ret);
13456   return ret;
13457 }
13458
13459
13460 static int
13461 api_interface_name_renumber (vat_main_t * vam)
13462 {
13463   unformat_input_t *line_input = vam->input;
13464   vl_api_interface_name_renumber_t *mp;
13465   u32 sw_if_index = ~0;
13466   u32 new_show_dev_instance = ~0;
13467   int ret;
13468
13469   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13470     {
13471       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13472                     &sw_if_index))
13473         ;
13474       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13475         ;
13476       else if (unformat (line_input, "new_show_dev_instance %d",
13477                          &new_show_dev_instance))
13478         ;
13479       else
13480         break;
13481     }
13482
13483   if (sw_if_index == ~0)
13484     {
13485       errmsg ("missing interface name or sw_if_index");
13486       return -99;
13487     }
13488
13489   if (new_show_dev_instance == ~0)
13490     {
13491       errmsg ("missing new_show_dev_instance");
13492       return -99;
13493     }
13494
13495   M (INTERFACE_NAME_RENUMBER, mp);
13496
13497   mp->sw_if_index = ntohl (sw_if_index);
13498   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13499
13500   S (mp);
13501   W (ret);
13502   return ret;
13503 }
13504
13505 static int
13506 api_ip_probe_neighbor (vat_main_t * vam)
13507 {
13508   unformat_input_t *i = vam->input;
13509   vl_api_ip_probe_neighbor_t *mp;
13510   vl_api_address_t dst_adr = { };
13511   u8 int_set = 0;
13512   u8 adr_set = 0;
13513   u32 sw_if_index;
13514   int ret;
13515
13516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13517     {
13518       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13519         int_set = 1;
13520       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13521         int_set = 1;
13522       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13523         adr_set = 1;
13524       else
13525         break;
13526     }
13527
13528   if (int_set == 0)
13529     {
13530       errmsg ("missing interface");
13531       return -99;
13532     }
13533
13534   if (adr_set == 0)
13535     {
13536       errmsg ("missing addresses");
13537       return -99;
13538     }
13539
13540   M (IP_PROBE_NEIGHBOR, mp);
13541
13542   mp->sw_if_index = ntohl (sw_if_index);
13543   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13544
13545   S (mp);
13546   W (ret);
13547   return ret;
13548 }
13549
13550 static int
13551 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13552 {
13553   unformat_input_t *i = vam->input;
13554   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13555   u8 mode = IP_SCAN_V46_NEIGHBORS;
13556   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13557   int ret;
13558
13559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560     {
13561       if (unformat (i, "ip4"))
13562         mode = IP_SCAN_V4_NEIGHBORS;
13563       else if (unformat (i, "ip6"))
13564         mode = IP_SCAN_V6_NEIGHBORS;
13565       if (unformat (i, "both"))
13566         mode = IP_SCAN_V46_NEIGHBORS;
13567       else if (unformat (i, "disable"))
13568         mode = IP_SCAN_DISABLED;
13569       else if (unformat (i, "interval %d", &interval))
13570         ;
13571       else if (unformat (i, "max-time %d", &time))
13572         ;
13573       else if (unformat (i, "max-update %d", &update))
13574         ;
13575       else if (unformat (i, "delay %d", &delay))
13576         ;
13577       else if (unformat (i, "stale %d", &stale))
13578         ;
13579       else
13580         break;
13581     }
13582
13583   if (interval > 255)
13584     {
13585       errmsg ("interval cannot exceed 255 minutes.");
13586       return -99;
13587     }
13588   if (time > 255)
13589     {
13590       errmsg ("max-time cannot exceed 255 usec.");
13591       return -99;
13592     }
13593   if (update > 255)
13594     {
13595       errmsg ("max-update cannot exceed 255.");
13596       return -99;
13597     }
13598   if (delay > 255)
13599     {
13600       errmsg ("delay cannot exceed 255 msec.");
13601       return -99;
13602     }
13603   if (stale > 255)
13604     {
13605       errmsg ("stale cannot exceed 255 minutes.");
13606       return -99;
13607     }
13608
13609   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13610   mp->mode = mode;
13611   mp->scan_interval = interval;
13612   mp->max_proc_time = time;
13613   mp->max_update = update;
13614   mp->scan_int_delay = delay;
13615   mp->stale_threshold = stale;
13616
13617   S (mp);
13618   W (ret);
13619   return ret;
13620 }
13621
13622 static int
13623 api_want_ip4_arp_events (vat_main_t * vam)
13624 {
13625   unformat_input_t *line_input = vam->input;
13626   vl_api_want_ip4_arp_events_t *mp;
13627   ip4_address_t address;
13628   int address_set = 0;
13629   u32 enable_disable = 1;
13630   int ret;
13631
13632   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13633     {
13634       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13635         address_set = 1;
13636       else if (unformat (line_input, "del"))
13637         enable_disable = 0;
13638       else
13639         break;
13640     }
13641
13642   if (address_set == 0)
13643     {
13644       errmsg ("missing addresses");
13645       return -99;
13646     }
13647
13648   M (WANT_IP4_ARP_EVENTS, mp);
13649   mp->enable_disable = enable_disable;
13650   mp->pid = htonl (getpid ());
13651   clib_memcpy (mp->ip, &address, sizeof (address));
13652
13653   S (mp);
13654   W (ret);
13655   return ret;
13656 }
13657
13658 static int
13659 api_want_ip6_nd_events (vat_main_t * vam)
13660 {
13661   unformat_input_t *line_input = vam->input;
13662   vl_api_want_ip6_nd_events_t *mp;
13663   vl_api_ip6_address_t address;
13664   int address_set = 0;
13665   u32 enable_disable = 1;
13666   int ret;
13667
13668   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13669     {
13670       if (unformat
13671           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13672         address_set = 1;
13673       else if (unformat (line_input, "del"))
13674         enable_disable = 0;
13675       else
13676         break;
13677     }
13678
13679   if (address_set == 0)
13680     {
13681       errmsg ("missing addresses");
13682       return -99;
13683     }
13684
13685   M (WANT_IP6_ND_EVENTS, mp);
13686   mp->enable_disable = enable_disable;
13687   mp->pid = htonl (getpid ());
13688   clib_memcpy (&mp->ip, &address, sizeof (address));
13689
13690   S (mp);
13691   W (ret);
13692   return ret;
13693 }
13694
13695 static int
13696 api_want_l2_macs_events (vat_main_t * vam)
13697 {
13698   unformat_input_t *line_input = vam->input;
13699   vl_api_want_l2_macs_events_t *mp;
13700   u8 enable_disable = 1;
13701   u32 scan_delay = 0;
13702   u32 max_macs_in_event = 0;
13703   u32 learn_limit = 0;
13704   int ret;
13705
13706   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13707     {
13708       if (unformat (line_input, "learn-limit %d", &learn_limit))
13709         ;
13710       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13711         ;
13712       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13713         ;
13714       else if (unformat (line_input, "disable"))
13715         enable_disable = 0;
13716       else
13717         break;
13718     }
13719
13720   M (WANT_L2_MACS_EVENTS, mp);
13721   mp->enable_disable = enable_disable;
13722   mp->pid = htonl (getpid ());
13723   mp->learn_limit = htonl (learn_limit);
13724   mp->scan_delay = (u8) scan_delay;
13725   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13726   S (mp);
13727   W (ret);
13728   return ret;
13729 }
13730
13731 static int
13732 api_input_acl_set_interface (vat_main_t * vam)
13733 {
13734   unformat_input_t *i = vam->input;
13735   vl_api_input_acl_set_interface_t *mp;
13736   u32 sw_if_index;
13737   int sw_if_index_set;
13738   u32 ip4_table_index = ~0;
13739   u32 ip6_table_index = ~0;
13740   u32 l2_table_index = ~0;
13741   u8 is_add = 1;
13742   int ret;
13743
13744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13745     {
13746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13747         sw_if_index_set = 1;
13748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13749         sw_if_index_set = 1;
13750       else if (unformat (i, "del"))
13751         is_add = 0;
13752       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13753         ;
13754       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13755         ;
13756       else if (unformat (i, "l2-table %d", &l2_table_index))
13757         ;
13758       else
13759         {
13760           clib_warning ("parse error '%U'", format_unformat_error, i);
13761           return -99;
13762         }
13763     }
13764
13765   if (sw_if_index_set == 0)
13766     {
13767       errmsg ("missing interface name or sw_if_index");
13768       return -99;
13769     }
13770
13771   M (INPUT_ACL_SET_INTERFACE, mp);
13772
13773   mp->sw_if_index = ntohl (sw_if_index);
13774   mp->ip4_table_index = ntohl (ip4_table_index);
13775   mp->ip6_table_index = ntohl (ip6_table_index);
13776   mp->l2_table_index = ntohl (l2_table_index);
13777   mp->is_add = is_add;
13778
13779   S (mp);
13780   W (ret);
13781   return ret;
13782 }
13783
13784 static int
13785 api_output_acl_set_interface (vat_main_t * vam)
13786 {
13787   unformat_input_t *i = vam->input;
13788   vl_api_output_acl_set_interface_t *mp;
13789   u32 sw_if_index;
13790   int sw_if_index_set;
13791   u32 ip4_table_index = ~0;
13792   u32 ip6_table_index = ~0;
13793   u32 l2_table_index = ~0;
13794   u8 is_add = 1;
13795   int ret;
13796
13797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13798     {
13799       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13800         sw_if_index_set = 1;
13801       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13802         sw_if_index_set = 1;
13803       else if (unformat (i, "del"))
13804         is_add = 0;
13805       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13806         ;
13807       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13808         ;
13809       else if (unformat (i, "l2-table %d", &l2_table_index))
13810         ;
13811       else
13812         {
13813           clib_warning ("parse error '%U'", format_unformat_error, i);
13814           return -99;
13815         }
13816     }
13817
13818   if (sw_if_index_set == 0)
13819     {
13820       errmsg ("missing interface name or sw_if_index");
13821       return -99;
13822     }
13823
13824   M (OUTPUT_ACL_SET_INTERFACE, mp);
13825
13826   mp->sw_if_index = ntohl (sw_if_index);
13827   mp->ip4_table_index = ntohl (ip4_table_index);
13828   mp->ip6_table_index = ntohl (ip6_table_index);
13829   mp->l2_table_index = ntohl (l2_table_index);
13830   mp->is_add = is_add;
13831
13832   S (mp);
13833   W (ret);
13834   return ret;
13835 }
13836
13837 static int
13838 api_ip_address_dump (vat_main_t * vam)
13839 {
13840   unformat_input_t *i = vam->input;
13841   vl_api_ip_address_dump_t *mp;
13842   vl_api_control_ping_t *mp_ping;
13843   u32 sw_if_index = ~0;
13844   u8 sw_if_index_set = 0;
13845   u8 ipv4_set = 0;
13846   u8 ipv6_set = 0;
13847   int ret;
13848
13849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13850     {
13851       if (unformat (i, "sw_if_index %d", &sw_if_index))
13852         sw_if_index_set = 1;
13853       else
13854         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13855         sw_if_index_set = 1;
13856       else if (unformat (i, "ipv4"))
13857         ipv4_set = 1;
13858       else if (unformat (i, "ipv6"))
13859         ipv6_set = 1;
13860       else
13861         break;
13862     }
13863
13864   if (ipv4_set && ipv6_set)
13865     {
13866       errmsg ("ipv4 and ipv6 flags cannot be both set");
13867       return -99;
13868     }
13869
13870   if ((!ipv4_set) && (!ipv6_set))
13871     {
13872       errmsg ("no ipv4 nor ipv6 flag set");
13873       return -99;
13874     }
13875
13876   if (sw_if_index_set == 0)
13877     {
13878       errmsg ("missing interface name or sw_if_index");
13879       return -99;
13880     }
13881
13882   vam->current_sw_if_index = sw_if_index;
13883   vam->is_ipv6 = ipv6_set;
13884
13885   M (IP_ADDRESS_DUMP, mp);
13886   mp->sw_if_index = ntohl (sw_if_index);
13887   mp->is_ipv6 = ipv6_set;
13888   S (mp);
13889
13890   /* Use a control ping for synchronization */
13891   MPING (CONTROL_PING, mp_ping);
13892   S (mp_ping);
13893
13894   W (ret);
13895   return ret;
13896 }
13897
13898 static int
13899 api_ip_dump (vat_main_t * vam)
13900 {
13901   vl_api_ip_dump_t *mp;
13902   vl_api_control_ping_t *mp_ping;
13903   unformat_input_t *in = vam->input;
13904   int ipv4_set = 0;
13905   int ipv6_set = 0;
13906   int is_ipv6;
13907   int i;
13908   int ret;
13909
13910   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13911     {
13912       if (unformat (in, "ipv4"))
13913         ipv4_set = 1;
13914       else if (unformat (in, "ipv6"))
13915         ipv6_set = 1;
13916       else
13917         break;
13918     }
13919
13920   if (ipv4_set && ipv6_set)
13921     {
13922       errmsg ("ipv4 and ipv6 flags cannot be both set");
13923       return -99;
13924     }
13925
13926   if ((!ipv4_set) && (!ipv6_set))
13927     {
13928       errmsg ("no ipv4 nor ipv6 flag set");
13929       return -99;
13930     }
13931
13932   is_ipv6 = ipv6_set;
13933   vam->is_ipv6 = is_ipv6;
13934
13935   /* free old data */
13936   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13937     {
13938       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13939     }
13940   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13941
13942   M (IP_DUMP, mp);
13943   mp->is_ipv6 = ipv6_set;
13944   S (mp);
13945
13946   /* Use a control ping for synchronization */
13947   MPING (CONTROL_PING, mp_ping);
13948   S (mp_ping);
13949
13950   W (ret);
13951   return ret;
13952 }
13953
13954 static int
13955 api_ipsec_spd_add_del (vat_main_t * vam)
13956 {
13957   unformat_input_t *i = vam->input;
13958   vl_api_ipsec_spd_add_del_t *mp;
13959   u32 spd_id = ~0;
13960   u8 is_add = 1;
13961   int ret;
13962
13963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13964     {
13965       if (unformat (i, "spd_id %d", &spd_id))
13966         ;
13967       else if (unformat (i, "del"))
13968         is_add = 0;
13969       else
13970         {
13971           clib_warning ("parse error '%U'", format_unformat_error, i);
13972           return -99;
13973         }
13974     }
13975   if (spd_id == ~0)
13976     {
13977       errmsg ("spd_id must be set");
13978       return -99;
13979     }
13980
13981   M (IPSEC_SPD_ADD_DEL, mp);
13982
13983   mp->spd_id = ntohl (spd_id);
13984   mp->is_add = is_add;
13985
13986   S (mp);
13987   W (ret);
13988   return ret;
13989 }
13990
13991 static int
13992 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13993 {
13994   unformat_input_t *i = vam->input;
13995   vl_api_ipsec_interface_add_del_spd_t *mp;
13996   u32 sw_if_index;
13997   u8 sw_if_index_set = 0;
13998   u32 spd_id = (u32) ~ 0;
13999   u8 is_add = 1;
14000   int ret;
14001
14002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (i, "del"))
14005         is_add = 0;
14006       else if (unformat (i, "spd_id %d", &spd_id))
14007         ;
14008       else
14009         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14010         sw_if_index_set = 1;
14011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14012         sw_if_index_set = 1;
14013       else
14014         {
14015           clib_warning ("parse error '%U'", format_unformat_error, i);
14016           return -99;
14017         }
14018
14019     }
14020
14021   if (spd_id == (u32) ~ 0)
14022     {
14023       errmsg ("spd_id must be set");
14024       return -99;
14025     }
14026
14027   if (sw_if_index_set == 0)
14028     {
14029       errmsg ("missing interface name or sw_if_index");
14030       return -99;
14031     }
14032
14033   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14034
14035   mp->spd_id = ntohl (spd_id);
14036   mp->sw_if_index = ntohl (sw_if_index);
14037   mp->is_add = is_add;
14038
14039   S (mp);
14040   W (ret);
14041   return ret;
14042 }
14043
14044 static int
14045 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_ipsec_spd_entry_add_del_t *mp;
14049   u8 is_add = 1, is_outbound = 0;
14050   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14051   i32 priority = 0;
14052   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14053   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14054   vl_api_address_t laddr_start = { }, laddr_stop =
14055   {
14056   }, raddr_start =
14057   {
14058   }, raddr_stop =
14059   {
14060   };
14061   int ret;
14062
14063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14064     {
14065       if (unformat (i, "del"))
14066         is_add = 0;
14067       if (unformat (i, "outbound"))
14068         is_outbound = 1;
14069       if (unformat (i, "inbound"))
14070         is_outbound = 0;
14071       else if (unformat (i, "spd_id %d", &spd_id))
14072         ;
14073       else if (unformat (i, "sa_id %d", &sa_id))
14074         ;
14075       else if (unformat (i, "priority %d", &priority))
14076         ;
14077       else if (unformat (i, "protocol %d", &protocol))
14078         ;
14079       else if (unformat (i, "lport_start %d", &lport_start))
14080         ;
14081       else if (unformat (i, "lport_stop %d", &lport_stop))
14082         ;
14083       else if (unformat (i, "rport_start %d", &rport_start))
14084         ;
14085       else if (unformat (i, "rport_stop %d", &rport_stop))
14086         ;
14087       else if (unformat (i, "laddr_start %U",
14088                          unformat_vl_api_address, &laddr_start))
14089         ;
14090       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14091                          &laddr_stop))
14092         ;
14093       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14094                          &raddr_start))
14095         ;
14096       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14097                          &raddr_stop))
14098         ;
14099       else
14100         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14101         {
14102           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14103             {
14104               clib_warning ("unsupported action: 'resolve'");
14105               return -99;
14106             }
14107         }
14108       else
14109         {
14110           clib_warning ("parse error '%U'", format_unformat_error, i);
14111           return -99;
14112         }
14113
14114     }
14115
14116   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14117
14118   mp->is_add = is_add;
14119
14120   mp->entry.spd_id = ntohl (spd_id);
14121   mp->entry.priority = ntohl (priority);
14122   mp->entry.is_outbound = is_outbound;
14123
14124   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14125                sizeof (vl_api_address_t));
14126   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14127                sizeof (vl_api_address_t));
14128   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14129                sizeof (vl_api_address_t));
14130   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14131                sizeof (vl_api_address_t));
14132
14133   mp->entry.protocol = (u8) protocol;
14134   mp->entry.local_port_start = ntohs ((u16) lport_start);
14135   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14136   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14137   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14138   mp->entry.policy = (u8) policy;
14139   mp->entry.sa_id = ntohl (sa_id);
14140
14141   S (mp);
14142   W (ret);
14143   return ret;
14144 }
14145
14146 static int
14147 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14148 {
14149   unformat_input_t *i = vam->input;
14150   vl_api_ipsec_sad_entry_add_del_t *mp;
14151   u32 sad_id = 0, spi = 0;
14152   u8 *ck = 0, *ik = 0;
14153   u8 is_add = 1;
14154
14155   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14156   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14157   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14158   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14159   vl_api_address_t tun_src, tun_dst;
14160   int ret;
14161
14162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14163     {
14164       if (unformat (i, "del"))
14165         is_add = 0;
14166       else if (unformat (i, "sad_id %d", &sad_id))
14167         ;
14168       else if (unformat (i, "spi %d", &spi))
14169         ;
14170       else if (unformat (i, "esp"))
14171         protocol = IPSEC_API_PROTO_ESP;
14172       else
14173         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14174         {
14175           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14176           if (ADDRESS_IP6 == tun_src.af)
14177             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14178         }
14179       else
14180         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14181         {
14182           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14183           if (ADDRESS_IP6 == tun_src.af)
14184             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14185         }
14186       else
14187         if (unformat (i, "crypto_alg %U",
14188                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14189         ;
14190       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14191         ;
14192       else if (unformat (i, "integ_alg %U",
14193                          unformat_ipsec_api_integ_alg, &integ_alg))
14194         ;
14195       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14196         ;
14197       else
14198         {
14199           clib_warning ("parse error '%U'", format_unformat_error, i);
14200           return -99;
14201         }
14202
14203     }
14204
14205   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14206
14207   mp->is_add = is_add;
14208   mp->entry.sad_id = ntohl (sad_id);
14209   mp->entry.protocol = protocol;
14210   mp->entry.spi = ntohl (spi);
14211   mp->entry.flags = flags;
14212
14213   mp->entry.crypto_algorithm = crypto_alg;
14214   mp->entry.integrity_algorithm = integ_alg;
14215   mp->entry.crypto_key.length = vec_len (ck);
14216   mp->entry.integrity_key.length = vec_len (ik);
14217
14218   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14219     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14220
14221   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14222     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14223
14224   if (ck)
14225     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14226   if (ik)
14227     clib_memcpy (mp->entry.integrity_key.data, ik,
14228                  mp->entry.integrity_key.length);
14229
14230   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14231     {
14232       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14233                    sizeof (mp->entry.tunnel_src));
14234       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14235                    sizeof (mp->entry.tunnel_dst));
14236     }
14237
14238   S (mp);
14239   W (ret);
14240   return ret;
14241 }
14242
14243 static int
14244 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14245 {
14246   unformat_input_t *i = vam->input;
14247   vl_api_ipsec_tunnel_if_add_del_t *mp;
14248   u32 local_spi = 0, remote_spi = 0;
14249   u32 crypto_alg = 0, integ_alg = 0;
14250   u8 *lck = NULL, *rck = NULL;
14251   u8 *lik = NULL, *rik = NULL;
14252   vl_api_address_t local_ip = { 0 };
14253   vl_api_address_t remote_ip = { 0 };
14254   f64 before = 0;
14255   u8 is_add = 1;
14256   u8 esn = 0;
14257   u8 anti_replay = 0;
14258   u8 renumber = 0;
14259   u32 instance = ~0;
14260   u32 count = 1, jj;
14261   int ret = -1;
14262
14263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14264     {
14265       if (unformat (i, "del"))
14266         is_add = 0;
14267       else if (unformat (i, "esn"))
14268         esn = 1;
14269       else if (unformat (i, "anti-replay"))
14270         anti_replay = 1;
14271       else if (unformat (i, "count %d", &count))
14272         ;
14273       else if (unformat (i, "local_spi %d", &local_spi))
14274         ;
14275       else if (unformat (i, "remote_spi %d", &remote_spi))
14276         ;
14277       else
14278         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14279         ;
14280       else
14281         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14282         ;
14283       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14284         ;
14285       else
14286         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14287         ;
14288       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14289         ;
14290       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14291         ;
14292       else
14293         if (unformat
14294             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14295         {
14296           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14297             {
14298               errmsg ("unsupported crypto-alg: '%U'\n",
14299                       format_ipsec_crypto_alg, crypto_alg);
14300               return -99;
14301             }
14302         }
14303       else
14304         if (unformat
14305             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14306         {
14307           if (integ_alg >= IPSEC_INTEG_N_ALG)
14308             {
14309               errmsg ("unsupported integ-alg: '%U'\n",
14310                       format_ipsec_integ_alg, integ_alg);
14311               return -99;
14312             }
14313         }
14314       else if (unformat (i, "instance %u", &instance))
14315         renumber = 1;
14316       else
14317         {
14318           errmsg ("parse error '%U'\n", format_unformat_error, i);
14319           return -99;
14320         }
14321     }
14322
14323   if (count > 1)
14324     {
14325       /* Turn on async mode */
14326       vam->async_mode = 1;
14327       vam->async_errors = 0;
14328       before = vat_time_now (vam);
14329     }
14330
14331   for (jj = 0; jj < count; jj++)
14332     {
14333       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14334
14335       mp->is_add = is_add;
14336       mp->esn = esn;
14337       mp->anti_replay = anti_replay;
14338
14339       if (jj > 0)
14340         increment_address (&remote_ip);
14341
14342       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14343       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14344
14345       mp->local_spi = htonl (local_spi + jj);
14346       mp->remote_spi = htonl (remote_spi + jj);
14347       mp->crypto_alg = (u8) crypto_alg;
14348
14349       mp->local_crypto_key_len = 0;
14350       if (lck)
14351         {
14352           mp->local_crypto_key_len = vec_len (lck);
14353           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14354             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14355           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14356         }
14357
14358       mp->remote_crypto_key_len = 0;
14359       if (rck)
14360         {
14361           mp->remote_crypto_key_len = vec_len (rck);
14362           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14363             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14364           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14365         }
14366
14367       mp->integ_alg = (u8) integ_alg;
14368
14369       mp->local_integ_key_len = 0;
14370       if (lik)
14371         {
14372           mp->local_integ_key_len = vec_len (lik);
14373           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14374             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14375           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14376         }
14377
14378       mp->remote_integ_key_len = 0;
14379       if (rik)
14380         {
14381           mp->remote_integ_key_len = vec_len (rik);
14382           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14383             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14384           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14385         }
14386
14387       if (renumber)
14388         {
14389           mp->renumber = renumber;
14390           mp->show_instance = ntohl (instance);
14391         }
14392       S (mp);
14393     }
14394
14395   /* When testing multiple add/del ops, use a control-ping to sync */
14396   if (count > 1)
14397     {
14398       vl_api_control_ping_t *mp_ping;
14399       f64 after;
14400       f64 timeout;
14401
14402       /* Shut off async mode */
14403       vam->async_mode = 0;
14404
14405       MPING (CONTROL_PING, mp_ping);
14406       S (mp_ping);
14407
14408       timeout = vat_time_now (vam) + 1.0;
14409       while (vat_time_now (vam) < timeout)
14410         if (vam->result_ready == 1)
14411           goto out;
14412       vam->retval = -99;
14413
14414     out:
14415       if (vam->retval == -99)
14416         errmsg ("timeout");
14417
14418       if (vam->async_errors > 0)
14419         {
14420           errmsg ("%d asynchronous errors", vam->async_errors);
14421           vam->retval = -98;
14422         }
14423       vam->async_errors = 0;
14424       after = vat_time_now (vam);
14425
14426       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14427       if (jj > 0)
14428         count = jj;
14429
14430       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14431              count, after - before, count / (after - before));
14432     }
14433   else
14434     {
14435       /* Wait for a reply... */
14436       W (ret);
14437       return ret;
14438     }
14439
14440   return ret;
14441 }
14442
14443 static void
14444 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14445 {
14446   vat_main_t *vam = &vat_main;
14447
14448   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14449          "crypto_key %U integ_alg %u integ_key %U flags %x "
14450          "tunnel_src_addr %U tunnel_dst_addr %U "
14451          "salt %u seq_outbound %lu last_seq_inbound %lu "
14452          "replay_window %lu\n",
14453          ntohl (mp->entry.sad_id),
14454          ntohl (mp->sw_if_index),
14455          ntohl (mp->entry.spi),
14456          ntohl (mp->entry.protocol),
14457          ntohl (mp->entry.crypto_algorithm),
14458          format_hex_bytes, mp->entry.crypto_key.data,
14459          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14460          format_hex_bytes, mp->entry.integrity_key.data,
14461          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14462          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14463          &mp->entry.tunnel_dst, ntohl (mp->salt),
14464          clib_net_to_host_u64 (mp->seq_outbound),
14465          clib_net_to_host_u64 (mp->last_seq_inbound),
14466          clib_net_to_host_u64 (mp->replay_window));
14467 }
14468
14469 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14470 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14471
14472 static void vl_api_ipsec_sa_details_t_handler_json
14473   (vl_api_ipsec_sa_details_t * mp)
14474 {
14475   vat_main_t *vam = &vat_main;
14476   vat_json_node_t *node = NULL;
14477   vl_api_ipsec_sad_flags_t flags;
14478
14479   if (VAT_JSON_ARRAY != vam->json_tree.type)
14480     {
14481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14482       vat_json_init_array (&vam->json_tree);
14483     }
14484   node = vat_json_array_add (&vam->json_tree);
14485
14486   vat_json_init_object (node);
14487   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14488   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14489   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14490   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14491   vat_json_object_add_uint (node, "crypto_alg",
14492                             ntohl (mp->entry.crypto_algorithm));
14493   vat_json_object_add_uint (node, "integ_alg",
14494                             ntohl (mp->entry.integrity_algorithm));
14495   flags = ntohl (mp->entry.flags);
14496   vat_json_object_add_uint (node, "use_esn",
14497                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14498   vat_json_object_add_uint (node, "use_anti_replay",
14499                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14500   vat_json_object_add_uint (node, "is_tunnel",
14501                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14502   vat_json_object_add_uint (node, "is_tunnel_ip6",
14503                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14504   vat_json_object_add_uint (node, "udp_encap",
14505                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14506   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14507                              mp->entry.crypto_key.length);
14508   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14509                              mp->entry.integrity_key.length);
14510   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14511   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14512   vat_json_object_add_uint (node, "replay_window",
14513                             clib_net_to_host_u64 (mp->replay_window));
14514 }
14515
14516 static int
14517 api_ipsec_sa_dump (vat_main_t * vam)
14518 {
14519   unformat_input_t *i = vam->input;
14520   vl_api_ipsec_sa_dump_t *mp;
14521   vl_api_control_ping_t *mp_ping;
14522   u32 sa_id = ~0;
14523   int ret;
14524
14525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14526     {
14527       if (unformat (i, "sa_id %d", &sa_id))
14528         ;
14529       else
14530         {
14531           clib_warning ("parse error '%U'", format_unformat_error, i);
14532           return -99;
14533         }
14534     }
14535
14536   M (IPSEC_SA_DUMP, mp);
14537
14538   mp->sa_id = ntohl (sa_id);
14539
14540   S (mp);
14541
14542   /* Use a control ping for synchronization */
14543   M (CONTROL_PING, mp_ping);
14544   S (mp_ping);
14545
14546   W (ret);
14547   return ret;
14548 }
14549
14550 static int
14551 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14552 {
14553   unformat_input_t *i = vam->input;
14554   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14555   u32 sw_if_index = ~0;
14556   u32 sa_id = ~0;
14557   u8 is_outbound = (u8) ~ 0;
14558   int ret;
14559
14560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14561     {
14562       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14563         ;
14564       else if (unformat (i, "sa_id %d", &sa_id))
14565         ;
14566       else if (unformat (i, "outbound"))
14567         is_outbound = 1;
14568       else if (unformat (i, "inbound"))
14569         is_outbound = 0;
14570       else
14571         {
14572           clib_warning ("parse error '%U'", format_unformat_error, i);
14573           return -99;
14574         }
14575     }
14576
14577   if (sw_if_index == ~0)
14578     {
14579       errmsg ("interface must be specified");
14580       return -99;
14581     }
14582
14583   if (sa_id == ~0)
14584     {
14585       errmsg ("SA ID must be specified");
14586       return -99;
14587     }
14588
14589   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14590
14591   mp->sw_if_index = htonl (sw_if_index);
14592   mp->sa_id = htonl (sa_id);
14593   mp->is_outbound = is_outbound;
14594
14595   S (mp);
14596   W (ret);
14597
14598   return ret;
14599 }
14600
14601 static int
14602 api_get_first_msg_id (vat_main_t * vam)
14603 {
14604   vl_api_get_first_msg_id_t *mp;
14605   unformat_input_t *i = vam->input;
14606   u8 *name;
14607   u8 name_set = 0;
14608   int ret;
14609
14610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14611     {
14612       if (unformat (i, "client %s", &name))
14613         name_set = 1;
14614       else
14615         break;
14616     }
14617
14618   if (name_set == 0)
14619     {
14620       errmsg ("missing client name");
14621       return -99;
14622     }
14623   vec_add1 (name, 0);
14624
14625   if (vec_len (name) > 63)
14626     {
14627       errmsg ("client name too long");
14628       return -99;
14629     }
14630
14631   M (GET_FIRST_MSG_ID, mp);
14632   clib_memcpy (mp->name, name, vec_len (name));
14633   S (mp);
14634   W (ret);
14635   return ret;
14636 }
14637
14638 static int
14639 api_cop_interface_enable_disable (vat_main_t * vam)
14640 {
14641   unformat_input_t *line_input = vam->input;
14642   vl_api_cop_interface_enable_disable_t *mp;
14643   u32 sw_if_index = ~0;
14644   u8 enable_disable = 1;
14645   int ret;
14646
14647   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14648     {
14649       if (unformat (line_input, "disable"))
14650         enable_disable = 0;
14651       if (unformat (line_input, "enable"))
14652         enable_disable = 1;
14653       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14654                          vam, &sw_if_index))
14655         ;
14656       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14657         ;
14658       else
14659         break;
14660     }
14661
14662   if (sw_if_index == ~0)
14663     {
14664       errmsg ("missing interface name or sw_if_index");
14665       return -99;
14666     }
14667
14668   /* Construct the API message */
14669   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14670   mp->sw_if_index = ntohl (sw_if_index);
14671   mp->enable_disable = enable_disable;
14672
14673   /* send it... */
14674   S (mp);
14675   /* Wait for the reply */
14676   W (ret);
14677   return ret;
14678 }
14679
14680 static int
14681 api_cop_whitelist_enable_disable (vat_main_t * vam)
14682 {
14683   unformat_input_t *line_input = vam->input;
14684   vl_api_cop_whitelist_enable_disable_t *mp;
14685   u32 sw_if_index = ~0;
14686   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14687   u32 fib_id = 0;
14688   int ret;
14689
14690   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14691     {
14692       if (unformat (line_input, "ip4"))
14693         ip4 = 1;
14694       else if (unformat (line_input, "ip6"))
14695         ip6 = 1;
14696       else if (unformat (line_input, "default"))
14697         default_cop = 1;
14698       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14699                          vam, &sw_if_index))
14700         ;
14701       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14702         ;
14703       else if (unformat (line_input, "fib-id %d", &fib_id))
14704         ;
14705       else
14706         break;
14707     }
14708
14709   if (sw_if_index == ~0)
14710     {
14711       errmsg ("missing interface name or sw_if_index");
14712       return -99;
14713     }
14714
14715   /* Construct the API message */
14716   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14717   mp->sw_if_index = ntohl (sw_if_index);
14718   mp->fib_id = ntohl (fib_id);
14719   mp->ip4 = ip4;
14720   mp->ip6 = ip6;
14721   mp->default_cop = default_cop;
14722
14723   /* send it... */
14724   S (mp);
14725   /* Wait for the reply */
14726   W (ret);
14727   return ret;
14728 }
14729
14730 static int
14731 api_get_node_graph (vat_main_t * vam)
14732 {
14733   vl_api_get_node_graph_t *mp;
14734   int ret;
14735
14736   M (GET_NODE_GRAPH, mp);
14737
14738   /* send it... */
14739   S (mp);
14740   /* Wait for the reply */
14741   W (ret);
14742   return ret;
14743 }
14744
14745 /* *INDENT-OFF* */
14746 /** Used for parsing LISP eids */
14747 typedef CLIB_PACKED(struct{
14748   u8 addr[16];   /**< eid address */
14749   u32 len;       /**< prefix length if IP */
14750   u8 type;      /**< type of eid */
14751 }) lisp_eid_vat_t;
14752 /* *INDENT-ON* */
14753
14754 static uword
14755 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14756 {
14757   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14758
14759   clib_memset (a, 0, sizeof (a[0]));
14760
14761   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14762     {
14763       a->type = 0;              /* ipv4 type */
14764     }
14765   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14766     {
14767       a->type = 1;              /* ipv6 type */
14768     }
14769   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14770     {
14771       a->type = 2;              /* mac type */
14772     }
14773   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14774     {
14775       a->type = 3;              /* NSH type */
14776       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14777       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14778     }
14779   else
14780     {
14781       return 0;
14782     }
14783
14784   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14785     {
14786       return 0;
14787     }
14788
14789   return 1;
14790 }
14791
14792 static int
14793 lisp_eid_size_vat (u8 type)
14794 {
14795   switch (type)
14796     {
14797     case 0:
14798       return 4;
14799     case 1:
14800       return 16;
14801     case 2:
14802       return 6;
14803     case 3:
14804       return 5;
14805     }
14806   return 0;
14807 }
14808
14809 static void
14810 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14811 {
14812   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14813 }
14814
14815 static int
14816 api_one_add_del_locator_set (vat_main_t * vam)
14817 {
14818   unformat_input_t *input = vam->input;
14819   vl_api_one_add_del_locator_set_t *mp;
14820   u8 is_add = 1;
14821   u8 *locator_set_name = NULL;
14822   u8 locator_set_name_set = 0;
14823   vl_api_local_locator_t locator, *locators = 0;
14824   u32 sw_if_index, priority, weight;
14825   u32 data_len = 0;
14826
14827   int ret;
14828   /* Parse args required to build the message */
14829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14830     {
14831       if (unformat (input, "del"))
14832         {
14833           is_add = 0;
14834         }
14835       else if (unformat (input, "locator-set %s", &locator_set_name))
14836         {
14837           locator_set_name_set = 1;
14838         }
14839       else if (unformat (input, "sw_if_index %u p %u w %u",
14840                          &sw_if_index, &priority, &weight))
14841         {
14842           locator.sw_if_index = htonl (sw_if_index);
14843           locator.priority = priority;
14844           locator.weight = weight;
14845           vec_add1 (locators, locator);
14846         }
14847       else
14848         if (unformat
14849             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14850              &sw_if_index, &priority, &weight))
14851         {
14852           locator.sw_if_index = htonl (sw_if_index);
14853           locator.priority = priority;
14854           locator.weight = weight;
14855           vec_add1 (locators, locator);
14856         }
14857       else
14858         break;
14859     }
14860
14861   if (locator_set_name_set == 0)
14862     {
14863       errmsg ("missing locator-set name");
14864       vec_free (locators);
14865       return -99;
14866     }
14867
14868   if (vec_len (locator_set_name) > 64)
14869     {
14870       errmsg ("locator-set name too long");
14871       vec_free (locator_set_name);
14872       vec_free (locators);
14873       return -99;
14874     }
14875   vec_add1 (locator_set_name, 0);
14876
14877   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14878
14879   /* Construct the API message */
14880   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14881
14882   mp->is_add = is_add;
14883   clib_memcpy (mp->locator_set_name, locator_set_name,
14884                vec_len (locator_set_name));
14885   vec_free (locator_set_name);
14886
14887   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14888   if (locators)
14889     clib_memcpy (mp->locators, locators, data_len);
14890   vec_free (locators);
14891
14892   /* send it... */
14893   S (mp);
14894
14895   /* Wait for a reply... */
14896   W (ret);
14897   return ret;
14898 }
14899
14900 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14901
14902 static int
14903 api_one_add_del_locator (vat_main_t * vam)
14904 {
14905   unformat_input_t *input = vam->input;
14906   vl_api_one_add_del_locator_t *mp;
14907   u32 tmp_if_index = ~0;
14908   u32 sw_if_index = ~0;
14909   u8 sw_if_index_set = 0;
14910   u8 sw_if_index_if_name_set = 0;
14911   u32 priority = ~0;
14912   u8 priority_set = 0;
14913   u32 weight = ~0;
14914   u8 weight_set = 0;
14915   u8 is_add = 1;
14916   u8 *locator_set_name = NULL;
14917   u8 locator_set_name_set = 0;
14918   int ret;
14919
14920   /* Parse args required to build the message */
14921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14922     {
14923       if (unformat (input, "del"))
14924         {
14925           is_add = 0;
14926         }
14927       else if (unformat (input, "locator-set %s", &locator_set_name))
14928         {
14929           locator_set_name_set = 1;
14930         }
14931       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14932                          &tmp_if_index))
14933         {
14934           sw_if_index_if_name_set = 1;
14935           sw_if_index = tmp_if_index;
14936         }
14937       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14938         {
14939           sw_if_index_set = 1;
14940           sw_if_index = tmp_if_index;
14941         }
14942       else if (unformat (input, "p %d", &priority))
14943         {
14944           priority_set = 1;
14945         }
14946       else if (unformat (input, "w %d", &weight))
14947         {
14948           weight_set = 1;
14949         }
14950       else
14951         break;
14952     }
14953
14954   if (locator_set_name_set == 0)
14955     {
14956       errmsg ("missing locator-set name");
14957       return -99;
14958     }
14959
14960   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14961     {
14962       errmsg ("missing sw_if_index");
14963       vec_free (locator_set_name);
14964       return -99;
14965     }
14966
14967   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14968     {
14969       errmsg ("cannot use both params interface name and sw_if_index");
14970       vec_free (locator_set_name);
14971       return -99;
14972     }
14973
14974   if (priority_set == 0)
14975     {
14976       errmsg ("missing locator-set priority");
14977       vec_free (locator_set_name);
14978       return -99;
14979     }
14980
14981   if (weight_set == 0)
14982     {
14983       errmsg ("missing locator-set weight");
14984       vec_free (locator_set_name);
14985       return -99;
14986     }
14987
14988   if (vec_len (locator_set_name) > 64)
14989     {
14990       errmsg ("locator-set name too long");
14991       vec_free (locator_set_name);
14992       return -99;
14993     }
14994   vec_add1 (locator_set_name, 0);
14995
14996   /* Construct the API message */
14997   M (ONE_ADD_DEL_LOCATOR, mp);
14998
14999   mp->is_add = is_add;
15000   mp->sw_if_index = ntohl (sw_if_index);
15001   mp->priority = priority;
15002   mp->weight = weight;
15003   clib_memcpy (mp->locator_set_name, locator_set_name,
15004                vec_len (locator_set_name));
15005   vec_free (locator_set_name);
15006
15007   /* send it... */
15008   S (mp);
15009
15010   /* Wait for a reply... */
15011   W (ret);
15012   return ret;
15013 }
15014
15015 #define api_lisp_add_del_locator api_one_add_del_locator
15016
15017 uword
15018 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15019 {
15020   u32 *key_id = va_arg (*args, u32 *);
15021   u8 *s = 0;
15022
15023   if (unformat (input, "%s", &s))
15024     {
15025       if (!strcmp ((char *) s, "sha1"))
15026         key_id[0] = HMAC_SHA_1_96;
15027       else if (!strcmp ((char *) s, "sha256"))
15028         key_id[0] = HMAC_SHA_256_128;
15029       else
15030         {
15031           clib_warning ("invalid key_id: '%s'", s);
15032           key_id[0] = HMAC_NO_KEY;
15033         }
15034     }
15035   else
15036     return 0;
15037
15038   vec_free (s);
15039   return 1;
15040 }
15041
15042 static int
15043 api_one_add_del_local_eid (vat_main_t * vam)
15044 {
15045   unformat_input_t *input = vam->input;
15046   vl_api_one_add_del_local_eid_t *mp;
15047   u8 is_add = 1;
15048   u8 eid_set = 0;
15049   lisp_eid_vat_t _eid, *eid = &_eid;
15050   u8 *locator_set_name = 0;
15051   u8 locator_set_name_set = 0;
15052   u32 vni = 0;
15053   u16 key_id = 0;
15054   u8 *key = 0;
15055   int ret;
15056
15057   /* Parse args required to build the message */
15058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15059     {
15060       if (unformat (input, "del"))
15061         {
15062           is_add = 0;
15063         }
15064       else if (unformat (input, "vni %d", &vni))
15065         {
15066           ;
15067         }
15068       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15069         {
15070           eid_set = 1;
15071         }
15072       else if (unformat (input, "locator-set %s", &locator_set_name))
15073         {
15074           locator_set_name_set = 1;
15075         }
15076       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15077         ;
15078       else if (unformat (input, "secret-key %_%v%_", &key))
15079         ;
15080       else
15081         break;
15082     }
15083
15084   if (locator_set_name_set == 0)
15085     {
15086       errmsg ("missing locator-set name");
15087       return -99;
15088     }
15089
15090   if (0 == eid_set)
15091     {
15092       errmsg ("EID address not set!");
15093       vec_free (locator_set_name);
15094       return -99;
15095     }
15096
15097   if (key && (0 == key_id))
15098     {
15099       errmsg ("invalid key_id!");
15100       return -99;
15101     }
15102
15103   if (vec_len (key) > 64)
15104     {
15105       errmsg ("key too long");
15106       vec_free (key);
15107       return -99;
15108     }
15109
15110   if (vec_len (locator_set_name) > 64)
15111     {
15112       errmsg ("locator-set name too long");
15113       vec_free (locator_set_name);
15114       return -99;
15115     }
15116   vec_add1 (locator_set_name, 0);
15117
15118   /* Construct the API message */
15119   M (ONE_ADD_DEL_LOCAL_EID, mp);
15120
15121   mp->is_add = is_add;
15122   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15123   mp->eid_type = eid->type;
15124   mp->prefix_len = eid->len;
15125   mp->vni = clib_host_to_net_u32 (vni);
15126   mp->key_id = clib_host_to_net_u16 (key_id);
15127   clib_memcpy (mp->locator_set_name, locator_set_name,
15128                vec_len (locator_set_name));
15129   clib_memcpy (mp->key, key, vec_len (key));
15130
15131   vec_free (locator_set_name);
15132   vec_free (key);
15133
15134   /* send it... */
15135   S (mp);
15136
15137   /* Wait for a reply... */
15138   W (ret);
15139   return ret;
15140 }
15141
15142 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15143
15144 static int
15145 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15146 {
15147   u32 dp_table = 0, vni = 0;;
15148   unformat_input_t *input = vam->input;
15149   vl_api_gpe_add_del_fwd_entry_t *mp;
15150   u8 is_add = 1;
15151   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15152   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15153   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15154   u32 action = ~0, w;
15155   ip4_address_t rmt_rloc4, lcl_rloc4;
15156   ip6_address_t rmt_rloc6, lcl_rloc6;
15157   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15158   int ret;
15159
15160   clib_memset (&rloc, 0, sizeof (rloc));
15161
15162   /* Parse args required to build the message */
15163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15164     {
15165       if (unformat (input, "del"))
15166         is_add = 0;
15167       else if (unformat (input, "add"))
15168         is_add = 1;
15169       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15170         {
15171           rmt_eid_set = 1;
15172         }
15173       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15174         {
15175           lcl_eid_set = 1;
15176         }
15177       else if (unformat (input, "vrf %d", &dp_table))
15178         ;
15179       else if (unformat (input, "bd %d", &dp_table))
15180         ;
15181       else if (unformat (input, "vni %d", &vni))
15182         ;
15183       else if (unformat (input, "w %d", &w))
15184         {
15185           if (!curr_rloc)
15186             {
15187               errmsg ("No RLOC configured for setting priority/weight!");
15188               return -99;
15189             }
15190           curr_rloc->weight = w;
15191         }
15192       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15193                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15194         {
15195           rloc.is_ip4 = 1;
15196
15197           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15198           rloc.weight = 0;
15199           vec_add1 (lcl_locs, rloc);
15200
15201           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15202           vec_add1 (rmt_locs, rloc);
15203           /* weight saved in rmt loc */
15204           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15205         }
15206       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15207                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15208         {
15209           rloc.is_ip4 = 0;
15210           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15211           rloc.weight = 0;
15212           vec_add1 (lcl_locs, rloc);
15213
15214           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15215           vec_add1 (rmt_locs, rloc);
15216           /* weight saved in rmt loc */
15217           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15218         }
15219       else if (unformat (input, "action %d", &action))
15220         {
15221           ;
15222         }
15223       else
15224         {
15225           clib_warning ("parse error '%U'", format_unformat_error, input);
15226           return -99;
15227         }
15228     }
15229
15230   if (!rmt_eid_set)
15231     {
15232       errmsg ("remote eid addresses not set");
15233       return -99;
15234     }
15235
15236   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15237     {
15238       errmsg ("eid types don't match");
15239       return -99;
15240     }
15241
15242   if (0 == rmt_locs && (u32) ~ 0 == action)
15243     {
15244       errmsg ("action not set for negative mapping");
15245       return -99;
15246     }
15247
15248   /* Construct the API message */
15249   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15250       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15251
15252   mp->is_add = is_add;
15253   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15254   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15255   mp->eid_type = rmt_eid->type;
15256   mp->dp_table = clib_host_to_net_u32 (dp_table);
15257   mp->vni = clib_host_to_net_u32 (vni);
15258   mp->rmt_len = rmt_eid->len;
15259   mp->lcl_len = lcl_eid->len;
15260   mp->action = action;
15261
15262   if (0 != rmt_locs && 0 != lcl_locs)
15263     {
15264       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15265       clib_memcpy (mp->locs, lcl_locs,
15266                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15267
15268       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15269       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15270                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15271     }
15272   vec_free (lcl_locs);
15273   vec_free (rmt_locs);
15274
15275   /* send it... */
15276   S (mp);
15277
15278   /* Wait for a reply... */
15279   W (ret);
15280   return ret;
15281 }
15282
15283 static int
15284 api_one_add_del_map_server (vat_main_t * vam)
15285 {
15286   unformat_input_t *input = vam->input;
15287   vl_api_one_add_del_map_server_t *mp;
15288   u8 is_add = 1;
15289   u8 ipv4_set = 0;
15290   u8 ipv6_set = 0;
15291   ip4_address_t ipv4;
15292   ip6_address_t ipv6;
15293   int ret;
15294
15295   /* Parse args required to build the message */
15296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15297     {
15298       if (unformat (input, "del"))
15299         {
15300           is_add = 0;
15301         }
15302       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15303         {
15304           ipv4_set = 1;
15305         }
15306       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15307         {
15308           ipv6_set = 1;
15309         }
15310       else
15311         break;
15312     }
15313
15314   if (ipv4_set && ipv6_set)
15315     {
15316       errmsg ("both eid v4 and v6 addresses set");
15317       return -99;
15318     }
15319
15320   if (!ipv4_set && !ipv6_set)
15321     {
15322       errmsg ("eid addresses not set");
15323       return -99;
15324     }
15325
15326   /* Construct the API message */
15327   M (ONE_ADD_DEL_MAP_SERVER, mp);
15328
15329   mp->is_add = is_add;
15330   if (ipv6_set)
15331     {
15332       mp->is_ipv6 = 1;
15333       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15334     }
15335   else
15336     {
15337       mp->is_ipv6 = 0;
15338       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15339     }
15340
15341   /* send it... */
15342   S (mp);
15343
15344   /* Wait for a reply... */
15345   W (ret);
15346   return ret;
15347 }
15348
15349 #define api_lisp_add_del_map_server api_one_add_del_map_server
15350
15351 static int
15352 api_one_add_del_map_resolver (vat_main_t * vam)
15353 {
15354   unformat_input_t *input = vam->input;
15355   vl_api_one_add_del_map_resolver_t *mp;
15356   u8 is_add = 1;
15357   u8 ipv4_set = 0;
15358   u8 ipv6_set = 0;
15359   ip4_address_t ipv4;
15360   ip6_address_t ipv6;
15361   int ret;
15362
15363   /* Parse args required to build the message */
15364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15365     {
15366       if (unformat (input, "del"))
15367         {
15368           is_add = 0;
15369         }
15370       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15371         {
15372           ipv4_set = 1;
15373         }
15374       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15375         {
15376           ipv6_set = 1;
15377         }
15378       else
15379         break;
15380     }
15381
15382   if (ipv4_set && ipv6_set)
15383     {
15384       errmsg ("both eid v4 and v6 addresses set");
15385       return -99;
15386     }
15387
15388   if (!ipv4_set && !ipv6_set)
15389     {
15390       errmsg ("eid addresses not set");
15391       return -99;
15392     }
15393
15394   /* Construct the API message */
15395   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15396
15397   mp->is_add = is_add;
15398   if (ipv6_set)
15399     {
15400       mp->is_ipv6 = 1;
15401       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15402     }
15403   else
15404     {
15405       mp->is_ipv6 = 0;
15406       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15407     }
15408
15409   /* send it... */
15410   S (mp);
15411
15412   /* Wait for a reply... */
15413   W (ret);
15414   return ret;
15415 }
15416
15417 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15418
15419 static int
15420 api_lisp_gpe_enable_disable (vat_main_t * vam)
15421 {
15422   unformat_input_t *input = vam->input;
15423   vl_api_gpe_enable_disable_t *mp;
15424   u8 is_set = 0;
15425   u8 is_en = 1;
15426   int ret;
15427
15428   /* Parse args required to build the message */
15429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15430     {
15431       if (unformat (input, "enable"))
15432         {
15433           is_set = 1;
15434           is_en = 1;
15435         }
15436       else if (unformat (input, "disable"))
15437         {
15438           is_set = 1;
15439           is_en = 0;
15440         }
15441       else
15442         break;
15443     }
15444
15445   if (is_set == 0)
15446     {
15447       errmsg ("Value not set");
15448       return -99;
15449     }
15450
15451   /* Construct the API message */
15452   M (GPE_ENABLE_DISABLE, mp);
15453
15454   mp->is_en = is_en;
15455
15456   /* send it... */
15457   S (mp);
15458
15459   /* Wait for a reply... */
15460   W (ret);
15461   return ret;
15462 }
15463
15464 static int
15465 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15466 {
15467   unformat_input_t *input = vam->input;
15468   vl_api_one_rloc_probe_enable_disable_t *mp;
15469   u8 is_set = 0;
15470   u8 is_en = 0;
15471   int ret;
15472
15473   /* Parse args required to build the message */
15474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (input, "enable"))
15477         {
15478           is_set = 1;
15479           is_en = 1;
15480         }
15481       else if (unformat (input, "disable"))
15482         is_set = 1;
15483       else
15484         break;
15485     }
15486
15487   if (!is_set)
15488     {
15489       errmsg ("Value not set");
15490       return -99;
15491     }
15492
15493   /* Construct the API message */
15494   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15495
15496   mp->is_enabled = is_en;
15497
15498   /* send it... */
15499   S (mp);
15500
15501   /* Wait for a reply... */
15502   W (ret);
15503   return ret;
15504 }
15505
15506 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15507
15508 static int
15509 api_one_map_register_enable_disable (vat_main_t * vam)
15510 {
15511   unformat_input_t *input = vam->input;
15512   vl_api_one_map_register_enable_disable_t *mp;
15513   u8 is_set = 0;
15514   u8 is_en = 0;
15515   int ret;
15516
15517   /* Parse args required to build the message */
15518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15519     {
15520       if (unformat (input, "enable"))
15521         {
15522           is_set = 1;
15523           is_en = 1;
15524         }
15525       else if (unformat (input, "disable"))
15526         is_set = 1;
15527       else
15528         break;
15529     }
15530
15531   if (!is_set)
15532     {
15533       errmsg ("Value not set");
15534       return -99;
15535     }
15536
15537   /* Construct the API message */
15538   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15539
15540   mp->is_enabled = is_en;
15541
15542   /* send it... */
15543   S (mp);
15544
15545   /* Wait for a reply... */
15546   W (ret);
15547   return ret;
15548 }
15549
15550 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15551
15552 static int
15553 api_one_enable_disable (vat_main_t * vam)
15554 {
15555   unformat_input_t *input = vam->input;
15556   vl_api_one_enable_disable_t *mp;
15557   u8 is_set = 0;
15558   u8 is_en = 0;
15559   int ret;
15560
15561   /* Parse args required to build the message */
15562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15563     {
15564       if (unformat (input, "enable"))
15565         {
15566           is_set = 1;
15567           is_en = 1;
15568         }
15569       else if (unformat (input, "disable"))
15570         {
15571           is_set = 1;
15572         }
15573       else
15574         break;
15575     }
15576
15577   if (!is_set)
15578     {
15579       errmsg ("Value not set");
15580       return -99;
15581     }
15582
15583   /* Construct the API message */
15584   M (ONE_ENABLE_DISABLE, mp);
15585
15586   mp->is_en = is_en;
15587
15588   /* send it... */
15589   S (mp);
15590
15591   /* Wait for a reply... */
15592   W (ret);
15593   return ret;
15594 }
15595
15596 #define api_lisp_enable_disable api_one_enable_disable
15597
15598 static int
15599 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15600 {
15601   unformat_input_t *input = vam->input;
15602   vl_api_one_enable_disable_xtr_mode_t *mp;
15603   u8 is_set = 0;
15604   u8 is_en = 0;
15605   int ret;
15606
15607   /* Parse args required to build the message */
15608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15609     {
15610       if (unformat (input, "enable"))
15611         {
15612           is_set = 1;
15613           is_en = 1;
15614         }
15615       else if (unformat (input, "disable"))
15616         {
15617           is_set = 1;
15618         }
15619       else
15620         break;
15621     }
15622
15623   if (!is_set)
15624     {
15625       errmsg ("Value not set");
15626       return -99;
15627     }
15628
15629   /* Construct the API message */
15630   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15631
15632   mp->is_en = is_en;
15633
15634   /* send it... */
15635   S (mp);
15636
15637   /* Wait for a reply... */
15638   W (ret);
15639   return ret;
15640 }
15641
15642 static int
15643 api_one_show_xtr_mode (vat_main_t * vam)
15644 {
15645   vl_api_one_show_xtr_mode_t *mp;
15646   int ret;
15647
15648   /* Construct the API message */
15649   M (ONE_SHOW_XTR_MODE, mp);
15650
15651   /* send it... */
15652   S (mp);
15653
15654   /* Wait for a reply... */
15655   W (ret);
15656   return ret;
15657 }
15658
15659 static int
15660 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15661 {
15662   unformat_input_t *input = vam->input;
15663   vl_api_one_enable_disable_pitr_mode_t *mp;
15664   u8 is_set = 0;
15665   u8 is_en = 0;
15666   int ret;
15667
15668   /* Parse args required to build the message */
15669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (input, "enable"))
15672         {
15673           is_set = 1;
15674           is_en = 1;
15675         }
15676       else if (unformat (input, "disable"))
15677         {
15678           is_set = 1;
15679         }
15680       else
15681         break;
15682     }
15683
15684   if (!is_set)
15685     {
15686       errmsg ("Value not set");
15687       return -99;
15688     }
15689
15690   /* Construct the API message */
15691   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15692
15693   mp->is_en = is_en;
15694
15695   /* send it... */
15696   S (mp);
15697
15698   /* Wait for a reply... */
15699   W (ret);
15700   return ret;
15701 }
15702
15703 static int
15704 api_one_show_pitr_mode (vat_main_t * vam)
15705 {
15706   vl_api_one_show_pitr_mode_t *mp;
15707   int ret;
15708
15709   /* Construct the API message */
15710   M (ONE_SHOW_PITR_MODE, mp);
15711
15712   /* send it... */
15713   S (mp);
15714
15715   /* Wait for a reply... */
15716   W (ret);
15717   return ret;
15718 }
15719
15720 static int
15721 api_one_enable_disable_petr_mode (vat_main_t * vam)
15722 {
15723   unformat_input_t *input = vam->input;
15724   vl_api_one_enable_disable_petr_mode_t *mp;
15725   u8 is_set = 0;
15726   u8 is_en = 0;
15727   int ret;
15728
15729   /* Parse args required to build the message */
15730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15731     {
15732       if (unformat (input, "enable"))
15733         {
15734           is_set = 1;
15735           is_en = 1;
15736         }
15737       else if (unformat (input, "disable"))
15738         {
15739           is_set = 1;
15740         }
15741       else
15742         break;
15743     }
15744
15745   if (!is_set)
15746     {
15747       errmsg ("Value not set");
15748       return -99;
15749     }
15750
15751   /* Construct the API message */
15752   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15753
15754   mp->is_en = is_en;
15755
15756   /* send it... */
15757   S (mp);
15758
15759   /* Wait for a reply... */
15760   W (ret);
15761   return ret;
15762 }
15763
15764 static int
15765 api_one_show_petr_mode (vat_main_t * vam)
15766 {
15767   vl_api_one_show_petr_mode_t *mp;
15768   int ret;
15769
15770   /* Construct the API message */
15771   M (ONE_SHOW_PETR_MODE, mp);
15772
15773   /* send it... */
15774   S (mp);
15775
15776   /* Wait for a reply... */
15777   W (ret);
15778   return ret;
15779 }
15780
15781 static int
15782 api_show_one_map_register_state (vat_main_t * vam)
15783 {
15784   vl_api_show_one_map_register_state_t *mp;
15785   int ret;
15786
15787   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15788
15789   /* send */
15790   S (mp);
15791
15792   /* wait for reply */
15793   W (ret);
15794   return ret;
15795 }
15796
15797 #define api_show_lisp_map_register_state api_show_one_map_register_state
15798
15799 static int
15800 api_show_one_rloc_probe_state (vat_main_t * vam)
15801 {
15802   vl_api_show_one_rloc_probe_state_t *mp;
15803   int ret;
15804
15805   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15806
15807   /* send */
15808   S (mp);
15809
15810   /* wait for reply */
15811   W (ret);
15812   return ret;
15813 }
15814
15815 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15816
15817 static int
15818 api_one_add_del_ndp_entry (vat_main_t * vam)
15819 {
15820   vl_api_one_add_del_ndp_entry_t *mp;
15821   unformat_input_t *input = vam->input;
15822   u8 is_add = 1;
15823   u8 mac_set = 0;
15824   u8 bd_set = 0;
15825   u8 ip_set = 0;
15826   u8 mac[6] = { 0, };
15827   u8 ip6[16] = { 0, };
15828   u32 bd = ~0;
15829   int ret;
15830
15831   /* Parse args required to build the message */
15832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15833     {
15834       if (unformat (input, "del"))
15835         is_add = 0;
15836       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15837         mac_set = 1;
15838       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15839         ip_set = 1;
15840       else if (unformat (input, "bd %d", &bd))
15841         bd_set = 1;
15842       else
15843         {
15844           errmsg ("parse error '%U'", format_unformat_error, input);
15845           return -99;
15846         }
15847     }
15848
15849   if (!bd_set || !ip_set || (!mac_set && is_add))
15850     {
15851       errmsg ("Missing BD, IP or MAC!");
15852       return -99;
15853     }
15854
15855   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15856   mp->is_add = is_add;
15857   clib_memcpy (mp->mac, mac, 6);
15858   mp->bd = clib_host_to_net_u32 (bd);
15859   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15860
15861   /* send */
15862   S (mp);
15863
15864   /* wait for reply */
15865   W (ret);
15866   return ret;
15867 }
15868
15869 static int
15870 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15871 {
15872   vl_api_one_add_del_l2_arp_entry_t *mp;
15873   unformat_input_t *input = vam->input;
15874   u8 is_add = 1;
15875   u8 mac_set = 0;
15876   u8 bd_set = 0;
15877   u8 ip_set = 0;
15878   u8 mac[6] = { 0, };
15879   u32 ip4 = 0, bd = ~0;
15880   int ret;
15881
15882   /* Parse args required to build the message */
15883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15884     {
15885       if (unformat (input, "del"))
15886         is_add = 0;
15887       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15888         mac_set = 1;
15889       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15890         ip_set = 1;
15891       else if (unformat (input, "bd %d", &bd))
15892         bd_set = 1;
15893       else
15894         {
15895           errmsg ("parse error '%U'", format_unformat_error, input);
15896           return -99;
15897         }
15898     }
15899
15900   if (!bd_set || !ip_set || (!mac_set && is_add))
15901     {
15902       errmsg ("Missing BD, IP or MAC!");
15903       return -99;
15904     }
15905
15906   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15907   mp->is_add = is_add;
15908   clib_memcpy (mp->mac, mac, 6);
15909   mp->bd = clib_host_to_net_u32 (bd);
15910   mp->ip4 = ip4;
15911
15912   /* send */
15913   S (mp);
15914
15915   /* wait for reply */
15916   W (ret);
15917   return ret;
15918 }
15919
15920 static int
15921 api_one_ndp_bd_get (vat_main_t * vam)
15922 {
15923   vl_api_one_ndp_bd_get_t *mp;
15924   int ret;
15925
15926   M (ONE_NDP_BD_GET, mp);
15927
15928   /* send */
15929   S (mp);
15930
15931   /* wait for reply */
15932   W (ret);
15933   return ret;
15934 }
15935
15936 static int
15937 api_one_ndp_entries_get (vat_main_t * vam)
15938 {
15939   vl_api_one_ndp_entries_get_t *mp;
15940   unformat_input_t *input = vam->input;
15941   u8 bd_set = 0;
15942   u32 bd = ~0;
15943   int ret;
15944
15945   /* Parse args required to build the message */
15946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat (input, "bd %d", &bd))
15949         bd_set = 1;
15950       else
15951         {
15952           errmsg ("parse error '%U'", format_unformat_error, input);
15953           return -99;
15954         }
15955     }
15956
15957   if (!bd_set)
15958     {
15959       errmsg ("Expected bridge domain!");
15960       return -99;
15961     }
15962
15963   M (ONE_NDP_ENTRIES_GET, mp);
15964   mp->bd = clib_host_to_net_u32 (bd);
15965
15966   /* send */
15967   S (mp);
15968
15969   /* wait for reply */
15970   W (ret);
15971   return ret;
15972 }
15973
15974 static int
15975 api_one_l2_arp_bd_get (vat_main_t * vam)
15976 {
15977   vl_api_one_l2_arp_bd_get_t *mp;
15978   int ret;
15979
15980   M (ONE_L2_ARP_BD_GET, mp);
15981
15982   /* send */
15983   S (mp);
15984
15985   /* wait for reply */
15986   W (ret);
15987   return ret;
15988 }
15989
15990 static int
15991 api_one_l2_arp_entries_get (vat_main_t * vam)
15992 {
15993   vl_api_one_l2_arp_entries_get_t *mp;
15994   unformat_input_t *input = vam->input;
15995   u8 bd_set = 0;
15996   u32 bd = ~0;
15997   int ret;
15998
15999   /* Parse args required to build the message */
16000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16001     {
16002       if (unformat (input, "bd %d", &bd))
16003         bd_set = 1;
16004       else
16005         {
16006           errmsg ("parse error '%U'", format_unformat_error, input);
16007           return -99;
16008         }
16009     }
16010
16011   if (!bd_set)
16012     {
16013       errmsg ("Expected bridge domain!");
16014       return -99;
16015     }
16016
16017   M (ONE_L2_ARP_ENTRIES_GET, mp);
16018   mp->bd = clib_host_to_net_u32 (bd);
16019
16020   /* send */
16021   S (mp);
16022
16023   /* wait for reply */
16024   W (ret);
16025   return ret;
16026 }
16027
16028 static int
16029 api_one_stats_enable_disable (vat_main_t * vam)
16030 {
16031   vl_api_one_stats_enable_disable_t *mp;
16032   unformat_input_t *input = vam->input;
16033   u8 is_set = 0;
16034   u8 is_en = 0;
16035   int ret;
16036
16037   /* Parse args required to build the message */
16038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16039     {
16040       if (unformat (input, "enable"))
16041         {
16042           is_set = 1;
16043           is_en = 1;
16044         }
16045       else if (unformat (input, "disable"))
16046         {
16047           is_set = 1;
16048         }
16049       else
16050         break;
16051     }
16052
16053   if (!is_set)
16054     {
16055       errmsg ("Value not set");
16056       return -99;
16057     }
16058
16059   M (ONE_STATS_ENABLE_DISABLE, mp);
16060   mp->is_en = is_en;
16061
16062   /* send */
16063   S (mp);
16064
16065   /* wait for reply */
16066   W (ret);
16067   return ret;
16068 }
16069
16070 static int
16071 api_show_one_stats_enable_disable (vat_main_t * vam)
16072 {
16073   vl_api_show_one_stats_enable_disable_t *mp;
16074   int ret;
16075
16076   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16077
16078   /* send */
16079   S (mp);
16080
16081   /* wait for reply */
16082   W (ret);
16083   return ret;
16084 }
16085
16086 static int
16087 api_show_one_map_request_mode (vat_main_t * vam)
16088 {
16089   vl_api_show_one_map_request_mode_t *mp;
16090   int ret;
16091
16092   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16093
16094   /* send */
16095   S (mp);
16096
16097   /* wait for reply */
16098   W (ret);
16099   return ret;
16100 }
16101
16102 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16103
16104 static int
16105 api_one_map_request_mode (vat_main_t * vam)
16106 {
16107   unformat_input_t *input = vam->input;
16108   vl_api_one_map_request_mode_t *mp;
16109   u8 mode = 0;
16110   int ret;
16111
16112   /* Parse args required to build the message */
16113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16114     {
16115       if (unformat (input, "dst-only"))
16116         mode = 0;
16117       else if (unformat (input, "src-dst"))
16118         mode = 1;
16119       else
16120         {
16121           errmsg ("parse error '%U'", format_unformat_error, input);
16122           return -99;
16123         }
16124     }
16125
16126   M (ONE_MAP_REQUEST_MODE, mp);
16127
16128   mp->mode = mode;
16129
16130   /* send */
16131   S (mp);
16132
16133   /* wait for reply */
16134   W (ret);
16135   return ret;
16136 }
16137
16138 #define api_lisp_map_request_mode api_one_map_request_mode
16139
16140 /**
16141  * Enable/disable ONE proxy ITR.
16142  *
16143  * @param vam vpp API test context
16144  * @return return code
16145  */
16146 static int
16147 api_one_pitr_set_locator_set (vat_main_t * vam)
16148 {
16149   u8 ls_name_set = 0;
16150   unformat_input_t *input = vam->input;
16151   vl_api_one_pitr_set_locator_set_t *mp;
16152   u8 is_add = 1;
16153   u8 *ls_name = 0;
16154   int ret;
16155
16156   /* Parse args required to build the message */
16157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16158     {
16159       if (unformat (input, "del"))
16160         is_add = 0;
16161       else if (unformat (input, "locator-set %s", &ls_name))
16162         ls_name_set = 1;
16163       else
16164         {
16165           errmsg ("parse error '%U'", format_unformat_error, input);
16166           return -99;
16167         }
16168     }
16169
16170   if (!ls_name_set)
16171     {
16172       errmsg ("locator-set name not set!");
16173       return -99;
16174     }
16175
16176   M (ONE_PITR_SET_LOCATOR_SET, mp);
16177
16178   mp->is_add = is_add;
16179   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16180   vec_free (ls_name);
16181
16182   /* send */
16183   S (mp);
16184
16185   /* wait for reply */
16186   W (ret);
16187   return ret;
16188 }
16189
16190 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16191
16192 static int
16193 api_one_nsh_set_locator_set (vat_main_t * vam)
16194 {
16195   u8 ls_name_set = 0;
16196   unformat_input_t *input = vam->input;
16197   vl_api_one_nsh_set_locator_set_t *mp;
16198   u8 is_add = 1;
16199   u8 *ls_name = 0;
16200   int ret;
16201
16202   /* Parse args required to build the message */
16203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16204     {
16205       if (unformat (input, "del"))
16206         is_add = 0;
16207       else if (unformat (input, "ls %s", &ls_name))
16208         ls_name_set = 1;
16209       else
16210         {
16211           errmsg ("parse error '%U'", format_unformat_error, input);
16212           return -99;
16213         }
16214     }
16215
16216   if (!ls_name_set && is_add)
16217     {
16218       errmsg ("locator-set name not set!");
16219       return -99;
16220     }
16221
16222   M (ONE_NSH_SET_LOCATOR_SET, mp);
16223
16224   mp->is_add = is_add;
16225   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16226   vec_free (ls_name);
16227
16228   /* send */
16229   S (mp);
16230
16231   /* wait for reply */
16232   W (ret);
16233   return ret;
16234 }
16235
16236 static int
16237 api_show_one_pitr (vat_main_t * vam)
16238 {
16239   vl_api_show_one_pitr_t *mp;
16240   int ret;
16241
16242   if (!vam->json_output)
16243     {
16244       print (vam->ofp, "%=20s", "lisp status:");
16245     }
16246
16247   M (SHOW_ONE_PITR, mp);
16248   /* send it... */
16249   S (mp);
16250
16251   /* Wait for a reply... */
16252   W (ret);
16253   return ret;
16254 }
16255
16256 #define api_show_lisp_pitr api_show_one_pitr
16257
16258 static int
16259 api_one_use_petr (vat_main_t * vam)
16260 {
16261   unformat_input_t *input = vam->input;
16262   vl_api_one_use_petr_t *mp;
16263   u8 is_add = 0;
16264   ip_address_t ip;
16265   int ret;
16266
16267   clib_memset (&ip, 0, sizeof (ip));
16268
16269   /* Parse args required to build the message */
16270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16271     {
16272       if (unformat (input, "disable"))
16273         is_add = 0;
16274       else
16275         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16276         {
16277           is_add = 1;
16278           ip_addr_version (&ip) = IP4;
16279         }
16280       else
16281         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16282         {
16283           is_add = 1;
16284           ip_addr_version (&ip) = IP6;
16285         }
16286       else
16287         {
16288           errmsg ("parse error '%U'", format_unformat_error, input);
16289           return -99;
16290         }
16291     }
16292
16293   M (ONE_USE_PETR, mp);
16294
16295   mp->is_add = is_add;
16296   if (is_add)
16297     {
16298       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16299       if (mp->is_ip4)
16300         clib_memcpy (mp->address, &ip, 4);
16301       else
16302         clib_memcpy (mp->address, &ip, 16);
16303     }
16304
16305   /* send */
16306   S (mp);
16307
16308   /* wait for reply */
16309   W (ret);
16310   return ret;
16311 }
16312
16313 #define api_lisp_use_petr api_one_use_petr
16314
16315 static int
16316 api_show_one_nsh_mapping (vat_main_t * vam)
16317 {
16318   vl_api_show_one_use_petr_t *mp;
16319   int ret;
16320
16321   if (!vam->json_output)
16322     {
16323       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16324     }
16325
16326   M (SHOW_ONE_NSH_MAPPING, mp);
16327   /* send it... */
16328   S (mp);
16329
16330   /* Wait for a reply... */
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_show_one_use_petr (vat_main_t * vam)
16337 {
16338   vl_api_show_one_use_petr_t *mp;
16339   int ret;
16340
16341   if (!vam->json_output)
16342     {
16343       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16344     }
16345
16346   M (SHOW_ONE_USE_PETR, mp);
16347   /* send it... */
16348   S (mp);
16349
16350   /* Wait for a reply... */
16351   W (ret);
16352   return ret;
16353 }
16354
16355 #define api_show_lisp_use_petr api_show_one_use_petr
16356
16357 /**
16358  * Add/delete mapping between vni and vrf
16359  */
16360 static int
16361 api_one_eid_table_add_del_map (vat_main_t * vam)
16362 {
16363   unformat_input_t *input = vam->input;
16364   vl_api_one_eid_table_add_del_map_t *mp;
16365   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16366   u32 vni, vrf, bd_index;
16367   int ret;
16368
16369   /* Parse args required to build the message */
16370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16371     {
16372       if (unformat (input, "del"))
16373         is_add = 0;
16374       else if (unformat (input, "vrf %d", &vrf))
16375         vrf_set = 1;
16376       else if (unformat (input, "bd_index %d", &bd_index))
16377         bd_index_set = 1;
16378       else if (unformat (input, "vni %d", &vni))
16379         vni_set = 1;
16380       else
16381         break;
16382     }
16383
16384   if (!vni_set || (!vrf_set && !bd_index_set))
16385     {
16386       errmsg ("missing arguments!");
16387       return -99;
16388     }
16389
16390   if (vrf_set && bd_index_set)
16391     {
16392       errmsg ("error: both vrf and bd entered!");
16393       return -99;
16394     }
16395
16396   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16397
16398   mp->is_add = is_add;
16399   mp->vni = htonl (vni);
16400   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16401   mp->is_l2 = bd_index_set;
16402
16403   /* send */
16404   S (mp);
16405
16406   /* wait for reply */
16407   W (ret);
16408   return ret;
16409 }
16410
16411 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16412
16413 uword
16414 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16415 {
16416   u32 *action = va_arg (*args, u32 *);
16417   u8 *s = 0;
16418
16419   if (unformat (input, "%s", &s))
16420     {
16421       if (!strcmp ((char *) s, "no-action"))
16422         action[0] = 0;
16423       else if (!strcmp ((char *) s, "natively-forward"))
16424         action[0] = 1;
16425       else if (!strcmp ((char *) s, "send-map-request"))
16426         action[0] = 2;
16427       else if (!strcmp ((char *) s, "drop"))
16428         action[0] = 3;
16429       else
16430         {
16431           clib_warning ("invalid action: '%s'", s);
16432           action[0] = 3;
16433         }
16434     }
16435   else
16436     return 0;
16437
16438   vec_free (s);
16439   return 1;
16440 }
16441
16442 /**
16443  * Add/del remote mapping to/from ONE control plane
16444  *
16445  * @param vam vpp API test context
16446  * @return return code
16447  */
16448 static int
16449 api_one_add_del_remote_mapping (vat_main_t * vam)
16450 {
16451   unformat_input_t *input = vam->input;
16452   vl_api_one_add_del_remote_mapping_t *mp;
16453   u32 vni = 0;
16454   lisp_eid_vat_t _eid, *eid = &_eid;
16455   lisp_eid_vat_t _seid, *seid = &_seid;
16456   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16457   u32 action = ~0, p, w, data_len;
16458   ip4_address_t rloc4;
16459   ip6_address_t rloc6;
16460   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16461   int ret;
16462
16463   clib_memset (&rloc, 0, sizeof (rloc));
16464
16465   /* Parse args required to build the message */
16466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16467     {
16468       if (unformat (input, "del-all"))
16469         {
16470           del_all = 1;
16471         }
16472       else if (unformat (input, "del"))
16473         {
16474           is_add = 0;
16475         }
16476       else if (unformat (input, "add"))
16477         {
16478           is_add = 1;
16479         }
16480       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16481         {
16482           eid_set = 1;
16483         }
16484       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16485         {
16486           seid_set = 1;
16487         }
16488       else if (unformat (input, "vni %d", &vni))
16489         {
16490           ;
16491         }
16492       else if (unformat (input, "p %d w %d", &p, &w))
16493         {
16494           if (!curr_rloc)
16495             {
16496               errmsg ("No RLOC configured for setting priority/weight!");
16497               return -99;
16498             }
16499           curr_rloc->priority = p;
16500           curr_rloc->weight = w;
16501         }
16502       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16503         {
16504           rloc.is_ip4 = 1;
16505           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16506           vec_add1 (rlocs, rloc);
16507           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16508         }
16509       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16510         {
16511           rloc.is_ip4 = 0;
16512           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16513           vec_add1 (rlocs, rloc);
16514           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16515         }
16516       else if (unformat (input, "action %U",
16517                          unformat_negative_mapping_action, &action))
16518         {
16519           ;
16520         }
16521       else
16522         {
16523           clib_warning ("parse error '%U'", format_unformat_error, input);
16524           return -99;
16525         }
16526     }
16527
16528   if (0 == eid_set)
16529     {
16530       errmsg ("missing params!");
16531       return -99;
16532     }
16533
16534   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16535     {
16536       errmsg ("no action set for negative map-reply!");
16537       return -99;
16538     }
16539
16540   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16541
16542   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16543   mp->is_add = is_add;
16544   mp->vni = htonl (vni);
16545   mp->action = (u8) action;
16546   mp->is_src_dst = seid_set;
16547   mp->eid_len = eid->len;
16548   mp->seid_len = seid->len;
16549   mp->del_all = del_all;
16550   mp->eid_type = eid->type;
16551   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16552   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16553
16554   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16555   clib_memcpy (mp->rlocs, rlocs, data_len);
16556   vec_free (rlocs);
16557
16558   /* send it... */
16559   S (mp);
16560
16561   /* Wait for a reply... */
16562   W (ret);
16563   return ret;
16564 }
16565
16566 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16567
16568 /**
16569  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16570  * forwarding entries in data-plane accordingly.
16571  *
16572  * @param vam vpp API test context
16573  * @return return code
16574  */
16575 static int
16576 api_one_add_del_adjacency (vat_main_t * vam)
16577 {
16578   unformat_input_t *input = vam->input;
16579   vl_api_one_add_del_adjacency_t *mp;
16580   u32 vni = 0;
16581   ip4_address_t leid4, reid4;
16582   ip6_address_t leid6, reid6;
16583   u8 reid_mac[6] = { 0 };
16584   u8 leid_mac[6] = { 0 };
16585   u8 reid_type, leid_type;
16586   u32 leid_len = 0, reid_len = 0, len;
16587   u8 is_add = 1;
16588   int ret;
16589
16590   leid_type = reid_type = (u8) ~ 0;
16591
16592   /* Parse args required to build the message */
16593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16594     {
16595       if (unformat (input, "del"))
16596         {
16597           is_add = 0;
16598         }
16599       else if (unformat (input, "add"))
16600         {
16601           is_add = 1;
16602         }
16603       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16604                          &reid4, &len))
16605         {
16606           reid_type = 0;        /* ipv4 */
16607           reid_len = len;
16608         }
16609       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16610                          &reid6, &len))
16611         {
16612           reid_type = 1;        /* ipv6 */
16613           reid_len = len;
16614         }
16615       else if (unformat (input, "reid %U", unformat_ethernet_address,
16616                          reid_mac))
16617         {
16618           reid_type = 2;        /* mac */
16619         }
16620       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16621                          &leid4, &len))
16622         {
16623           leid_type = 0;        /* ipv4 */
16624           leid_len = len;
16625         }
16626       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16627                          &leid6, &len))
16628         {
16629           leid_type = 1;        /* ipv6 */
16630           leid_len = len;
16631         }
16632       else if (unformat (input, "leid %U", unformat_ethernet_address,
16633                          leid_mac))
16634         {
16635           leid_type = 2;        /* mac */
16636         }
16637       else if (unformat (input, "vni %d", &vni))
16638         {
16639           ;
16640         }
16641       else
16642         {
16643           errmsg ("parse error '%U'", format_unformat_error, input);
16644           return -99;
16645         }
16646     }
16647
16648   if ((u8) ~ 0 == reid_type)
16649     {
16650       errmsg ("missing params!");
16651       return -99;
16652     }
16653
16654   if (leid_type != reid_type)
16655     {
16656       errmsg ("remote and local EIDs are of different types!");
16657       return -99;
16658     }
16659
16660   M (ONE_ADD_DEL_ADJACENCY, mp);
16661   mp->is_add = is_add;
16662   mp->vni = htonl (vni);
16663   mp->leid_len = leid_len;
16664   mp->reid_len = reid_len;
16665   mp->eid_type = reid_type;
16666
16667   switch (mp->eid_type)
16668     {
16669     case 0:
16670       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16671       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16672       break;
16673     case 1:
16674       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16675       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16676       break;
16677     case 2:
16678       clib_memcpy (mp->leid, leid_mac, 6);
16679       clib_memcpy (mp->reid, reid_mac, 6);
16680       break;
16681     default:
16682       errmsg ("unknown EID type %d!", mp->eid_type);
16683       return 0;
16684     }
16685
16686   /* send it... */
16687   S (mp);
16688
16689   /* Wait for a reply... */
16690   W (ret);
16691   return ret;
16692 }
16693
16694 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16695
16696 uword
16697 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16698 {
16699   u32 *mode = va_arg (*args, u32 *);
16700
16701   if (unformat (input, "lisp"))
16702     *mode = 0;
16703   else if (unformat (input, "vxlan"))
16704     *mode = 1;
16705   else
16706     return 0;
16707
16708   return 1;
16709 }
16710
16711 static int
16712 api_gpe_get_encap_mode (vat_main_t * vam)
16713 {
16714   vl_api_gpe_get_encap_mode_t *mp;
16715   int ret;
16716
16717   /* Construct the API message */
16718   M (GPE_GET_ENCAP_MODE, mp);
16719
16720   /* send it... */
16721   S (mp);
16722
16723   /* Wait for a reply... */
16724   W (ret);
16725   return ret;
16726 }
16727
16728 static int
16729 api_gpe_set_encap_mode (vat_main_t * vam)
16730 {
16731   unformat_input_t *input = vam->input;
16732   vl_api_gpe_set_encap_mode_t *mp;
16733   int ret;
16734   u32 mode = 0;
16735
16736   /* Parse args required to build the message */
16737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16738     {
16739       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16740         ;
16741       else
16742         break;
16743     }
16744
16745   /* Construct the API message */
16746   M (GPE_SET_ENCAP_MODE, mp);
16747
16748   mp->mode = mode;
16749
16750   /* send it... */
16751   S (mp);
16752
16753   /* Wait for a reply... */
16754   W (ret);
16755   return ret;
16756 }
16757
16758 static int
16759 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16760 {
16761   unformat_input_t *input = vam->input;
16762   vl_api_gpe_add_del_iface_t *mp;
16763   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16764   u32 dp_table = 0, vni = 0;
16765   int ret;
16766
16767   /* Parse args required to build the message */
16768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16769     {
16770       if (unformat (input, "up"))
16771         {
16772           action_set = 1;
16773           is_add = 1;
16774         }
16775       else if (unformat (input, "down"))
16776         {
16777           action_set = 1;
16778           is_add = 0;
16779         }
16780       else if (unformat (input, "table_id %d", &dp_table))
16781         {
16782           dp_table_set = 1;
16783         }
16784       else if (unformat (input, "bd_id %d", &dp_table))
16785         {
16786           dp_table_set = 1;
16787           is_l2 = 1;
16788         }
16789       else if (unformat (input, "vni %d", &vni))
16790         {
16791           vni_set = 1;
16792         }
16793       else
16794         break;
16795     }
16796
16797   if (action_set == 0)
16798     {
16799       errmsg ("Action not set");
16800       return -99;
16801     }
16802   if (dp_table_set == 0 || vni_set == 0)
16803     {
16804       errmsg ("vni and dp_table must be set");
16805       return -99;
16806     }
16807
16808   /* Construct the API message */
16809   M (GPE_ADD_DEL_IFACE, mp);
16810
16811   mp->is_add = is_add;
16812   mp->dp_table = clib_host_to_net_u32 (dp_table);
16813   mp->is_l2 = is_l2;
16814   mp->vni = clib_host_to_net_u32 (vni);
16815
16816   /* send it... */
16817   S (mp);
16818
16819   /* Wait for a reply... */
16820   W (ret);
16821   return ret;
16822 }
16823
16824 static int
16825 api_one_map_register_fallback_threshold (vat_main_t * vam)
16826 {
16827   unformat_input_t *input = vam->input;
16828   vl_api_one_map_register_fallback_threshold_t *mp;
16829   u32 value = 0;
16830   u8 is_set = 0;
16831   int ret;
16832
16833   /* Parse args required to build the message */
16834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16835     {
16836       if (unformat (input, "%u", &value))
16837         is_set = 1;
16838       else
16839         {
16840           clib_warning ("parse error '%U'", format_unformat_error, input);
16841           return -99;
16842         }
16843     }
16844
16845   if (!is_set)
16846     {
16847       errmsg ("fallback threshold value is missing!");
16848       return -99;
16849     }
16850
16851   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16852   mp->value = clib_host_to_net_u32 (value);
16853
16854   /* send it... */
16855   S (mp);
16856
16857   /* Wait for a reply... */
16858   W (ret);
16859   return ret;
16860 }
16861
16862 static int
16863 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16864 {
16865   vl_api_show_one_map_register_fallback_threshold_t *mp;
16866   int ret;
16867
16868   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16869
16870   /* send it... */
16871   S (mp);
16872
16873   /* Wait for a reply... */
16874   W (ret);
16875   return ret;
16876 }
16877
16878 uword
16879 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16880 {
16881   u32 *proto = va_arg (*args, u32 *);
16882
16883   if (unformat (input, "udp"))
16884     *proto = 1;
16885   else if (unformat (input, "api"))
16886     *proto = 2;
16887   else
16888     return 0;
16889
16890   return 1;
16891 }
16892
16893 static int
16894 api_one_set_transport_protocol (vat_main_t * vam)
16895 {
16896   unformat_input_t *input = vam->input;
16897   vl_api_one_set_transport_protocol_t *mp;
16898   u8 is_set = 0;
16899   u32 protocol = 0;
16900   int ret;
16901
16902   /* Parse args required to build the message */
16903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16904     {
16905       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16906         is_set = 1;
16907       else
16908         {
16909           clib_warning ("parse error '%U'", format_unformat_error, input);
16910           return -99;
16911         }
16912     }
16913
16914   if (!is_set)
16915     {
16916       errmsg ("Transport protocol missing!");
16917       return -99;
16918     }
16919
16920   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16921   mp->protocol = (u8) protocol;
16922
16923   /* send it... */
16924   S (mp);
16925
16926   /* Wait for a reply... */
16927   W (ret);
16928   return ret;
16929 }
16930
16931 static int
16932 api_one_get_transport_protocol (vat_main_t * vam)
16933 {
16934   vl_api_one_get_transport_protocol_t *mp;
16935   int ret;
16936
16937   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16938
16939   /* send it... */
16940   S (mp);
16941
16942   /* Wait for a reply... */
16943   W (ret);
16944   return ret;
16945 }
16946
16947 static int
16948 api_one_map_register_set_ttl (vat_main_t * vam)
16949 {
16950   unformat_input_t *input = vam->input;
16951   vl_api_one_map_register_set_ttl_t *mp;
16952   u32 ttl = 0;
16953   u8 is_set = 0;
16954   int ret;
16955
16956   /* Parse args required to build the message */
16957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16958     {
16959       if (unformat (input, "%u", &ttl))
16960         is_set = 1;
16961       else
16962         {
16963           clib_warning ("parse error '%U'", format_unformat_error, input);
16964           return -99;
16965         }
16966     }
16967
16968   if (!is_set)
16969     {
16970       errmsg ("TTL value missing!");
16971       return -99;
16972     }
16973
16974   M (ONE_MAP_REGISTER_SET_TTL, mp);
16975   mp->ttl = clib_host_to_net_u32 (ttl);
16976
16977   /* send it... */
16978   S (mp);
16979
16980   /* Wait for a reply... */
16981   W (ret);
16982   return ret;
16983 }
16984
16985 static int
16986 api_show_one_map_register_ttl (vat_main_t * vam)
16987 {
16988   vl_api_show_one_map_register_ttl_t *mp;
16989   int ret;
16990
16991   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16992
16993   /* send it... */
16994   S (mp);
16995
16996   /* Wait for a reply... */
16997   W (ret);
16998   return ret;
16999 }
17000
17001 /**
17002  * Add/del map request itr rlocs from ONE control plane and updates
17003  *
17004  * @param vam vpp API test context
17005  * @return return code
17006  */
17007 static int
17008 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17009 {
17010   unformat_input_t *input = vam->input;
17011   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17012   u8 *locator_set_name = 0;
17013   u8 locator_set_name_set = 0;
17014   u8 is_add = 1;
17015   int ret;
17016
17017   /* Parse args required to build the message */
17018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17019     {
17020       if (unformat (input, "del"))
17021         {
17022           is_add = 0;
17023         }
17024       else if (unformat (input, "%_%v%_", &locator_set_name))
17025         {
17026           locator_set_name_set = 1;
17027         }
17028       else
17029         {
17030           clib_warning ("parse error '%U'", format_unformat_error, input);
17031           return -99;
17032         }
17033     }
17034
17035   if (is_add && !locator_set_name_set)
17036     {
17037       errmsg ("itr-rloc is not set!");
17038       return -99;
17039     }
17040
17041   if (is_add && vec_len (locator_set_name) > 64)
17042     {
17043       errmsg ("itr-rloc locator-set name too long");
17044       vec_free (locator_set_name);
17045       return -99;
17046     }
17047
17048   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17049   mp->is_add = is_add;
17050   if (is_add)
17051     {
17052       clib_memcpy (mp->locator_set_name, locator_set_name,
17053                    vec_len (locator_set_name));
17054     }
17055   else
17056     {
17057       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17058     }
17059   vec_free (locator_set_name);
17060
17061   /* send it... */
17062   S (mp);
17063
17064   /* Wait for a reply... */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17070
17071 static int
17072 api_one_locator_dump (vat_main_t * vam)
17073 {
17074   unformat_input_t *input = vam->input;
17075   vl_api_one_locator_dump_t *mp;
17076   vl_api_control_ping_t *mp_ping;
17077   u8 is_index_set = 0, is_name_set = 0;
17078   u8 *ls_name = 0;
17079   u32 ls_index = ~0;
17080   int ret;
17081
17082   /* Parse args required to build the message */
17083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17084     {
17085       if (unformat (input, "ls_name %_%v%_", &ls_name))
17086         {
17087           is_name_set = 1;
17088         }
17089       else if (unformat (input, "ls_index %d", &ls_index))
17090         {
17091           is_index_set = 1;
17092         }
17093       else
17094         {
17095           errmsg ("parse error '%U'", format_unformat_error, input);
17096           return -99;
17097         }
17098     }
17099
17100   if (!is_index_set && !is_name_set)
17101     {
17102       errmsg ("error: expected one of index or name!");
17103       return -99;
17104     }
17105
17106   if (is_index_set && is_name_set)
17107     {
17108       errmsg ("error: only one param expected!");
17109       return -99;
17110     }
17111
17112   if (vec_len (ls_name) > 62)
17113     {
17114       errmsg ("error: locator set name too long!");
17115       return -99;
17116     }
17117
17118   if (!vam->json_output)
17119     {
17120       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17121     }
17122
17123   M (ONE_LOCATOR_DUMP, mp);
17124   mp->is_index_set = is_index_set;
17125
17126   if (is_index_set)
17127     mp->ls_index = clib_host_to_net_u32 (ls_index);
17128   else
17129     {
17130       vec_add1 (ls_name, 0);
17131       strncpy ((char *) mp->ls_name, (char *) ls_name,
17132                sizeof (mp->ls_name) - 1);
17133     }
17134
17135   /* send it... */
17136   S (mp);
17137
17138   /* Use a control ping for synchronization */
17139   MPING (CONTROL_PING, mp_ping);
17140   S (mp_ping);
17141
17142   /* Wait for a reply... */
17143   W (ret);
17144   return ret;
17145 }
17146
17147 #define api_lisp_locator_dump api_one_locator_dump
17148
17149 static int
17150 api_one_locator_set_dump (vat_main_t * vam)
17151 {
17152   vl_api_one_locator_set_dump_t *mp;
17153   vl_api_control_ping_t *mp_ping;
17154   unformat_input_t *input = vam->input;
17155   u8 filter = 0;
17156   int ret;
17157
17158   /* Parse args required to build the message */
17159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17160     {
17161       if (unformat (input, "local"))
17162         {
17163           filter = 1;
17164         }
17165       else if (unformat (input, "remote"))
17166         {
17167           filter = 2;
17168         }
17169       else
17170         {
17171           errmsg ("parse error '%U'", format_unformat_error, input);
17172           return -99;
17173         }
17174     }
17175
17176   if (!vam->json_output)
17177     {
17178       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17179     }
17180
17181   M (ONE_LOCATOR_SET_DUMP, mp);
17182
17183   mp->filter = filter;
17184
17185   /* send it... */
17186   S (mp);
17187
17188   /* Use a control ping for synchronization */
17189   MPING (CONTROL_PING, mp_ping);
17190   S (mp_ping);
17191
17192   /* Wait for a reply... */
17193   W (ret);
17194   return ret;
17195 }
17196
17197 #define api_lisp_locator_set_dump api_one_locator_set_dump
17198
17199 static int
17200 api_one_eid_table_map_dump (vat_main_t * vam)
17201 {
17202   u8 is_l2 = 0;
17203   u8 mode_set = 0;
17204   unformat_input_t *input = vam->input;
17205   vl_api_one_eid_table_map_dump_t *mp;
17206   vl_api_control_ping_t *mp_ping;
17207   int ret;
17208
17209   /* Parse args required to build the message */
17210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17211     {
17212       if (unformat (input, "l2"))
17213         {
17214           is_l2 = 1;
17215           mode_set = 1;
17216         }
17217       else if (unformat (input, "l3"))
17218         {
17219           is_l2 = 0;
17220           mode_set = 1;
17221         }
17222       else
17223         {
17224           errmsg ("parse error '%U'", format_unformat_error, input);
17225           return -99;
17226         }
17227     }
17228
17229   if (!mode_set)
17230     {
17231       errmsg ("expected one of 'l2' or 'l3' parameter!");
17232       return -99;
17233     }
17234
17235   if (!vam->json_output)
17236     {
17237       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17238     }
17239
17240   M (ONE_EID_TABLE_MAP_DUMP, mp);
17241   mp->is_l2 = is_l2;
17242
17243   /* send it... */
17244   S (mp);
17245
17246   /* Use a control ping for synchronization */
17247   MPING (CONTROL_PING, mp_ping);
17248   S (mp_ping);
17249
17250   /* Wait for a reply... */
17251   W (ret);
17252   return ret;
17253 }
17254
17255 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17256
17257 static int
17258 api_one_eid_table_vni_dump (vat_main_t * vam)
17259 {
17260   vl_api_one_eid_table_vni_dump_t *mp;
17261   vl_api_control_ping_t *mp_ping;
17262   int ret;
17263
17264   if (!vam->json_output)
17265     {
17266       print (vam->ofp, "VNI");
17267     }
17268
17269   M (ONE_EID_TABLE_VNI_DUMP, mp);
17270
17271   /* send it... */
17272   S (mp);
17273
17274   /* Use a control ping for synchronization */
17275   MPING (CONTROL_PING, mp_ping);
17276   S (mp_ping);
17277
17278   /* Wait for a reply... */
17279   W (ret);
17280   return ret;
17281 }
17282
17283 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17284
17285 static int
17286 api_one_eid_table_dump (vat_main_t * vam)
17287 {
17288   unformat_input_t *i = vam->input;
17289   vl_api_one_eid_table_dump_t *mp;
17290   vl_api_control_ping_t *mp_ping;
17291   struct in_addr ip4;
17292   struct in6_addr ip6;
17293   u8 mac[6];
17294   u8 eid_type = ~0, eid_set = 0;
17295   u32 prefix_length = ~0, t, vni = 0;
17296   u8 filter = 0;
17297   int ret;
17298   lisp_nsh_api_t nsh;
17299
17300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17301     {
17302       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17303         {
17304           eid_set = 1;
17305           eid_type = 0;
17306           prefix_length = t;
17307         }
17308       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17309         {
17310           eid_set = 1;
17311           eid_type = 1;
17312           prefix_length = t;
17313         }
17314       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17315         {
17316           eid_set = 1;
17317           eid_type = 2;
17318         }
17319       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17320         {
17321           eid_set = 1;
17322           eid_type = 3;
17323         }
17324       else if (unformat (i, "vni %d", &t))
17325         {
17326           vni = t;
17327         }
17328       else if (unformat (i, "local"))
17329         {
17330           filter = 1;
17331         }
17332       else if (unformat (i, "remote"))
17333         {
17334           filter = 2;
17335         }
17336       else
17337         {
17338           errmsg ("parse error '%U'", format_unformat_error, i);
17339           return -99;
17340         }
17341     }
17342
17343   if (!vam->json_output)
17344     {
17345       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17346              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17347     }
17348
17349   M (ONE_EID_TABLE_DUMP, mp);
17350
17351   mp->filter = filter;
17352   if (eid_set)
17353     {
17354       mp->eid_set = 1;
17355       mp->vni = htonl (vni);
17356       mp->eid_type = eid_type;
17357       switch (eid_type)
17358         {
17359         case 0:
17360           mp->prefix_length = prefix_length;
17361           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17362           break;
17363         case 1:
17364           mp->prefix_length = prefix_length;
17365           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17366           break;
17367         case 2:
17368           clib_memcpy (mp->eid, mac, sizeof (mac));
17369           break;
17370         case 3:
17371           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17372           break;
17373         default:
17374           errmsg ("unknown EID type %d!", eid_type);
17375           return -99;
17376         }
17377     }
17378
17379   /* send it... */
17380   S (mp);
17381
17382   /* Use a control ping for synchronization */
17383   MPING (CONTROL_PING, mp_ping);
17384   S (mp_ping);
17385
17386   /* Wait for a reply... */
17387   W (ret);
17388   return ret;
17389 }
17390
17391 #define api_lisp_eid_table_dump api_one_eid_table_dump
17392
17393 static int
17394 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17395 {
17396   unformat_input_t *i = vam->input;
17397   vl_api_gpe_fwd_entries_get_t *mp;
17398   u8 vni_set = 0;
17399   u32 vni = ~0;
17400   int ret;
17401
17402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17403     {
17404       if (unformat (i, "vni %d", &vni))
17405         {
17406           vni_set = 1;
17407         }
17408       else
17409         {
17410           errmsg ("parse error '%U'", format_unformat_error, i);
17411           return -99;
17412         }
17413     }
17414
17415   if (!vni_set)
17416     {
17417       errmsg ("vni not set!");
17418       return -99;
17419     }
17420
17421   if (!vam->json_output)
17422     {
17423       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17424              "leid", "reid");
17425     }
17426
17427   M (GPE_FWD_ENTRIES_GET, mp);
17428   mp->vni = clib_host_to_net_u32 (vni);
17429
17430   /* send it... */
17431   S (mp);
17432
17433   /* Wait for a reply... */
17434   W (ret);
17435   return ret;
17436 }
17437
17438 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17439 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17440 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17441 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17442 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17443 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17444 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17445 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17446
17447 static int
17448 api_one_adjacencies_get (vat_main_t * vam)
17449 {
17450   unformat_input_t *i = vam->input;
17451   vl_api_one_adjacencies_get_t *mp;
17452   u8 vni_set = 0;
17453   u32 vni = ~0;
17454   int ret;
17455
17456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17457     {
17458       if (unformat (i, "vni %d", &vni))
17459         {
17460           vni_set = 1;
17461         }
17462       else
17463         {
17464           errmsg ("parse error '%U'", format_unformat_error, i);
17465           return -99;
17466         }
17467     }
17468
17469   if (!vni_set)
17470     {
17471       errmsg ("vni not set!");
17472       return -99;
17473     }
17474
17475   if (!vam->json_output)
17476     {
17477       print (vam->ofp, "%s %40s", "leid", "reid");
17478     }
17479
17480   M (ONE_ADJACENCIES_GET, mp);
17481   mp->vni = clib_host_to_net_u32 (vni);
17482
17483   /* send it... */
17484   S (mp);
17485
17486   /* Wait for a reply... */
17487   W (ret);
17488   return ret;
17489 }
17490
17491 #define api_lisp_adjacencies_get api_one_adjacencies_get
17492
17493 static int
17494 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17495 {
17496   unformat_input_t *i = vam->input;
17497   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17498   int ret;
17499   u8 ip_family_set = 0, is_ip4 = 1;
17500
17501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17502     {
17503       if (unformat (i, "ip4"))
17504         {
17505           ip_family_set = 1;
17506           is_ip4 = 1;
17507         }
17508       else if (unformat (i, "ip6"))
17509         {
17510           ip_family_set = 1;
17511           is_ip4 = 0;
17512         }
17513       else
17514         {
17515           errmsg ("parse error '%U'", format_unformat_error, i);
17516           return -99;
17517         }
17518     }
17519
17520   if (!ip_family_set)
17521     {
17522       errmsg ("ip family not set!");
17523       return -99;
17524     }
17525
17526   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17527   mp->is_ip4 = is_ip4;
17528
17529   /* send it... */
17530   S (mp);
17531
17532   /* Wait for a reply... */
17533   W (ret);
17534   return ret;
17535 }
17536
17537 static int
17538 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17539 {
17540   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17541   int ret;
17542
17543   if (!vam->json_output)
17544     {
17545       print (vam->ofp, "VNIs");
17546     }
17547
17548   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 static int
17559 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17560 {
17561   unformat_input_t *i = vam->input;
17562   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17563   int ret = 0;
17564   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17565   struct in_addr ip4;
17566   struct in6_addr ip6;
17567   u32 table_id = 0, nh_sw_if_index = ~0;
17568
17569   clib_memset (&ip4, 0, sizeof (ip4));
17570   clib_memset (&ip6, 0, sizeof (ip6));
17571
17572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17573     {
17574       if (unformat (i, "del"))
17575         is_add = 0;
17576       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17577                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17578         {
17579           ip_set = 1;
17580           is_ip4 = 1;
17581         }
17582       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17583                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17584         {
17585           ip_set = 1;
17586           is_ip4 = 0;
17587         }
17588       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17589         {
17590           ip_set = 1;
17591           is_ip4 = 1;
17592           nh_sw_if_index = ~0;
17593         }
17594       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17595         {
17596           ip_set = 1;
17597           is_ip4 = 0;
17598           nh_sw_if_index = ~0;
17599         }
17600       else if (unformat (i, "table %d", &table_id))
17601         ;
17602       else
17603         {
17604           errmsg ("parse error '%U'", format_unformat_error, i);
17605           return -99;
17606         }
17607     }
17608
17609   if (!ip_set)
17610     {
17611       errmsg ("nh addr not set!");
17612       return -99;
17613     }
17614
17615   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17616   mp->is_add = is_add;
17617   mp->table_id = clib_host_to_net_u32 (table_id);
17618   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17619   mp->is_ip4 = is_ip4;
17620   if (is_ip4)
17621     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17622   else
17623     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17624
17625   /* send it... */
17626   S (mp);
17627
17628   /* Wait for a reply... */
17629   W (ret);
17630   return ret;
17631 }
17632
17633 static int
17634 api_one_map_server_dump (vat_main_t * vam)
17635 {
17636   vl_api_one_map_server_dump_t *mp;
17637   vl_api_control_ping_t *mp_ping;
17638   int ret;
17639
17640   if (!vam->json_output)
17641     {
17642       print (vam->ofp, "%=20s", "Map server");
17643     }
17644
17645   M (ONE_MAP_SERVER_DUMP, mp);
17646   /* send it... */
17647   S (mp);
17648
17649   /* Use a control ping for synchronization */
17650   MPING (CONTROL_PING, mp_ping);
17651   S (mp_ping);
17652
17653   /* Wait for a reply... */
17654   W (ret);
17655   return ret;
17656 }
17657
17658 #define api_lisp_map_server_dump api_one_map_server_dump
17659
17660 static int
17661 api_one_map_resolver_dump (vat_main_t * vam)
17662 {
17663   vl_api_one_map_resolver_dump_t *mp;
17664   vl_api_control_ping_t *mp_ping;
17665   int ret;
17666
17667   if (!vam->json_output)
17668     {
17669       print (vam->ofp, "%=20s", "Map resolver");
17670     }
17671
17672   M (ONE_MAP_RESOLVER_DUMP, mp);
17673   /* send it... */
17674   S (mp);
17675
17676   /* Use a control ping for synchronization */
17677   MPING (CONTROL_PING, mp_ping);
17678   S (mp_ping);
17679
17680   /* Wait for a reply... */
17681   W (ret);
17682   return ret;
17683 }
17684
17685 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17686
17687 static int
17688 api_one_stats_flush (vat_main_t * vam)
17689 {
17690   vl_api_one_stats_flush_t *mp;
17691   int ret = 0;
17692
17693   M (ONE_STATS_FLUSH, mp);
17694   S (mp);
17695   W (ret);
17696   return ret;
17697 }
17698
17699 static int
17700 api_one_stats_dump (vat_main_t * vam)
17701 {
17702   vl_api_one_stats_dump_t *mp;
17703   vl_api_control_ping_t *mp_ping;
17704   int ret;
17705
17706   M (ONE_STATS_DUMP, mp);
17707   /* send it... */
17708   S (mp);
17709
17710   /* Use a control ping for synchronization */
17711   MPING (CONTROL_PING, mp_ping);
17712   S (mp_ping);
17713
17714   /* Wait for a reply... */
17715   W (ret);
17716   return ret;
17717 }
17718
17719 static int
17720 api_show_one_status (vat_main_t * vam)
17721 {
17722   vl_api_show_one_status_t *mp;
17723   int ret;
17724
17725   if (!vam->json_output)
17726     {
17727       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17728     }
17729
17730   M (SHOW_ONE_STATUS, mp);
17731   /* send it... */
17732   S (mp);
17733   /* Wait for a reply... */
17734   W (ret);
17735   return ret;
17736 }
17737
17738 #define api_show_lisp_status api_show_one_status
17739
17740 static int
17741 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17742 {
17743   vl_api_gpe_fwd_entry_path_dump_t *mp;
17744   vl_api_control_ping_t *mp_ping;
17745   unformat_input_t *i = vam->input;
17746   u32 fwd_entry_index = ~0;
17747   int ret;
17748
17749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17750     {
17751       if (unformat (i, "index %d", &fwd_entry_index))
17752         ;
17753       else
17754         break;
17755     }
17756
17757   if (~0 == fwd_entry_index)
17758     {
17759       errmsg ("no index specified!");
17760       return -99;
17761     }
17762
17763   if (!vam->json_output)
17764     {
17765       print (vam->ofp, "first line");
17766     }
17767
17768   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17769
17770   /* send it... */
17771   S (mp);
17772   /* Use a control ping for synchronization */
17773   MPING (CONTROL_PING, mp_ping);
17774   S (mp_ping);
17775
17776   /* Wait for a reply... */
17777   W (ret);
17778   return ret;
17779 }
17780
17781 static int
17782 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17783 {
17784   vl_api_one_get_map_request_itr_rlocs_t *mp;
17785   int ret;
17786
17787   if (!vam->json_output)
17788     {
17789       print (vam->ofp, "%=20s", "itr-rlocs:");
17790     }
17791
17792   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17793   /* send it... */
17794   S (mp);
17795   /* Wait for a reply... */
17796   W (ret);
17797   return ret;
17798 }
17799
17800 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17801
17802 static int
17803 api_af_packet_create (vat_main_t * vam)
17804 {
17805   unformat_input_t *i = vam->input;
17806   vl_api_af_packet_create_t *mp;
17807   u8 *host_if_name = 0;
17808   u8 hw_addr[6];
17809   u8 random_hw_addr = 1;
17810   int ret;
17811
17812   clib_memset (hw_addr, 0, sizeof (hw_addr));
17813
17814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17815     {
17816       if (unformat (i, "name %s", &host_if_name))
17817         vec_add1 (host_if_name, 0);
17818       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17819         random_hw_addr = 0;
17820       else
17821         break;
17822     }
17823
17824   if (!vec_len (host_if_name))
17825     {
17826       errmsg ("host-interface name must be specified");
17827       return -99;
17828     }
17829
17830   if (vec_len (host_if_name) > 64)
17831     {
17832       errmsg ("host-interface name too long");
17833       return -99;
17834     }
17835
17836   M (AF_PACKET_CREATE, mp);
17837
17838   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17839   clib_memcpy (mp->hw_addr, hw_addr, 6);
17840   mp->use_random_hw_addr = random_hw_addr;
17841   vec_free (host_if_name);
17842
17843   S (mp);
17844
17845   /* *INDENT-OFF* */
17846   W2 (ret,
17847       ({
17848         if (ret == 0)
17849           fprintf (vam->ofp ? vam->ofp : stderr,
17850                    " new sw_if_index = %d\n", vam->sw_if_index);
17851       }));
17852   /* *INDENT-ON* */
17853   return ret;
17854 }
17855
17856 static int
17857 api_af_packet_delete (vat_main_t * vam)
17858 {
17859   unformat_input_t *i = vam->input;
17860   vl_api_af_packet_delete_t *mp;
17861   u8 *host_if_name = 0;
17862   int ret;
17863
17864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17865     {
17866       if (unformat (i, "name %s", &host_if_name))
17867         vec_add1 (host_if_name, 0);
17868       else
17869         break;
17870     }
17871
17872   if (!vec_len (host_if_name))
17873     {
17874       errmsg ("host-interface name must be specified");
17875       return -99;
17876     }
17877
17878   if (vec_len (host_if_name) > 64)
17879     {
17880       errmsg ("host-interface name too long");
17881       return -99;
17882     }
17883
17884   M (AF_PACKET_DELETE, mp);
17885
17886   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17887   vec_free (host_if_name);
17888
17889   S (mp);
17890   W (ret);
17891   return ret;
17892 }
17893
17894 static void vl_api_af_packet_details_t_handler
17895   (vl_api_af_packet_details_t * mp)
17896 {
17897   vat_main_t *vam = &vat_main;
17898
17899   print (vam->ofp, "%-16s %d",
17900          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17901 }
17902
17903 static void vl_api_af_packet_details_t_handler_json
17904   (vl_api_af_packet_details_t * mp)
17905 {
17906   vat_main_t *vam = &vat_main;
17907   vat_json_node_t *node = NULL;
17908
17909   if (VAT_JSON_ARRAY != vam->json_tree.type)
17910     {
17911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17912       vat_json_init_array (&vam->json_tree);
17913     }
17914   node = vat_json_array_add (&vam->json_tree);
17915
17916   vat_json_init_object (node);
17917   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17918   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17919 }
17920
17921 static int
17922 api_af_packet_dump (vat_main_t * vam)
17923 {
17924   vl_api_af_packet_dump_t *mp;
17925   vl_api_control_ping_t *mp_ping;
17926   int ret;
17927
17928   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17929   /* Get list of tap interfaces */
17930   M (AF_PACKET_DUMP, mp);
17931   S (mp);
17932
17933   /* Use a control ping for synchronization */
17934   MPING (CONTROL_PING, mp_ping);
17935   S (mp_ping);
17936
17937   W (ret);
17938   return ret;
17939 }
17940
17941 static int
17942 api_policer_add_del (vat_main_t * vam)
17943 {
17944   unformat_input_t *i = vam->input;
17945   vl_api_policer_add_del_t *mp;
17946   u8 is_add = 1;
17947   u8 *name = 0;
17948   u32 cir = 0;
17949   u32 eir = 0;
17950   u64 cb = 0;
17951   u64 eb = 0;
17952   u8 rate_type = 0;
17953   u8 round_type = 0;
17954   u8 type = 0;
17955   u8 color_aware = 0;
17956   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17957   int ret;
17958
17959   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17960   conform_action.dscp = 0;
17961   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17962   exceed_action.dscp = 0;
17963   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17964   violate_action.dscp = 0;
17965
17966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17967     {
17968       if (unformat (i, "del"))
17969         is_add = 0;
17970       else if (unformat (i, "name %s", &name))
17971         vec_add1 (name, 0);
17972       else if (unformat (i, "cir %u", &cir))
17973         ;
17974       else if (unformat (i, "eir %u", &eir))
17975         ;
17976       else if (unformat (i, "cb %u", &cb))
17977         ;
17978       else if (unformat (i, "eb %u", &eb))
17979         ;
17980       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17981                          &rate_type))
17982         ;
17983       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17984                          &round_type))
17985         ;
17986       else if (unformat (i, "type %U", unformat_policer_type, &type))
17987         ;
17988       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17989                          &conform_action))
17990         ;
17991       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17992                          &exceed_action))
17993         ;
17994       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17995                          &violate_action))
17996         ;
17997       else if (unformat (i, "color-aware"))
17998         color_aware = 1;
17999       else
18000         break;
18001     }
18002
18003   if (!vec_len (name))
18004     {
18005       errmsg ("policer name must be specified");
18006       return -99;
18007     }
18008
18009   if (vec_len (name) > 64)
18010     {
18011       errmsg ("policer name too long");
18012       return -99;
18013     }
18014
18015   M (POLICER_ADD_DEL, mp);
18016
18017   clib_memcpy (mp->name, name, vec_len (name));
18018   vec_free (name);
18019   mp->is_add = is_add;
18020   mp->cir = ntohl (cir);
18021   mp->eir = ntohl (eir);
18022   mp->cb = clib_net_to_host_u64 (cb);
18023   mp->eb = clib_net_to_host_u64 (eb);
18024   mp->rate_type = rate_type;
18025   mp->round_type = round_type;
18026   mp->type = type;
18027   mp->conform_action_type = conform_action.action_type;
18028   mp->conform_dscp = conform_action.dscp;
18029   mp->exceed_action_type = exceed_action.action_type;
18030   mp->exceed_dscp = exceed_action.dscp;
18031   mp->violate_action_type = violate_action.action_type;
18032   mp->violate_dscp = violate_action.dscp;
18033   mp->color_aware = color_aware;
18034
18035   S (mp);
18036   W (ret);
18037   return ret;
18038 }
18039
18040 static int
18041 api_policer_dump (vat_main_t * vam)
18042 {
18043   unformat_input_t *i = vam->input;
18044   vl_api_policer_dump_t *mp;
18045   vl_api_control_ping_t *mp_ping;
18046   u8 *match_name = 0;
18047   u8 match_name_valid = 0;
18048   int ret;
18049
18050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18051     {
18052       if (unformat (i, "name %s", &match_name))
18053         {
18054           vec_add1 (match_name, 0);
18055           match_name_valid = 1;
18056         }
18057       else
18058         break;
18059     }
18060
18061   M (POLICER_DUMP, mp);
18062   mp->match_name_valid = match_name_valid;
18063   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18064   vec_free (match_name);
18065   /* send it... */
18066   S (mp);
18067
18068   /* Use a control ping for synchronization */
18069   MPING (CONTROL_PING, mp_ping);
18070   S (mp_ping);
18071
18072   /* Wait for a reply... */
18073   W (ret);
18074   return ret;
18075 }
18076
18077 static int
18078 api_policer_classify_set_interface (vat_main_t * vam)
18079 {
18080   unformat_input_t *i = vam->input;
18081   vl_api_policer_classify_set_interface_t *mp;
18082   u32 sw_if_index;
18083   int sw_if_index_set;
18084   u32 ip4_table_index = ~0;
18085   u32 ip6_table_index = ~0;
18086   u32 l2_table_index = ~0;
18087   u8 is_add = 1;
18088   int ret;
18089
18090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18091     {
18092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18093         sw_if_index_set = 1;
18094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18095         sw_if_index_set = 1;
18096       else if (unformat (i, "del"))
18097         is_add = 0;
18098       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18099         ;
18100       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18101         ;
18102       else if (unformat (i, "l2-table %d", &l2_table_index))
18103         ;
18104       else
18105         {
18106           clib_warning ("parse error '%U'", format_unformat_error, i);
18107           return -99;
18108         }
18109     }
18110
18111   if (sw_if_index_set == 0)
18112     {
18113       errmsg ("missing interface name or sw_if_index");
18114       return -99;
18115     }
18116
18117   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18118
18119   mp->sw_if_index = ntohl (sw_if_index);
18120   mp->ip4_table_index = ntohl (ip4_table_index);
18121   mp->ip6_table_index = ntohl (ip6_table_index);
18122   mp->l2_table_index = ntohl (l2_table_index);
18123   mp->is_add = is_add;
18124
18125   S (mp);
18126   W (ret);
18127   return ret;
18128 }
18129
18130 static int
18131 api_policer_classify_dump (vat_main_t * vam)
18132 {
18133   unformat_input_t *i = vam->input;
18134   vl_api_policer_classify_dump_t *mp;
18135   vl_api_control_ping_t *mp_ping;
18136   u8 type = POLICER_CLASSIFY_N_TABLES;
18137   int ret;
18138
18139   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18140     ;
18141   else
18142     {
18143       errmsg ("classify table type must be specified");
18144       return -99;
18145     }
18146
18147   if (!vam->json_output)
18148     {
18149       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18150     }
18151
18152   M (POLICER_CLASSIFY_DUMP, mp);
18153   mp->type = type;
18154   /* send it... */
18155   S (mp);
18156
18157   /* Use a control ping for synchronization */
18158   MPING (CONTROL_PING, mp_ping);
18159   S (mp_ping);
18160
18161   /* Wait for a reply... */
18162   W (ret);
18163   return ret;
18164 }
18165
18166 static int
18167 api_netmap_create (vat_main_t * vam)
18168 {
18169   unformat_input_t *i = vam->input;
18170   vl_api_netmap_create_t *mp;
18171   u8 *if_name = 0;
18172   u8 hw_addr[6];
18173   u8 random_hw_addr = 1;
18174   u8 is_pipe = 0;
18175   u8 is_master = 0;
18176   int ret;
18177
18178   clib_memset (hw_addr, 0, sizeof (hw_addr));
18179
18180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18181     {
18182       if (unformat (i, "name %s", &if_name))
18183         vec_add1 (if_name, 0);
18184       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18185         random_hw_addr = 0;
18186       else if (unformat (i, "pipe"))
18187         is_pipe = 1;
18188       else if (unformat (i, "master"))
18189         is_master = 1;
18190       else if (unformat (i, "slave"))
18191         is_master = 0;
18192       else
18193         break;
18194     }
18195
18196   if (!vec_len (if_name))
18197     {
18198       errmsg ("interface name must be specified");
18199       return -99;
18200     }
18201
18202   if (vec_len (if_name) > 64)
18203     {
18204       errmsg ("interface name too long");
18205       return -99;
18206     }
18207
18208   M (NETMAP_CREATE, mp);
18209
18210   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18211   clib_memcpy (mp->hw_addr, hw_addr, 6);
18212   mp->use_random_hw_addr = random_hw_addr;
18213   mp->is_pipe = is_pipe;
18214   mp->is_master = is_master;
18215   vec_free (if_name);
18216
18217   S (mp);
18218   W (ret);
18219   return ret;
18220 }
18221
18222 static int
18223 api_netmap_delete (vat_main_t * vam)
18224 {
18225   unformat_input_t *i = vam->input;
18226   vl_api_netmap_delete_t *mp;
18227   u8 *if_name = 0;
18228   int ret;
18229
18230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18231     {
18232       if (unformat (i, "name %s", &if_name))
18233         vec_add1 (if_name, 0);
18234       else
18235         break;
18236     }
18237
18238   if (!vec_len (if_name))
18239     {
18240       errmsg ("interface name must be specified");
18241       return -99;
18242     }
18243
18244   if (vec_len (if_name) > 64)
18245     {
18246       errmsg ("interface name too long");
18247       return -99;
18248     }
18249
18250   M (NETMAP_DELETE, mp);
18251
18252   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18253   vec_free (if_name);
18254
18255   S (mp);
18256   W (ret);
18257   return ret;
18258 }
18259
18260 static u8 *
18261 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18262 {
18263   vl_api_fib_path_nh_proto_t proto =
18264     va_arg (*args, vl_api_fib_path_nh_proto_t);
18265
18266   switch (proto)
18267     {
18268     case FIB_API_PATH_NH_PROTO_IP4:
18269       s = format (s, "ip4");
18270       break;
18271     case FIB_API_PATH_NH_PROTO_IP6:
18272       s = format (s, "ip6");
18273       break;
18274     case FIB_API_PATH_NH_PROTO_MPLS:
18275       s = format (s, "mpls");
18276       break;
18277     case FIB_API_PATH_NH_PROTO_BIER:
18278       s = format (s, "bier");
18279       break;
18280     case FIB_API_PATH_NH_PROTO_ETHERNET:
18281       s = format (s, "ethernet");
18282       break;
18283     }
18284
18285   return (s);
18286 }
18287
18288 static u8 *
18289 format_vl_api_ip_address_union (u8 * s, va_list * args)
18290 {
18291   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18292   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18293
18294   switch (af)
18295     {
18296     case ADDRESS_IP4:
18297       s = format (s, "%U", format_ip4_address, u->ip4);
18298       break;
18299     case ADDRESS_IP6:
18300       s = format (s, "%U", format_ip6_address, u->ip6);
18301       break;
18302     }
18303   return (s);
18304 }
18305
18306 static u8 *
18307 format_vl_api_fib_path_type (u8 * s, va_list * args)
18308 {
18309   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18310
18311   switch (t)
18312     {
18313     case FIB_API_PATH_TYPE_NORMAL:
18314       s = format (s, "normal");
18315       break;
18316     case FIB_API_PATH_TYPE_LOCAL:
18317       s = format (s, "local");
18318       break;
18319     case FIB_API_PATH_TYPE_DROP:
18320       s = format (s, "drop");
18321       break;
18322     case FIB_API_PATH_TYPE_UDP_ENCAP:
18323       s = format (s, "udp-encap");
18324       break;
18325     case FIB_API_PATH_TYPE_BIER_IMP:
18326       s = format (s, "bier-imp");
18327       break;
18328     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18329       s = format (s, "unreach");
18330       break;
18331     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18332       s = format (s, "prohibit");
18333       break;
18334     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18335       s = format (s, "src-lookup");
18336       break;
18337     case FIB_API_PATH_TYPE_DVR:
18338       s = format (s, "dvr");
18339       break;
18340     case FIB_API_PATH_TYPE_INTERFACE_RX:
18341       s = format (s, "interface-rx");
18342       break;
18343     case FIB_API_PATH_TYPE_CLASSIFY:
18344       s = format (s, "classify");
18345       break;
18346     }
18347
18348   return (s);
18349 }
18350
18351 static void
18352 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18353 {
18354   print (vam->ofp,
18355          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18356          ntohl (fp->weight), ntohl (fp->sw_if_index),
18357          format_vl_api_fib_path_type, fp->type,
18358          format_fib_api_path_nh_proto, fp->proto,
18359          format_vl_api_ip_address_union, &fp->nh.address);
18360 }
18361
18362 static void
18363 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18364                                  vl_api_fib_path_t * fp)
18365 {
18366   struct in_addr ip4;
18367   struct in6_addr ip6;
18368
18369   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18370   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18371   vat_json_object_add_uint (node, "type", fp->type);
18372   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18373   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18374     {
18375       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18376       vat_json_object_add_ip4 (node, "next_hop", ip4);
18377     }
18378   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18379     {
18380       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18381       vat_json_object_add_ip6 (node, "next_hop", ip6);
18382     }
18383 }
18384
18385 static void
18386 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18387 {
18388   vat_main_t *vam = &vat_main;
18389   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18390   vl_api_fib_path_t *fp;
18391   i32 i;
18392
18393   print (vam->ofp, "sw_if_index %d via:",
18394          ntohl (mp->mt_tunnel.mt_sw_if_index));
18395   fp = mp->mt_tunnel.mt_paths;
18396   for (i = 0; i < count; i++)
18397     {
18398       vl_api_fib_path_print (vam, fp);
18399       fp++;
18400     }
18401
18402   print (vam->ofp, "");
18403 }
18404
18405 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18406 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18407
18408 static void
18409 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18410 {
18411   vat_main_t *vam = &vat_main;
18412   vat_json_node_t *node = NULL;
18413   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18414   vl_api_fib_path_t *fp;
18415   i32 i;
18416
18417   if (VAT_JSON_ARRAY != vam->json_tree.type)
18418     {
18419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18420       vat_json_init_array (&vam->json_tree);
18421     }
18422   node = vat_json_array_add (&vam->json_tree);
18423
18424   vat_json_init_object (node);
18425   vat_json_object_add_uint (node, "sw_if_index",
18426                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18427
18428   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18429
18430   fp = mp->mt_tunnel.mt_paths;
18431   for (i = 0; i < count; i++)
18432     {
18433       vl_api_mpls_fib_path_json_print (node, fp);
18434       fp++;
18435     }
18436 }
18437
18438 static int
18439 api_mpls_tunnel_dump (vat_main_t * vam)
18440 {
18441   vl_api_mpls_tunnel_dump_t *mp;
18442   vl_api_control_ping_t *mp_ping;
18443   int ret;
18444
18445   M (MPLS_TUNNEL_DUMP, mp);
18446
18447   S (mp);
18448
18449   /* Use a control ping for synchronization */
18450   MPING (CONTROL_PING, mp_ping);
18451   S (mp_ping);
18452
18453   W (ret);
18454   return ret;
18455 }
18456
18457 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18458 #define vl_api_mpls_table_details_t_print vl_noop_handler
18459
18460
18461 static void
18462 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18463 {
18464   vat_main_t *vam = &vat_main;
18465
18466   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18467 }
18468
18469 static void vl_api_mpls_table_details_t_handler_json
18470   (vl_api_mpls_table_details_t * mp)
18471 {
18472   vat_main_t *vam = &vat_main;
18473   vat_json_node_t *node = NULL;
18474
18475   if (VAT_JSON_ARRAY != vam->json_tree.type)
18476     {
18477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18478       vat_json_init_array (&vam->json_tree);
18479     }
18480   node = vat_json_array_add (&vam->json_tree);
18481
18482   vat_json_init_object (node);
18483   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18484 }
18485
18486 static int
18487 api_mpls_table_dump (vat_main_t * vam)
18488 {
18489   vl_api_mpls_table_dump_t *mp;
18490   vl_api_control_ping_t *mp_ping;
18491   int ret;
18492
18493   M (MPLS_TABLE_DUMP, mp);
18494   S (mp);
18495
18496   /* Use a control ping for synchronization */
18497   MPING (CONTROL_PING, mp_ping);
18498   S (mp_ping);
18499
18500   W (ret);
18501   return ret;
18502 }
18503
18504 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18505 #define vl_api_mpls_route_details_t_print vl_noop_handler
18506
18507 static void
18508 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18509 {
18510   vat_main_t *vam = &vat_main;
18511   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18512   vl_api_fib_path_t *fp;
18513   int i;
18514
18515   print (vam->ofp,
18516          "table-id %d, label %u, ess_bit %u",
18517          ntohl (mp->mr_route.mr_table_id),
18518          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18519   fp = mp->mr_route.mr_paths;
18520   for (i = 0; i < count; i++)
18521     {
18522       vl_api_fib_path_print (vam, fp);
18523       fp++;
18524     }
18525 }
18526
18527 static void vl_api_mpls_route_details_t_handler_json
18528   (vl_api_mpls_route_details_t * mp)
18529 {
18530   vat_main_t *vam = &vat_main;
18531   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18532   vat_json_node_t *node = NULL;
18533   vl_api_fib_path_t *fp;
18534   int i;
18535
18536   if (VAT_JSON_ARRAY != vam->json_tree.type)
18537     {
18538       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18539       vat_json_init_array (&vam->json_tree);
18540     }
18541   node = vat_json_array_add (&vam->json_tree);
18542
18543   vat_json_init_object (node);
18544   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18545   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18546   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18547   vat_json_object_add_uint (node, "path_count", count);
18548   fp = mp->mr_route.mr_paths;
18549   for (i = 0; i < count; i++)
18550     {
18551       vl_api_mpls_fib_path_json_print (node, fp);
18552       fp++;
18553     }
18554 }
18555
18556 static int
18557 api_mpls_route_dump (vat_main_t * vam)
18558 {
18559   unformat_input_t *input = vam->input;
18560   vl_api_mpls_route_dump_t *mp;
18561   vl_api_control_ping_t *mp_ping;
18562   u32 table_id;
18563   int ret;
18564
18565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18566     {
18567       if (unformat (input, "table_id %d", &table_id))
18568         ;
18569       else
18570         break;
18571     }
18572   if (table_id == ~0)
18573     {
18574       errmsg ("missing table id");
18575       return -99;
18576     }
18577
18578   M (MPLS_ROUTE_DUMP, mp);
18579
18580   mp->table.mt_table_id = ntohl (table_id);
18581   S (mp);
18582
18583   /* Use a control ping for synchronization */
18584   MPING (CONTROL_PING, mp_ping);
18585   S (mp_ping);
18586
18587   W (ret);
18588   return ret;
18589 }
18590
18591 #define vl_api_ip_table_details_t_endian vl_noop_handler
18592 #define vl_api_ip_table_details_t_print vl_noop_handler
18593
18594 static void
18595 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18596 {
18597   vat_main_t *vam = &vat_main;
18598
18599   print (vam->ofp,
18600          "%s; table-id %d, prefix %U/%d",
18601          mp->table.name, ntohl (mp->table.table_id));
18602 }
18603
18604
18605 static void vl_api_ip_table_details_t_handler_json
18606   (vl_api_ip_table_details_t * mp)
18607 {
18608   vat_main_t *vam = &vat_main;
18609   vat_json_node_t *node = NULL;
18610
18611   if (VAT_JSON_ARRAY != vam->json_tree.type)
18612     {
18613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18614       vat_json_init_array (&vam->json_tree);
18615     }
18616   node = vat_json_array_add (&vam->json_tree);
18617
18618   vat_json_init_object (node);
18619   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18620 }
18621
18622 static int
18623 api_ip_table_dump (vat_main_t * vam)
18624 {
18625   vl_api_ip_table_dump_t *mp;
18626   vl_api_control_ping_t *mp_ping;
18627   int ret;
18628
18629   M (IP_TABLE_DUMP, mp);
18630   S (mp);
18631
18632   /* Use a control ping for synchronization */
18633   MPING (CONTROL_PING, mp_ping);
18634   S (mp_ping);
18635
18636   W (ret);
18637   return ret;
18638 }
18639
18640 static int
18641 api_ip_mtable_dump (vat_main_t * vam)
18642 {
18643   vl_api_ip_mtable_dump_t *mp;
18644   vl_api_control_ping_t *mp_ping;
18645   int ret;
18646
18647   M (IP_MTABLE_DUMP, mp);
18648   S (mp);
18649
18650   /* Use a control ping for synchronization */
18651   MPING (CONTROL_PING, mp_ping);
18652   S (mp_ping);
18653
18654   W (ret);
18655   return ret;
18656 }
18657
18658 static int
18659 api_ip_mroute_dump (vat_main_t * vam)
18660 {
18661   unformat_input_t *input = vam->input;
18662   vl_api_control_ping_t *mp_ping;
18663   vl_api_ip_mroute_dump_t *mp;
18664   int ret, is_ip6;
18665   u32 table_id;
18666
18667   is_ip6 = 0;
18668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18669     {
18670       if (unformat (input, "table_id %d", &table_id))
18671         ;
18672       else if (unformat (input, "ip6"))
18673         is_ip6 = 1;
18674       else if (unformat (input, "ip4"))
18675         is_ip6 = 0;
18676       else
18677         break;
18678     }
18679   if (table_id == ~0)
18680     {
18681       errmsg ("missing table id");
18682       return -99;
18683     }
18684
18685   M (IP_MROUTE_DUMP, mp);
18686   mp->table.table_id = table_id;
18687   mp->table.is_ip6 = is_ip6;
18688   S (mp);
18689
18690   /* Use a control ping for synchronization */
18691   MPING (CONTROL_PING, mp_ping);
18692   S (mp_ping);
18693
18694   W (ret);
18695   return ret;
18696 }
18697
18698 static void vl_api_ip_neighbor_details_t_handler
18699   (vl_api_ip_neighbor_details_t * mp)
18700 {
18701   vat_main_t *vam = &vat_main;
18702
18703   print (vam->ofp, "%c %U %U",
18704          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18705          format_vl_api_mac_address, &mp->neighbor.mac_address,
18706          format_vl_api_address, &mp->neighbor.ip_address);
18707 }
18708
18709 static void vl_api_ip_neighbor_details_t_handler_json
18710   (vl_api_ip_neighbor_details_t * mp)
18711 {
18712
18713   vat_main_t *vam = &vat_main;
18714   vat_json_node_t *node;
18715
18716   if (VAT_JSON_ARRAY != vam->json_tree.type)
18717     {
18718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18719       vat_json_init_array (&vam->json_tree);
18720     }
18721   node = vat_json_array_add (&vam->json_tree);
18722
18723   vat_json_init_object (node);
18724   vat_json_object_add_string_copy
18725     (node, "flag",
18726      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18727       (u8 *) "static" : (u8 *) "dynamic"));
18728
18729   vat_json_object_add_string_copy (node, "link_layer",
18730                                    format (0, "%U", format_vl_api_mac_address,
18731                                            &mp->neighbor.mac_address));
18732   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18733 }
18734
18735 static int
18736 api_ip_neighbor_dump (vat_main_t * vam)
18737 {
18738   unformat_input_t *i = vam->input;
18739   vl_api_ip_neighbor_dump_t *mp;
18740   vl_api_control_ping_t *mp_ping;
18741   u8 is_ipv6 = 0;
18742   u32 sw_if_index = ~0;
18743   int ret;
18744
18745   /* Parse args required to build the message */
18746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18747     {
18748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18749         ;
18750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18751         ;
18752       else if (unformat (i, "ip6"))
18753         is_ipv6 = 1;
18754       else
18755         break;
18756     }
18757
18758   if (sw_if_index == ~0)
18759     {
18760       errmsg ("missing interface name or sw_if_index");
18761       return -99;
18762     }
18763
18764   M (IP_NEIGHBOR_DUMP, mp);
18765   mp->is_ipv6 = (u8) is_ipv6;
18766   mp->sw_if_index = ntohl (sw_if_index);
18767   S (mp);
18768
18769   /* Use a control ping for synchronization */
18770   MPING (CONTROL_PING, mp_ping);
18771   S (mp_ping);
18772
18773   W (ret);
18774   return ret;
18775 }
18776
18777 #define vl_api_ip_route_details_t_endian vl_noop_handler
18778 #define vl_api_ip_route_details_t_print vl_noop_handler
18779
18780 static void
18781 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18782 {
18783   vat_main_t *vam = &vat_main;
18784   u8 count = mp->route.n_paths;
18785   vl_api_fib_path_t *fp;
18786   int i;
18787
18788   print (vam->ofp,
18789          "table-id %d, prefix %U/%d",
18790          ntohl (mp->route.table_id),
18791          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18792   for (i = 0; i < count; i++)
18793     {
18794       fp = &mp->route.paths[i];
18795
18796       vl_api_fib_path_print (vam, fp);
18797       fp++;
18798     }
18799 }
18800
18801 static void vl_api_ip_route_details_t_handler_json
18802   (vl_api_ip_route_details_t * mp)
18803 {
18804   vat_main_t *vam = &vat_main;
18805   u8 count = mp->route.n_paths;
18806   vat_json_node_t *node = NULL;
18807   struct in_addr ip4;
18808   struct in6_addr ip6;
18809   vl_api_fib_path_t *fp;
18810   int i;
18811
18812   if (VAT_JSON_ARRAY != vam->json_tree.type)
18813     {
18814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18815       vat_json_init_array (&vam->json_tree);
18816     }
18817   node = vat_json_array_add (&vam->json_tree);
18818
18819   vat_json_init_object (node);
18820   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18821   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18822     {
18823       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18824       vat_json_object_add_ip6 (node, "prefix", ip6);
18825     }
18826   else
18827     {
18828       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18829       vat_json_object_add_ip4 (node, "prefix", ip4);
18830     }
18831   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18832   vat_json_object_add_uint (node, "path_count", count);
18833   for (i = 0; i < count; i++)
18834     {
18835       fp = &mp->route.paths[i];
18836       vl_api_mpls_fib_path_json_print (node, fp);
18837     }
18838 }
18839
18840 static int
18841 api_ip_route_dump (vat_main_t * vam)
18842 {
18843   unformat_input_t *input = vam->input;
18844   vl_api_ip_route_dump_t *mp;
18845   vl_api_control_ping_t *mp_ping;
18846   u32 table_id;
18847   u8 is_ip6;
18848   int ret;
18849
18850   is_ip6 = 0;
18851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18852     {
18853       if (unformat (input, "table_id %d", &table_id))
18854         ;
18855       else if (unformat (input, "ip6"))
18856         is_ip6 = 1;
18857       else if (unformat (input, "ip4"))
18858         is_ip6 = 0;
18859       else
18860         break;
18861     }
18862   if (table_id == ~0)
18863     {
18864       errmsg ("missing table id");
18865       return -99;
18866     }
18867
18868   M (IP_ROUTE_DUMP, mp);
18869
18870   mp->table.table_id = table_id;
18871   mp->table.is_ip6 = is_ip6;
18872
18873   S (mp);
18874
18875   /* Use a control ping for synchronization */
18876   MPING (CONTROL_PING, mp_ping);
18877   S (mp_ping);
18878
18879   W (ret);
18880   return ret;
18881 }
18882
18883 int
18884 api_classify_table_ids (vat_main_t * vam)
18885 {
18886   vl_api_classify_table_ids_t *mp;
18887   int ret;
18888
18889   /* Construct the API message */
18890   M (CLASSIFY_TABLE_IDS, mp);
18891   mp->context = 0;
18892
18893   S (mp);
18894   W (ret);
18895   return ret;
18896 }
18897
18898 int
18899 api_classify_table_by_interface (vat_main_t * vam)
18900 {
18901   unformat_input_t *input = vam->input;
18902   vl_api_classify_table_by_interface_t *mp;
18903
18904   u32 sw_if_index = ~0;
18905   int ret;
18906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18907     {
18908       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18909         ;
18910       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18911         ;
18912       else
18913         break;
18914     }
18915   if (sw_if_index == ~0)
18916     {
18917       errmsg ("missing interface name or sw_if_index");
18918       return -99;
18919     }
18920
18921   /* Construct the API message */
18922   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18923   mp->context = 0;
18924   mp->sw_if_index = ntohl (sw_if_index);
18925
18926   S (mp);
18927   W (ret);
18928   return ret;
18929 }
18930
18931 int
18932 api_classify_table_info (vat_main_t * vam)
18933 {
18934   unformat_input_t *input = vam->input;
18935   vl_api_classify_table_info_t *mp;
18936
18937   u32 table_id = ~0;
18938   int ret;
18939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18940     {
18941       if (unformat (input, "table_id %d", &table_id))
18942         ;
18943       else
18944         break;
18945     }
18946   if (table_id == ~0)
18947     {
18948       errmsg ("missing table id");
18949       return -99;
18950     }
18951
18952   /* Construct the API message */
18953   M (CLASSIFY_TABLE_INFO, mp);
18954   mp->context = 0;
18955   mp->table_id = ntohl (table_id);
18956
18957   S (mp);
18958   W (ret);
18959   return ret;
18960 }
18961
18962 int
18963 api_classify_session_dump (vat_main_t * vam)
18964 {
18965   unformat_input_t *input = vam->input;
18966   vl_api_classify_session_dump_t *mp;
18967   vl_api_control_ping_t *mp_ping;
18968
18969   u32 table_id = ~0;
18970   int ret;
18971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18972     {
18973       if (unformat (input, "table_id %d", &table_id))
18974         ;
18975       else
18976         break;
18977     }
18978   if (table_id == ~0)
18979     {
18980       errmsg ("missing table id");
18981       return -99;
18982     }
18983
18984   /* Construct the API message */
18985   M (CLASSIFY_SESSION_DUMP, mp);
18986   mp->context = 0;
18987   mp->table_id = ntohl (table_id);
18988   S (mp);
18989
18990   /* Use a control ping for synchronization */
18991   MPING (CONTROL_PING, mp_ping);
18992   S (mp_ping);
18993
18994   W (ret);
18995   return ret;
18996 }
18997
18998 static void
18999 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19000 {
19001   vat_main_t *vam = &vat_main;
19002
19003   print (vam->ofp, "collector_address %U, collector_port %d, "
19004          "src_address %U, vrf_id %d, path_mtu %u, "
19005          "template_interval %u, udp_checksum %d",
19006          format_ip4_address, mp->collector_address,
19007          ntohs (mp->collector_port),
19008          format_ip4_address, mp->src_address,
19009          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19010          ntohl (mp->template_interval), mp->udp_checksum);
19011
19012   vam->retval = 0;
19013   vam->result_ready = 1;
19014 }
19015
19016 static void
19017   vl_api_ipfix_exporter_details_t_handler_json
19018   (vl_api_ipfix_exporter_details_t * mp)
19019 {
19020   vat_main_t *vam = &vat_main;
19021   vat_json_node_t node;
19022   struct in_addr collector_address;
19023   struct in_addr src_address;
19024
19025   vat_json_init_object (&node);
19026   clib_memcpy (&collector_address, &mp->collector_address,
19027                sizeof (collector_address));
19028   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19029   vat_json_object_add_uint (&node, "collector_port",
19030                             ntohs (mp->collector_port));
19031   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19032   vat_json_object_add_ip4 (&node, "src_address", src_address);
19033   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19034   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19035   vat_json_object_add_uint (&node, "template_interval",
19036                             ntohl (mp->template_interval));
19037   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19038
19039   vat_json_print (vam->ofp, &node);
19040   vat_json_free (&node);
19041   vam->retval = 0;
19042   vam->result_ready = 1;
19043 }
19044
19045 int
19046 api_ipfix_exporter_dump (vat_main_t * vam)
19047 {
19048   vl_api_ipfix_exporter_dump_t *mp;
19049   int ret;
19050
19051   /* Construct the API message */
19052   M (IPFIX_EXPORTER_DUMP, mp);
19053   mp->context = 0;
19054
19055   S (mp);
19056   W (ret);
19057   return ret;
19058 }
19059
19060 static int
19061 api_ipfix_classify_stream_dump (vat_main_t * vam)
19062 {
19063   vl_api_ipfix_classify_stream_dump_t *mp;
19064   int ret;
19065
19066   /* Construct the API message */
19067   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19068   mp->context = 0;
19069
19070   S (mp);
19071   W (ret);
19072   return ret;
19073   /* NOTREACHED */
19074   return 0;
19075 }
19076
19077 static void
19078   vl_api_ipfix_classify_stream_details_t_handler
19079   (vl_api_ipfix_classify_stream_details_t * mp)
19080 {
19081   vat_main_t *vam = &vat_main;
19082   print (vam->ofp, "domain_id %d, src_port %d",
19083          ntohl (mp->domain_id), ntohs (mp->src_port));
19084   vam->retval = 0;
19085   vam->result_ready = 1;
19086 }
19087
19088 static void
19089   vl_api_ipfix_classify_stream_details_t_handler_json
19090   (vl_api_ipfix_classify_stream_details_t * mp)
19091 {
19092   vat_main_t *vam = &vat_main;
19093   vat_json_node_t node;
19094
19095   vat_json_init_object (&node);
19096   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19097   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19098
19099   vat_json_print (vam->ofp, &node);
19100   vat_json_free (&node);
19101   vam->retval = 0;
19102   vam->result_ready = 1;
19103 }
19104
19105 static int
19106 api_ipfix_classify_table_dump (vat_main_t * vam)
19107 {
19108   vl_api_ipfix_classify_table_dump_t *mp;
19109   vl_api_control_ping_t *mp_ping;
19110   int ret;
19111
19112   if (!vam->json_output)
19113     {
19114       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19115              "transport_protocol");
19116     }
19117
19118   /* Construct the API message */
19119   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19120
19121   /* send it... */
19122   S (mp);
19123
19124   /* Use a control ping for synchronization */
19125   MPING (CONTROL_PING, mp_ping);
19126   S (mp_ping);
19127
19128   W (ret);
19129   return ret;
19130 }
19131
19132 static void
19133   vl_api_ipfix_classify_table_details_t_handler
19134   (vl_api_ipfix_classify_table_details_t * mp)
19135 {
19136   vat_main_t *vam = &vat_main;
19137   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19138          mp->transport_protocol);
19139 }
19140
19141 static void
19142   vl_api_ipfix_classify_table_details_t_handler_json
19143   (vl_api_ipfix_classify_table_details_t * mp)
19144 {
19145   vat_json_node_t *node = NULL;
19146   vat_main_t *vam = &vat_main;
19147
19148   if (VAT_JSON_ARRAY != vam->json_tree.type)
19149     {
19150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19151       vat_json_init_array (&vam->json_tree);
19152     }
19153
19154   node = vat_json_array_add (&vam->json_tree);
19155   vat_json_init_object (node);
19156
19157   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19158   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19159   vat_json_object_add_uint (node, "transport_protocol",
19160                             mp->transport_protocol);
19161 }
19162
19163 static int
19164 api_sw_interface_span_enable_disable (vat_main_t * vam)
19165 {
19166   unformat_input_t *i = vam->input;
19167   vl_api_sw_interface_span_enable_disable_t *mp;
19168   u32 src_sw_if_index = ~0;
19169   u32 dst_sw_if_index = ~0;
19170   u8 state = 3;
19171   int ret;
19172   u8 is_l2 = 0;
19173
19174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19175     {
19176       if (unformat
19177           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19178         ;
19179       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19180         ;
19181       else
19182         if (unformat
19183             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19184         ;
19185       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19186         ;
19187       else if (unformat (i, "disable"))
19188         state = 0;
19189       else if (unformat (i, "rx"))
19190         state = 1;
19191       else if (unformat (i, "tx"))
19192         state = 2;
19193       else if (unformat (i, "both"))
19194         state = 3;
19195       else if (unformat (i, "l2"))
19196         is_l2 = 1;
19197       else
19198         break;
19199     }
19200
19201   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19202
19203   mp->sw_if_index_from = htonl (src_sw_if_index);
19204   mp->sw_if_index_to = htonl (dst_sw_if_index);
19205   mp->state = state;
19206   mp->is_l2 = is_l2;
19207
19208   S (mp);
19209   W (ret);
19210   return ret;
19211 }
19212
19213 static void
19214 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19215                                             * mp)
19216 {
19217   vat_main_t *vam = &vat_main;
19218   u8 *sw_if_from_name = 0;
19219   u8 *sw_if_to_name = 0;
19220   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19221   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19222   char *states[] = { "none", "rx", "tx", "both" };
19223   hash_pair_t *p;
19224
19225   /* *INDENT-OFF* */
19226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19227   ({
19228     if ((u32) p->value[0] == sw_if_index_from)
19229       {
19230         sw_if_from_name = (u8 *)(p->key);
19231         if (sw_if_to_name)
19232           break;
19233       }
19234     if ((u32) p->value[0] == sw_if_index_to)
19235       {
19236         sw_if_to_name = (u8 *)(p->key);
19237         if (sw_if_from_name)
19238           break;
19239       }
19240   }));
19241   /* *INDENT-ON* */
19242   print (vam->ofp, "%20s => %20s (%s) %s",
19243          sw_if_from_name, sw_if_to_name, states[mp->state],
19244          mp->is_l2 ? "l2" : "device");
19245 }
19246
19247 static void
19248   vl_api_sw_interface_span_details_t_handler_json
19249   (vl_api_sw_interface_span_details_t * mp)
19250 {
19251   vat_main_t *vam = &vat_main;
19252   vat_json_node_t *node = NULL;
19253   u8 *sw_if_from_name = 0;
19254   u8 *sw_if_to_name = 0;
19255   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19256   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19257   hash_pair_t *p;
19258
19259   /* *INDENT-OFF* */
19260   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19261   ({
19262     if ((u32) p->value[0] == sw_if_index_from)
19263       {
19264         sw_if_from_name = (u8 *)(p->key);
19265         if (sw_if_to_name)
19266           break;
19267       }
19268     if ((u32) p->value[0] == sw_if_index_to)
19269       {
19270         sw_if_to_name = (u8 *)(p->key);
19271         if (sw_if_from_name)
19272           break;
19273       }
19274   }));
19275   /* *INDENT-ON* */
19276
19277   if (VAT_JSON_ARRAY != vam->json_tree.type)
19278     {
19279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19280       vat_json_init_array (&vam->json_tree);
19281     }
19282   node = vat_json_array_add (&vam->json_tree);
19283
19284   vat_json_init_object (node);
19285   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19286   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19287   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19288   if (0 != sw_if_to_name)
19289     {
19290       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19291     }
19292   vat_json_object_add_uint (node, "state", mp->state);
19293   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19294 }
19295
19296 static int
19297 api_sw_interface_span_dump (vat_main_t * vam)
19298 {
19299   unformat_input_t *input = vam->input;
19300   vl_api_sw_interface_span_dump_t *mp;
19301   vl_api_control_ping_t *mp_ping;
19302   u8 is_l2 = 0;
19303   int ret;
19304
19305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19306     {
19307       if (unformat (input, "l2"))
19308         is_l2 = 1;
19309       else
19310         break;
19311     }
19312
19313   M (SW_INTERFACE_SPAN_DUMP, mp);
19314   mp->is_l2 = is_l2;
19315   S (mp);
19316
19317   /* Use a control ping for synchronization */
19318   MPING (CONTROL_PING, mp_ping);
19319   S (mp_ping);
19320
19321   W (ret);
19322   return ret;
19323 }
19324
19325 int
19326 api_pg_create_interface (vat_main_t * vam)
19327 {
19328   unformat_input_t *input = vam->input;
19329   vl_api_pg_create_interface_t *mp;
19330
19331   u32 if_id = ~0, gso_size = 0;
19332   u8 gso_enabled = 0;
19333   int ret;
19334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19335     {
19336       if (unformat (input, "if_id %d", &if_id))
19337         ;
19338       else if (unformat (input, "gso-enabled"))
19339         {
19340           gso_enabled = 1;
19341           if (unformat (input, "gso-size %u", &gso_size))
19342             ;
19343           else
19344             {
19345               errmsg ("missing gso-size");
19346               return -99;
19347             }
19348         }
19349       else
19350         break;
19351     }
19352   if (if_id == ~0)
19353     {
19354       errmsg ("missing pg interface index");
19355       return -99;
19356     }
19357
19358   /* Construct the API message */
19359   M (PG_CREATE_INTERFACE, mp);
19360   mp->context = 0;
19361   mp->interface_id = ntohl (if_id);
19362   mp->gso_enabled = gso_enabled;
19363
19364   S (mp);
19365   W (ret);
19366   return ret;
19367 }
19368
19369 int
19370 api_pg_capture (vat_main_t * vam)
19371 {
19372   unformat_input_t *input = vam->input;
19373   vl_api_pg_capture_t *mp;
19374
19375   u32 if_id = ~0;
19376   u8 enable = 1;
19377   u32 count = 1;
19378   u8 pcap_file_set = 0;
19379   u8 *pcap_file = 0;
19380   int ret;
19381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19382     {
19383       if (unformat (input, "if_id %d", &if_id))
19384         ;
19385       else if (unformat (input, "pcap %s", &pcap_file))
19386         pcap_file_set = 1;
19387       else if (unformat (input, "count %d", &count))
19388         ;
19389       else if (unformat (input, "disable"))
19390         enable = 0;
19391       else
19392         break;
19393     }
19394   if (if_id == ~0)
19395     {
19396       errmsg ("missing pg interface index");
19397       return -99;
19398     }
19399   if (pcap_file_set > 0)
19400     {
19401       if (vec_len (pcap_file) > 255)
19402         {
19403           errmsg ("pcap file name is too long");
19404           return -99;
19405         }
19406     }
19407
19408   u32 name_len = vec_len (pcap_file);
19409   /* Construct the API message */
19410   M (PG_CAPTURE, mp);
19411   mp->context = 0;
19412   mp->interface_id = ntohl (if_id);
19413   mp->is_enabled = enable;
19414   mp->count = ntohl (count);
19415   mp->pcap_name_length = ntohl (name_len);
19416   if (pcap_file_set != 0)
19417     {
19418       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19419     }
19420   vec_free (pcap_file);
19421
19422   S (mp);
19423   W (ret);
19424   return ret;
19425 }
19426
19427 int
19428 api_pg_enable_disable (vat_main_t * vam)
19429 {
19430   unformat_input_t *input = vam->input;
19431   vl_api_pg_enable_disable_t *mp;
19432
19433   u8 enable = 1;
19434   u8 stream_name_set = 0;
19435   u8 *stream_name = 0;
19436   int ret;
19437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19438     {
19439       if (unformat (input, "stream %s", &stream_name))
19440         stream_name_set = 1;
19441       else if (unformat (input, "disable"))
19442         enable = 0;
19443       else
19444         break;
19445     }
19446
19447   if (stream_name_set > 0)
19448     {
19449       if (vec_len (stream_name) > 255)
19450         {
19451           errmsg ("stream name too long");
19452           return -99;
19453         }
19454     }
19455
19456   u32 name_len = vec_len (stream_name);
19457   /* Construct the API message */
19458   M (PG_ENABLE_DISABLE, mp);
19459   mp->context = 0;
19460   mp->is_enabled = enable;
19461   if (stream_name_set != 0)
19462     {
19463       mp->stream_name_length = ntohl (name_len);
19464       clib_memcpy (mp->stream_name, stream_name, name_len);
19465     }
19466   vec_free (stream_name);
19467
19468   S (mp);
19469   W (ret);
19470   return ret;
19471 }
19472
19473 int
19474 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19475 {
19476   unformat_input_t *input = vam->input;
19477   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19478
19479   u16 *low_ports = 0;
19480   u16 *high_ports = 0;
19481   u16 this_low;
19482   u16 this_hi;
19483   vl_api_prefix_t prefix;
19484   u32 tmp, tmp2;
19485   u8 prefix_set = 0;
19486   u32 vrf_id = ~0;
19487   u8 is_add = 1;
19488   int ret;
19489
19490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19491     {
19492       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19493         prefix_set = 1;
19494       else if (unformat (input, "vrf %d", &vrf_id))
19495         ;
19496       else if (unformat (input, "del"))
19497         is_add = 0;
19498       else if (unformat (input, "port %d", &tmp))
19499         {
19500           if (tmp == 0 || tmp > 65535)
19501             {
19502               errmsg ("port %d out of range", tmp);
19503               return -99;
19504             }
19505           this_low = tmp;
19506           this_hi = this_low + 1;
19507           vec_add1 (low_ports, this_low);
19508           vec_add1 (high_ports, this_hi);
19509         }
19510       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19511         {
19512           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19513             {
19514               errmsg ("incorrect range parameters");
19515               return -99;
19516             }
19517           this_low = tmp;
19518           /* Note: in debug CLI +1 is added to high before
19519              passing to real fn that does "the work"
19520              (ip_source_and_port_range_check_add_del).
19521              This fn is a wrapper around the binary API fn a
19522              control plane will call, which expects this increment
19523              to have occurred. Hence letting the binary API control
19524              plane fn do the increment for consistency between VAT
19525              and other control planes.
19526            */
19527           this_hi = tmp2;
19528           vec_add1 (low_ports, this_low);
19529           vec_add1 (high_ports, this_hi);
19530         }
19531       else
19532         break;
19533     }
19534
19535   if (prefix_set == 0)
19536     {
19537       errmsg ("<address>/<mask> not specified");
19538       return -99;
19539     }
19540
19541   if (vrf_id == ~0)
19542     {
19543       errmsg ("VRF ID required, not specified");
19544       return -99;
19545     }
19546
19547   if (vrf_id == 0)
19548     {
19549       errmsg
19550         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19551       return -99;
19552     }
19553
19554   if (vec_len (low_ports) == 0)
19555     {
19556       errmsg ("At least one port or port range required");
19557       return -99;
19558     }
19559
19560   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19561
19562   mp->is_add = is_add;
19563
19564   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19565
19566   mp->number_of_ranges = vec_len (low_ports);
19567
19568   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19569   vec_free (low_ports);
19570
19571   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19572   vec_free (high_ports);
19573
19574   mp->vrf_id = ntohl (vrf_id);
19575
19576   S (mp);
19577   W (ret);
19578   return ret;
19579 }
19580
19581 int
19582 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19583 {
19584   unformat_input_t *input = vam->input;
19585   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19586   u32 sw_if_index = ~0;
19587   int vrf_set = 0;
19588   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19589   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19590   u8 is_add = 1;
19591   int ret;
19592
19593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19594     {
19595       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19596         ;
19597       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19598         ;
19599       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19600         vrf_set = 1;
19601       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19602         vrf_set = 1;
19603       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19604         vrf_set = 1;
19605       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19606         vrf_set = 1;
19607       else if (unformat (input, "del"))
19608         is_add = 0;
19609       else
19610         break;
19611     }
19612
19613   if (sw_if_index == ~0)
19614     {
19615       errmsg ("Interface required but not specified");
19616       return -99;
19617     }
19618
19619   if (vrf_set == 0)
19620     {
19621       errmsg ("VRF ID required but not specified");
19622       return -99;
19623     }
19624
19625   if (tcp_out_vrf_id == 0
19626       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19627     {
19628       errmsg
19629         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19630       return -99;
19631     }
19632
19633   /* Construct the API message */
19634   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19635
19636   mp->sw_if_index = ntohl (sw_if_index);
19637   mp->is_add = is_add;
19638   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19639   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19640   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19641   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19642
19643   /* send it... */
19644   S (mp);
19645
19646   /* Wait for a reply... */
19647   W (ret);
19648   return ret;
19649 }
19650
19651 static int
19652 api_set_punt (vat_main_t * vam)
19653 {
19654   unformat_input_t *i = vam->input;
19655   vl_api_address_family_t af;
19656   vl_api_set_punt_t *mp;
19657   u32 protocol = ~0;
19658   u32 port = ~0;
19659   int is_add = 1;
19660   int ret;
19661
19662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19663     {
19664       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19665         ;
19666       else if (unformat (i, "protocol %d", &protocol))
19667         ;
19668       else if (unformat (i, "port %d", &port))
19669         ;
19670       else if (unformat (i, "del"))
19671         is_add = 0;
19672       else
19673         {
19674           clib_warning ("parse error '%U'", format_unformat_error, i);
19675           return -99;
19676         }
19677     }
19678
19679   M (SET_PUNT, mp);
19680
19681   mp->is_add = (u8) is_add;
19682   mp->punt.type = PUNT_API_TYPE_L4;
19683   mp->punt.punt.l4.af = af;
19684   mp->punt.punt.l4.protocol = (u8) protocol;
19685   mp->punt.punt.l4.port = htons ((u16) port);
19686
19687   S (mp);
19688   W (ret);
19689   return ret;
19690 }
19691
19692 static int
19693 api_delete_subif (vat_main_t * vam)
19694 {
19695   unformat_input_t *i = vam->input;
19696   vl_api_delete_subif_t *mp;
19697   u32 sw_if_index = ~0;
19698   int ret;
19699
19700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19701     {
19702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19703         ;
19704       if (unformat (i, "sw_if_index %d", &sw_if_index))
19705         ;
19706       else
19707         break;
19708     }
19709
19710   if (sw_if_index == ~0)
19711     {
19712       errmsg ("missing sw_if_index");
19713       return -99;
19714     }
19715
19716   /* Construct the API message */
19717   M (DELETE_SUBIF, mp);
19718   mp->sw_if_index = ntohl (sw_if_index);
19719
19720   S (mp);
19721   W (ret);
19722   return ret;
19723 }
19724
19725 #define foreach_pbb_vtr_op      \
19726 _("disable",  L2_VTR_DISABLED)  \
19727 _("pop",  L2_VTR_POP_2)         \
19728 _("push",  L2_VTR_PUSH_2)
19729
19730 static int
19731 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19732 {
19733   unformat_input_t *i = vam->input;
19734   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19735   u32 sw_if_index = ~0, vtr_op = ~0;
19736   u16 outer_tag = ~0;
19737   u8 dmac[6], smac[6];
19738   u8 dmac_set = 0, smac_set = 0;
19739   u16 vlanid = 0;
19740   u32 sid = ~0;
19741   u32 tmp;
19742   int ret;
19743
19744   /* Shut up coverity */
19745   clib_memset (dmac, 0, sizeof (dmac));
19746   clib_memset (smac, 0, sizeof (smac));
19747
19748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19749     {
19750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19751         ;
19752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19753         ;
19754       else if (unformat (i, "vtr_op %d", &vtr_op))
19755         ;
19756 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19757       foreach_pbb_vtr_op
19758 #undef _
19759         else if (unformat (i, "translate_pbb_stag"))
19760         {
19761           if (unformat (i, "%d", &tmp))
19762             {
19763               vtr_op = L2_VTR_TRANSLATE_2_1;
19764               outer_tag = tmp;
19765             }
19766           else
19767             {
19768               errmsg
19769                 ("translate_pbb_stag operation requires outer tag definition");
19770               return -99;
19771             }
19772         }
19773       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19774         dmac_set++;
19775       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19776         smac_set++;
19777       else if (unformat (i, "sid %d", &sid))
19778         ;
19779       else if (unformat (i, "vlanid %d", &tmp))
19780         vlanid = tmp;
19781       else
19782         {
19783           clib_warning ("parse error '%U'", format_unformat_error, i);
19784           return -99;
19785         }
19786     }
19787
19788   if ((sw_if_index == ~0) || (vtr_op == ~0))
19789     {
19790       errmsg ("missing sw_if_index or vtr operation");
19791       return -99;
19792     }
19793   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19794       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19795     {
19796       errmsg
19797         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19798       return -99;
19799     }
19800
19801   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19802   mp->sw_if_index = ntohl (sw_if_index);
19803   mp->vtr_op = ntohl (vtr_op);
19804   mp->outer_tag = ntohs (outer_tag);
19805   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19806   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19807   mp->b_vlanid = ntohs (vlanid);
19808   mp->i_sid = ntohl (sid);
19809
19810   S (mp);
19811   W (ret);
19812   return ret;
19813 }
19814
19815 static int
19816 api_flow_classify_set_interface (vat_main_t * vam)
19817 {
19818   unformat_input_t *i = vam->input;
19819   vl_api_flow_classify_set_interface_t *mp;
19820   u32 sw_if_index;
19821   int sw_if_index_set;
19822   u32 ip4_table_index = ~0;
19823   u32 ip6_table_index = ~0;
19824   u8 is_add = 1;
19825   int ret;
19826
19827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19828     {
19829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19830         sw_if_index_set = 1;
19831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19832         sw_if_index_set = 1;
19833       else if (unformat (i, "del"))
19834         is_add = 0;
19835       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19836         ;
19837       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19838         ;
19839       else
19840         {
19841           clib_warning ("parse error '%U'", format_unformat_error, i);
19842           return -99;
19843         }
19844     }
19845
19846   if (sw_if_index_set == 0)
19847     {
19848       errmsg ("missing interface name or sw_if_index");
19849       return -99;
19850     }
19851
19852   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19853
19854   mp->sw_if_index = ntohl (sw_if_index);
19855   mp->ip4_table_index = ntohl (ip4_table_index);
19856   mp->ip6_table_index = ntohl (ip6_table_index);
19857   mp->is_add = is_add;
19858
19859   S (mp);
19860   W (ret);
19861   return ret;
19862 }
19863
19864 static int
19865 api_flow_classify_dump (vat_main_t * vam)
19866 {
19867   unformat_input_t *i = vam->input;
19868   vl_api_flow_classify_dump_t *mp;
19869   vl_api_control_ping_t *mp_ping;
19870   u8 type = FLOW_CLASSIFY_N_TABLES;
19871   int ret;
19872
19873   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19874     ;
19875   else
19876     {
19877       errmsg ("classify table type must be specified");
19878       return -99;
19879     }
19880
19881   if (!vam->json_output)
19882     {
19883       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19884     }
19885
19886   M (FLOW_CLASSIFY_DUMP, mp);
19887   mp->type = type;
19888   /* send it... */
19889   S (mp);
19890
19891   /* Use a control ping for synchronization */
19892   MPING (CONTROL_PING, mp_ping);
19893   S (mp_ping);
19894
19895   /* Wait for a reply... */
19896   W (ret);
19897   return ret;
19898 }
19899
19900 static int
19901 api_feature_enable_disable (vat_main_t * vam)
19902 {
19903   unformat_input_t *i = vam->input;
19904   vl_api_feature_enable_disable_t *mp;
19905   u8 *arc_name = 0;
19906   u8 *feature_name = 0;
19907   u32 sw_if_index = ~0;
19908   u8 enable = 1;
19909   int ret;
19910
19911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19912     {
19913       if (unformat (i, "arc_name %s", &arc_name))
19914         ;
19915       else if (unformat (i, "feature_name %s", &feature_name))
19916         ;
19917       else
19918         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19919         ;
19920       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19921         ;
19922       else if (unformat (i, "disable"))
19923         enable = 0;
19924       else
19925         break;
19926     }
19927
19928   if (arc_name == 0)
19929     {
19930       errmsg ("missing arc name");
19931       return -99;
19932     }
19933   if (vec_len (arc_name) > 63)
19934     {
19935       errmsg ("arc name too long");
19936     }
19937
19938   if (feature_name == 0)
19939     {
19940       errmsg ("missing feature name");
19941       return -99;
19942     }
19943   if (vec_len (feature_name) > 63)
19944     {
19945       errmsg ("feature name too long");
19946     }
19947
19948   if (sw_if_index == ~0)
19949     {
19950       errmsg ("missing interface name or sw_if_index");
19951       return -99;
19952     }
19953
19954   /* Construct the API message */
19955   M (FEATURE_ENABLE_DISABLE, mp);
19956   mp->sw_if_index = ntohl (sw_if_index);
19957   mp->enable = enable;
19958   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19959   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19960   vec_free (arc_name);
19961   vec_free (feature_name);
19962
19963   S (mp);
19964   W (ret);
19965   return ret;
19966 }
19967
19968 static int
19969 api_sw_interface_tag_add_del (vat_main_t * vam)
19970 {
19971   unformat_input_t *i = vam->input;
19972   vl_api_sw_interface_tag_add_del_t *mp;
19973   u32 sw_if_index = ~0;
19974   u8 *tag = 0;
19975   u8 enable = 1;
19976   int ret;
19977
19978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19979     {
19980       if (unformat (i, "tag %s", &tag))
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, "del"))
19987         enable = 0;
19988       else
19989         break;
19990     }
19991
19992   if (sw_if_index == ~0)
19993     {
19994       errmsg ("missing interface name or sw_if_index");
19995       return -99;
19996     }
19997
19998   if (enable && (tag == 0))
19999     {
20000       errmsg ("no tag specified");
20001       return -99;
20002     }
20003
20004   /* Construct the API message */
20005   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20006   mp->sw_if_index = ntohl (sw_if_index);
20007   mp->is_add = enable;
20008   if (enable)
20009     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20010   vec_free (tag);
20011
20012   S (mp);
20013   W (ret);
20014   return ret;
20015 }
20016
20017 static int
20018 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20019 {
20020   unformat_input_t *i = vam->input;
20021   vl_api_mac_address_t mac = { 0 };
20022   vl_api_sw_interface_add_del_mac_address_t *mp;
20023   u32 sw_if_index = ~0;
20024   u8 is_add = 1;
20025   u8 mac_set = 0;
20026   int ret;
20027
20028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20029     {
20030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20031         ;
20032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20033         ;
20034       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20035         mac_set++;
20036       else if (unformat (i, "del"))
20037         is_add = 0;
20038       else
20039         break;
20040     }
20041
20042   if (sw_if_index == ~0)
20043     {
20044       errmsg ("missing interface name or sw_if_index");
20045       return -99;
20046     }
20047
20048   if (!mac_set)
20049     {
20050       errmsg ("missing MAC address");
20051       return -99;
20052     }
20053
20054   /* Construct the API message */
20055   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20056   mp->sw_if_index = ntohl (sw_if_index);
20057   mp->is_add = is_add;
20058   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20059
20060   S (mp);
20061   W (ret);
20062   return ret;
20063 }
20064
20065 static void vl_api_l2_xconnect_details_t_handler
20066   (vl_api_l2_xconnect_details_t * mp)
20067 {
20068   vat_main_t *vam = &vat_main;
20069
20070   print (vam->ofp, "%15d%15d",
20071          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20072 }
20073
20074 static void vl_api_l2_xconnect_details_t_handler_json
20075   (vl_api_l2_xconnect_details_t * mp)
20076 {
20077   vat_main_t *vam = &vat_main;
20078   vat_json_node_t *node = NULL;
20079
20080   if (VAT_JSON_ARRAY != vam->json_tree.type)
20081     {
20082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20083       vat_json_init_array (&vam->json_tree);
20084     }
20085   node = vat_json_array_add (&vam->json_tree);
20086
20087   vat_json_init_object (node);
20088   vat_json_object_add_uint (node, "rx_sw_if_index",
20089                             ntohl (mp->rx_sw_if_index));
20090   vat_json_object_add_uint (node, "tx_sw_if_index",
20091                             ntohl (mp->tx_sw_if_index));
20092 }
20093
20094 static int
20095 api_l2_xconnect_dump (vat_main_t * vam)
20096 {
20097   vl_api_l2_xconnect_dump_t *mp;
20098   vl_api_control_ping_t *mp_ping;
20099   int ret;
20100
20101   if (!vam->json_output)
20102     {
20103       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20104     }
20105
20106   M (L2_XCONNECT_DUMP, mp);
20107
20108   S (mp);
20109
20110   /* Use a control ping for synchronization */
20111   MPING (CONTROL_PING, mp_ping);
20112   S (mp_ping);
20113
20114   W (ret);
20115   return ret;
20116 }
20117
20118 static int
20119 api_hw_interface_set_mtu (vat_main_t * vam)
20120 {
20121   unformat_input_t *i = vam->input;
20122   vl_api_hw_interface_set_mtu_t *mp;
20123   u32 sw_if_index = ~0;
20124   u32 mtu = 0;
20125   int ret;
20126
20127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20128     {
20129       if (unformat (i, "mtu %d", &mtu))
20130         ;
20131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20132         ;
20133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20134         ;
20135       else
20136         break;
20137     }
20138
20139   if (sw_if_index == ~0)
20140     {
20141       errmsg ("missing interface name or sw_if_index");
20142       return -99;
20143     }
20144
20145   if (mtu == 0)
20146     {
20147       errmsg ("no mtu specified");
20148       return -99;
20149     }
20150
20151   /* Construct the API message */
20152   M (HW_INTERFACE_SET_MTU, mp);
20153   mp->sw_if_index = ntohl (sw_if_index);
20154   mp->mtu = ntohs ((u16) mtu);
20155
20156   S (mp);
20157   W (ret);
20158   return ret;
20159 }
20160
20161 static int
20162 api_p2p_ethernet_add (vat_main_t * vam)
20163 {
20164   unformat_input_t *i = vam->input;
20165   vl_api_p2p_ethernet_add_t *mp;
20166   u32 parent_if_index = ~0;
20167   u32 sub_id = ~0;
20168   u8 remote_mac[6];
20169   u8 mac_set = 0;
20170   int ret;
20171
20172   clib_memset (remote_mac, 0, sizeof (remote_mac));
20173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20174     {
20175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20176         ;
20177       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20178         ;
20179       else
20180         if (unformat
20181             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20182         mac_set++;
20183       else if (unformat (i, "sub_id %d", &sub_id))
20184         ;
20185       else
20186         {
20187           clib_warning ("parse error '%U'", format_unformat_error, i);
20188           return -99;
20189         }
20190     }
20191
20192   if (parent_if_index == ~0)
20193     {
20194       errmsg ("missing interface name or sw_if_index");
20195       return -99;
20196     }
20197   if (mac_set == 0)
20198     {
20199       errmsg ("missing remote mac address");
20200       return -99;
20201     }
20202   if (sub_id == ~0)
20203     {
20204       errmsg ("missing sub-interface id");
20205       return -99;
20206     }
20207
20208   M (P2P_ETHERNET_ADD, mp);
20209   mp->parent_if_index = ntohl (parent_if_index);
20210   mp->subif_id = ntohl (sub_id);
20211   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20212
20213   S (mp);
20214   W (ret);
20215   return ret;
20216 }
20217
20218 static int
20219 api_p2p_ethernet_del (vat_main_t * vam)
20220 {
20221   unformat_input_t *i = vam->input;
20222   vl_api_p2p_ethernet_del_t *mp;
20223   u32 parent_if_index = ~0;
20224   u8 remote_mac[6];
20225   u8 mac_set = 0;
20226   int ret;
20227
20228   clib_memset (remote_mac, 0, sizeof (remote_mac));
20229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20230     {
20231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20232         ;
20233       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20234         ;
20235       else
20236         if (unformat
20237             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20238         mac_set++;
20239       else
20240         {
20241           clib_warning ("parse error '%U'", format_unformat_error, i);
20242           return -99;
20243         }
20244     }
20245
20246   if (parent_if_index == ~0)
20247     {
20248       errmsg ("missing interface name or sw_if_index");
20249       return -99;
20250     }
20251   if (mac_set == 0)
20252     {
20253       errmsg ("missing remote mac address");
20254       return -99;
20255     }
20256
20257   M (P2P_ETHERNET_DEL, mp);
20258   mp->parent_if_index = ntohl (parent_if_index);
20259   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20260
20261   S (mp);
20262   W (ret);
20263   return ret;
20264 }
20265
20266 static int
20267 api_lldp_config (vat_main_t * vam)
20268 {
20269   unformat_input_t *i = vam->input;
20270   vl_api_lldp_config_t *mp;
20271   int tx_hold = 0;
20272   int tx_interval = 0;
20273   u8 *sys_name = NULL;
20274   int ret;
20275
20276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20277     {
20278       if (unformat (i, "system-name %s", &sys_name))
20279         ;
20280       else if (unformat (i, "tx-hold %d", &tx_hold))
20281         ;
20282       else if (unformat (i, "tx-interval %d", &tx_interval))
20283         ;
20284       else
20285         {
20286           clib_warning ("parse error '%U'", format_unformat_error, i);
20287           return -99;
20288         }
20289     }
20290
20291   vec_add1 (sys_name, 0);
20292
20293   M (LLDP_CONFIG, mp);
20294   mp->tx_hold = htonl (tx_hold);
20295   mp->tx_interval = htonl (tx_interval);
20296   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20297   vec_free (sys_name);
20298
20299   S (mp);
20300   W (ret);
20301   return ret;
20302 }
20303
20304 static int
20305 api_sw_interface_set_lldp (vat_main_t * vam)
20306 {
20307   unformat_input_t *i = vam->input;
20308   vl_api_sw_interface_set_lldp_t *mp;
20309   u32 sw_if_index = ~0;
20310   u32 enable = 1;
20311   u8 *port_desc = NULL, *mgmt_oid = NULL;
20312   ip4_address_t ip4_addr;
20313   ip6_address_t ip6_addr;
20314   int ret;
20315
20316   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20317   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20318
20319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20320     {
20321       if (unformat (i, "disable"))
20322         enable = 0;
20323       else
20324         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20325         ;
20326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20327         ;
20328       else if (unformat (i, "port-desc %s", &port_desc))
20329         ;
20330       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20331         ;
20332       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20333         ;
20334       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20335         ;
20336       else
20337         break;
20338     }
20339
20340   if (sw_if_index == ~0)
20341     {
20342       errmsg ("missing interface name or sw_if_index");
20343       return -99;
20344     }
20345
20346   /* Construct the API message */
20347   vec_add1 (port_desc, 0);
20348   vec_add1 (mgmt_oid, 0);
20349   M (SW_INTERFACE_SET_LLDP, mp);
20350   mp->sw_if_index = ntohl (sw_if_index);
20351   mp->enable = enable;
20352   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20353   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20354   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20355   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20356   vec_free (port_desc);
20357   vec_free (mgmt_oid);
20358
20359   S (mp);
20360   W (ret);
20361   return ret;
20362 }
20363
20364 static int
20365 api_tcp_configure_src_addresses (vat_main_t * vam)
20366 {
20367   vl_api_tcp_configure_src_addresses_t *mp;
20368   unformat_input_t *i = vam->input;
20369   ip4_address_t v4first, v4last;
20370   ip6_address_t v6first, v6last;
20371   u8 range_set = 0;
20372   u32 vrf_id = 0;
20373   int ret;
20374
20375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20376     {
20377       if (unformat (i, "%U - %U",
20378                     unformat_ip4_address, &v4first,
20379                     unformat_ip4_address, &v4last))
20380         {
20381           if (range_set)
20382             {
20383               errmsg ("one range per message (range already set)");
20384               return -99;
20385             }
20386           range_set = 1;
20387         }
20388       else if (unformat (i, "%U - %U",
20389                          unformat_ip6_address, &v6first,
20390                          unformat_ip6_address, &v6last))
20391         {
20392           if (range_set)
20393             {
20394               errmsg ("one range per message (range already set)");
20395               return -99;
20396             }
20397           range_set = 2;
20398         }
20399       else if (unformat (i, "vrf %d", &vrf_id))
20400         ;
20401       else
20402         break;
20403     }
20404
20405   if (range_set == 0)
20406     {
20407       errmsg ("address range not set");
20408       return -99;
20409     }
20410
20411   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20412   mp->vrf_id = ntohl (vrf_id);
20413   /* ipv6? */
20414   if (range_set == 2)
20415     {
20416       mp->is_ipv6 = 1;
20417       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20418       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20419     }
20420   else
20421     {
20422       mp->is_ipv6 = 0;
20423       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20424       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20425     }
20426   S (mp);
20427   W (ret);
20428   return ret;
20429 }
20430
20431 static void vl_api_app_namespace_add_del_reply_t_handler
20432   (vl_api_app_namespace_add_del_reply_t * mp)
20433 {
20434   vat_main_t *vam = &vat_main;
20435   i32 retval = ntohl (mp->retval);
20436   if (vam->async_mode)
20437     {
20438       vam->async_errors += (retval < 0);
20439     }
20440   else
20441     {
20442       vam->retval = retval;
20443       if (retval == 0)
20444         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20445       vam->result_ready = 1;
20446     }
20447 }
20448
20449 static void vl_api_app_namespace_add_del_reply_t_handler_json
20450   (vl_api_app_namespace_add_del_reply_t * mp)
20451 {
20452   vat_main_t *vam = &vat_main;
20453   vat_json_node_t node;
20454
20455   vat_json_init_object (&node);
20456   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20457   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20458
20459   vat_json_print (vam->ofp, &node);
20460   vat_json_free (&node);
20461
20462   vam->retval = ntohl (mp->retval);
20463   vam->result_ready = 1;
20464 }
20465
20466 static int
20467 api_app_namespace_add_del (vat_main_t * vam)
20468 {
20469   vl_api_app_namespace_add_del_t *mp;
20470   unformat_input_t *i = vam->input;
20471   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20472   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20473   u64 secret;
20474   int ret;
20475
20476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20477     {
20478       if (unformat (i, "id %_%v%_", &ns_id))
20479         ;
20480       else if (unformat (i, "secret %lu", &secret))
20481         secret_set = 1;
20482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20483         sw_if_index_set = 1;
20484       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20485         ;
20486       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20487         ;
20488       else
20489         break;
20490     }
20491   if (!ns_id || !secret_set || !sw_if_index_set)
20492     {
20493       errmsg ("namespace id, secret and sw_if_index must be set");
20494       return -99;
20495     }
20496   if (vec_len (ns_id) > 64)
20497     {
20498       errmsg ("namespace id too long");
20499       return -99;
20500     }
20501   M (APP_NAMESPACE_ADD_DEL, mp);
20502
20503   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20504   mp->namespace_id_len = vec_len (ns_id);
20505   mp->secret = clib_host_to_net_u64 (secret);
20506   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20507   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20508   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20509   vec_free (ns_id);
20510   S (mp);
20511   W (ret);
20512   return ret;
20513 }
20514
20515 static int
20516 api_sock_init_shm (vat_main_t * vam)
20517 {
20518 #if VPP_API_TEST_BUILTIN == 0
20519   unformat_input_t *i = vam->input;
20520   vl_api_shm_elem_config_t *config = 0;
20521   u64 size = 64 << 20;
20522   int rv;
20523
20524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20525     {
20526       if (unformat (i, "size %U", unformat_memory_size, &size))
20527         ;
20528       else
20529         break;
20530     }
20531
20532   /*
20533    * Canned custom ring allocator config.
20534    * Should probably parse all of this
20535    */
20536   vec_validate (config, 6);
20537   config[0].type = VL_API_VLIB_RING;
20538   config[0].size = 256;
20539   config[0].count = 32;
20540
20541   config[1].type = VL_API_VLIB_RING;
20542   config[1].size = 1024;
20543   config[1].count = 16;
20544
20545   config[2].type = VL_API_VLIB_RING;
20546   config[2].size = 4096;
20547   config[2].count = 2;
20548
20549   config[3].type = VL_API_CLIENT_RING;
20550   config[3].size = 256;
20551   config[3].count = 32;
20552
20553   config[4].type = VL_API_CLIENT_RING;
20554   config[4].size = 1024;
20555   config[4].count = 16;
20556
20557   config[5].type = VL_API_CLIENT_RING;
20558   config[5].size = 4096;
20559   config[5].count = 2;
20560
20561   config[6].type = VL_API_QUEUE;
20562   config[6].count = 128;
20563   config[6].size = sizeof (uword);
20564
20565   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20566   if (!rv)
20567     vam->client_index_invalid = 1;
20568   return rv;
20569 #else
20570   return -99;
20571 #endif
20572 }
20573
20574 static void
20575 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20576 {
20577   vat_main_t *vam = &vat_main;
20578
20579   if (mp->is_ip4)
20580     {
20581       print (vam->ofp,
20582              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20583              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20584              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20585              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20586              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20587              clib_net_to_host_u32 (mp->action_index), mp->tag);
20588     }
20589   else
20590     {
20591       print (vam->ofp,
20592              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20593              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20594              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20595              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20596              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20597              clib_net_to_host_u32 (mp->action_index), mp->tag);
20598     }
20599 }
20600
20601 static void
20602 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20603                                              mp)
20604 {
20605   vat_main_t *vam = &vat_main;
20606   vat_json_node_t *node = NULL;
20607   struct in6_addr ip6;
20608   struct in_addr ip4;
20609
20610   if (VAT_JSON_ARRAY != vam->json_tree.type)
20611     {
20612       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20613       vat_json_init_array (&vam->json_tree);
20614     }
20615   node = vat_json_array_add (&vam->json_tree);
20616   vat_json_init_object (node);
20617
20618   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20619   vat_json_object_add_uint (node, "appns_index",
20620                             clib_net_to_host_u32 (mp->appns_index));
20621   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20622   vat_json_object_add_uint (node, "scope", mp->scope);
20623   vat_json_object_add_uint (node, "action_index",
20624                             clib_net_to_host_u32 (mp->action_index));
20625   vat_json_object_add_uint (node, "lcl_port",
20626                             clib_net_to_host_u16 (mp->lcl_port));
20627   vat_json_object_add_uint (node, "rmt_port",
20628                             clib_net_to_host_u16 (mp->rmt_port));
20629   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20630   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20631   vat_json_object_add_string_copy (node, "tag", mp->tag);
20632   if (mp->is_ip4)
20633     {
20634       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20635       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20636       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20637       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20638     }
20639   else
20640     {
20641       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20642       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20643       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20644       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20645     }
20646 }
20647
20648 static int
20649 api_session_rule_add_del (vat_main_t * vam)
20650 {
20651   vl_api_session_rule_add_del_t *mp;
20652   unformat_input_t *i = vam->input;
20653   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20654   u32 appns_index = 0, scope = 0;
20655   ip4_address_t lcl_ip4, rmt_ip4;
20656   ip6_address_t lcl_ip6, rmt_ip6;
20657   u8 is_ip4 = 1, conn_set = 0;
20658   u8 is_add = 1, *tag = 0;
20659   int ret;
20660
20661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20662     {
20663       if (unformat (i, "del"))
20664         is_add = 0;
20665       else if (unformat (i, "add"))
20666         ;
20667       else if (unformat (i, "proto tcp"))
20668         proto = 0;
20669       else if (unformat (i, "proto udp"))
20670         proto = 1;
20671       else if (unformat (i, "appns %d", &appns_index))
20672         ;
20673       else if (unformat (i, "scope %d", &scope))
20674         ;
20675       else if (unformat (i, "tag %_%v%_", &tag))
20676         ;
20677       else
20678         if (unformat
20679             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20680              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20681              &rmt_port))
20682         {
20683           is_ip4 = 1;
20684           conn_set = 1;
20685         }
20686       else
20687         if (unformat
20688             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20689              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20690              &rmt_port))
20691         {
20692           is_ip4 = 0;
20693           conn_set = 1;
20694         }
20695       else if (unformat (i, "action %d", &action))
20696         ;
20697       else
20698         break;
20699     }
20700   if (proto == ~0 || !conn_set || action == ~0)
20701     {
20702       errmsg ("transport proto, connection and action must be set");
20703       return -99;
20704     }
20705
20706   if (scope > 3)
20707     {
20708       errmsg ("scope should be 0-3");
20709       return -99;
20710     }
20711
20712   M (SESSION_RULE_ADD_DEL, mp);
20713
20714   mp->is_ip4 = is_ip4;
20715   mp->transport_proto = proto;
20716   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20717   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20718   mp->lcl_plen = lcl_plen;
20719   mp->rmt_plen = rmt_plen;
20720   mp->action_index = clib_host_to_net_u32 (action);
20721   mp->appns_index = clib_host_to_net_u32 (appns_index);
20722   mp->scope = scope;
20723   mp->is_add = is_add;
20724   if (is_ip4)
20725     {
20726       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20727       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20728     }
20729   else
20730     {
20731       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20732       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20733     }
20734   if (tag)
20735     {
20736       clib_memcpy (mp->tag, tag, vec_len (tag));
20737       vec_free (tag);
20738     }
20739
20740   S (mp);
20741   W (ret);
20742   return ret;
20743 }
20744
20745 static int
20746 api_session_rules_dump (vat_main_t * vam)
20747 {
20748   vl_api_session_rules_dump_t *mp;
20749   vl_api_control_ping_t *mp_ping;
20750   int ret;
20751
20752   if (!vam->json_output)
20753     {
20754       print (vam->ofp, "%=20s", "Session Rules");
20755     }
20756
20757   M (SESSION_RULES_DUMP, mp);
20758   /* send it... */
20759   S (mp);
20760
20761   /* Use a control ping for synchronization */
20762   MPING (CONTROL_PING, mp_ping);
20763   S (mp_ping);
20764
20765   /* Wait for a reply... */
20766   W (ret);
20767   return ret;
20768 }
20769
20770 static int
20771 api_ip_container_proxy_add_del (vat_main_t * vam)
20772 {
20773   vl_api_ip_container_proxy_add_del_t *mp;
20774   unformat_input_t *i = vam->input;
20775   u32 sw_if_index = ~0;
20776   vl_api_prefix_t pfx = { };
20777   u8 is_add = 1;
20778   int ret;
20779
20780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20781     {
20782       if (unformat (i, "del"))
20783         is_add = 0;
20784       else if (unformat (i, "add"))
20785         ;
20786       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20787         ;
20788       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20789         ;
20790       else
20791         break;
20792     }
20793   if (sw_if_index == ~0 || pfx.len == 0)
20794     {
20795       errmsg ("address and sw_if_index must be set");
20796       return -99;
20797     }
20798
20799   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20800
20801   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20802   mp->is_add = is_add;
20803   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20804
20805   S (mp);
20806   W (ret);
20807   return ret;
20808 }
20809
20810 static int
20811 api_qos_record_enable_disable (vat_main_t * vam)
20812 {
20813   unformat_input_t *i = vam->input;
20814   vl_api_qos_record_enable_disable_t *mp;
20815   u32 sw_if_index, qs = 0xff;
20816   u8 sw_if_index_set = 0;
20817   u8 enable = 1;
20818   int ret;
20819
20820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20821     {
20822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20823         sw_if_index_set = 1;
20824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20825         sw_if_index_set = 1;
20826       else if (unformat (i, "%U", unformat_qos_source, &qs))
20827         ;
20828       else if (unformat (i, "disable"))
20829         enable = 0;
20830       else
20831         {
20832           clib_warning ("parse error '%U'", format_unformat_error, i);
20833           return -99;
20834         }
20835     }
20836
20837   if (sw_if_index_set == 0)
20838     {
20839       errmsg ("missing interface name or sw_if_index");
20840       return -99;
20841     }
20842   if (qs == 0xff)
20843     {
20844       errmsg ("input location must be specified");
20845       return -99;
20846     }
20847
20848   M (QOS_RECORD_ENABLE_DISABLE, mp);
20849
20850   mp->record.sw_if_index = ntohl (sw_if_index);
20851   mp->record.input_source = qs;
20852   mp->enable = enable;
20853
20854   S (mp);
20855   W (ret);
20856   return ret;
20857 }
20858
20859
20860 static int
20861 q_or_quit (vat_main_t * vam)
20862 {
20863 #if VPP_API_TEST_BUILTIN == 0
20864   longjmp (vam->jump_buf, 1);
20865 #endif
20866   return 0;                     /* not so much */
20867 }
20868
20869 static int
20870 q (vat_main_t * vam)
20871 {
20872   return q_or_quit (vam);
20873 }
20874
20875 static int
20876 quit (vat_main_t * vam)
20877 {
20878   return q_or_quit (vam);
20879 }
20880
20881 static int
20882 comment (vat_main_t * vam)
20883 {
20884   return 0;
20885 }
20886
20887 static int
20888 elog_save (vat_main_t * vam)
20889 {
20890 #if VPP_API_TEST_BUILTIN == 0
20891   elog_main_t *em = &vam->elog_main;
20892   unformat_input_t *i = vam->input;
20893   char *file, *chroot_file;
20894   clib_error_t *error;
20895
20896   if (!unformat (i, "%s", &file))
20897     {
20898       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20899       return 0;
20900     }
20901
20902   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20903   if (strstr (file, "..") || index (file, '/'))
20904     {
20905       errmsg ("illegal characters in filename '%s'", file);
20906       return 0;
20907     }
20908
20909   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20910
20911   vec_free (file);
20912
20913   errmsg ("Saving %wd of %wd events to %s",
20914           elog_n_events_in_buffer (em),
20915           elog_buffer_capacity (em), chroot_file);
20916
20917   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20918   vec_free (chroot_file);
20919
20920   if (error)
20921     clib_error_report (error);
20922 #else
20923   errmsg ("Use the vpp event loger...");
20924 #endif
20925
20926   return 0;
20927 }
20928
20929 static int
20930 elog_setup (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   u32 nevents = 128 << 10;
20936
20937   (void) unformat (i, "nevents %d", &nevents);
20938
20939   elog_init (em, nevents);
20940   vl_api_set_elog_main (em);
20941   vl_api_set_elog_trace_api_messages (1);
20942   errmsg ("Event logger initialized with %u events", nevents);
20943 #else
20944   errmsg ("Use the vpp event loger...");
20945 #endif
20946   return 0;
20947 }
20948
20949 static int
20950 elog_enable (vat_main_t * vam)
20951 {
20952 #if VPP_API_TEST_BUILTIN == 0
20953   elog_main_t *em = &vam->elog_main;
20954
20955   elog_enable_disable (em, 1 /* enable */ );
20956   vl_api_set_elog_trace_api_messages (1);
20957   errmsg ("Event logger enabled...");
20958 #else
20959   errmsg ("Use the vpp event loger...");
20960 #endif
20961   return 0;
20962 }
20963
20964 static int
20965 elog_disable (vat_main_t * vam)
20966 {
20967 #if VPP_API_TEST_BUILTIN == 0
20968   elog_main_t *em = &vam->elog_main;
20969
20970   elog_enable_disable (em, 0 /* enable */ );
20971   vl_api_set_elog_trace_api_messages (1);
20972   errmsg ("Event logger disabled...");
20973 #else
20974   errmsg ("Use the vpp event loger...");
20975 #endif
20976   return 0;
20977 }
20978
20979 static int
20980 statseg (vat_main_t * vam)
20981 {
20982   ssvm_private_t *ssvmp = &vam->stat_segment;
20983   ssvm_shared_header_t *shared_header = ssvmp->sh;
20984   vlib_counter_t **counters;
20985   u64 thread0_index1_packets;
20986   u64 thread0_index1_bytes;
20987   f64 vector_rate, input_rate;
20988   uword *p;
20989
20990   uword *counter_vector_by_name;
20991   if (vam->stat_segment_lockp == 0)
20992     {
20993       errmsg ("Stat segment not mapped...");
20994       return -99;
20995     }
20996
20997   /* look up "/if/rx for sw_if_index 1 as a test */
20998
20999   clib_spinlock_lock (vam->stat_segment_lockp);
21000
21001   counter_vector_by_name = (uword *) shared_header->opaque[1];
21002
21003   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21004   if (p == 0)
21005     {
21006       clib_spinlock_unlock (vam->stat_segment_lockp);
21007       errmsg ("/if/tx not found?");
21008       return -99;
21009     }
21010
21011   /* Fish per-thread vector of combined counters from shared memory */
21012   counters = (vlib_counter_t **) p[0];
21013
21014   if (vec_len (counters[0]) < 2)
21015     {
21016       clib_spinlock_unlock (vam->stat_segment_lockp);
21017       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21018       return -99;
21019     }
21020
21021   /* Read thread 0 sw_if_index 1 counter */
21022   thread0_index1_packets = counters[0][1].packets;
21023   thread0_index1_bytes = counters[0][1].bytes;
21024
21025   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21026   if (p == 0)
21027     {
21028       clib_spinlock_unlock (vam->stat_segment_lockp);
21029       errmsg ("vector_rate not found?");
21030       return -99;
21031     }
21032
21033   vector_rate = *(f64 *) (p[0]);
21034   p = hash_get_mem (counter_vector_by_name, "input_rate");
21035   if (p == 0)
21036     {
21037       clib_spinlock_unlock (vam->stat_segment_lockp);
21038       errmsg ("input_rate not found?");
21039       return -99;
21040     }
21041   input_rate = *(f64 *) (p[0]);
21042
21043   clib_spinlock_unlock (vam->stat_segment_lockp);
21044
21045   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21046          vector_rate, input_rate);
21047   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21048          thread0_index1_packets, thread0_index1_bytes);
21049
21050   return 0;
21051 }
21052
21053 static int
21054 cmd_cmp (void *a1, void *a2)
21055 {
21056   u8 **c1 = a1;
21057   u8 **c2 = a2;
21058
21059   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21060 }
21061
21062 static int
21063 help (vat_main_t * vam)
21064 {
21065   u8 **cmds = 0;
21066   u8 *name = 0;
21067   hash_pair_t *p;
21068   unformat_input_t *i = vam->input;
21069   int j;
21070
21071   if (unformat (i, "%s", &name))
21072     {
21073       uword *hs;
21074
21075       vec_add1 (name, 0);
21076
21077       hs = hash_get_mem (vam->help_by_name, name);
21078       if (hs)
21079         print (vam->ofp, "usage: %s %s", name, hs[0]);
21080       else
21081         print (vam->ofp, "No such msg / command '%s'", name);
21082       vec_free (name);
21083       return 0;
21084     }
21085
21086   print (vam->ofp, "Help is available for the following:");
21087
21088     /* *INDENT-OFF* */
21089     hash_foreach_pair (p, vam->function_by_name,
21090     ({
21091       vec_add1 (cmds, (u8 *)(p->key));
21092     }));
21093     /* *INDENT-ON* */
21094
21095   vec_sort_with_function (cmds, cmd_cmp);
21096
21097   for (j = 0; j < vec_len (cmds); j++)
21098     print (vam->ofp, "%s", cmds[j]);
21099
21100   vec_free (cmds);
21101   return 0;
21102 }
21103
21104 static int
21105 set (vat_main_t * vam)
21106 {
21107   u8 *name = 0, *value = 0;
21108   unformat_input_t *i = vam->input;
21109
21110   if (unformat (i, "%s", &name))
21111     {
21112       /* The input buffer is a vector, not a string. */
21113       value = vec_dup (i->buffer);
21114       vec_delete (value, i->index, 0);
21115       /* Almost certainly has a trailing newline */
21116       if (value[vec_len (value) - 1] == '\n')
21117         value[vec_len (value) - 1] = 0;
21118       /* Make sure it's a proper string, one way or the other */
21119       vec_add1 (value, 0);
21120       (void) clib_macro_set_value (&vam->macro_main,
21121                                    (char *) name, (char *) value);
21122     }
21123   else
21124     errmsg ("usage: set <name> <value>");
21125
21126   vec_free (name);
21127   vec_free (value);
21128   return 0;
21129 }
21130
21131 static int
21132 unset (vat_main_t * vam)
21133 {
21134   u8 *name = 0;
21135
21136   if (unformat (vam->input, "%s", &name))
21137     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21138       errmsg ("unset: %s wasn't set", name);
21139   vec_free (name);
21140   return 0;
21141 }
21142
21143 typedef struct
21144 {
21145   u8 *name;
21146   u8 *value;
21147 } macro_sort_t;
21148
21149
21150 static int
21151 macro_sort_cmp (void *a1, void *a2)
21152 {
21153   macro_sort_t *s1 = a1;
21154   macro_sort_t *s2 = a2;
21155
21156   return strcmp ((char *) (s1->name), (char *) (s2->name));
21157 }
21158
21159 static int
21160 dump_macro_table (vat_main_t * vam)
21161 {
21162   macro_sort_t *sort_me = 0, *sm;
21163   int i;
21164   hash_pair_t *p;
21165
21166     /* *INDENT-OFF* */
21167     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21168     ({
21169       vec_add2 (sort_me, sm, 1);
21170       sm->name = (u8 *)(p->key);
21171       sm->value = (u8 *) (p->value[0]);
21172     }));
21173     /* *INDENT-ON* */
21174
21175   vec_sort_with_function (sort_me, macro_sort_cmp);
21176
21177   if (vec_len (sort_me))
21178     print (vam->ofp, "%-15s%s", "Name", "Value");
21179   else
21180     print (vam->ofp, "The macro table is empty...");
21181
21182   for (i = 0; i < vec_len (sort_me); i++)
21183     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21184   return 0;
21185 }
21186
21187 static int
21188 dump_node_table (vat_main_t * vam)
21189 {
21190   int i, j;
21191   vlib_node_t *node, *next_node;
21192
21193   if (vec_len (vam->graph_nodes) == 0)
21194     {
21195       print (vam->ofp, "Node table empty, issue get_node_graph...");
21196       return 0;
21197     }
21198
21199   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21200     {
21201       node = vam->graph_nodes[0][i];
21202       print (vam->ofp, "[%d] %s", i, node->name);
21203       for (j = 0; j < vec_len (node->next_nodes); j++)
21204         {
21205           if (node->next_nodes[j] != ~0)
21206             {
21207               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21208               print (vam->ofp, "  [%d] %s", j, next_node->name);
21209             }
21210         }
21211     }
21212   return 0;
21213 }
21214
21215 static int
21216 value_sort_cmp (void *a1, void *a2)
21217 {
21218   name_sort_t *n1 = a1;
21219   name_sort_t *n2 = a2;
21220
21221   if (n1->value < n2->value)
21222     return -1;
21223   if (n1->value > n2->value)
21224     return 1;
21225   return 0;
21226 }
21227
21228
21229 static int
21230 dump_msg_api_table (vat_main_t * vam)
21231 {
21232   api_main_t *am = &api_main;
21233   name_sort_t *nses = 0, *ns;
21234   hash_pair_t *hp;
21235   int i;
21236
21237   /* *INDENT-OFF* */
21238   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21239   ({
21240     vec_add2 (nses, ns, 1);
21241     ns->name = (u8 *)(hp->key);
21242     ns->value = (u32) hp->value[0];
21243   }));
21244   /* *INDENT-ON* */
21245
21246   vec_sort_with_function (nses, value_sort_cmp);
21247
21248   for (i = 0; i < vec_len (nses); i++)
21249     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21250   vec_free (nses);
21251   return 0;
21252 }
21253
21254 static int
21255 get_msg_id (vat_main_t * vam)
21256 {
21257   u8 *name_and_crc;
21258   u32 message_index;
21259
21260   if (unformat (vam->input, "%s", &name_and_crc))
21261     {
21262       message_index = vl_msg_api_get_msg_index (name_and_crc);
21263       if (message_index == ~0)
21264         {
21265           print (vam->ofp, " '%s' not found", name_and_crc);
21266           return 0;
21267         }
21268       print (vam->ofp, " '%s' has message index %d",
21269              name_and_crc, message_index);
21270       return 0;
21271     }
21272   errmsg ("name_and_crc required...");
21273   return 0;
21274 }
21275
21276 static int
21277 search_node_table (vat_main_t * vam)
21278 {
21279   unformat_input_t *line_input = vam->input;
21280   u8 *node_to_find;
21281   int j;
21282   vlib_node_t *node, *next_node;
21283   uword *p;
21284
21285   if (vam->graph_node_index_by_name == 0)
21286     {
21287       print (vam->ofp, "Node table empty, issue get_node_graph...");
21288       return 0;
21289     }
21290
21291   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21292     {
21293       if (unformat (line_input, "%s", &node_to_find))
21294         {
21295           vec_add1 (node_to_find, 0);
21296           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21297           if (p == 0)
21298             {
21299               print (vam->ofp, "%s not found...", node_to_find);
21300               goto out;
21301             }
21302           node = vam->graph_nodes[0][p[0]];
21303           print (vam->ofp, "[%d] %s", p[0], node->name);
21304           for (j = 0; j < vec_len (node->next_nodes); j++)
21305             {
21306               if (node->next_nodes[j] != ~0)
21307                 {
21308                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21309                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21310                 }
21311             }
21312         }
21313
21314       else
21315         {
21316           clib_warning ("parse error '%U'", format_unformat_error,
21317                         line_input);
21318           return -99;
21319         }
21320
21321     out:
21322       vec_free (node_to_find);
21323
21324     }
21325
21326   return 0;
21327 }
21328
21329
21330 static int
21331 script (vat_main_t * vam)
21332 {
21333 #if (VPP_API_TEST_BUILTIN==0)
21334   u8 *s = 0;
21335   char *save_current_file;
21336   unformat_input_t save_input;
21337   jmp_buf save_jump_buf;
21338   u32 save_line_number;
21339
21340   FILE *new_fp, *save_ifp;
21341
21342   if (unformat (vam->input, "%s", &s))
21343     {
21344       new_fp = fopen ((char *) s, "r");
21345       if (new_fp == 0)
21346         {
21347           errmsg ("Couldn't open script file %s", s);
21348           vec_free (s);
21349           return -99;
21350         }
21351     }
21352   else
21353     {
21354       errmsg ("Missing script name");
21355       return -99;
21356     }
21357
21358   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21359   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21360   save_ifp = vam->ifp;
21361   save_line_number = vam->input_line_number;
21362   save_current_file = (char *) vam->current_file;
21363
21364   vam->input_line_number = 0;
21365   vam->ifp = new_fp;
21366   vam->current_file = s;
21367   do_one_file (vam);
21368
21369   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21370   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21371   vam->ifp = save_ifp;
21372   vam->input_line_number = save_line_number;
21373   vam->current_file = (u8 *) save_current_file;
21374   vec_free (s);
21375
21376   return 0;
21377 #else
21378   clib_warning ("use the exec command...");
21379   return -99;
21380 #endif
21381 }
21382
21383 static int
21384 echo (vat_main_t * vam)
21385 {
21386   print (vam->ofp, "%v", vam->input->buffer);
21387   return 0;
21388 }
21389
21390 /* List of API message constructors, CLI names map to api_xxx */
21391 #define foreach_vpe_api_msg                                             \
21392 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21393 _(sw_interface_dump,"")                                                 \
21394 _(sw_interface_set_flags,                                               \
21395   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21396 _(sw_interface_add_del_address,                                         \
21397   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21398 _(sw_interface_set_rx_mode,                                             \
21399   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21400 _(sw_interface_set_rx_placement,                                        \
21401   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21402 _(sw_interface_rx_placement_dump,                                       \
21403   "[<intfc> | sw_if_index <id>]")                                         \
21404 _(sw_interface_set_table,                                               \
21405   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21406 _(sw_interface_set_mpls_enable,                                         \
21407   "<intfc> | sw_if_index [disable | dis]")                              \
21408 _(sw_interface_set_vpath,                                               \
21409   "<intfc> | sw_if_index <id> enable | disable")                        \
21410 _(sw_interface_set_vxlan_bypass,                                        \
21411   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21412 _(sw_interface_set_geneve_bypass,                                       \
21413   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21414 _(sw_interface_set_l2_xconnect,                                         \
21415   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21416   "enable | disable")                                                   \
21417 _(sw_interface_set_l2_bridge,                                           \
21418   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21419   "[shg <split-horizon-group>] [bvi]\n"                                 \
21420   "enable | disable")                                                   \
21421 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21422 _(bridge_domain_add_del,                                                \
21423   "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") \
21424 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21425 _(l2fib_add_del,                                                        \
21426   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21427 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21428 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21429 _(l2_flags,                                                             \
21430   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21431 _(bridge_flags,                                                         \
21432   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21433 _(tap_create_v2,                                                        \
21434   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21435 _(tap_delete_v2,                                                        \
21436   "<vpp-if-name> | sw_if_index <id>")                                   \
21437 _(sw_interface_tap_v2_dump, "")                                         \
21438 _(virtio_pci_create,                                                    \
21439   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21440 _(virtio_pci_delete,                                                    \
21441   "<vpp-if-name> | sw_if_index <id>")                                   \
21442 _(sw_interface_virtio_pci_dump, "")                                     \
21443 _(bond_create,                                                          \
21444   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21445   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21446   "[id <if-id>]")                                                       \
21447 _(bond_delete,                                                          \
21448   "<vpp-if-name> | sw_if_index <id>")                                   \
21449 _(bond_enslave,                                                         \
21450   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21451 _(bond_detach_slave,                                                    \
21452   "sw_if_index <n>")                                                    \
21453  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21454 _(sw_interface_bond_dump, "")                                           \
21455 _(sw_interface_slave_dump,                                              \
21456   "<vpp-if-name> | sw_if_index <id>")                                   \
21457 _(ip_table_add_del,                                                     \
21458   "table <n> [ipv6] [add | del]\n")                                     \
21459 _(ip_route_add_del,                                                     \
21460   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21461   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21462   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21463   "[multipath] [count <n>] [del]")                                      \
21464 _(ip_mroute_add_del,                                                    \
21465   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21466   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21467 _(mpls_table_add_del,                                                   \
21468   "table <n> [add | del]\n")                                            \
21469 _(mpls_route_add_del,                                                   \
21470   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21471   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21472   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21473   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21474   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21475   "[count <n>] [del]")                                                  \
21476 _(mpls_ip_bind_unbind,                                                  \
21477   "<label> <addr/len>")                                                 \
21478 _(mpls_tunnel_add_del,                                                  \
21479   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21480   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21481   "[l2-only]  [out-label <n>]")                                         \
21482 _(sr_mpls_policy_add,                                                   \
21483   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21484 _(sr_mpls_policy_del,                                                   \
21485   "bsid <id>")                                                          \
21486 _(bier_table_add_del,                                                   \
21487   "<label> <sub-domain> <set> <bsl> [del]")                             \
21488 _(bier_route_add_del,                                                   \
21489   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21490   "[<intfc> | sw_if_index <id>]"                                        \
21491   "[weight <n>] [del] [multipath]")                                     \
21492 _(proxy_arp_add_del,                                                    \
21493   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21494 _(proxy_arp_intfc_enable_disable,                                       \
21495   "<intfc> | sw_if_index <id> enable | disable")                        \
21496 _(sw_interface_set_unnumbered,                                          \
21497   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21498 _(ip_neighbor_add_del,                                                  \
21499   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21500   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21501 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21502 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21503   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21504   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21505   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21506 _(reset_fib, "vrf <n> [ipv6]")                                          \
21507 _(set_ip_flow_hash,                                                     \
21508   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21509 _(sw_interface_ip6_enable_disable,                                      \
21510   "<intfc> | sw_if_index <id> enable | disable")                        \
21511 _(ip6nd_proxy_add_del,                                                  \
21512   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21513 _(ip6nd_proxy_dump, "")                                                 \
21514 _(sw_interface_ip6nd_ra_prefix,                                         \
21515   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21516   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21517   "[nolink] [isno]")                                                    \
21518 _(sw_interface_ip6nd_ra_config,                                         \
21519   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21520   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21521   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21522 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21523 _(l2_patch_add_del,                                                     \
21524   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21525   "enable | disable")                                                   \
21526 _(sr_localsid_add_del,                                                  \
21527   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21528   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21529 _(classify_add_del_table,                                               \
21530   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21531   " [del] [del-chain] mask <mask-value>\n"                              \
21532   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21533   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21534 _(classify_add_del_session,                                             \
21535   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21536   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21537   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21538   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21539 _(classify_set_interface_ip_table,                                      \
21540   "<intfc> | sw_if_index <nn> table <nn>")                              \
21541 _(classify_set_interface_l2_tables,                                     \
21542   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21543   "  [other-table <nn>]")                                               \
21544 _(get_node_index, "node <node-name")                                    \
21545 _(add_node_next, "node <node-name> next <next-node-name>")              \
21546 _(l2tpv3_create_tunnel,                                                 \
21547   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21548   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21549   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21550 _(l2tpv3_set_tunnel_cookies,                                            \
21551   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21552   "[new_remote_cookie <nn>]\n")                                         \
21553 _(l2tpv3_interface_enable_disable,                                      \
21554   "<intfc> | sw_if_index <nn> enable | disable")                        \
21555 _(l2tpv3_set_lookup_key,                                                \
21556   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21557 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21558 _(vxlan_offload_rx,                                                     \
21559   "hw { <interface name> | hw_if_index <nn>} "                          \
21560   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21561 _(vxlan_add_del_tunnel,                                                 \
21562   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21563   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21564   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21565 _(geneve_add_del_tunnel,                                                \
21566   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21567   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21568   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21569 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21570 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21571 _(gre_tunnel_add_del,                                                   \
21572   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21573   "[teb | erspan <session-id>] [del]")                                  \
21574 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21575 _(l2_fib_clear_table, "")                                               \
21576 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21577 _(l2_interface_vlan_tag_rewrite,                                        \
21578   "<intfc> | sw_if_index <nn> \n"                                       \
21579   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21580   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21581 _(create_vhost_user_if,                                                 \
21582         "socket <filename> [server] [renumber <dev_instance>] "         \
21583         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21584         "[mac <mac_address>]")                                          \
21585 _(modify_vhost_user_if,                                                 \
21586         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21587         "[server] [renumber <dev_instance>] [gso]")                     \
21588 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21589 _(sw_interface_vhost_user_dump, "")                                     \
21590 _(show_version, "")                                                     \
21591 _(show_threads, "")                                                     \
21592 _(vxlan_gpe_add_del_tunnel,                                             \
21593   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21594   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21595   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21596   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21597 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21598 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21599 _(interface_name_renumber,                                              \
21600   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21601 _(input_acl_set_interface,                                              \
21602   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21603   "  [l2-table <nn>] [del]")                                            \
21604 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21605 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21606   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21607 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21608 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21609 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21610 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21611 _(ip_dump, "ipv4 | ipv6")                                               \
21612 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21613 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21614   "  spid_id <n> ")                                                     \
21615 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21616   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21617   "  integ_alg <alg> integ_key <hex>")                                  \
21618 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21619   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21620   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21621   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21622 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21623   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21624   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21625   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21626   "  [instance <n>]")     \
21627 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21628 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21629 _(delete_loopback,"sw_if_index <nn>")                                   \
21630 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21631 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21632 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21633 _(want_interface_events,  "enable|disable")                             \
21634 _(get_first_msg_id, "client <name>")                                    \
21635 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21636 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21637   "fib-id <nn> [ip4][ip6][default]")                                    \
21638 _(get_node_graph, " ")                                                  \
21639 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21640 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21641 _(ioam_disable, "")                                                     \
21642 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21643                             " sw_if_index <sw_if_index> p <priority> "  \
21644                             "w <weight>] [del]")                        \
21645 _(one_add_del_locator, "locator-set <locator_name> "                    \
21646                         "iface <intf> | sw_if_index <sw_if_index> "     \
21647                         "p <priority> w <weight> [del]")                \
21648 _(one_add_del_local_eid,"vni <vni> eid "                                \
21649                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21650                          "locator-set <locator_name> [del]"             \
21651                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21652 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21653 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21654 _(one_enable_disable, "enable|disable")                                 \
21655 _(one_map_register_enable_disable, "enable|disable")                    \
21656 _(one_map_register_fallback_threshold, "<value>")                       \
21657 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21658 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21659                                "[seid <seid>] "                         \
21660                                "rloc <locator> p <prio> "               \
21661                                "w <weight> [rloc <loc> ... ] "          \
21662                                "action <action> [del-all]")             \
21663 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21664                           "<local-eid>")                                \
21665 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21666 _(one_use_petr, "ip-address> | disable")                                \
21667 _(one_map_request_mode, "src-dst|dst-only")                             \
21668 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21669 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21670 _(one_locator_set_dump, "[local | remote]")                             \
21671 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21672 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21673                        "[local] | [remote]")                            \
21674 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21675 _(one_ndp_bd_get, "")                                                   \
21676 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21677 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21678 _(one_l2_arp_bd_get, "")                                                \
21679 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21680 _(one_stats_enable_disable, "enable|disable")                           \
21681 _(show_one_stats_enable_disable, "")                                    \
21682 _(one_eid_table_vni_dump, "")                                           \
21683 _(one_eid_table_map_dump, "l2|l3")                                      \
21684 _(one_map_resolver_dump, "")                                            \
21685 _(one_map_server_dump, "")                                              \
21686 _(one_adjacencies_get, "vni <vni>")                                     \
21687 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21688 _(show_one_rloc_probe_state, "")                                        \
21689 _(show_one_map_register_state, "")                                      \
21690 _(show_one_status, "")                                                  \
21691 _(one_stats_dump, "")                                                   \
21692 _(one_stats_flush, "")                                                  \
21693 _(one_get_map_request_itr_rlocs, "")                                    \
21694 _(one_map_register_set_ttl, "<ttl>")                                    \
21695 _(one_set_transport_protocol, "udp|api")                                \
21696 _(one_get_transport_protocol, "")                                       \
21697 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21698 _(one_show_xtr_mode, "")                                                \
21699 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21700 _(one_show_pitr_mode, "")                                               \
21701 _(one_enable_disable_petr_mode, "enable|disable")                       \
21702 _(one_show_petr_mode, "")                                               \
21703 _(show_one_nsh_mapping, "")                                             \
21704 _(show_one_pitr, "")                                                    \
21705 _(show_one_use_petr, "")                                                \
21706 _(show_one_map_request_mode, "")                                        \
21707 _(show_one_map_register_ttl, "")                                        \
21708 _(show_one_map_register_fallback_threshold, "")                         \
21709 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21710                             " sw_if_index <sw_if_index> p <priority> "  \
21711                             "w <weight>] [del]")                        \
21712 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21713                         "iface <intf> | sw_if_index <sw_if_index> "     \
21714                         "p <priority> w <weight> [del]")                \
21715 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21716                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21717                          "locator-set <locator_name> [del]"             \
21718                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21719 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21720 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21721 _(lisp_enable_disable, "enable|disable")                                \
21722 _(lisp_map_register_enable_disable, "enable|disable")                   \
21723 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21724 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21725                                "[seid <seid>] "                         \
21726                                "rloc <locator> p <prio> "               \
21727                                "w <weight> [rloc <loc> ... ] "          \
21728                                "action <action> [del-all]")             \
21729 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21730                           "<local-eid>")                                \
21731 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21732 _(lisp_use_petr, "<ip-address> | disable")                              \
21733 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21734 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21735 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21736 _(lisp_locator_set_dump, "[local | remote]")                            \
21737 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21738 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21739                        "[local] | [remote]")                            \
21740 _(lisp_eid_table_vni_dump, "")                                          \
21741 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21742 _(lisp_map_resolver_dump, "")                                           \
21743 _(lisp_map_server_dump, "")                                             \
21744 _(lisp_adjacencies_get, "vni <vni>")                                    \
21745 _(gpe_fwd_entry_vnis_get, "")                                           \
21746 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21747 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21748                                 "[table <table-id>]")                   \
21749 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21750 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21751 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21752 _(gpe_get_encap_mode, "")                                               \
21753 _(lisp_gpe_add_del_iface, "up|down")                                    \
21754 _(lisp_gpe_enable_disable, "enable|disable")                            \
21755 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21756   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21757 _(show_lisp_rloc_probe_state, "")                                       \
21758 _(show_lisp_map_register_state, "")                                     \
21759 _(show_lisp_status, "")                                                 \
21760 _(lisp_get_map_request_itr_rlocs, "")                                   \
21761 _(show_lisp_pitr, "")                                                   \
21762 _(show_lisp_use_petr, "")                                               \
21763 _(show_lisp_map_request_mode, "")                                       \
21764 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21765 _(af_packet_delete, "name <host interface name>")                       \
21766 _(af_packet_dump, "")                                                   \
21767 _(policer_add_del, "name <policer name> <params> [del]")                \
21768 _(policer_dump, "[name <policer name>]")                                \
21769 _(policer_classify_set_interface,                                       \
21770   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21771   "  [l2-table <nn>] [del]")                                            \
21772 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21773 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21774     "[master|slave]")                                                   \
21775 _(netmap_delete, "name <interface name>")                               \
21776 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21777 _(mpls_table_dump, "")                                                  \
21778 _(mpls_route_dump, "table-id <ID>")                                     \
21779 _(classify_table_ids, "")                                               \
21780 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21781 _(classify_table_info, "table_id <nn>")                                 \
21782 _(classify_session_dump, "table_id <nn>")                               \
21783 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21784     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21785     "[template_interval <nn>] [udp_checksum]")                          \
21786 _(ipfix_exporter_dump, "")                                              \
21787 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21788 _(ipfix_classify_stream_dump, "")                                       \
21789 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21790 _(ipfix_classify_table_dump, "")                                        \
21791 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21792 _(sw_interface_span_dump, "[l2]")                                           \
21793 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21794 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21795 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21796 _(pg_enable_disable, "[stream <id>] disable")                           \
21797 _(ip_source_and_port_range_check_add_del,                               \
21798   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21799 _(ip_source_and_port_range_check_interface_add_del,                     \
21800   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21801   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21802 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21803 _(l2_interface_pbb_tag_rewrite,                                         \
21804   "<intfc> | sw_if_index <nn> \n"                                       \
21805   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21806   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21807 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21808 _(flow_classify_set_interface,                                          \
21809   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21810 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21811 _(ip_table_dump, "")                                                    \
21812 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21813 _(ip_mtable_dump, "")                                                   \
21814 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21815 _(feature_enable_disable, "arc_name <arc_name> "                        \
21816   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21817 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21818 "[disable]")                                                            \
21819 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21820   "mac <mac-address> [del]")                                            \
21821 _(l2_xconnect_dump, "")                                                 \
21822 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21823 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21824 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21825 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21826 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21827 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21828 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21829   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21830 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21831 _(sock_init_shm, "size <nnn>")                                          \
21832 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21833 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21834   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21835 _(session_rules_dump, "")                                               \
21836 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21837 _(output_acl_set_interface,                                             \
21838   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21839   "  [l2-table <nn>] [del]")                                            \
21840 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21841
21842 /* List of command functions, CLI names map directly to functions */
21843 #define foreach_cli_function                                    \
21844 _(comment, "usage: comment <ignore-rest-of-line>")              \
21845 _(dump_interface_table, "usage: dump_interface_table")          \
21846 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21847 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21848 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21849 _(dump_macro_table, "usage: dump_macro_table ")                 \
21850 _(dump_node_table, "usage: dump_node_table")                    \
21851 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21852 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21853 _(elog_disable, "usage: elog_disable")                          \
21854 _(elog_enable, "usage: elog_enable")                            \
21855 _(elog_save, "usage: elog_save <filename>")                     \
21856 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21857 _(echo, "usage: echo <message>")                                \
21858 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21859 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21860 _(help, "usage: help")                                          \
21861 _(q, "usage: quit")                                             \
21862 _(quit, "usage: quit")                                          \
21863 _(search_node_table, "usage: search_node_table <name>...")      \
21864 _(set, "usage: set <variable-name> <value>")                    \
21865 _(script, "usage: script <file-name>")                          \
21866 _(statseg, "usage: statseg")                                    \
21867 _(unset, "usage: unset <variable-name>")
21868
21869 #define _(N,n)                                  \
21870     static void vl_api_##n##_t_handler_uni      \
21871     (vl_api_##n##_t * mp)                       \
21872     {                                           \
21873         vat_main_t * vam = &vat_main;           \
21874         if (vam->json_output) {                 \
21875             vl_api_##n##_t_handler_json(mp);    \
21876         } else {                                \
21877             vl_api_##n##_t_handler(mp);         \
21878         }                                       \
21879     }
21880 foreach_vpe_api_reply_msg;
21881 #if VPP_API_TEST_BUILTIN == 0
21882 foreach_standalone_reply_msg;
21883 #endif
21884 #undef _
21885
21886 void
21887 vat_api_hookup (vat_main_t * vam)
21888 {
21889 #define _(N,n)                                                  \
21890     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21891                            vl_api_##n##_t_handler_uni,          \
21892                            vl_noop_handler,                     \
21893                            vl_api_##n##_t_endian,               \
21894                            vl_api_##n##_t_print,                \
21895                            sizeof(vl_api_##n##_t), 1);
21896   foreach_vpe_api_reply_msg;
21897 #if VPP_API_TEST_BUILTIN == 0
21898   foreach_standalone_reply_msg;
21899 #endif
21900 #undef _
21901
21902 #if (VPP_API_TEST_BUILTIN==0)
21903   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21904
21905   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21906
21907   vam->function_by_name = hash_create_string (0, sizeof (uword));
21908
21909   vam->help_by_name = hash_create_string (0, sizeof (uword));
21910 #endif
21911
21912   /* API messages we can send */
21913 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21914   foreach_vpe_api_msg;
21915 #undef _
21916
21917   /* Help strings */
21918 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21919   foreach_vpe_api_msg;
21920 #undef _
21921
21922   /* CLI functions */
21923 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21924   foreach_cli_function;
21925 #undef _
21926
21927   /* Help strings */
21928 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21929   foreach_cli_function;
21930 #undef _
21931 }
21932
21933 #if VPP_API_TEST_BUILTIN
21934 static clib_error_t *
21935 vat_api_hookup_shim (vlib_main_t * vm)
21936 {
21937   vat_api_hookup (&vat_main);
21938   return 0;
21939 }
21940
21941 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21942 #endif
21943
21944 /*
21945  * fd.io coding-style-patch-verification: ON
21946  *
21947  * Local Variables:
21948  * eval: (c-set-style "gnu")
21949  * End:
21950  */