virtio: remove configurable queue size support
[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 <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.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 #define vl_print(handle, ...)
77 #define vl_printfun
78 #include <vpp/api/vpe_all_api_h.h>
79 #undef vl_printfun
80
81 #define __plugin_msg_base 0
82 #include <vlibapi/vat_helper_macros.h>
83
84 #if VPP_API_TEST_BUILTIN == 0
85 #include <netdb.h>
86
87 u32
88 vl (void *p)
89 {
90   return vec_len (p);
91 }
92
93 int
94 vat_socket_connect (vat_main_t * vam)
95 {
96   int rv;
97   vam->socket_client_main = &socket_client_main;
98   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
99                                       "vpp_api_test",
100                                       0 /* default socket rx, tx buffer */ )))
101     return rv;
102   /* vpp expects the client index in network order */
103   vam->my_client_index = htonl (socket_client_main.client_index);
104   return 0;
105 }
106 #else /* vpp built-in case, we don't do sockets... */
107 int
108 vat_socket_connect (vat_main_t * vam)
109 {
110   return 0;
111 }
112
113 int
114 vl_socket_client_read (int wait)
115 {
116   return -1;
117 };
118
119 int
120 vl_socket_client_write ()
121 {
122   return -1;
123 };
124
125 void *
126 vl_socket_client_msg_alloc (int nbytes)
127 {
128   return 0;
129 }
130 #endif
131
132
133 f64
134 vat_time_now (vat_main_t * vam)
135 {
136 #if VPP_API_TEST_BUILTIN
137   return vlib_time_now (vam->vlib_main);
138 #else
139   return clib_time_now (&vam->clib_time);
140 #endif
141 }
142
143 void
144 errmsg (char *fmt, ...)
145 {
146   vat_main_t *vam = &vat_main;
147   va_list va;
148   u8 *s;
149
150   va_start (va, fmt);
151   s = va_format (0, fmt, &va);
152   va_end (va);
153
154   vec_add1 (s, 0);
155
156 #if VPP_API_TEST_BUILTIN
157   vlib_cli_output (vam->vlib_main, (char *) s);
158 #else
159   {
160     if (vam->ifp != stdin)
161       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162                vam->input_line_number);
163     fformat (vam->ofp, (char *) s);
164     fflush (vam->ofp);
165   }
166 #endif
167
168   vec_free (s);
169 }
170
171 #if VPP_API_TEST_BUILTIN == 0
172 static uword
173 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
174 {
175   vat_main_t *vam = va_arg (*args, vat_main_t *);
176   u32 *result = va_arg (*args, u32 *);
177   u8 *if_name;
178   uword *p;
179
180   if (!unformat (input, "%s", &if_name))
181     return 0;
182
183   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
184   if (p == 0)
185     return 0;
186   *result = p[0];
187   return 1;
188 }
189
190 static uword
191 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
192 {
193   return 0;
194 }
195
196 /* Parse an IP4 address %d.%d.%d.%d. */
197 uword
198 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 {
200   u8 *result = va_arg (*args, u8 *);
201   unsigned a[4];
202
203   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
204     return 0;
205
206   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
207     return 0;
208
209   result[0] = a[0];
210   result[1] = a[1];
211   result[2] = a[2];
212   result[3] = a[3];
213
214   return 1;
215 }
216
217 uword
218 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 {
220   u8 *result = va_arg (*args, u8 *);
221   u32 i, a[6];
222
223   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
224                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
225     return 0;
226
227   /* Check range. */
228   for (i = 0; i < 6; i++)
229     if (a[i] >= (1 << 8))
230       return 0;
231
232   for (i = 0; i < 6; i++)
233     result[i] = a[i];
234
235   return 1;
236 }
237
238 /* Returns ethernet type as an int in host byte order. */
239 uword
240 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
241                                         va_list * args)
242 {
243   u16 *result = va_arg (*args, u16 *);
244   int type;
245
246   /* Numeric type. */
247   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248     {
249       if (type >= (1 << 16))
250         return 0;
251       *result = type;
252       return 1;
253     }
254   return 0;
255 }
256
257 /* Parse an IP6 address. */
258 uword
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 {
261   ip6_address_t *result = va_arg (*args, ip6_address_t *);
262   u16 hex_quads[8];
263   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264   uword c, n_colon, double_colon_index;
265
266   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267   double_colon_index = ARRAY_LEN (hex_quads);
268   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269     {
270       hex_digit = 16;
271       if (c >= '0' && c <= '9')
272         hex_digit = c - '0';
273       else if (c >= 'a' && c <= 'f')
274         hex_digit = c + 10 - 'a';
275       else if (c >= 'A' && c <= 'F')
276         hex_digit = c + 10 - 'A';
277       else if (c == ':' && n_colon < 2)
278         n_colon++;
279       else
280         {
281           unformat_put_input (input);
282           break;
283         }
284
285       /* Too many hex quads. */
286       if (n_hex_quads >= ARRAY_LEN (hex_quads))
287         return 0;
288
289       if (hex_digit < 16)
290         {
291           hex_quad = (hex_quad << 4) | hex_digit;
292
293           /* Hex quad must fit in 16 bits. */
294           if (n_hex_digits >= 4)
295             return 0;
296
297           n_colon = 0;
298           n_hex_digits++;
299         }
300
301       /* Save position of :: */
302       if (n_colon == 2)
303         {
304           /* More than one :: ? */
305           if (double_colon_index < ARRAY_LEN (hex_quads))
306             return 0;
307           double_colon_index = n_hex_quads;
308         }
309
310       if (n_colon > 0 && n_hex_digits > 0)
311         {
312           hex_quads[n_hex_quads++] = hex_quad;
313           hex_quad = 0;
314           n_hex_digits = 0;
315         }
316     }
317
318   if (n_hex_digits > 0)
319     hex_quads[n_hex_quads++] = hex_quad;
320
321   {
322     word i;
323
324     /* Expand :: to appropriate number of zero hex quads. */
325     if (double_colon_index < ARRAY_LEN (hex_quads))
326       {
327         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328
329         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330           hex_quads[n_zero + i] = hex_quads[i];
331
332         for (i = 0; i < n_zero; i++)
333           hex_quads[double_colon_index + i] = 0;
334
335         n_hex_quads = ARRAY_LEN (hex_quads);
336       }
337
338     /* Too few hex quads given. */
339     if (n_hex_quads < ARRAY_LEN (hex_quads))
340       return 0;
341
342     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
344
345     return 1;
346   }
347 }
348
349 uword
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 {
352   u32 *r = va_arg (*args, u32 *);
353
354   if (0);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356   foreach_ipsec_policy_action
357 #undef _
358     else
359     return 0;
360   return 1;
361 }
362
363 u8 *
364 format_ipsec_crypto_alg (u8 * s, va_list * args)
365 {
366   u32 i = va_arg (*args, u32);
367   u8 *t = 0;
368
369   switch (i)
370     {
371 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
372       foreach_ipsec_crypto_alg
373 #undef _
374     default:
375       return format (s, "unknown");
376     }
377   return format (s, "%s", t);
378 }
379
380 u8 *
381 format_ipsec_integ_alg (u8 * s, va_list * args)
382 {
383   u32 i = va_arg (*args, u32);
384   u8 *t = 0;
385
386   switch (i)
387     {
388 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
389       foreach_ipsec_integ_alg
390 #undef _
391     default:
392       return format (s, "unknown");
393     }
394   return format (s, "%s", t);
395 }
396
397 #else /* VPP_API_TEST_BUILTIN == 1 */
398 static uword
399 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
400 {
401   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
402   vnet_main_t *vnm = vnet_get_main ();
403   u32 *result = va_arg (*args, u32 *);
404
405   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
406 }
407
408 static uword
409 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __attribute__ ((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_hw_interface, vnm, result);
416 }
417
418 #endif /* VPP_API_TEST_BUILTIN */
419
420 uword
421 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
422 {
423   u32 *r = va_arg (*args, u32 *);
424
425   if (0);
426 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
427   foreach_ipsec_crypto_alg
428 #undef _
429     else
430     return 0;
431   return 1;
432 }
433
434 uword
435 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
436 {
437   u32 *r = va_arg (*args, u32 *);
438
439   if (0);
440 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
441   foreach_ipsec_integ_alg
442 #undef _
443     else
444     return 0;
445   return 1;
446 }
447
448 static uword
449 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
450 {
451   u8 *r = va_arg (*args, u8 *);
452
453   if (unformat (input, "kbps"))
454     *r = SSE2_QOS_RATE_KBPS;
455   else if (unformat (input, "pps"))
456     *r = SSE2_QOS_RATE_PPS;
457   else
458     return 0;
459   return 1;
460 }
461
462 static uword
463 unformat_policer_round_type (unformat_input_t * input, va_list * args)
464 {
465   u8 *r = va_arg (*args, u8 *);
466
467   if (unformat (input, "closest"))
468     *r = SSE2_QOS_ROUND_TO_CLOSEST;
469   else if (unformat (input, "up"))
470     *r = SSE2_QOS_ROUND_TO_UP;
471   else if (unformat (input, "down"))
472     *r = SSE2_QOS_ROUND_TO_DOWN;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "1r2c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R2C;
485   else if (unformat (input, "1r3c"))
486     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
487   else if (unformat (input, "2r3c-2698"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
489   else if (unformat (input, "2r3c-4115"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
491   else if (unformat (input, "2r3c-mef5cf1"))
492     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
493   else
494     return 0;
495   return 1;
496 }
497
498 static uword
499 unformat_dscp (unformat_input_t * input, va_list * va)
500 {
501   u8 *r = va_arg (*va, u8 *);
502
503   if (0);
504 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
505   foreach_vnet_dscp
506 #undef _
507     else
508     return 0;
509   return 1;
510 }
511
512 static uword
513 unformat_policer_action_type (unformat_input_t * input, va_list * va)
514 {
515   sse2_qos_pol_action_params_st *a
516     = va_arg (*va, sse2_qos_pol_action_params_st *);
517
518   if (unformat (input, "drop"))
519     a->action_type = SSE2_QOS_ACTION_DROP;
520   else if (unformat (input, "transmit"))
521     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
522   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
523     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
524   else
525     return 0;
526   return 1;
527 }
528
529 static uword
530 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
531 {
532   u32 *r = va_arg (*va, u32 *);
533   u32 tid;
534
535   if (unformat (input, "ip4"))
536     tid = POLICER_CLASSIFY_TABLE_IP4;
537   else if (unformat (input, "ip6"))
538     tid = POLICER_CLASSIFY_TABLE_IP6;
539   else if (unformat (input, "l2"))
540     tid = POLICER_CLASSIFY_TABLE_L2;
541   else
542     return 0;
543
544   *r = tid;
545   return 1;
546 }
547
548 static uword
549 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
550 {
551   u32 *r = va_arg (*va, u32 *);
552   u32 tid;
553
554   if (unformat (input, "ip4"))
555     tid = FLOW_CLASSIFY_TABLE_IP4;
556   else if (unformat (input, "ip6"))
557     tid = FLOW_CLASSIFY_TABLE_IP6;
558   else
559     return 0;
560
561   *r = tid;
562   return 1;
563 }
564
565 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
566 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
567 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
568 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
569
570 #if (VPP_API_TEST_BUILTIN==0)
571 uword
572 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
573 {
574   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
575   mfib_itf_attribute_t attr;
576
577   old = *iflags;
578   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
579   {
580     if (unformat (input, mfib_itf_flag_long_names[attr]))
581       *iflags |= (1 << attr);
582   }
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_names[attr]))
586       *iflags |= (1 << attr);
587   }
588
589   return (old == *iflags ? 0 : 1);
590 }
591
592 uword
593 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
594 {
595   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
596   mfib_entry_attribute_t attr;
597
598   old = *eflags;
599   FOR_EACH_MFIB_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_flag_long_names[attr]))
602       *eflags |= (1 << attr);
603   }
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_names[attr]))
607       *eflags |= (1 << attr);
608   }
609
610   return (old == *eflags ? 0 : 1);
611 }
612
613 u8 *
614 format_ip4_address (u8 * s, va_list * args)
615 {
616   u8 *a = va_arg (*args, u8 *);
617   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
618 }
619
620 u8 *
621 format_ip6_address (u8 * s, va_list * args)
622 {
623   ip6_address_t *a = va_arg (*args, ip6_address_t *);
624   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
625
626   i_max_n_zero = ARRAY_LEN (a->as_u16);
627   max_n_zeros = 0;
628   i_first_zero = i_max_n_zero;
629   n_zeros = 0;
630   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
631     {
632       u32 is_zero = a->as_u16[i] == 0;
633       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
634         {
635           i_first_zero = i;
636           n_zeros = 0;
637         }
638       n_zeros += is_zero;
639       if ((!is_zero && n_zeros > max_n_zeros)
640           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
641         {
642           i_max_n_zero = i_first_zero;
643           max_n_zeros = n_zeros;
644           i_first_zero = ARRAY_LEN (a->as_u16);
645           n_zeros = 0;
646         }
647     }
648
649   last_double_colon = 0;
650   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
651     {
652       if (i == i_max_n_zero && max_n_zeros > 1)
653         {
654           s = format (s, "::");
655           i += max_n_zeros - 1;
656           last_double_colon = 1;
657         }
658       else
659         {
660           s = format (s, "%s%x",
661                       (last_double_colon || i == 0) ? "" : ":",
662                       clib_net_to_host_u16 (a->as_u16[i]));
663           last_double_colon = 0;
664         }
665     }
666
667   return s;
668 }
669
670 /* Format an IP46 address. */
671 u8 *
672 format_ip46_address (u8 * s, va_list * args)
673 {
674   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
675   ip46_type_t type = va_arg (*args, ip46_type_t);
676   int is_ip4 = 1;
677
678   switch (type)
679     {
680     case IP46_TYPE_ANY:
681       is_ip4 = ip46_address_is_ip4 (ip46);
682       break;
683     case IP46_TYPE_IP4:
684       is_ip4 = 1;
685       break;
686     case IP46_TYPE_IP6:
687       is_ip4 = 0;
688       break;
689     }
690
691   return is_ip4 ?
692     format (s, "%U", format_ip4_address, &ip46->ip4) :
693     format (s, "%U", format_ip6_address, &ip46->ip6);
694 }
695
696 u8 *
697 format_ethernet_address (u8 * s, va_list * args)
698 {
699   u8 *a = va_arg (*args, u8 *);
700
701   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
702                  a[0], a[1], a[2], a[3], a[4], a[5]);
703 }
704 #endif
705
706 static void
707 increment_v4_address (ip4_address_t * a)
708 {
709   u32 v;
710
711   v = ntohl (a->as_u32) + 1;
712   a->as_u32 = ntohl (v);
713 }
714
715 static void
716 increment_vl_v4_address (vl_api_ip4_address_t * a)
717 {
718   u32 v;
719
720   v = *(u32 *) a;
721   v = ntohl (v);
722   v++;
723   v = ntohl (v);
724   clib_memcpy (a, &v, sizeof (v));
725 }
726
727 static void
728 increment_vl_address (vl_api_address_t * a)
729 {
730   if (ADDRESS_IP4 == a->af)
731     increment_vl_v4_address (&a->un.ip4);
732 }
733
734 static void
735 increment_v6_address (ip6_address_t * a)
736 {
737   u64 v0, v1;
738
739   v0 = clib_net_to_host_u64 (a->as_u64[0]);
740   v1 = clib_net_to_host_u64 (a->as_u64[1]);
741
742   v1 += 1;
743   if (v1 == 0)
744     v0 += 1;
745   a->as_u64[0] = clib_net_to_host_u64 (v0);
746   a->as_u64[1] = clib_net_to_host_u64 (v1);
747 }
748
749 static void
750 increment_mac_address (u8 * mac)
751 {
752   u64 tmp = *((u64 *) mac);
753   tmp = clib_net_to_host_u64 (tmp);
754   tmp += 1 << 16;               /* skip unused (least significant) octets */
755   tmp = clib_host_to_net_u64 (tmp);
756
757   clib_memcpy (mac, &tmp, 6);
758 }
759
760 static void vl_api_create_loopback_reply_t_handler
761   (vl_api_create_loopback_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_reply_t_handler_json
773   (vl_api_create_loopback_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_create_loopback_instance_reply_t_handler
789   (vl_api_create_loopback_instance_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_create_loopback_instance_reply_t_handler_json
801   (vl_api_create_loopback_instance_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_af_packet_create_reply_t_handler
817   (vl_api_af_packet_create_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_af_packet_create_reply_t_handler_json
829   (vl_api_af_packet_create_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_vlan_subif_reply_t_handler
846   (vl_api_create_vlan_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_vlan_subif_reply_t_handler_json
858   (vl_api_create_vlan_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_subif_reply_t_handler
875   (vl_api_create_subif_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->sw_if_index = ntohl (mp->sw_if_index);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_subif_reply_t_handler_json
887   (vl_api_create_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
895
896   vat_json_print (vam->ofp, &node);
897   vat_json_free (&node);
898
899   vam->retval = ntohl (mp->retval);
900   vam->result_ready = 1;
901 }
902
903 static void vl_api_interface_name_renumber_reply_t_handler
904   (vl_api_interface_name_renumber_reply_t * mp)
905 {
906   vat_main_t *vam = &vat_main;
907   i32 retval = ntohl (mp->retval);
908
909   vam->retval = retval;
910   vam->regenerate_interface_table = 1;
911   vam->result_ready = 1;
912 }
913
914 static void vl_api_interface_name_renumber_reply_t_handler_json
915   (vl_api_interface_name_renumber_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   vat_json_node_t node;
919
920   vat_json_init_object (&node);
921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
922
923   vat_json_print (vam->ofp, &node);
924   vat_json_free (&node);
925
926   vam->retval = ntohl (mp->retval);
927   vam->result_ready = 1;
928 }
929
930 /*
931  * Special-case: build the interface table, maintain
932  * the next loopback sw_if_index vbl.
933  */
934 static void vl_api_sw_interface_details_t_handler
935   (vl_api_sw_interface_details_t * mp)
936 {
937   vat_main_t *vam = &vat_main;
938   u8 *s = format (0, "%s%c", mp->interface_name, 0);
939
940   hash_set_mem (vam->sw_if_index_by_interface_name, s,
941                 ntohl (mp->sw_if_index));
942
943   /* In sub interface case, fill the sub interface table entry */
944   if (mp->sw_if_index != mp->sup_sw_if_index)
945     {
946       sw_interface_subif_t *sub = NULL;
947
948       vec_add2 (vam->sw_if_subif_table, sub, 1);
949
950       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
951       strncpy ((char *) sub->interface_name, (char *) s,
952                vec_len (sub->interface_name));
953       sub->sw_if_index = ntohl (mp->sw_if_index);
954       sub->sub_id = ntohl (mp->sub_id);
955
956       sub->sub_dot1ad = mp->sub_dot1ad;
957       sub->sub_number_of_tags = mp->sub_number_of_tags;
958       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
959       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
960       sub->sub_exact_match = mp->sub_exact_match;
961       sub->sub_default = mp->sub_default;
962       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
963       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
964
965       /* vlan tag rewrite */
966       sub->vtr_op = ntohl (mp->vtr_op);
967       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
968       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
969       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
970     }
971 }
972
973 static void vl_api_sw_interface_details_t_handler_json
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   vat_json_node_t *node = NULL;
978
979   if (VAT_JSON_ARRAY != vam->json_tree.type)
980     {
981       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
982       vat_json_init_array (&vam->json_tree);
983     }
984   node = vat_json_array_add (&vam->json_tree);
985
986   vat_json_init_object (node);
987   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
988   vat_json_object_add_uint (node, "sup_sw_if_index",
989                             ntohl (mp->sup_sw_if_index));
990   vat_json_object_add_uint (node, "l2_address_length",
991                             ntohl (mp->l2_address_length));
992   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
993                              sizeof (mp->l2_address));
994   vat_json_object_add_string_copy (node, "interface_name",
995                                    mp->interface_name);
996   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
997   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
998   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
999   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1000   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1001   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1002   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1003   vat_json_object_add_uint (node, "sub_number_of_tags",
1004                             mp->sub_number_of_tags);
1005   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1006                             ntohs (mp->sub_outer_vlan_id));
1007   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1008                             ntohs (mp->sub_inner_vlan_id));
1009   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1010   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1012                             mp->sub_outer_vlan_id_any);
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1014                             mp->sub_inner_vlan_id_any);
1015   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1016   vat_json_object_add_uint (node, "vtr_push_dot1q",
1017                             ntohl (mp->vtr_push_dot1q));
1018   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1019   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1020   if (mp->sub_dot1ah)
1021     {
1022       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1023                                        format (0, "%U",
1024                                                format_ethernet_address,
1025                                                &mp->b_dmac));
1026       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1027                                        format (0, "%U",
1028                                                format_ethernet_address,
1029                                                &mp->b_smac));
1030       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1031       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1032     }
1033 }
1034
1035 #if VPP_API_TEST_BUILTIN == 0
1036 static void vl_api_sw_interface_event_t_handler
1037   (vl_api_sw_interface_event_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   if (vam->interface_event_display)
1041     errmsg ("interface flags: sw_if_index %d %s %s",
1042             ntohl (mp->sw_if_index),
1043             mp->admin_up_down ? "admin-up" : "admin-down",
1044             mp->link_up_down ? "link-up" : "link-down");
1045 }
1046 #endif
1047
1048 static void vl_api_sw_interface_event_t_handler_json
1049   (vl_api_sw_interface_event_t * mp)
1050 {
1051   /* JSON output not supported */
1052 }
1053
1054 static void
1055 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059
1060   vam->retval = retval;
1061   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vam->result_ready = 1;
1063 }
1064
1065 static void
1066 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070   api_main_t *am = &api_main;
1071   void *oldheap;
1072   u8 *reply;
1073
1074   vat_json_init_object (&node);
1075   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1076   vat_json_object_add_uint (&node, "reply_in_shmem",
1077                             ntohl (mp->reply_in_shmem));
1078   /* Toss the shared-memory original... */
1079   pthread_mutex_lock (&am->vlib_rp->mutex);
1080   oldheap = svm_push_data_heap (am->vlib_rp);
1081
1082   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1083   vec_free (reply);
1084
1085   svm_pop_heap (oldheap);
1086   pthread_mutex_unlock (&am->vlib_rp->mutex);
1087
1088   vat_json_print (vam->ofp, &node);
1089   vat_json_free (&node);
1090
1091   vam->retval = ntohl (mp->retval);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   i32 retval = ntohl (mp->retval);
1100   u32 length = vl_api_string_len (&mp->reply);
1101
1102   vec_reset_length (vam->cmd_reply);
1103
1104   vam->retval = retval;
1105   if (retval == 0)
1106     {
1107       vec_validate (vam->cmd_reply, length);
1108       clib_memcpy ((char *) (vam->cmd_reply),
1109                    vl_api_from_api_string (&mp->reply), length);
1110       vam->cmd_reply[length] = 0;
1111     }
1112   vam->result_ready = 1;
1113 }
1114
1115 static void
1116 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1117 {
1118   vat_main_t *vam = &vat_main;
1119   vat_json_node_t node;
1120
1121   vec_reset_length (vam->cmd_reply);
1122
1123   vat_json_init_object (&node);
1124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1125   vat_json_object_add_string_copy (&node, "reply",
1126                                    vl_api_from_api_string (&mp->reply));
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void vl_api_classify_add_del_table_reply_t_handler
1136   (vl_api_classify_add_del_table_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   i32 retval = ntohl (mp->retval);
1140   if (vam->async_mode)
1141     {
1142       vam->async_errors += (retval < 0);
1143     }
1144   else
1145     {
1146       vam->retval = retval;
1147       if (retval == 0 &&
1148           ((mp->new_table_index != 0xFFFFFFFF) ||
1149            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1150            (mp->match_n_vectors != 0xFFFFFFFF)))
1151         /*
1152          * Note: this is just barely thread-safe, depends on
1153          * the main thread spinning waiting for an answer...
1154          */
1155         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1156                 ntohl (mp->new_table_index),
1157                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1158       vam->result_ready = 1;
1159     }
1160 }
1161
1162 static void vl_api_classify_add_del_table_reply_t_handler_json
1163   (vl_api_classify_add_del_table_reply_t * mp)
1164 {
1165   vat_main_t *vam = &vat_main;
1166   vat_json_node_t node;
1167
1168   vat_json_init_object (&node);
1169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1170   vat_json_object_add_uint (&node, "new_table_index",
1171                             ntohl (mp->new_table_index));
1172   vat_json_object_add_uint (&node, "skip_n_vectors",
1173                             ntohl (mp->skip_n_vectors));
1174   vat_json_object_add_uint (&node, "match_n_vectors",
1175                             ntohl (mp->match_n_vectors));
1176
1177   vat_json_print (vam->ofp, &node);
1178   vat_json_free (&node);
1179
1180   vam->retval = ntohl (mp->retval);
1181   vam->result_ready = 1;
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   i32 retval = ntohl (mp->retval);
1189   if (vam->async_mode)
1190     {
1191       vam->async_errors += (retval < 0);
1192     }
1193   else
1194     {
1195       vam->retval = retval;
1196       if (retval == 0)
1197         errmsg ("node index %d", ntohl (mp->node_index));
1198       vam->result_ready = 1;
1199     }
1200 }
1201
1202 static void vl_api_get_node_index_reply_t_handler_json
1203   (vl_api_get_node_index_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   vat_json_node_t node;
1207
1208   vat_json_init_object (&node);
1209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1210   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1211
1212   vat_json_print (vam->ofp, &node);
1213   vat_json_free (&node);
1214
1215   vam->retval = ntohl (mp->retval);
1216   vam->result_ready = 1;
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   i32 retval = ntohl (mp->retval);
1224   if (vam->async_mode)
1225     {
1226       vam->async_errors += (retval < 0);
1227     }
1228   else
1229     {
1230       vam->retval = retval;
1231       if (retval == 0)
1232         errmsg ("next node index %d", ntohl (mp->next_index));
1233       vam->result_ready = 1;
1234     }
1235 }
1236
1237 static void vl_api_get_next_index_reply_t_handler_json
1238   (vl_api_get_next_index_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   vat_json_node_t node;
1242
1243   vat_json_init_object (&node);
1244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1245   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   i32 retval = ntohl (mp->retval);
1259   if (vam->async_mode)
1260     {
1261       vam->async_errors += (retval < 0);
1262     }
1263   else
1264     {
1265       vam->retval = retval;
1266       if (retval == 0)
1267         errmsg ("next index %d", ntohl (mp->next_index));
1268       vam->result_ready = 1;
1269     }
1270 }
1271
1272 static void vl_api_add_node_next_reply_t_handler_json
1273   (vl_api_add_node_next_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   vat_json_node_t node;
1277
1278   vat_json_init_object (&node);
1279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1280   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1281
1282   vat_json_print (vam->ofp, &node);
1283   vat_json_free (&node);
1284
1285   vam->retval = ntohl (mp->retval);
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_show_version_reply_t_handler
1290   (vl_api_show_version_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (retval >= 0)
1296     {
1297       char *s;
1298       char *p = (char *) &mp->program;
1299
1300       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1301       errmsg ("        program: %s\n", s);
1302       free (s);
1303
1304       p +=
1305         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        version: %s\n", s);
1308       free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1313       errmsg ("     build date: %s\n", s);
1314       free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1319       errmsg ("build directory: %s\n", s);
1320       free (s);
1321     }
1322   vam->retval = retval;
1323   vam->result_ready = 1;
1324 }
1325
1326 static void vl_api_show_version_reply_t_handler_json
1327   (vl_api_show_version_reply_t * mp)
1328 {
1329   vat_main_t *vam = &vat_main;
1330   vat_json_node_t node;
1331
1332   vat_json_init_object (&node);
1333   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1334   char *p = (char *) &mp->program;
1335   vat_json_object_add_string_copy (&node, "program",
1336                                    vl_api_from_api_string ((vl_api_string_t *)
1337                                                            p));
1338   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1339   vat_json_object_add_string_copy (&node, "version",
1340                                    vl_api_from_api_string ((vl_api_string_t *)
1341                                                            p));
1342   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1343   vat_json_object_add_string_copy (&node, "build_date",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    vl_api_from_api_string ((vl_api_string_t *)
1349                                                            p));
1350
1351   vat_json_print (vam->ofp, &node);
1352   vat_json_free (&node);
1353
1354   vam->retval = ntohl (mp->retval);
1355   vam->result_ready = 1;
1356 }
1357
1358 static void vl_api_show_threads_reply_t_handler
1359   (vl_api_show_threads_reply_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   i32 retval = ntohl (mp->retval);
1363   int i, count = 0;
1364
1365   if (retval >= 0)
1366     count = ntohl (mp->count);
1367
1368   for (i = 0; i < count; i++)
1369     print (vam->ofp,
1370            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1371            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1372            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1373            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1374            ntohl (mp->thread_data[i].cpu_socket));
1375
1376   vam->retval = retval;
1377   vam->result_ready = 1;
1378 }
1379
1380 static void vl_api_show_threads_reply_t_handler_json
1381   (vl_api_show_threads_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   vat_json_node_t node;
1385   vl_api_thread_data_t *td;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", retval);
1394   vat_json_object_add_uint (&node, "count", count);
1395
1396   for (i = 0; i < count; i++)
1397     {
1398       td = &mp->thread_data[i];
1399       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1400       vat_json_object_add_string_copy (&node, "name", td->name);
1401       vat_json_object_add_string_copy (&node, "type", td->type);
1402       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1403       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1404       vat_json_object_add_int (&node, "core", ntohl (td->id));
1405       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1406     }
1407
1408   vat_json_print (vam->ofp, &node);
1409   vat_json_free (&node);
1410
1411   vam->retval = retval;
1412   vam->result_ready = 1;
1413 }
1414
1415 static int
1416 api_show_threads (vat_main_t * vam)
1417 {
1418   vl_api_show_threads_t *mp;
1419   int ret;
1420
1421   print (vam->ofp,
1422          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1423          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1424
1425   M (SHOW_THREADS, mp);
1426
1427   S (mp);
1428   W (ret);
1429   return ret;
1430 }
1431
1432 static void
1433 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1434 {
1435   u32 sw_if_index = ntohl (mp->sw_if_index);
1436   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1437           mp->mac_ip ? "mac/ip binding" : "address resolution",
1438           ntohl (mp->pid), format_ip4_address, mp->ip,
1439           format_vl_api_mac_address, &mp->mac, sw_if_index);
1440 }
1441
1442 static void
1443 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1444 {
1445   /* JSON output not supported */
1446 }
1447
1448 static void
1449 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1450 {
1451   u32 sw_if_index = ntohl (mp->sw_if_index);
1452   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1453           mp->mac_ip ? "mac/ip binding" : "address resolution",
1454           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1455           format_vl_api_mac_address, mp->mac, sw_if_index);
1456 }
1457
1458 static void
1459 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1460 {
1461   /* JSON output not supported */
1462 }
1463
1464 static void
1465 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1466 {
1467   u32 n_macs = ntohl (mp->n_macs);
1468   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1469           ntohl (mp->pid), mp->client_index, n_macs);
1470   int i;
1471   for (i = 0; i < n_macs; i++)
1472     {
1473       vl_api_mac_entry_t *mac = &mp->mac[i];
1474       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1475               i + 1, ntohl (mac->sw_if_index),
1476               format_ethernet_address, mac->mac_addr, mac->action);
1477       if (i == 1000)
1478         break;
1479     }
1480 }
1481
1482 static void
1483 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1484 {
1485   /* JSON output not supported */
1486 }
1487
1488 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1489 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1490
1491 /*
1492  * Special-case: build the bridge domain table, maintain
1493  * the next bd id vbl.
1494  */
1495 static void vl_api_bridge_domain_details_t_handler
1496   (vl_api_bridge_domain_details_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1500   int i;
1501
1502   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1503          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1504
1505   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1506          ntohl (mp->bd_id), mp->learn, mp->forward,
1507          mp->flood, ntohl (mp->bvi_sw_if_index),
1508          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1509
1510   if (n_sw_ifs)
1511     {
1512       vl_api_bridge_domain_sw_if_t *sw_ifs;
1513       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1514              "Interface Name");
1515
1516       sw_ifs = mp->sw_if_details;
1517       for (i = 0; i < n_sw_ifs; i++)
1518         {
1519           u8 *sw_if_name = 0;
1520           u32 sw_if_index;
1521           hash_pair_t *p;
1522
1523           sw_if_index = ntohl (sw_ifs->sw_if_index);
1524
1525           /* *INDENT-OFF* */
1526           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1527                              ({
1528                                if ((u32) p->value[0] == sw_if_index)
1529                                  {
1530                                    sw_if_name = (u8 *)(p->key);
1531                                    break;
1532                                  }
1533                              }));
1534           /* *INDENT-ON* */
1535           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1536                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1537                  "sw_if_index not found!");
1538
1539           sw_ifs++;
1540         }
1541     }
1542 }
1543
1544 static void vl_api_bridge_domain_details_t_handler_json
1545   (vl_api_bridge_domain_details_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t *node, *array = NULL;
1549   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1550
1551   if (VAT_JSON_ARRAY != vam->json_tree.type)
1552     {
1553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1554       vat_json_init_array (&vam->json_tree);
1555     }
1556   node = vat_json_array_add (&vam->json_tree);
1557
1558   vat_json_init_object (node);
1559   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1560   vat_json_object_add_uint (node, "flood", mp->flood);
1561   vat_json_object_add_uint (node, "forward", mp->forward);
1562   vat_json_object_add_uint (node, "learn", mp->learn);
1563   vat_json_object_add_uint (node, "bvi_sw_if_index",
1564                             ntohl (mp->bvi_sw_if_index));
1565   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1566   array = vat_json_object_add (node, "sw_if");
1567   vat_json_init_array (array);
1568
1569
1570
1571   if (n_sw_ifs)
1572     {
1573       vl_api_bridge_domain_sw_if_t *sw_ifs;
1574       int i;
1575
1576       sw_ifs = mp->sw_if_details;
1577       for (i = 0; i < n_sw_ifs; i++)
1578         {
1579           node = vat_json_array_add (array);
1580           vat_json_init_object (node);
1581           vat_json_object_add_uint (node, "sw_if_index",
1582                                     ntohl (sw_ifs->sw_if_index));
1583           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1584           sw_ifs++;
1585         }
1586     }
1587 }
1588
1589 static void vl_api_control_ping_reply_t_handler
1590   (vl_api_control_ping_reply_t * mp)
1591 {
1592   vat_main_t *vam = &vat_main;
1593   i32 retval = ntohl (mp->retval);
1594   if (vam->async_mode)
1595     {
1596       vam->async_errors += (retval < 0);
1597     }
1598   else
1599     {
1600       vam->retval = retval;
1601       vam->result_ready = 1;
1602     }
1603   if (vam->socket_client_main)
1604     vam->socket_client_main->control_pings_outstanding--;
1605 }
1606
1607 static void vl_api_control_ping_reply_t_handler_json
1608   (vl_api_control_ping_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612
1613   if (VAT_JSON_NONE != vam->json_tree.type)
1614     {
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vat_json_free (&vam->json_tree);
1617       vam->json_tree.type = VAT_JSON_NONE;
1618     }
1619   else
1620     {
1621       /* just print [] */
1622       vat_json_init_array (&vam->json_tree);
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vam->json_tree.type = VAT_JSON_NONE;
1625     }
1626
1627   vam->retval = retval;
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632   vl_api_bridge_domain_set_mac_age_reply_t_handler
1633   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1649   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2_flags_reply_t_handler_json
1681   (vl_api_l2_flags_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1689                             ntohl (mp->resulting_feature_bitmap));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_bridge_flags_reply_t_handler
1699   (vl_api_bridge_flags_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_bridge_flags_reply_t_handler_json
1715   (vl_api_bridge_flags_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1723                             ntohl (mp->resulting_feature_bitmap));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732 static void
1733 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747
1748 }
1749
1750 static void vl_api_tap_create_v2_reply_t_handler_json
1751   (vl_api_tap_create_v2_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765
1766 }
1767
1768 static void
1769 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->result_ready = 1;
1781     }
1782 }
1783
1784 static void vl_api_tap_delete_v2_reply_t_handler_json
1785   (vl_api_tap_delete_v2_reply_t * mp)
1786 {
1787   vat_main_t *vam = &vat_main;
1788   vat_json_node_t node;
1789
1790   vat_json_init_object (&node);
1791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void
1801 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1802                                           mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   i32 retval = ntohl (mp->retval);
1806   if (vam->async_mode)
1807     {
1808       vam->async_errors += (retval < 0);
1809     }
1810   else
1811     {
1812       vam->retval = retval;
1813       vam->sw_if_index = ntohl (mp->sw_if_index);
1814       vam->result_ready = 1;
1815     }
1816 }
1817
1818 static void vl_api_virtio_pci_create_reply_t_handler_json
1819   (vl_api_virtio_pci_create_reply_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   vat_json_node_t node;
1823
1824   vat_json_init_object (&node);
1825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1826   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1827
1828   vat_json_print (vam->ofp, &node);
1829   vat_json_free (&node);
1830
1831   vam->retval = ntohl (mp->retval);
1832   vam->result_ready = 1;
1833
1834 }
1835
1836 static void
1837 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1838                                           mp)
1839 {
1840   vat_main_t *vam = &vat_main;
1841   i32 retval = ntohl (mp->retval);
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->result_ready = 1;
1850     }
1851 }
1852
1853 static void vl_api_virtio_pci_delete_reply_t_handler_json
1854   (vl_api_virtio_pci_delete_reply_t * mp)
1855 {
1856   vat_main_t *vam = &vat_main;
1857   vat_json_node_t node;
1858
1859   vat_json_init_object (&node);
1860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1861
1862   vat_json_print (vam->ofp, &node);
1863   vat_json_free (&node);
1864
1865   vam->retval = ntohl (mp->retval);
1866   vam->result_ready = 1;
1867 }
1868
1869 static void
1870 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1871 {
1872   vat_main_t *vam = &vat_main;
1873   i32 retval = ntohl (mp->retval);
1874
1875   if (vam->async_mode)
1876     {
1877       vam->async_errors += (retval < 0);
1878     }
1879   else
1880     {
1881       vam->retval = retval;
1882       vam->sw_if_index = ntohl (mp->sw_if_index);
1883       vam->result_ready = 1;
1884     }
1885 }
1886
1887 static void vl_api_bond_create_reply_t_handler_json
1888   (vl_api_bond_create_reply_t * mp)
1889 {
1890   vat_main_t *vam = &vat_main;
1891   vat_json_node_t node;
1892
1893   vat_json_init_object (&node);
1894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1895   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_delete_reply_t_handler_json
1922   (vl_api_bond_delete_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1939 {
1940   vat_main_t *vam = &vat_main;
1941   i32 retval = ntohl (mp->retval);
1942
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_bond_enslave_reply_t_handler_json
1955   (vl_api_bond_enslave_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962
1963   vat_json_print (vam->ofp, &node);
1964   vat_json_free (&node);
1965
1966   vam->retval = ntohl (mp->retval);
1967   vam->result_ready = 1;
1968 }
1969
1970 static void
1971 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1972                                           mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976
1977   if (vam->async_mode)
1978     {
1979       vam->async_errors += (retval < 0);
1980     }
1981   else
1982     {
1983       vam->retval = retval;
1984       vam->result_ready = 1;
1985     }
1986 }
1987
1988 static void vl_api_bond_detach_slave_reply_t_handler_json
1989   (vl_api_bond_detach_slave_reply_t * mp)
1990 {
1991   vat_main_t *vam = &vat_main;
1992   vat_json_node_t node;
1993
1994   vat_json_init_object (&node);
1995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1996
1997   vat_json_print (vam->ofp, &node);
1998   vat_json_free (&node);
1999
2000   vam->retval = ntohl (mp->retval);
2001   vam->result_ready = 1;
2002 }
2003
2004 static void vl_api_sw_interface_bond_details_t_handler
2005   (vl_api_sw_interface_bond_details_t * mp)
2006 {
2007   vat_main_t *vam = &vat_main;
2008
2009   print (vam->ofp,
2010          "%-16s %-12d %-12U %-13U %-14u %-14u",
2011          mp->interface_name, ntohl (mp->sw_if_index),
2012          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2013          ntohl (mp->active_slaves), ntohl (mp->slaves));
2014 }
2015
2016 static void vl_api_sw_interface_bond_details_t_handler_json
2017   (vl_api_sw_interface_bond_details_t * mp)
2018 {
2019   vat_main_t *vam = &vat_main;
2020   vat_json_node_t *node = NULL;
2021
2022   if (VAT_JSON_ARRAY != vam->json_tree.type)
2023     {
2024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2025       vat_json_init_array (&vam->json_tree);
2026     }
2027   node = vat_json_array_add (&vam->json_tree);
2028
2029   vat_json_init_object (node);
2030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2031   vat_json_object_add_string_copy (node, "interface_name",
2032                                    mp->interface_name);
2033   vat_json_object_add_uint (node, "mode", mp->mode);
2034   vat_json_object_add_uint (node, "load_balance", mp->lb);
2035   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2036   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2037 }
2038
2039 static int
2040 api_sw_interface_bond_dump (vat_main_t * vam)
2041 {
2042   vl_api_sw_interface_bond_dump_t *mp;
2043   vl_api_control_ping_t *mp_ping;
2044   int ret;
2045
2046   print (vam->ofp,
2047          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2048          "interface name", "sw_if_index", "mode", "load balance",
2049          "active slaves", "slaves");
2050
2051   /* Get list of bond interfaces */
2052   M (SW_INTERFACE_BOND_DUMP, mp);
2053   S (mp);
2054
2055   /* Use a control ping for synchronization */
2056   MPING (CONTROL_PING, mp_ping);
2057   S (mp_ping);
2058
2059   W (ret);
2060   return ret;
2061 }
2062
2063 static void vl_api_sw_interface_slave_details_t_handler
2064   (vl_api_sw_interface_slave_details_t * mp)
2065 {
2066   vat_main_t *vam = &vat_main;
2067
2068   print (vam->ofp,
2069          "%-25s %-12d %-12d %d", mp->interface_name,
2070          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler_json
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077   vat_json_node_t *node = NULL;
2078
2079   if (VAT_JSON_ARRAY != vam->json_tree.type)
2080     {
2081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2082       vat_json_init_array (&vam->json_tree);
2083     }
2084   node = vat_json_array_add (&vam->json_tree);
2085
2086   vat_json_init_object (node);
2087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2088   vat_json_object_add_string_copy (node, "interface_name",
2089                                    mp->interface_name);
2090   vat_json_object_add_uint (node, "passive", mp->is_passive);
2091   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2092 }
2093
2094 static int
2095 api_sw_interface_slave_dump (vat_main_t * vam)
2096 {
2097   unformat_input_t *i = vam->input;
2098   vl_api_sw_interface_slave_dump_t *mp;
2099   vl_api_control_ping_t *mp_ping;
2100   u32 sw_if_index = ~0;
2101   u8 sw_if_index_set = 0;
2102   int ret;
2103
2104   /* Parse args required to build the message */
2105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2106     {
2107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2108         sw_if_index_set = 1;
2109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2110         sw_if_index_set = 1;
2111       else
2112         break;
2113     }
2114
2115   if (sw_if_index_set == 0)
2116     {
2117       errmsg ("missing vpp interface name. ");
2118       return -99;
2119     }
2120
2121   print (vam->ofp,
2122          "\n%-25s %-12s %-12s %s",
2123          "slave interface name", "sw_if_index", "passive", "long_timeout");
2124
2125   /* Get list of bond interfaces */
2126   M (SW_INTERFACE_SLAVE_DUMP, mp);
2127   mp->sw_if_index = ntohl (sw_if_index);
2128   S (mp);
2129
2130   /* Use a control ping for synchronization */
2131   MPING (CONTROL_PING, mp_ping);
2132   S (mp_ping);
2133
2134   W (ret);
2135   return ret;
2136 }
2137
2138 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2139   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2140 {
2141   vat_main_t *vam = &vat_main;
2142   i32 retval = ntohl (mp->retval);
2143   if (vam->async_mode)
2144     {
2145       vam->async_errors += (retval < 0);
2146     }
2147   else
2148     {
2149       vam->retval = retval;
2150       vam->sw_if_index = ntohl (mp->sw_if_index);
2151       vam->result_ready = 1;
2152     }
2153   vam->regenerate_interface_table = 1;
2154 }
2155
2156 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2157   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2158 {
2159   vat_main_t *vam = &vat_main;
2160   vat_json_node_t node;
2161
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2165                             ntohl (mp->sw_if_index));
2166
2167   vat_json_print (vam->ofp, &node);
2168   vat_json_free (&node);
2169
2170   vam->retval = ntohl (mp->retval);
2171   vam->result_ready = 1;
2172 }
2173
2174 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2175   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   i32 retval = ntohl (mp->retval);
2179   if (vam->async_mode)
2180     {
2181       vam->async_errors += (retval < 0);
2182     }
2183   else
2184     {
2185       vam->retval = retval;
2186       vam->sw_if_index = ntohl (mp->sw_if_index);
2187       vam->result_ready = 1;
2188     }
2189 }
2190
2191 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2192   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2193 {
2194   vat_main_t *vam = &vat_main;
2195   vat_json_node_t node;
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2200
2201   vat_json_print (vam->ofp, &node);
2202   vat_json_free (&node);
2203
2204   vam->retval = ntohl (mp->retval);
2205   vam->result_ready = 1;
2206 }
2207
2208 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2209   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   i32 retval = ntohl (mp->retval);
2213   if (vam->async_mode)
2214     {
2215       vam->async_errors += (retval < 0);
2216     }
2217   else
2218     {
2219       vam->retval = retval;
2220       vam->result_ready = 1;
2221     }
2222 }
2223
2224 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2225   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2226 {
2227   vat_main_t *vam = &vat_main;
2228   vat_json_node_t node;
2229
2230   vat_json_init_object (&node);
2231   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2232   vat_json_object_add_uint (&node, "fwd_entry_index",
2233                             clib_net_to_host_u32 (mp->fwd_entry_index));
2234
2235   vat_json_print (vam->ofp, &node);
2236   vat_json_free (&node);
2237
2238   vam->retval = ntohl (mp->retval);
2239   vam->result_ready = 1;
2240 }
2241
2242 u8 *
2243 format_lisp_transport_protocol (u8 * s, va_list * args)
2244 {
2245   u32 proto = va_arg (*args, u32);
2246
2247   switch (proto)
2248     {
2249     case 1:
2250       return format (s, "udp");
2251     case 2:
2252       return format (s, "api");
2253     default:
2254       return 0;
2255     }
2256   return 0;
2257 }
2258
2259 static void vl_api_one_get_transport_protocol_reply_t_handler
2260   (vl_api_one_get_transport_protocol_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   i32 retval = ntohl (mp->retval);
2264   if (vam->async_mode)
2265     {
2266       vam->async_errors += (retval < 0);
2267     }
2268   else
2269     {
2270       u32 proto = mp->protocol;
2271       print (vam->ofp, "Transport protocol: %U",
2272              format_lisp_transport_protocol, proto);
2273       vam->retval = retval;
2274       vam->result_ready = 1;
2275     }
2276 }
2277
2278 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2279   (vl_api_one_get_transport_protocol_reply_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   vat_json_node_t node;
2283   u8 *s;
2284
2285   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2286   vec_add1 (s, 0);
2287
2288   vat_json_init_object (&node);
2289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2290   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2291
2292   vec_free (s);
2293   vat_json_print (vam->ofp, &node);
2294   vat_json_free (&node);
2295
2296   vam->retval = ntohl (mp->retval);
2297   vam->result_ready = 1;
2298 }
2299
2300 static void vl_api_one_add_del_locator_set_reply_t_handler
2301   (vl_api_one_add_del_locator_set_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       vam->retval = retval;
2312       vam->result_ready = 1;
2313     }
2314 }
2315
2316 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2317   (vl_api_one_add_del_locator_set_reply_t * mp)
2318 {
2319   vat_main_t *vam = &vat_main;
2320   vat_json_node_t node;
2321
2322   vat_json_init_object (&node);
2323   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2324   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2325
2326   vat_json_print (vam->ofp, &node);
2327   vat_json_free (&node);
2328
2329   vam->retval = ntohl (mp->retval);
2330   vam->result_ready = 1;
2331 }
2332
2333 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2334   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2335 {
2336   vat_main_t *vam = &vat_main;
2337   i32 retval = ntohl (mp->retval);
2338   if (vam->async_mode)
2339     {
2340       vam->async_errors += (retval < 0);
2341     }
2342   else
2343     {
2344       vam->retval = retval;
2345       vam->sw_if_index = ntohl (mp->sw_if_index);
2346       vam->result_ready = 1;
2347     }
2348   vam->regenerate_interface_table = 1;
2349 }
2350
2351 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2352   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   vat_json_node_t node;
2356
2357   vat_json_init_object (&node);
2358   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2359   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2360
2361   vat_json_print (vam->ofp, &node);
2362   vat_json_free (&node);
2363
2364   vam->retval = ntohl (mp->retval);
2365   vam->result_ready = 1;
2366 }
2367
2368 static void vl_api_vxlan_offload_rx_reply_t_handler
2369   (vl_api_vxlan_offload_rx_reply_t * mp)
2370 {
2371   vat_main_t *vam = &vat_main;
2372   i32 retval = ntohl (mp->retval);
2373   if (vam->async_mode)
2374     {
2375       vam->async_errors += (retval < 0);
2376     }
2377   else
2378     {
2379       vam->retval = retval;
2380       vam->result_ready = 1;
2381     }
2382 }
2383
2384 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2385   (vl_api_vxlan_offload_rx_reply_t * mp)
2386 {
2387   vat_main_t *vam = &vat_main;
2388   vat_json_node_t node;
2389
2390   vat_json_init_object (&node);
2391   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2392
2393   vat_json_print (vam->ofp, &node);
2394   vat_json_free (&node);
2395
2396   vam->retval = ntohl (mp->retval);
2397   vam->result_ready = 1;
2398 }
2399
2400 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2401   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2402 {
2403   vat_main_t *vam = &vat_main;
2404   i32 retval = ntohl (mp->retval);
2405   if (vam->async_mode)
2406     {
2407       vam->async_errors += (retval < 0);
2408     }
2409   else
2410     {
2411       vam->retval = retval;
2412       vam->sw_if_index = ntohl (mp->sw_if_index);
2413       vam->result_ready = 1;
2414     }
2415 }
2416
2417 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2418   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   vat_json_node_t node;
2422
2423   vat_json_init_object (&node);
2424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427   vat_json_print (vam->ofp, &node);
2428   vat_json_free (&node);
2429
2430   vam->retval = ntohl (mp->retval);
2431   vam->result_ready = 1;
2432 }
2433
2434 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2435   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   i32 retval = ntohl (mp->retval);
2439   if (vam->async_mode)
2440     {
2441       vam->async_errors += (retval < 0);
2442     }
2443   else
2444     {
2445       vam->retval = retval;
2446       vam->sw_if_index = ntohl (mp->sw_if_index);
2447       vam->result_ready = 1;
2448     }
2449   vam->regenerate_interface_table = 1;
2450 }
2451
2452 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2453   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2454 {
2455   vat_main_t *vam = &vat_main;
2456   vat_json_node_t node;
2457
2458   vat_json_init_object (&node);
2459   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462   vat_json_print (vam->ofp, &node);
2463   vat_json_free (&node);
2464
2465   vam->retval = ntohl (mp->retval);
2466   vam->result_ready = 1;
2467 }
2468
2469 static void vl_api_gre_tunnel_add_del_reply_t_handler
2470   (vl_api_gre_tunnel_add_del_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   i32 retval = ntohl (mp->retval);
2474   if (vam->async_mode)
2475     {
2476       vam->async_errors += (retval < 0);
2477     }
2478   else
2479     {
2480       vam->retval = retval;
2481       vam->sw_if_index = ntohl (mp->sw_if_index);
2482       vam->result_ready = 1;
2483     }
2484 }
2485
2486 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2487   (vl_api_gre_tunnel_add_del_reply_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t node;
2491
2492   vat_json_init_object (&node);
2493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2495
2496   vat_json_print (vam->ofp, &node);
2497   vat_json_free (&node);
2498
2499   vam->retval = ntohl (mp->retval);
2500   vam->result_ready = 1;
2501 }
2502
2503 static void vl_api_create_vhost_user_if_reply_t_handler
2504   (vl_api_create_vhost_user_if_reply_t * mp)
2505 {
2506   vat_main_t *vam = &vat_main;
2507   i32 retval = ntohl (mp->retval);
2508   if (vam->async_mode)
2509     {
2510       vam->async_errors += (retval < 0);
2511     }
2512   else
2513     {
2514       vam->retval = retval;
2515       vam->sw_if_index = ntohl (mp->sw_if_index);
2516       vam->result_ready = 1;
2517     }
2518   vam->regenerate_interface_table = 1;
2519 }
2520
2521 static void vl_api_create_vhost_user_if_reply_t_handler_json
2522   (vl_api_create_vhost_user_if_reply_t * mp)
2523 {
2524   vat_main_t *vam = &vat_main;
2525   vat_json_node_t node;
2526
2527   vat_json_init_object (&node);
2528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2529   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2530
2531   vat_json_print (vam->ofp, &node);
2532   vat_json_free (&node);
2533
2534   vam->retval = ntohl (mp->retval);
2535   vam->result_ready = 1;
2536 }
2537
2538 static void vl_api_dns_resolve_name_reply_t_handler
2539   (vl_api_dns_resolve_name_reply_t * mp)
2540 {
2541   vat_main_t *vam = &vat_main;
2542   i32 retval = ntohl (mp->retval);
2543   if (vam->async_mode)
2544     {
2545       vam->async_errors += (retval < 0);
2546     }
2547   else
2548     {
2549       vam->retval = retval;
2550       vam->result_ready = 1;
2551
2552       if (retval == 0)
2553         {
2554           if (mp->ip4_set)
2555             clib_warning ("ip4 address %U", format_ip4_address,
2556                           (ip4_address_t *) mp->ip4_address);
2557           if (mp->ip6_set)
2558             clib_warning ("ip6 address %U", format_ip6_address,
2559                           (ip6_address_t *) mp->ip6_address);
2560         }
2561       else
2562         clib_warning ("retval %d", retval);
2563     }
2564 }
2565
2566 static void vl_api_dns_resolve_name_reply_t_handler_json
2567   (vl_api_dns_resolve_name_reply_t * mp)
2568 {
2569   clib_warning ("not implemented");
2570 }
2571
2572 static void vl_api_dns_resolve_ip_reply_t_handler
2573   (vl_api_dns_resolve_ip_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   i32 retval = ntohl (mp->retval);
2577   if (vam->async_mode)
2578     {
2579       vam->async_errors += (retval < 0);
2580     }
2581   else
2582     {
2583       vam->retval = retval;
2584       vam->result_ready = 1;
2585
2586       if (retval == 0)
2587         {
2588           clib_warning ("canonical name %s", mp->name);
2589         }
2590       else
2591         clib_warning ("retval %d", retval);
2592     }
2593 }
2594
2595 static void vl_api_dns_resolve_ip_reply_t_handler_json
2596   (vl_api_dns_resolve_ip_reply_t * mp)
2597 {
2598   clib_warning ("not implemented");
2599 }
2600
2601
2602 static void vl_api_ip_address_details_t_handler
2603   (vl_api_ip_address_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_address_details_t empty_ip_address_details = { {0} };
2607   ip_address_details_t *address = NULL;
2608   ip_details_t *current_ip_details = NULL;
2609   ip_details_t *details = NULL;
2610
2611   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2612
2613   if (!details || vam->current_sw_if_index >= vec_len (details)
2614       || !details[vam->current_sw_if_index].present)
2615     {
2616       errmsg ("ip address details arrived but not stored");
2617       errmsg ("ip_dump should be called first");
2618       return;
2619     }
2620
2621   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2622
2623 #define addresses (current_ip_details->addr)
2624
2625   vec_validate_init_empty (addresses, vec_len (addresses),
2626                            empty_ip_address_details);
2627
2628   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2629
2630   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2631   address->prefix_length = mp->prefix_length;
2632 #undef addresses
2633 }
2634
2635 static void vl_api_ip_address_details_t_handler_json
2636   (vl_api_ip_address_details_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   vat_json_node_t *node = NULL;
2640   struct in6_addr ip6;
2641   struct in_addr ip4;
2642
2643   if (VAT_JSON_ARRAY != vam->json_tree.type)
2644     {
2645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2646       vat_json_init_array (&vam->json_tree);
2647     }
2648   node = vat_json_array_add (&vam->json_tree);
2649
2650   vat_json_init_object (node);
2651   if (vam->is_ipv6)
2652     {
2653       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2654       vat_json_object_add_ip6 (node, "ip", ip6);
2655     }
2656   else
2657     {
2658       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2659       vat_json_object_add_ip4 (node, "ip", ip4);
2660     }
2661   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2662 }
2663
2664 static void
2665 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   static ip_details_t empty_ip_details = { 0 };
2669   ip_details_t *ip = NULL;
2670   u32 sw_if_index = ~0;
2671
2672   sw_if_index = ntohl (mp->sw_if_index);
2673
2674   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2675                            sw_if_index, empty_ip_details);
2676
2677   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2678                          sw_if_index);
2679
2680   ip->present = 1;
2681 }
2682
2683 static void
2684 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2685 {
2686   vat_main_t *vam = &vat_main;
2687
2688   if (VAT_JSON_ARRAY != vam->json_tree.type)
2689     {
2690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2691       vat_json_init_array (&vam->json_tree);
2692     }
2693   vat_json_array_add_uint (&vam->json_tree,
2694                            clib_net_to_host_u32 (mp->sw_if_index));
2695 }
2696
2697 static void
2698 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2699 {
2700   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2701           "router_addr %U host_mac %U",
2702           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2703           mp->lease.hostname,
2704           format_ip4_address, &mp->lease.host_address,
2705           format_ip4_address, &mp->lease.router_address,
2706           format_ethernet_address, mp->lease.host_mac);
2707 }
2708
2709 static void vl_api_dhcp_compl_event_t_handler_json
2710   (vl_api_dhcp_compl_event_t * mp)
2711 {
2712   /* JSON output not supported */
2713 }
2714
2715 static void vl_api_get_first_msg_id_reply_t_handler
2716   (vl_api_get_first_msg_id_reply_t * mp)
2717 {
2718   vat_main_t *vam = &vat_main;
2719   i32 retval = ntohl (mp->retval);
2720
2721   if (vam->async_mode)
2722     {
2723       vam->async_errors += (retval < 0);
2724     }
2725   else
2726     {
2727       vam->retval = retval;
2728       vam->result_ready = 1;
2729     }
2730   if (retval >= 0)
2731     {
2732       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2733     }
2734 }
2735
2736 static void vl_api_get_first_msg_id_reply_t_handler_json
2737   (vl_api_get_first_msg_id_reply_t * mp)
2738 {
2739   vat_main_t *vam = &vat_main;
2740   vat_json_node_t node;
2741
2742   vat_json_init_object (&node);
2743   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2744   vat_json_object_add_uint (&node, "first_msg_id",
2745                             (uint) ntohs (mp->first_msg_id));
2746
2747   vat_json_print (vam->ofp, &node);
2748   vat_json_free (&node);
2749
2750   vam->retval = ntohl (mp->retval);
2751   vam->result_ready = 1;
2752 }
2753
2754 static void vl_api_get_node_graph_reply_t_handler
2755   (vl_api_get_node_graph_reply_t * mp)
2756 {
2757   vat_main_t *vam = &vat_main;
2758   api_main_t *am = &api_main;
2759   i32 retval = ntohl (mp->retval);
2760   u8 *pvt_copy, *reply;
2761   void *oldheap;
2762   vlib_node_t *node;
2763   int i;
2764
2765   if (vam->async_mode)
2766     {
2767       vam->async_errors += (retval < 0);
2768     }
2769   else
2770     {
2771       vam->retval = retval;
2772       vam->result_ready = 1;
2773     }
2774
2775   /* "Should never happen..." */
2776   if (retval != 0)
2777     return;
2778
2779   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2780   pvt_copy = vec_dup (reply);
2781
2782   /* Toss the shared-memory original... */
2783   pthread_mutex_lock (&am->vlib_rp->mutex);
2784   oldheap = svm_push_data_heap (am->vlib_rp);
2785
2786   vec_free (reply);
2787
2788   svm_pop_heap (oldheap);
2789   pthread_mutex_unlock (&am->vlib_rp->mutex);
2790
2791   if (vam->graph_nodes)
2792     {
2793       hash_free (vam->graph_node_index_by_name);
2794
2795       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2796         {
2797           node = vam->graph_nodes[0][i];
2798           vec_free (node->name);
2799           vec_free (node->next_nodes);
2800           vec_free (node);
2801         }
2802       vec_free (vam->graph_nodes[0]);
2803       vec_free (vam->graph_nodes);
2804     }
2805
2806   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2807   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2808   vec_free (pvt_copy);
2809
2810   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2811     {
2812       node = vam->graph_nodes[0][i];
2813       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2814     }
2815 }
2816
2817 static void vl_api_get_node_graph_reply_t_handler_json
2818   (vl_api_get_node_graph_reply_t * mp)
2819 {
2820   vat_main_t *vam = &vat_main;
2821   api_main_t *am = &api_main;
2822   void *oldheap;
2823   vat_json_node_t node;
2824   u8 *reply;
2825
2826   /* $$$$ make this real? */
2827   vat_json_init_object (&node);
2828   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2829   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2830
2831   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2832
2833   /* Toss the shared-memory original... */
2834   pthread_mutex_lock (&am->vlib_rp->mutex);
2835   oldheap = svm_push_data_heap (am->vlib_rp);
2836
2837   vec_free (reply);
2838
2839   svm_pop_heap (oldheap);
2840   pthread_mutex_unlock (&am->vlib_rp->mutex);
2841
2842   vat_json_print (vam->ofp, &node);
2843   vat_json_free (&node);
2844
2845   vam->retval = ntohl (mp->retval);
2846   vam->result_ready = 1;
2847 }
2848
2849 static void
2850 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2851 {
2852   vat_main_t *vam = &vat_main;
2853   u8 *s = 0;
2854
2855   if (mp->local)
2856     {
2857       s = format (s, "%=16d%=16d%=16d",
2858                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2859     }
2860   else
2861     {
2862       s = format (s, "%=16U%=16d%=16d",
2863                   mp->is_ipv6 ? format_ip6_address :
2864                   format_ip4_address,
2865                   mp->ip_address, mp->priority, mp->weight);
2866     }
2867
2868   print (vam->ofp, "%v", s);
2869   vec_free (s);
2870 }
2871
2872 static void
2873 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2874 {
2875   vat_main_t *vam = &vat_main;
2876   vat_json_node_t *node = NULL;
2877   struct in6_addr ip6;
2878   struct in_addr ip4;
2879
2880   if (VAT_JSON_ARRAY != vam->json_tree.type)
2881     {
2882       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2883       vat_json_init_array (&vam->json_tree);
2884     }
2885   node = vat_json_array_add (&vam->json_tree);
2886   vat_json_init_object (node);
2887
2888   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2889   vat_json_object_add_uint (node, "priority", mp->priority);
2890   vat_json_object_add_uint (node, "weight", mp->weight);
2891
2892   if (mp->local)
2893     vat_json_object_add_uint (node, "sw_if_index",
2894                               clib_net_to_host_u32 (mp->sw_if_index));
2895   else
2896     {
2897       if (mp->is_ipv6)
2898         {
2899           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2900           vat_json_object_add_ip6 (node, "address", ip6);
2901         }
2902       else
2903         {
2904           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2905           vat_json_object_add_ip4 (node, "address", ip4);
2906         }
2907     }
2908 }
2909
2910 static void
2911 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2912                                           mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   u8 *ls_name = 0;
2916
2917   ls_name = format (0, "%s", mp->ls_name);
2918
2919   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2920          ls_name);
2921   vec_free (ls_name);
2922 }
2923
2924 static void
2925   vl_api_one_locator_set_details_t_handler_json
2926   (vl_api_one_locator_set_details_t * mp)
2927 {
2928   vat_main_t *vam = &vat_main;
2929   vat_json_node_t *node = 0;
2930   u8 *ls_name = 0;
2931
2932   ls_name = format (0, "%s", mp->ls_name);
2933   vec_add1 (ls_name, 0);
2934
2935   if (VAT_JSON_ARRAY != vam->json_tree.type)
2936     {
2937       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2938       vat_json_init_array (&vam->json_tree);
2939     }
2940   node = vat_json_array_add (&vam->json_tree);
2941
2942   vat_json_init_object (node);
2943   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2944   vat_json_object_add_uint (node, "ls_index",
2945                             clib_net_to_host_u32 (mp->ls_index));
2946   vec_free (ls_name);
2947 }
2948
2949 typedef struct
2950 {
2951   u32 spi;
2952   u8 si;
2953 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2954
2955 uword
2956 unformat_nsh_address (unformat_input_t * input, va_list * args)
2957 {
2958   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2959   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2960 }
2961
2962 u8 *
2963 format_nsh_address_vat (u8 * s, va_list * args)
2964 {
2965   nsh_t *a = va_arg (*args, nsh_t *);
2966   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2967 }
2968
2969 static u8 *
2970 format_lisp_flat_eid (u8 * s, va_list * args)
2971 {
2972   u32 type = va_arg (*args, u32);
2973   u8 *eid = va_arg (*args, u8 *);
2974   u32 eid_len = va_arg (*args, u32);
2975
2976   switch (type)
2977     {
2978     case 0:
2979       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2980     case 1:
2981       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2982     case 2:
2983       return format (s, "%U", format_ethernet_address, eid);
2984     case 3:
2985       return format (s, "%U", format_nsh_address_vat, eid);
2986     }
2987   return 0;
2988 }
2989
2990 static u8 *
2991 format_lisp_eid_vat (u8 * s, va_list * args)
2992 {
2993   u32 type = va_arg (*args, u32);
2994   u8 *eid = va_arg (*args, u8 *);
2995   u32 eid_len = va_arg (*args, u32);
2996   u8 *seid = va_arg (*args, u8 *);
2997   u32 seid_len = va_arg (*args, u32);
2998   u32 is_src_dst = va_arg (*args, u32);
2999
3000   if (is_src_dst)
3001     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3002
3003   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3004
3005   return s;
3006 }
3007
3008 static void
3009 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3010 {
3011   vat_main_t *vam = &vat_main;
3012   u8 *s = 0, *eid = 0;
3013
3014   if (~0 == mp->locator_set_index)
3015     s = format (0, "action: %d", mp->action);
3016   else
3017     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3018
3019   eid = format (0, "%U", format_lisp_eid_vat,
3020                 mp->eid_type,
3021                 mp->eid,
3022                 mp->eid_prefix_len,
3023                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3024   vec_add1 (eid, 0);
3025
3026   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3027          clib_net_to_host_u32 (mp->vni),
3028          eid,
3029          mp->is_local ? "local" : "remote",
3030          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3031          clib_net_to_host_u16 (mp->key_id), mp->key);
3032
3033   vec_free (s);
3034   vec_free (eid);
3035 }
3036
3037 static void
3038 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3039                                              * mp)
3040 {
3041   vat_main_t *vam = &vat_main;
3042   vat_json_node_t *node = 0;
3043   u8 *eid = 0;
3044
3045   if (VAT_JSON_ARRAY != vam->json_tree.type)
3046     {
3047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3048       vat_json_init_array (&vam->json_tree);
3049     }
3050   node = vat_json_array_add (&vam->json_tree);
3051
3052   vat_json_init_object (node);
3053   if (~0 == mp->locator_set_index)
3054     vat_json_object_add_uint (node, "action", mp->action);
3055   else
3056     vat_json_object_add_uint (node, "locator_set_index",
3057                               clib_net_to_host_u32 (mp->locator_set_index));
3058
3059   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3060   if (mp->eid_type == 3)
3061     {
3062       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3063       vat_json_init_object (nsh_json);
3064       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3065       vat_json_object_add_uint (nsh_json, "spi",
3066                                 clib_net_to_host_u32 (nsh->spi));
3067       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3068     }
3069   else
3070     {
3071       eid = format (0, "%U", format_lisp_eid_vat,
3072                     mp->eid_type,
3073                     mp->eid,
3074                     mp->eid_prefix_len,
3075                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3076       vec_add1 (eid, 0);
3077       vat_json_object_add_string_copy (node, "eid", eid);
3078       vec_free (eid);
3079     }
3080   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3081   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3082   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3083
3084   if (mp->key_id)
3085     {
3086       vat_json_object_add_uint (node, "key_id",
3087                                 clib_net_to_host_u16 (mp->key_id));
3088       vat_json_object_add_string_copy (node, "key", mp->key);
3089     }
3090 }
3091
3092 static void
3093 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3094 {
3095   vat_main_t *vam = &vat_main;
3096   u8 *seid = 0, *deid = 0;
3097   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3098
3099   deid = format (0, "%U", format_lisp_eid_vat,
3100                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3101
3102   seid = format (0, "%U", format_lisp_eid_vat,
3103                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3104
3105   vec_add1 (deid, 0);
3106   vec_add1 (seid, 0);
3107
3108   if (mp->is_ip4)
3109     format_ip_address_fcn = format_ip4_address;
3110   else
3111     format_ip_address_fcn = format_ip6_address;
3112
3113
3114   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3115          clib_net_to_host_u32 (mp->vni),
3116          seid, deid,
3117          format_ip_address_fcn, mp->lloc,
3118          format_ip_address_fcn, mp->rloc,
3119          clib_net_to_host_u32 (mp->pkt_count),
3120          clib_net_to_host_u32 (mp->bytes));
3121
3122   vec_free (deid);
3123   vec_free (seid);
3124 }
3125
3126 static void
3127 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3128 {
3129   struct in6_addr ip6;
3130   struct in_addr ip4;
3131   vat_main_t *vam = &vat_main;
3132   vat_json_node_t *node = 0;
3133   u8 *deid = 0, *seid = 0;
3134
3135   if (VAT_JSON_ARRAY != vam->json_tree.type)
3136     {
3137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3138       vat_json_init_array (&vam->json_tree);
3139     }
3140   node = vat_json_array_add (&vam->json_tree);
3141
3142   vat_json_init_object (node);
3143   deid = format (0, "%U", format_lisp_eid_vat,
3144                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3145
3146   seid = format (0, "%U", format_lisp_eid_vat,
3147                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3148
3149   vec_add1 (deid, 0);
3150   vec_add1 (seid, 0);
3151
3152   vat_json_object_add_string_copy (node, "seid", seid);
3153   vat_json_object_add_string_copy (node, "deid", deid);
3154   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3155
3156   if (mp->is_ip4)
3157     {
3158       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3159       vat_json_object_add_ip4 (node, "lloc", ip4);
3160       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3161       vat_json_object_add_ip4 (node, "rloc", ip4);
3162     }
3163   else
3164     {
3165       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3166       vat_json_object_add_ip6 (node, "lloc", ip6);
3167       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3168       vat_json_object_add_ip6 (node, "rloc", ip6);
3169     }
3170   vat_json_object_add_uint (node, "pkt_count",
3171                             clib_net_to_host_u32 (mp->pkt_count));
3172   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3173
3174   vec_free (deid);
3175   vec_free (seid);
3176 }
3177
3178 static void
3179   vl_api_one_eid_table_map_details_t_handler
3180   (vl_api_one_eid_table_map_details_t * mp)
3181 {
3182   vat_main_t *vam = &vat_main;
3183
3184   u8 *line = format (0, "%=10d%=10d",
3185                      clib_net_to_host_u32 (mp->vni),
3186                      clib_net_to_host_u32 (mp->dp_table));
3187   print (vam->ofp, "%v", line);
3188   vec_free (line);
3189 }
3190
3191 static void
3192   vl_api_one_eid_table_map_details_t_handler_json
3193   (vl_api_one_eid_table_map_details_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196   vat_json_node_t *node = NULL;
3197
3198   if (VAT_JSON_ARRAY != vam->json_tree.type)
3199     {
3200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3201       vat_json_init_array (&vam->json_tree);
3202     }
3203   node = vat_json_array_add (&vam->json_tree);
3204   vat_json_init_object (node);
3205   vat_json_object_add_uint (node, "dp_table",
3206                             clib_net_to_host_u32 (mp->dp_table));
3207   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3208 }
3209
3210 static void
3211   vl_api_one_eid_table_vni_details_t_handler
3212   (vl_api_one_eid_table_vni_details_t * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215
3216   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3217   print (vam->ofp, "%v", line);
3218   vec_free (line);
3219 }
3220
3221 static void
3222   vl_api_one_eid_table_vni_details_t_handler_json
3223   (vl_api_one_eid_table_vni_details_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226   vat_json_node_t *node = NULL;
3227
3228   if (VAT_JSON_ARRAY != vam->json_tree.type)
3229     {
3230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3231       vat_json_init_array (&vam->json_tree);
3232     }
3233   node = vat_json_array_add (&vam->json_tree);
3234   vat_json_init_object (node);
3235   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3236 }
3237
3238 static void
3239   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3240   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   int retval = clib_net_to_host_u32 (mp->retval);
3244
3245   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3246   print (vam->ofp, "fallback threshold value: %d", mp->value);
3247
3248   vam->retval = retval;
3249   vam->result_ready = 1;
3250 }
3251
3252 static void
3253   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3254   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3255 {
3256   vat_main_t *vam = &vat_main;
3257   vat_json_node_t _node, *node = &_node;
3258   int retval = clib_net_to_host_u32 (mp->retval);
3259
3260   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3261   vat_json_init_object (node);
3262   vat_json_object_add_uint (node, "value", mp->value);
3263
3264   vat_json_print (vam->ofp, node);
3265   vat_json_free (node);
3266
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_map_register_state_reply_t_handler
3273   (vl_api_show_one_map_register_state_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   int retval = clib_net_to_host_u32 (mp->retval);
3277
3278   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3279
3280   vam->retval = retval;
3281   vam->result_ready = 1;
3282 }
3283
3284 static void
3285   vl_api_show_one_map_register_state_reply_t_handler_json
3286   (vl_api_show_one_map_register_state_reply_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   vat_json_node_t _node, *node = &_node;
3290   int retval = clib_net_to_host_u32 (mp->retval);
3291
3292   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3293
3294   vat_json_init_object (node);
3295   vat_json_object_add_string_copy (node, "state", s);
3296
3297   vat_json_print (vam->ofp, node);
3298   vat_json_free (node);
3299
3300   vam->retval = retval;
3301   vam->result_ready = 1;
3302   vec_free (s);
3303 }
3304
3305 static void
3306   vl_api_show_one_rloc_probe_state_reply_t_handler
3307   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   int retval = clib_net_to_host_u32 (mp->retval);
3311
3312   if (retval)
3313     goto end;
3314
3315   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3316 end:
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319 }
3320
3321 static void
3322   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3323   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t _node, *node = &_node;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3330   vat_json_init_object (node);
3331   vat_json_object_add_string_copy (node, "state", s);
3332
3333   vat_json_print (vam->ofp, node);
3334   vat_json_free (node);
3335
3336   vam->retval = retval;
3337   vam->result_ready = 1;
3338   vec_free (s);
3339 }
3340
3341 static void
3342   vl_api_show_one_stats_enable_disable_reply_t_handler
3343   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3344 {
3345   vat_main_t *vam = &vat_main;
3346   int retval = clib_net_to_host_u32 (mp->retval);
3347
3348   if (retval)
3349     goto end;
3350
3351   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3352 end:
3353   vam->retval = retval;
3354   vam->result_ready = 1;
3355 }
3356
3357 static void
3358   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3359   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3360 {
3361   vat_main_t *vam = &vat_main;
3362   vat_json_node_t _node, *node = &_node;
3363   int retval = clib_net_to_host_u32 (mp->retval);
3364
3365   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3366   vat_json_init_object (node);
3367   vat_json_object_add_string_copy (node, "state", s);
3368
3369   vat_json_print (vam->ofp, node);
3370   vat_json_free (node);
3371
3372   vam->retval = retval;
3373   vam->result_ready = 1;
3374   vec_free (s);
3375 }
3376
3377 static void
3378 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3379 {
3380   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3381   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3382   e->vni = clib_net_to_host_u32 (e->vni);
3383 }
3384
3385 static void
3386   gpe_fwd_entries_get_reply_t_net_to_host
3387   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3388 {
3389   u32 i;
3390
3391   mp->count = clib_net_to_host_u32 (mp->count);
3392   for (i = 0; i < mp->count; i++)
3393     {
3394       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3395     }
3396 }
3397
3398 static u8 *
3399 format_gpe_encap_mode (u8 * s, va_list * args)
3400 {
3401   u32 mode = va_arg (*args, u32);
3402
3403   switch (mode)
3404     {
3405     case 0:
3406       return format (s, "lisp");
3407     case 1:
3408       return format (s, "vxlan");
3409     }
3410   return 0;
3411 }
3412
3413 static void
3414   vl_api_gpe_get_encap_mode_reply_t_handler
3415   (vl_api_gpe_get_encap_mode_reply_t * mp)
3416 {
3417   vat_main_t *vam = &vat_main;
3418
3419   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3420   vam->retval = ntohl (mp->retval);
3421   vam->result_ready = 1;
3422 }
3423
3424 static void
3425   vl_api_gpe_get_encap_mode_reply_t_handler_json
3426   (vl_api_gpe_get_encap_mode_reply_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   vat_json_node_t node;
3430
3431   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3432   vec_add1 (encap_mode, 0);
3433
3434   vat_json_init_object (&node);
3435   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3436
3437   vec_free (encap_mode);
3438   vat_json_print (vam->ofp, &node);
3439   vat_json_free (&node);
3440
3441   vam->retval = ntohl (mp->retval);
3442   vam->result_ready = 1;
3443 }
3444
3445 static void
3446   vl_api_gpe_fwd_entry_path_details_t_handler
3447   (vl_api_gpe_fwd_entry_path_details_t * mp)
3448 {
3449   vat_main_t *vam = &vat_main;
3450   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3451
3452   if (mp->lcl_loc.is_ip4)
3453     format_ip_address_fcn = format_ip4_address;
3454   else
3455     format_ip_address_fcn = format_ip6_address;
3456
3457   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3458          format_ip_address_fcn, &mp->lcl_loc,
3459          format_ip_address_fcn, &mp->rmt_loc);
3460 }
3461
3462 static void
3463 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3464 {
3465   struct in6_addr ip6;
3466   struct in_addr ip4;
3467
3468   if (loc->is_ip4)
3469     {
3470       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3471       vat_json_object_add_ip4 (n, "address", ip4);
3472     }
3473   else
3474     {
3475       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3476       vat_json_object_add_ip6 (n, "address", ip6);
3477     }
3478   vat_json_object_add_uint (n, "weight", loc->weight);
3479 }
3480
3481 static void
3482   vl_api_gpe_fwd_entry_path_details_t_handler_json
3483   (vl_api_gpe_fwd_entry_path_details_t * mp)
3484 {
3485   vat_main_t *vam = &vat_main;
3486   vat_json_node_t *node = NULL;
3487   vat_json_node_t *loc_node;
3488
3489   if (VAT_JSON_ARRAY != vam->json_tree.type)
3490     {
3491       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3492       vat_json_init_array (&vam->json_tree);
3493     }
3494   node = vat_json_array_add (&vam->json_tree);
3495   vat_json_init_object (node);
3496
3497   loc_node = vat_json_object_add (node, "local_locator");
3498   vat_json_init_object (loc_node);
3499   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3500
3501   loc_node = vat_json_object_add (node, "remote_locator");
3502   vat_json_init_object (loc_node);
3503   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3504 }
3505
3506 static void
3507   vl_api_gpe_fwd_entries_get_reply_t_handler
3508   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3509 {
3510   vat_main_t *vam = &vat_main;
3511   u32 i;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513   vl_api_gpe_fwd_entry_t *e;
3514
3515   if (retval)
3516     goto end;
3517
3518   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3519
3520   for (i = 0; i < mp->count; i++)
3521     {
3522       e = &mp->entries[i];
3523       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3524              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3525              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3526     }
3527
3528 end:
3529   vam->retval = retval;
3530   vam->result_ready = 1;
3531 }
3532
3533 static void
3534   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3535   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3536 {
3537   u8 *s = 0;
3538   vat_main_t *vam = &vat_main;
3539   vat_json_node_t *e = 0, root;
3540   u32 i;
3541   int retval = clib_net_to_host_u32 (mp->retval);
3542   vl_api_gpe_fwd_entry_t *fwd;
3543
3544   if (retval)
3545     goto end;
3546
3547   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3548   vat_json_init_array (&root);
3549
3550   for (i = 0; i < mp->count; i++)
3551     {
3552       e = vat_json_array_add (&root);
3553       fwd = &mp->entries[i];
3554
3555       vat_json_init_object (e);
3556       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3557       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3558       vat_json_object_add_int (e, "vni", fwd->vni);
3559       vat_json_object_add_int (e, "action", fwd->action);
3560
3561       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3562                   fwd->leid_prefix_len);
3563       vec_add1 (s, 0);
3564       vat_json_object_add_string_copy (e, "leid", s);
3565       vec_free (s);
3566
3567       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3568                   fwd->reid_prefix_len);
3569       vec_add1 (s, 0);
3570       vat_json_object_add_string_copy (e, "reid", s);
3571       vec_free (s);
3572     }
3573
3574   vat_json_print (vam->ofp, &root);
3575   vat_json_free (&root);
3576
3577 end:
3578   vam->retval = retval;
3579   vam->result_ready = 1;
3580 }
3581
3582 static void
3583   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3584   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   u32 i, n;
3588   int retval = clib_net_to_host_u32 (mp->retval);
3589   vl_api_gpe_native_fwd_rpath_t *r;
3590
3591   if (retval)
3592     goto end;
3593
3594   n = clib_net_to_host_u32 (mp->count);
3595
3596   for (i = 0; i < n; i++)
3597     {
3598       r = &mp->entries[i];
3599       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3600              clib_net_to_host_u32 (r->fib_index),
3601              clib_net_to_host_u32 (r->nh_sw_if_index),
3602              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3603     }
3604
3605 end:
3606   vam->retval = retval;
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3612   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615   vat_json_node_t root, *e;
3616   u32 i, n;
3617   int retval = clib_net_to_host_u32 (mp->retval);
3618   vl_api_gpe_native_fwd_rpath_t *r;
3619   u8 *s;
3620
3621   if (retval)
3622     goto end;
3623
3624   n = clib_net_to_host_u32 (mp->count);
3625   vat_json_init_array (&root);
3626
3627   for (i = 0; i < n; i++)
3628     {
3629       e = vat_json_array_add (&root);
3630       vat_json_init_object (e);
3631       r = &mp->entries[i];
3632       s =
3633         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3634                 r->nh_addr);
3635       vec_add1 (s, 0);
3636       vat_json_object_add_string_copy (e, "ip4", s);
3637       vec_free (s);
3638
3639       vat_json_object_add_uint (e, "fib_index",
3640                                 clib_net_to_host_u32 (r->fib_index));
3641       vat_json_object_add_uint (e, "nh_sw_if_index",
3642                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3643     }
3644
3645   vat_json_print (vam->ofp, &root);
3646   vat_json_free (&root);
3647
3648 end:
3649   vam->retval = retval;
3650   vam->result_ready = 1;
3651 }
3652
3653 static void
3654   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3655   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3656 {
3657   vat_main_t *vam = &vat_main;
3658   u32 i, n;
3659   int retval = clib_net_to_host_u32 (mp->retval);
3660
3661   if (retval)
3662     goto end;
3663
3664   n = clib_net_to_host_u32 (mp->count);
3665
3666   for (i = 0; i < n; i++)
3667     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3668
3669 end:
3670   vam->retval = retval;
3671   vam->result_ready = 1;
3672 }
3673
3674 static void
3675   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3676   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3677 {
3678   vat_main_t *vam = &vat_main;
3679   vat_json_node_t root;
3680   u32 i, n;
3681   int retval = clib_net_to_host_u32 (mp->retval);
3682
3683   if (retval)
3684     goto end;
3685
3686   n = clib_net_to_host_u32 (mp->count);
3687   vat_json_init_array (&root);
3688
3689   for (i = 0; i < n; i++)
3690     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3691
3692   vat_json_print (vam->ofp, &root);
3693   vat_json_free (&root);
3694
3695 end:
3696   vam->retval = retval;
3697   vam->result_ready = 1;
3698 }
3699
3700 static void
3701   vl_api_one_ndp_entries_get_reply_t_handler
3702   (vl_api_one_ndp_entries_get_reply_t * mp)
3703 {
3704   vat_main_t *vam = &vat_main;
3705   u32 i, n;
3706   int retval = clib_net_to_host_u32 (mp->retval);
3707
3708   if (retval)
3709     goto end;
3710
3711   n = clib_net_to_host_u32 (mp->count);
3712
3713   for (i = 0; i < n; i++)
3714     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3715            format_ethernet_address, mp->entries[i].mac);
3716
3717 end:
3718   vam->retval = retval;
3719   vam->result_ready = 1;
3720 }
3721
3722 static void
3723   vl_api_one_ndp_entries_get_reply_t_handler_json
3724   (vl_api_one_ndp_entries_get_reply_t * mp)
3725 {
3726   u8 *s = 0;
3727   vat_main_t *vam = &vat_main;
3728   vat_json_node_t *e = 0, root;
3729   u32 i, n;
3730   int retval = clib_net_to_host_u32 (mp->retval);
3731   vl_api_one_ndp_entry_t *arp_entry;
3732
3733   if (retval)
3734     goto end;
3735
3736   n = clib_net_to_host_u32 (mp->count);
3737   vat_json_init_array (&root);
3738
3739   for (i = 0; i < n; i++)
3740     {
3741       e = vat_json_array_add (&root);
3742       arp_entry = &mp->entries[i];
3743
3744       vat_json_init_object (e);
3745       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3746       vec_add1 (s, 0);
3747
3748       vat_json_object_add_string_copy (e, "mac", s);
3749       vec_free (s);
3750
3751       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3752       vec_add1 (s, 0);
3753       vat_json_object_add_string_copy (e, "ip6", s);
3754       vec_free (s);
3755     }
3756
3757   vat_json_print (vam->ofp, &root);
3758   vat_json_free (&root);
3759
3760 end:
3761   vam->retval = retval;
3762   vam->result_ready = 1;
3763 }
3764
3765 static void
3766   vl_api_one_l2_arp_entries_get_reply_t_handler
3767   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3768 {
3769   vat_main_t *vam = &vat_main;
3770   u32 i, n;
3771   int retval = clib_net_to_host_u32 (mp->retval);
3772
3773   if (retval)
3774     goto end;
3775
3776   n = clib_net_to_host_u32 (mp->count);
3777
3778   for (i = 0; i < n; i++)
3779     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3780            format_ethernet_address, mp->entries[i].mac);
3781
3782 end:
3783   vam->retval = retval;
3784   vam->result_ready = 1;
3785 }
3786
3787 static void
3788   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3789   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3790 {
3791   u8 *s = 0;
3792   vat_main_t *vam = &vat_main;
3793   vat_json_node_t *e = 0, root;
3794   u32 i, n;
3795   int retval = clib_net_to_host_u32 (mp->retval);
3796   vl_api_one_l2_arp_entry_t *arp_entry;
3797
3798   if (retval)
3799     goto end;
3800
3801   n = clib_net_to_host_u32 (mp->count);
3802   vat_json_init_array (&root);
3803
3804   for (i = 0; i < n; i++)
3805     {
3806       e = vat_json_array_add (&root);
3807       arp_entry = &mp->entries[i];
3808
3809       vat_json_init_object (e);
3810       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3811       vec_add1 (s, 0);
3812
3813       vat_json_object_add_string_copy (e, "mac", s);
3814       vec_free (s);
3815
3816       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3817       vec_add1 (s, 0);
3818       vat_json_object_add_string_copy (e, "ip4", s);
3819       vec_free (s);
3820     }
3821
3822   vat_json_print (vam->ofp, &root);
3823   vat_json_free (&root);
3824
3825 end:
3826   vam->retval = retval;
3827   vam->result_ready = 1;
3828 }
3829
3830 static void
3831 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3832 {
3833   vat_main_t *vam = &vat_main;
3834   u32 i, n;
3835   int retval = clib_net_to_host_u32 (mp->retval);
3836
3837   if (retval)
3838     goto end;
3839
3840   n = clib_net_to_host_u32 (mp->count);
3841
3842   for (i = 0; i < n; i++)
3843     {
3844       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3845     }
3846
3847 end:
3848   vam->retval = retval;
3849   vam->result_ready = 1;
3850 }
3851
3852 static void
3853   vl_api_one_ndp_bd_get_reply_t_handler_json
3854   (vl_api_one_ndp_bd_get_reply_t * mp)
3855 {
3856   vat_main_t *vam = &vat_main;
3857   vat_json_node_t root;
3858   u32 i, n;
3859   int retval = clib_net_to_host_u32 (mp->retval);
3860
3861   if (retval)
3862     goto end;
3863
3864   n = clib_net_to_host_u32 (mp->count);
3865   vat_json_init_array (&root);
3866
3867   for (i = 0; i < n; i++)
3868     {
3869       vat_json_array_add_uint (&root,
3870                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3871     }
3872
3873   vat_json_print (vam->ofp, &root);
3874   vat_json_free (&root);
3875
3876 end:
3877   vam->retval = retval;
3878   vam->result_ready = 1;
3879 }
3880
3881 static void
3882   vl_api_one_l2_arp_bd_get_reply_t_handler
3883   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3884 {
3885   vat_main_t *vam = &vat_main;
3886   u32 i, n;
3887   int retval = clib_net_to_host_u32 (mp->retval);
3888
3889   if (retval)
3890     goto end;
3891
3892   n = clib_net_to_host_u32 (mp->count);
3893
3894   for (i = 0; i < n; i++)
3895     {
3896       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3897     }
3898
3899 end:
3900   vam->retval = retval;
3901   vam->result_ready = 1;
3902 }
3903
3904 static void
3905   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3906   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3907 {
3908   vat_main_t *vam = &vat_main;
3909   vat_json_node_t root;
3910   u32 i, n;
3911   int retval = clib_net_to_host_u32 (mp->retval);
3912
3913   if (retval)
3914     goto end;
3915
3916   n = clib_net_to_host_u32 (mp->count);
3917   vat_json_init_array (&root);
3918
3919   for (i = 0; i < n; i++)
3920     {
3921       vat_json_array_add_uint (&root,
3922                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3923     }
3924
3925   vat_json_print (vam->ofp, &root);
3926   vat_json_free (&root);
3927
3928 end:
3929   vam->retval = retval;
3930   vam->result_ready = 1;
3931 }
3932
3933 static void
3934   vl_api_one_adjacencies_get_reply_t_handler
3935   (vl_api_one_adjacencies_get_reply_t * mp)
3936 {
3937   vat_main_t *vam = &vat_main;
3938   u32 i, n;
3939   int retval = clib_net_to_host_u32 (mp->retval);
3940   vl_api_one_adjacency_t *a;
3941
3942   if (retval)
3943     goto end;
3944
3945   n = clib_net_to_host_u32 (mp->count);
3946
3947   for (i = 0; i < n; i++)
3948     {
3949       a = &mp->adjacencies[i];
3950       print (vam->ofp, "%U %40U",
3951              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3952              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3953     }
3954
3955 end:
3956   vam->retval = retval;
3957   vam->result_ready = 1;
3958 }
3959
3960 static void
3961   vl_api_one_adjacencies_get_reply_t_handler_json
3962   (vl_api_one_adjacencies_get_reply_t * mp)
3963 {
3964   u8 *s = 0;
3965   vat_main_t *vam = &vat_main;
3966   vat_json_node_t *e = 0, root;
3967   u32 i, n;
3968   int retval = clib_net_to_host_u32 (mp->retval);
3969   vl_api_one_adjacency_t *a;
3970
3971   if (retval)
3972     goto end;
3973
3974   n = clib_net_to_host_u32 (mp->count);
3975   vat_json_init_array (&root);
3976
3977   for (i = 0; i < n; i++)
3978     {
3979       e = vat_json_array_add (&root);
3980       a = &mp->adjacencies[i];
3981
3982       vat_json_init_object (e);
3983       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3984                   a->leid_prefix_len);
3985       vec_add1 (s, 0);
3986       vat_json_object_add_string_copy (e, "leid", s);
3987       vec_free (s);
3988
3989       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3990                   a->reid_prefix_len);
3991       vec_add1 (s, 0);
3992       vat_json_object_add_string_copy (e, "reid", s);
3993       vec_free (s);
3994     }
3995
3996   vat_json_print (vam->ofp, &root);
3997   vat_json_free (&root);
3998
3999 end:
4000   vam->retval = retval;
4001   vam->result_ready = 1;
4002 }
4003
4004 static void
4005 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4006 {
4007   vat_main_t *vam = &vat_main;
4008
4009   print (vam->ofp, "%=20U",
4010          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4011          mp->ip_address);
4012 }
4013
4014 static void
4015   vl_api_one_map_server_details_t_handler_json
4016   (vl_api_one_map_server_details_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   vat_json_node_t *node = NULL;
4020   struct in6_addr ip6;
4021   struct in_addr ip4;
4022
4023   if (VAT_JSON_ARRAY != vam->json_tree.type)
4024     {
4025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4026       vat_json_init_array (&vam->json_tree);
4027     }
4028   node = vat_json_array_add (&vam->json_tree);
4029
4030   vat_json_init_object (node);
4031   if (mp->is_ipv6)
4032     {
4033       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4034       vat_json_object_add_ip6 (node, "map-server", ip6);
4035     }
4036   else
4037     {
4038       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4039       vat_json_object_add_ip4 (node, "map-server", ip4);
4040     }
4041 }
4042
4043 static void
4044 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4045                                            * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048
4049   print (vam->ofp, "%=20U",
4050          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4051          mp->ip_address);
4052 }
4053
4054 static void
4055   vl_api_one_map_resolver_details_t_handler_json
4056   (vl_api_one_map_resolver_details_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t *node = NULL;
4060   struct in6_addr ip6;
4061   struct in_addr ip4;
4062
4063   if (VAT_JSON_ARRAY != vam->json_tree.type)
4064     {
4065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4066       vat_json_init_array (&vam->json_tree);
4067     }
4068   node = vat_json_array_add (&vam->json_tree);
4069
4070   vat_json_init_object (node);
4071   if (mp->is_ipv6)
4072     {
4073       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4074       vat_json_object_add_ip6 (node, "map resolver", ip6);
4075     }
4076   else
4077     {
4078       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4079       vat_json_object_add_ip4 (node, "map resolver", ip4);
4080     }
4081 }
4082
4083 static void
4084 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   i32 retval = ntohl (mp->retval);
4088
4089   if (0 <= retval)
4090     {
4091       print (vam->ofp, "feature: %s\ngpe: %s",
4092              mp->feature_status ? "enabled" : "disabled",
4093              mp->gpe_status ? "enabled" : "disabled");
4094     }
4095
4096   vam->retval = retval;
4097   vam->result_ready = 1;
4098 }
4099
4100 static void
4101   vl_api_show_one_status_reply_t_handler_json
4102   (vl_api_show_one_status_reply_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105   vat_json_node_t node;
4106   u8 *gpe_status = NULL;
4107   u8 *feature_status = NULL;
4108
4109   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4110   feature_status = format (0, "%s",
4111                            mp->feature_status ? "enabled" : "disabled");
4112   vec_add1 (gpe_status, 0);
4113   vec_add1 (feature_status, 0);
4114
4115   vat_json_init_object (&node);
4116   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4117   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4118
4119   vec_free (gpe_status);
4120   vec_free (feature_status);
4121
4122   vat_json_print (vam->ofp, &node);
4123   vat_json_free (&node);
4124
4125   vam->retval = ntohl (mp->retval);
4126   vam->result_ready = 1;
4127 }
4128
4129 static void
4130   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4131   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4132 {
4133   vat_main_t *vam = &vat_main;
4134   i32 retval = ntohl (mp->retval);
4135
4136   if (retval >= 0)
4137     {
4138       print (vam->ofp, "%=20s", mp->locator_set_name);
4139     }
4140
4141   vam->retval = retval;
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4147   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   vat_json_node_t *node = NULL;
4151
4152   if (VAT_JSON_ARRAY != vam->json_tree.type)
4153     {
4154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4155       vat_json_init_array (&vam->json_tree);
4156     }
4157   node = vat_json_array_add (&vam->json_tree);
4158
4159   vat_json_init_object (node);
4160   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4161
4162   vat_json_print (vam->ofp, node);
4163   vat_json_free (node);
4164
4165   vam->retval = ntohl (mp->retval);
4166   vam->result_ready = 1;
4167 }
4168
4169 static u8 *
4170 format_lisp_map_request_mode (u8 * s, va_list * args)
4171 {
4172   u32 mode = va_arg (*args, u32);
4173
4174   switch (mode)
4175     {
4176     case 0:
4177       return format (0, "dst-only");
4178     case 1:
4179       return format (0, "src-dst");
4180     }
4181   return 0;
4182 }
4183
4184 static void
4185   vl_api_show_one_map_request_mode_reply_t_handler
4186   (vl_api_show_one_map_request_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   i32 retval = ntohl (mp->retval);
4190
4191   if (0 <= retval)
4192     {
4193       u32 mode = mp->mode;
4194       print (vam->ofp, "map_request_mode: %U",
4195              format_lisp_map_request_mode, mode);
4196     }
4197
4198   vam->retval = retval;
4199   vam->result_ready = 1;
4200 }
4201
4202 static void
4203   vl_api_show_one_map_request_mode_reply_t_handler_json
4204   (vl_api_show_one_map_request_mode_reply_t * mp)
4205 {
4206   vat_main_t *vam = &vat_main;
4207   vat_json_node_t node;
4208   u8 *s = 0;
4209   u32 mode;
4210
4211   mode = mp->mode;
4212   s = format (0, "%U", format_lisp_map_request_mode, mode);
4213   vec_add1 (s, 0);
4214
4215   vat_json_init_object (&node);
4216   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4217   vat_json_print (vam->ofp, &node);
4218   vat_json_free (&node);
4219
4220   vec_free (s);
4221   vam->retval = ntohl (mp->retval);
4222   vam->result_ready = 1;
4223 }
4224
4225 static void
4226   vl_api_one_show_xtr_mode_reply_t_handler
4227   (vl_api_one_show_xtr_mode_reply_t * mp)
4228 {
4229   vat_main_t *vam = &vat_main;
4230   i32 retval = ntohl (mp->retval);
4231
4232   if (0 <= retval)
4233     {
4234       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4235     }
4236
4237   vam->retval = retval;
4238   vam->result_ready = 1;
4239 }
4240
4241 static void
4242   vl_api_one_show_xtr_mode_reply_t_handler_json
4243   (vl_api_one_show_xtr_mode_reply_t * mp)
4244 {
4245   vat_main_t *vam = &vat_main;
4246   vat_json_node_t node;
4247   u8 *status = 0;
4248
4249   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4250   vec_add1 (status, 0);
4251
4252   vat_json_init_object (&node);
4253   vat_json_object_add_string_copy (&node, "status", status);
4254
4255   vec_free (status);
4256
4257   vat_json_print (vam->ofp, &node);
4258   vat_json_free (&node);
4259
4260   vam->retval = ntohl (mp->retval);
4261   vam->result_ready = 1;
4262 }
4263
4264 static void
4265   vl_api_one_show_pitr_mode_reply_t_handler
4266   (vl_api_one_show_pitr_mode_reply_t * mp)
4267 {
4268   vat_main_t *vam = &vat_main;
4269   i32 retval = ntohl (mp->retval);
4270
4271   if (0 <= retval)
4272     {
4273       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4274     }
4275
4276   vam->retval = retval;
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_one_show_pitr_mode_reply_t_handler_json
4282   (vl_api_one_show_pitr_mode_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   vat_json_node_t node;
4286   u8 *status = 0;
4287
4288   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293
4294   vec_free (status);
4295
4296   vat_json_print (vam->ofp, &node);
4297   vat_json_free (&node);
4298
4299   vam->retval = ntohl (mp->retval);
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_one_show_petr_mode_reply_t_handler
4305   (vl_api_one_show_petr_mode_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   i32 retval = ntohl (mp->retval);
4309
4310   if (0 <= retval)
4311     {
4312       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_one_show_petr_mode_reply_t_handler_json
4321   (vl_api_one_show_petr_mode_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326
4327   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "status", status);
4332
4333   vec_free (status);
4334
4335   vat_json_print (vam->ofp, &node);
4336   vat_json_free (&node);
4337
4338   vam->retval = ntohl (mp->retval);
4339   vam->result_ready = 1;
4340 }
4341
4342 static void
4343   vl_api_show_one_use_petr_reply_t_handler
4344   (vl_api_show_one_use_petr_reply_t * mp)
4345 {
4346   vat_main_t *vam = &vat_main;
4347   i32 retval = ntohl (mp->retval);
4348
4349   if (0 <= retval)
4350     {
4351       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4352       if (mp->status)
4353         {
4354           print (vam->ofp, "Proxy-ETR address; %U",
4355                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4356                  mp->address);
4357         }
4358     }
4359
4360   vam->retval = retval;
4361   vam->result_ready = 1;
4362 }
4363
4364 static void
4365   vl_api_show_one_use_petr_reply_t_handler_json
4366   (vl_api_show_one_use_petr_reply_t * mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369   vat_json_node_t node;
4370   u8 *status = 0;
4371   struct in_addr ip4;
4372   struct in6_addr ip6;
4373
4374   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4375   vec_add1 (status, 0);
4376
4377   vat_json_init_object (&node);
4378   vat_json_object_add_string_copy (&node, "status", status);
4379   if (mp->status)
4380     {
4381       if (mp->is_ip4)
4382         {
4383           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4384           vat_json_object_add_ip6 (&node, "address", ip6);
4385         }
4386       else
4387         {
4388           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4389           vat_json_object_add_ip4 (&node, "address", ip4);
4390         }
4391     }
4392
4393   vec_free (status);
4394
4395   vat_json_print (vam->ofp, &node);
4396   vat_json_free (&node);
4397
4398   vam->retval = ntohl (mp->retval);
4399   vam->result_ready = 1;
4400 }
4401
4402 static void
4403   vl_api_show_one_nsh_mapping_reply_t_handler
4404   (vl_api_show_one_nsh_mapping_reply_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   i32 retval = ntohl (mp->retval);
4408
4409   if (0 <= retval)
4410     {
4411       print (vam->ofp, "%-20s%-16s",
4412              mp->is_set ? "set" : "not-set",
4413              mp->is_set ? (char *) mp->locator_set_name : "");
4414     }
4415
4416   vam->retval = retval;
4417   vam->result_ready = 1;
4418 }
4419
4420 static void
4421   vl_api_show_one_nsh_mapping_reply_t_handler_json
4422   (vl_api_show_one_nsh_mapping_reply_t * mp)
4423 {
4424   vat_main_t *vam = &vat_main;
4425   vat_json_node_t node;
4426   u8 *status = 0;
4427
4428   status = format (0, "%s", mp->is_set ? "yes" : "no");
4429   vec_add1 (status, 0);
4430
4431   vat_json_init_object (&node);
4432   vat_json_object_add_string_copy (&node, "is_set", status);
4433   if (mp->is_set)
4434     {
4435       vat_json_object_add_string_copy (&node, "locator_set",
4436                                        mp->locator_set_name);
4437     }
4438
4439   vec_free (status);
4440
4441   vat_json_print (vam->ofp, &node);
4442   vat_json_free (&node);
4443
4444   vam->retval = ntohl (mp->retval);
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449   vl_api_show_one_map_register_ttl_reply_t_handler
4450   (vl_api_show_one_map_register_ttl_reply_t * mp)
4451 {
4452   vat_main_t *vam = &vat_main;
4453   i32 retval = ntohl (mp->retval);
4454
4455   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4456
4457   if (0 <= retval)
4458     {
4459       print (vam->ofp, "ttl: %u", mp->ttl);
4460     }
4461
4462   vam->retval = retval;
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_show_one_map_register_ttl_reply_t_handler_json
4468   (vl_api_show_one_map_register_ttl_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   vat_json_node_t node;
4472
4473   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4474   vat_json_init_object (&node);
4475   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4476
4477   vat_json_print (vam->ofp, &node);
4478   vat_json_free (&node);
4479
4480   vam->retval = ntohl (mp->retval);
4481   vam->result_ready = 1;
4482 }
4483
4484 static void
4485 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   i32 retval = ntohl (mp->retval);
4489
4490   if (0 <= retval)
4491     {
4492       print (vam->ofp, "%-20s%-16s",
4493              mp->status ? "enabled" : "disabled",
4494              mp->status ? (char *) mp->locator_set_name : "");
4495     }
4496
4497   vam->retval = retval;
4498   vam->result_ready = 1;
4499 }
4500
4501 static void
4502 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4503 {
4504   vat_main_t *vam = &vat_main;
4505   vat_json_node_t node;
4506   u8 *status = 0;
4507
4508   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4509   vec_add1 (status, 0);
4510
4511   vat_json_init_object (&node);
4512   vat_json_object_add_string_copy (&node, "status", status);
4513   if (mp->status)
4514     {
4515       vat_json_object_add_string_copy (&node, "locator_set",
4516                                        mp->locator_set_name);
4517     }
4518
4519   vec_free (status);
4520
4521   vat_json_print (vam->ofp, &node);
4522   vat_json_free (&node);
4523
4524   vam->retval = ntohl (mp->retval);
4525   vam->result_ready = 1;
4526 }
4527
4528 static u8 *
4529 format_policer_type (u8 * s, va_list * va)
4530 {
4531   u32 i = va_arg (*va, u32);
4532
4533   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4534     s = format (s, "1r2c");
4535   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4536     s = format (s, "1r3c");
4537   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4538     s = format (s, "2r3c-2698");
4539   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4540     s = format (s, "2r3c-4115");
4541   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4542     s = format (s, "2r3c-mef5cf1");
4543   else
4544     s = format (s, "ILLEGAL");
4545   return s;
4546 }
4547
4548 static u8 *
4549 format_policer_rate_type (u8 * s, va_list * va)
4550 {
4551   u32 i = va_arg (*va, u32);
4552
4553   if (i == SSE2_QOS_RATE_KBPS)
4554     s = format (s, "kbps");
4555   else if (i == SSE2_QOS_RATE_PPS)
4556     s = format (s, "pps");
4557   else
4558     s = format (s, "ILLEGAL");
4559   return s;
4560 }
4561
4562 static u8 *
4563 format_policer_round_type (u8 * s, va_list * va)
4564 {
4565   u32 i = va_arg (*va, u32);
4566
4567   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4568     s = format (s, "closest");
4569   else if (i == SSE2_QOS_ROUND_TO_UP)
4570     s = format (s, "up");
4571   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4572     s = format (s, "down");
4573   else
4574     s = format (s, "ILLEGAL");
4575   return s;
4576 }
4577
4578 static u8 *
4579 format_policer_action_type (u8 * s, va_list * va)
4580 {
4581   u32 i = va_arg (*va, u32);
4582
4583   if (i == SSE2_QOS_ACTION_DROP)
4584     s = format (s, "drop");
4585   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4586     s = format (s, "transmit");
4587   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4588     s = format (s, "mark-and-transmit");
4589   else
4590     s = format (s, "ILLEGAL");
4591   return s;
4592 }
4593
4594 static u8 *
4595 format_dscp (u8 * s, va_list * va)
4596 {
4597   u32 i = va_arg (*va, u32);
4598   char *t = 0;
4599
4600   switch (i)
4601     {
4602 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4603       foreach_vnet_dscp
4604 #undef _
4605     default:
4606       return format (s, "ILLEGAL");
4607     }
4608   s = format (s, "%s", t);
4609   return s;
4610 }
4611
4612 static void
4613 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4614 {
4615   vat_main_t *vam = &vat_main;
4616   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4617
4618   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4619     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4620   else
4621     conform_dscp_str = format (0, "");
4622
4623   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4624     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4625   else
4626     exceed_dscp_str = format (0, "");
4627
4628   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4629     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4630   else
4631     violate_dscp_str = format (0, "");
4632
4633   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4634          "rate type %U, round type %U, %s rate, %s color-aware, "
4635          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4636          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4637          "conform action %U%s, exceed action %U%s, violate action %U%s",
4638          mp->name,
4639          format_policer_type, mp->type,
4640          ntohl (mp->cir),
4641          ntohl (mp->eir),
4642          clib_net_to_host_u64 (mp->cb),
4643          clib_net_to_host_u64 (mp->eb),
4644          format_policer_rate_type, mp->rate_type,
4645          format_policer_round_type, mp->round_type,
4646          mp->single_rate ? "single" : "dual",
4647          mp->color_aware ? "is" : "not",
4648          ntohl (mp->cir_tokens_per_period),
4649          ntohl (mp->pir_tokens_per_period),
4650          ntohl (mp->scale),
4651          ntohl (mp->current_limit),
4652          ntohl (mp->current_bucket),
4653          ntohl (mp->extended_limit),
4654          ntohl (mp->extended_bucket),
4655          clib_net_to_host_u64 (mp->last_update_time),
4656          format_policer_action_type, mp->conform_action_type,
4657          conform_dscp_str,
4658          format_policer_action_type, mp->exceed_action_type,
4659          exceed_dscp_str,
4660          format_policer_action_type, mp->violate_action_type,
4661          violate_dscp_str);
4662
4663   vec_free (conform_dscp_str);
4664   vec_free (exceed_dscp_str);
4665   vec_free (violate_dscp_str);
4666 }
4667
4668 static void vl_api_policer_details_t_handler_json
4669   (vl_api_policer_details_t * mp)
4670 {
4671   vat_main_t *vam = &vat_main;
4672   vat_json_node_t *node;
4673   u8 *rate_type_str, *round_type_str, *type_str;
4674   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4675
4676   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4677   round_type_str =
4678     format (0, "%U", format_policer_round_type, mp->round_type);
4679   type_str = format (0, "%U", format_policer_type, mp->type);
4680   conform_action_str = format (0, "%U", format_policer_action_type,
4681                                mp->conform_action_type);
4682   exceed_action_str = format (0, "%U", format_policer_action_type,
4683                               mp->exceed_action_type);
4684   violate_action_str = format (0, "%U", format_policer_action_type,
4685                                mp->violate_action_type);
4686
4687   if (VAT_JSON_ARRAY != vam->json_tree.type)
4688     {
4689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4690       vat_json_init_array (&vam->json_tree);
4691     }
4692   node = vat_json_array_add (&vam->json_tree);
4693
4694   vat_json_init_object (node);
4695   vat_json_object_add_string_copy (node, "name", mp->name);
4696   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4697   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4698   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4699   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4700   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4701   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4702   vat_json_object_add_string_copy (node, "type", type_str);
4703   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4704   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4705   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4706   vat_json_object_add_uint (node, "cir_tokens_per_period",
4707                             ntohl (mp->cir_tokens_per_period));
4708   vat_json_object_add_uint (node, "eir_tokens_per_period",
4709                             ntohl (mp->pir_tokens_per_period));
4710   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4711   vat_json_object_add_uint (node, "current_bucket",
4712                             ntohl (mp->current_bucket));
4713   vat_json_object_add_uint (node, "extended_limit",
4714                             ntohl (mp->extended_limit));
4715   vat_json_object_add_uint (node, "extended_bucket",
4716                             ntohl (mp->extended_bucket));
4717   vat_json_object_add_uint (node, "last_update_time",
4718                             ntohl (mp->last_update_time));
4719   vat_json_object_add_string_copy (node, "conform_action",
4720                                    conform_action_str);
4721   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4722     {
4723       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4724       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4725       vec_free (dscp_str);
4726     }
4727   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4728   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4729     {
4730       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4731       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4732       vec_free (dscp_str);
4733     }
4734   vat_json_object_add_string_copy (node, "violate_action",
4735                                    violate_action_str);
4736   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4737     {
4738       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4739       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4740       vec_free (dscp_str);
4741     }
4742
4743   vec_free (rate_type_str);
4744   vec_free (round_type_str);
4745   vec_free (type_str);
4746   vec_free (conform_action_str);
4747   vec_free (exceed_action_str);
4748   vec_free (violate_action_str);
4749 }
4750
4751 static void
4752 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4753                                            mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   int i, count = ntohl (mp->count);
4757
4758   if (count > 0)
4759     print (vam->ofp, "classify table ids (%d) : ", count);
4760   for (i = 0; i < count; i++)
4761     {
4762       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4763       print (vam->ofp, (i < count - 1) ? "," : "");
4764     }
4765   vam->retval = ntohl (mp->retval);
4766   vam->result_ready = 1;
4767 }
4768
4769 static void
4770   vl_api_classify_table_ids_reply_t_handler_json
4771   (vl_api_classify_table_ids_reply_t * mp)
4772 {
4773   vat_main_t *vam = &vat_main;
4774   int i, count = ntohl (mp->count);
4775
4776   if (count > 0)
4777     {
4778       vat_json_node_t node;
4779
4780       vat_json_init_object (&node);
4781       for (i = 0; i < count; i++)
4782         {
4783           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4784         }
4785       vat_json_print (vam->ofp, &node);
4786       vat_json_free (&node);
4787     }
4788   vam->retval = ntohl (mp->retval);
4789   vam->result_ready = 1;
4790 }
4791
4792 static void
4793   vl_api_classify_table_by_interface_reply_t_handler
4794   (vl_api_classify_table_by_interface_reply_t * mp)
4795 {
4796   vat_main_t *vam = &vat_main;
4797   u32 table_id;
4798
4799   table_id = ntohl (mp->l2_table_id);
4800   if (table_id != ~0)
4801     print (vam->ofp, "l2 table id : %d", table_id);
4802   else
4803     print (vam->ofp, "l2 table id : No input ACL tables configured");
4804   table_id = ntohl (mp->ip4_table_id);
4805   if (table_id != ~0)
4806     print (vam->ofp, "ip4 table id : %d", table_id);
4807   else
4808     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4809   table_id = ntohl (mp->ip6_table_id);
4810   if (table_id != ~0)
4811     print (vam->ofp, "ip6 table id : %d", table_id);
4812   else
4813     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 static void
4819   vl_api_classify_table_by_interface_reply_t_handler_json
4820   (vl_api_classify_table_by_interface_reply_t * mp)
4821 {
4822   vat_main_t *vam = &vat_main;
4823   vat_json_node_t node;
4824
4825   vat_json_init_object (&node);
4826
4827   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4828   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4829   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4830
4831   vat_json_print (vam->ofp, &node);
4832   vat_json_free (&node);
4833
4834   vam->retval = ntohl (mp->retval);
4835   vam->result_ready = 1;
4836 }
4837
4838 static void vl_api_policer_add_del_reply_t_handler
4839   (vl_api_policer_add_del_reply_t * mp)
4840 {
4841   vat_main_t *vam = &vat_main;
4842   i32 retval = ntohl (mp->retval);
4843   if (vam->async_mode)
4844     {
4845       vam->async_errors += (retval < 0);
4846     }
4847   else
4848     {
4849       vam->retval = retval;
4850       vam->result_ready = 1;
4851       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4852         /*
4853          * Note: this is just barely thread-safe, depends on
4854          * the main thread spinning waiting for an answer...
4855          */
4856         errmsg ("policer index %d", ntohl (mp->policer_index));
4857     }
4858 }
4859
4860 static void vl_api_policer_add_del_reply_t_handler_json
4861   (vl_api_policer_add_del_reply_t * mp)
4862 {
4863   vat_main_t *vam = &vat_main;
4864   vat_json_node_t node;
4865
4866   vat_json_init_object (&node);
4867   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4868   vat_json_object_add_uint (&node, "policer_index",
4869                             ntohl (mp->policer_index));
4870
4871   vat_json_print (vam->ofp, &node);
4872   vat_json_free (&node);
4873
4874   vam->retval = ntohl (mp->retval);
4875   vam->result_ready = 1;
4876 }
4877
4878 /* Format hex dump. */
4879 u8 *
4880 format_hex_bytes (u8 * s, va_list * va)
4881 {
4882   u8 *bytes = va_arg (*va, u8 *);
4883   int n_bytes = va_arg (*va, int);
4884   uword i;
4885
4886   /* Print short or long form depending on byte count. */
4887   uword short_form = n_bytes <= 32;
4888   u32 indent = format_get_indent (s);
4889
4890   if (n_bytes == 0)
4891     return s;
4892
4893   for (i = 0; i < n_bytes; i++)
4894     {
4895       if (!short_form && (i % 32) == 0)
4896         s = format (s, "%08x: ", i);
4897       s = format (s, "%02x", bytes[i]);
4898       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4899         s = format (s, "\n%U", format_white_space, indent);
4900     }
4901
4902   return s;
4903 }
4904
4905 static void
4906 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4907                                             * mp)
4908 {
4909   vat_main_t *vam = &vat_main;
4910   i32 retval = ntohl (mp->retval);
4911   if (retval == 0)
4912     {
4913       print (vam->ofp, "classify table info :");
4914       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4915              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4916              ntohl (mp->miss_next_index));
4917       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4918              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4919              ntohl (mp->match_n_vectors));
4920       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4921              ntohl (mp->mask_length));
4922     }
4923   vam->retval = retval;
4924   vam->result_ready = 1;
4925 }
4926
4927 static void
4928   vl_api_classify_table_info_reply_t_handler_json
4929   (vl_api_classify_table_info_reply_t * mp)
4930 {
4931   vat_main_t *vam = &vat_main;
4932   vat_json_node_t node;
4933
4934   i32 retval = ntohl (mp->retval);
4935   if (retval == 0)
4936     {
4937       vat_json_init_object (&node);
4938
4939       vat_json_object_add_int (&node, "sessions",
4940                                ntohl (mp->active_sessions));
4941       vat_json_object_add_int (&node, "nexttbl",
4942                                ntohl (mp->next_table_index));
4943       vat_json_object_add_int (&node, "nextnode",
4944                                ntohl (mp->miss_next_index));
4945       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4946       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4947       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4948       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4949                       ntohl (mp->mask_length), 0);
4950       vat_json_object_add_string_copy (&node, "mask", s);
4951
4952       vat_json_print (vam->ofp, &node);
4953       vat_json_free (&node);
4954     }
4955   vam->retval = ntohl (mp->retval);
4956   vam->result_ready = 1;
4957 }
4958
4959 static void
4960 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4961                                            mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964
4965   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4966          ntohl (mp->hit_next_index), ntohl (mp->advance),
4967          ntohl (mp->opaque_index));
4968   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4969          ntohl (mp->match_length));
4970 }
4971
4972 static void
4973   vl_api_classify_session_details_t_handler_json
4974   (vl_api_classify_session_details_t * mp)
4975 {
4976   vat_main_t *vam = &vat_main;
4977   vat_json_node_t *node = NULL;
4978
4979   if (VAT_JSON_ARRAY != vam->json_tree.type)
4980     {
4981       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4982       vat_json_init_array (&vam->json_tree);
4983     }
4984   node = vat_json_array_add (&vam->json_tree);
4985
4986   vat_json_init_object (node);
4987   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4988   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4989   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4990   u8 *s =
4991     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4992             0);
4993   vat_json_object_add_string_copy (node, "match", s);
4994 }
4995
4996 static void vl_api_pg_create_interface_reply_t_handler
4997   (vl_api_pg_create_interface_reply_t * mp)
4998 {
4999   vat_main_t *vam = &vat_main;
5000
5001   vam->retval = ntohl (mp->retval);
5002   vam->result_ready = 1;
5003 }
5004
5005 static void vl_api_pg_create_interface_reply_t_handler_json
5006   (vl_api_pg_create_interface_reply_t * mp)
5007 {
5008   vat_main_t *vam = &vat_main;
5009   vat_json_node_t node;
5010
5011   i32 retval = ntohl (mp->retval);
5012   if (retval == 0)
5013     {
5014       vat_json_init_object (&node);
5015
5016       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5017
5018       vat_json_print (vam->ofp, &node);
5019       vat_json_free (&node);
5020     }
5021   vam->retval = ntohl (mp->retval);
5022   vam->result_ready = 1;
5023 }
5024
5025 static void vl_api_policer_classify_details_t_handler
5026   (vl_api_policer_classify_details_t * mp)
5027 {
5028   vat_main_t *vam = &vat_main;
5029
5030   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5031          ntohl (mp->table_index));
5032 }
5033
5034 static void vl_api_policer_classify_details_t_handler_json
5035   (vl_api_policer_classify_details_t * mp)
5036 {
5037   vat_main_t *vam = &vat_main;
5038   vat_json_node_t *node;
5039
5040   if (VAT_JSON_ARRAY != vam->json_tree.type)
5041     {
5042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5043       vat_json_init_array (&vam->json_tree);
5044     }
5045   node = vat_json_array_add (&vam->json_tree);
5046
5047   vat_json_init_object (node);
5048   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5049   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5050 }
5051
5052 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5053   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5054 {
5055   vat_main_t *vam = &vat_main;
5056   i32 retval = ntohl (mp->retval);
5057   if (vam->async_mode)
5058     {
5059       vam->async_errors += (retval < 0);
5060     }
5061   else
5062     {
5063       vam->retval = retval;
5064       vam->sw_if_index = ntohl (mp->sw_if_index);
5065       vam->result_ready = 1;
5066     }
5067   vam->regenerate_interface_table = 1;
5068 }
5069
5070 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5071   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5072 {
5073   vat_main_t *vam = &vat_main;
5074   vat_json_node_t node;
5075
5076   vat_json_init_object (&node);
5077   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5078   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5079
5080   vat_json_print (vam->ofp, &node);
5081   vat_json_free (&node);
5082
5083   vam->retval = ntohl (mp->retval);
5084   vam->result_ready = 1;
5085 }
5086
5087 static void vl_api_flow_classify_details_t_handler
5088   (vl_api_flow_classify_details_t * mp)
5089 {
5090   vat_main_t *vam = &vat_main;
5091
5092   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5093          ntohl (mp->table_index));
5094 }
5095
5096 static void vl_api_flow_classify_details_t_handler_json
5097   (vl_api_flow_classify_details_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100   vat_json_node_t *node;
5101
5102   if (VAT_JSON_ARRAY != vam->json_tree.type)
5103     {
5104       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5105       vat_json_init_array (&vam->json_tree);
5106     }
5107   node = vat_json_array_add (&vam->json_tree);
5108
5109   vat_json_init_object (node);
5110   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5111   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5112 }
5113
5114 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5115 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5116 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5117 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5118 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5119 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5120 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5121 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5122 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5123 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5124
5125 /*
5126  * Generate boilerplate reply handlers, which
5127  * dig the return value out of the xxx_reply_t API message,
5128  * stick it into vam->retval, and set vam->result_ready
5129  *
5130  * Could also do this by pointing N message decode slots at
5131  * a single function, but that could break in subtle ways.
5132  */
5133
5134 #define foreach_standard_reply_retval_handler           \
5135 _(sw_interface_set_flags_reply)                         \
5136 _(sw_interface_add_del_address_reply)                   \
5137 _(sw_interface_set_rx_mode_reply)                       \
5138 _(sw_interface_set_rx_placement_reply)                  \
5139 _(sw_interface_set_table_reply)                         \
5140 _(sw_interface_set_mpls_enable_reply)                   \
5141 _(sw_interface_set_vpath_reply)                         \
5142 _(sw_interface_set_vxlan_bypass_reply)                  \
5143 _(sw_interface_set_geneve_bypass_reply)                 \
5144 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5145 _(sw_interface_set_l2_bridge_reply)                     \
5146 _(bridge_domain_add_del_reply)                          \
5147 _(sw_interface_set_l2_xconnect_reply)                   \
5148 _(l2fib_add_del_reply)                                  \
5149 _(l2fib_flush_int_reply)                                \
5150 _(l2fib_flush_bd_reply)                                 \
5151 _(ip_add_del_route_reply)                               \
5152 _(ip_table_add_del_reply)                               \
5153 _(ip_mroute_add_del_reply)                              \
5154 _(mpls_route_add_del_reply)                             \
5155 _(mpls_table_add_del_reply)                             \
5156 _(mpls_ip_bind_unbind_reply)                            \
5157 _(bier_route_add_del_reply)                             \
5158 _(bier_table_add_del_reply)                             \
5159 _(proxy_arp_add_del_reply)                              \
5160 _(proxy_arp_intfc_enable_disable_reply)                 \
5161 _(sw_interface_set_unnumbered_reply)                    \
5162 _(ip_neighbor_add_del_reply)                            \
5163 _(oam_add_del_reply)                                    \
5164 _(reset_fib_reply)                                      \
5165 _(dhcp_proxy_config_reply)                              \
5166 _(dhcp_proxy_set_vss_reply)                             \
5167 _(dhcp_client_config_reply)                             \
5168 _(set_ip_flow_hash_reply)                               \
5169 _(sw_interface_ip6_enable_disable_reply)                \
5170 _(ip6nd_proxy_add_del_reply)                            \
5171 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5172 _(sw_interface_ip6nd_ra_config_reply)                   \
5173 _(set_arp_neighbor_limit_reply)                         \
5174 _(l2_patch_add_del_reply)                               \
5175 _(sr_mpls_policy_add_reply)                             \
5176 _(sr_mpls_policy_mod_reply)                             \
5177 _(sr_mpls_policy_del_reply)                             \
5178 _(sr_policy_add_reply)                                  \
5179 _(sr_policy_mod_reply)                                  \
5180 _(sr_policy_del_reply)                                  \
5181 _(sr_localsid_add_del_reply)                            \
5182 _(sr_steering_add_del_reply)                            \
5183 _(classify_add_del_session_reply)                       \
5184 _(classify_set_interface_ip_table_reply)                \
5185 _(classify_set_interface_l2_tables_reply)               \
5186 _(l2tpv3_set_tunnel_cookies_reply)                      \
5187 _(l2tpv3_interface_enable_disable_reply)                \
5188 _(l2tpv3_set_lookup_key_reply)                          \
5189 _(l2_fib_clear_table_reply)                             \
5190 _(l2_interface_efp_filter_reply)                        \
5191 _(l2_interface_vlan_tag_rewrite_reply)                  \
5192 _(modify_vhost_user_if_reply)                           \
5193 _(delete_vhost_user_if_reply)                           \
5194 _(ip_probe_neighbor_reply)                              \
5195 _(ip_scan_neighbor_enable_disable_reply)                \
5196 _(want_ip4_arp_events_reply)                            \
5197 _(want_ip6_nd_events_reply)                             \
5198 _(want_l2_macs_events_reply)                            \
5199 _(input_acl_set_interface_reply)                        \
5200 _(ipsec_spd_add_del_reply)                              \
5201 _(ipsec_interface_add_del_spd_reply)                    \
5202 _(ipsec_spd_entry_add_del_reply)                        \
5203 _(ipsec_sad_entry_add_del_reply)                        \
5204 _(ipsec_sa_set_key_reply)                               \
5205 _(ipsec_tunnel_if_add_del_reply)                        \
5206 _(ipsec_tunnel_if_set_key_reply)                        \
5207 _(ipsec_tunnel_if_set_sa_reply)                         \
5208 _(delete_loopback_reply)                                \
5209 _(bd_ip_mac_add_del_reply)                              \
5210 _(bd_ip_mac_flush_reply)                                \
5211 _(want_interface_events_reply)                          \
5212 _(cop_interface_enable_disable_reply)                   \
5213 _(cop_whitelist_enable_disable_reply)                   \
5214 _(sw_interface_clear_stats_reply)                       \
5215 _(ioam_enable_reply)                                    \
5216 _(ioam_disable_reply)                                   \
5217 _(one_add_del_locator_reply)                            \
5218 _(one_add_del_local_eid_reply)                          \
5219 _(one_add_del_remote_mapping_reply)                     \
5220 _(one_add_del_adjacency_reply)                          \
5221 _(one_add_del_map_resolver_reply)                       \
5222 _(one_add_del_map_server_reply)                         \
5223 _(one_enable_disable_reply)                             \
5224 _(one_rloc_probe_enable_disable_reply)                  \
5225 _(one_map_register_enable_disable_reply)                \
5226 _(one_map_register_set_ttl_reply)                       \
5227 _(one_set_transport_protocol_reply)                     \
5228 _(one_map_register_fallback_threshold_reply)            \
5229 _(one_pitr_set_locator_set_reply)                       \
5230 _(one_map_request_mode_reply)                           \
5231 _(one_add_del_map_request_itr_rlocs_reply)              \
5232 _(one_eid_table_add_del_map_reply)                      \
5233 _(one_use_petr_reply)                                   \
5234 _(one_stats_enable_disable_reply)                       \
5235 _(one_add_del_l2_arp_entry_reply)                       \
5236 _(one_add_del_ndp_entry_reply)                          \
5237 _(one_stats_flush_reply)                                \
5238 _(one_enable_disable_xtr_mode_reply)                    \
5239 _(one_enable_disable_pitr_mode_reply)                   \
5240 _(one_enable_disable_petr_mode_reply)                   \
5241 _(gpe_enable_disable_reply)                             \
5242 _(gpe_set_encap_mode_reply)                             \
5243 _(gpe_add_del_iface_reply)                              \
5244 _(gpe_add_del_native_fwd_rpath_reply)                   \
5245 _(af_packet_delete_reply)                               \
5246 _(policer_classify_set_interface_reply)                 \
5247 _(netmap_create_reply)                                  \
5248 _(netmap_delete_reply)                                  \
5249 _(set_ipfix_exporter_reply)                             \
5250 _(set_ipfix_classify_stream_reply)                      \
5251 _(ipfix_classify_table_add_del_reply)                   \
5252 _(flow_classify_set_interface_reply)                    \
5253 _(sw_interface_span_enable_disable_reply)               \
5254 _(pg_capture_reply)                                     \
5255 _(pg_enable_disable_reply)                              \
5256 _(ip_source_and_port_range_check_add_del_reply)         \
5257 _(ip_source_and_port_range_check_interface_add_del_reply)\
5258 _(delete_subif_reply)                                   \
5259 _(l2_interface_pbb_tag_rewrite_reply)                   \
5260 _(set_punt_reply)                                       \
5261 _(feature_enable_disable_reply)                         \
5262 _(sw_interface_tag_add_del_reply)                       \
5263 _(hw_interface_set_mtu_reply)                           \
5264 _(p2p_ethernet_add_reply)                               \
5265 _(p2p_ethernet_del_reply)                               \
5266 _(lldp_config_reply)                                    \
5267 _(sw_interface_set_lldp_reply)                          \
5268 _(tcp_configure_src_addresses_reply)                    \
5269 _(dns_enable_disable_reply)                             \
5270 _(dns_name_server_add_del_reply)                        \
5271 _(session_rule_add_del_reply)                           \
5272 _(ip_container_proxy_add_del_reply)                     \
5273 _(output_acl_set_interface_reply)                       \
5274 _(qos_record_enable_disable_reply)
5275
5276 #define _(n)                                    \
5277     static void vl_api_##n##_t_handler          \
5278     (vl_api_##n##_t * mp)                       \
5279     {                                           \
5280         vat_main_t * vam = &vat_main;           \
5281         i32 retval = ntohl(mp->retval);         \
5282         if (vam->async_mode) {                  \
5283             vam->async_errors += (retval < 0);  \
5284         } else {                                \
5285             vam->retval = retval;               \
5286             vam->result_ready = 1;              \
5287         }                                       \
5288     }
5289 foreach_standard_reply_retval_handler;
5290 #undef _
5291
5292 #define _(n)                                    \
5293     static void vl_api_##n##_t_handler_json     \
5294     (vl_api_##n##_t * mp)                       \
5295     {                                           \
5296         vat_main_t * vam = &vat_main;           \
5297         vat_json_node_t node;                   \
5298         vat_json_init_object(&node);            \
5299         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5300         vat_json_print(vam->ofp, &node);        \
5301         vam->retval = ntohl(mp->retval);        \
5302         vam->result_ready = 1;                  \
5303     }
5304 foreach_standard_reply_retval_handler;
5305 #undef _
5306
5307 /*
5308  * Table of message reply handlers, must include boilerplate handlers
5309  * we just generated
5310  */
5311
5312 #define foreach_vpe_api_reply_msg                                       \
5313 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5314 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5315 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5316 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5317 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5318 _(CLI_REPLY, cli_reply)                                                 \
5319 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5320 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5321   sw_interface_add_del_address_reply)                                   \
5322 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5323 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5324 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5325 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5326 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5327 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5328 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5329 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5330 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5331 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5332   sw_interface_set_l2_xconnect_reply)                                   \
5333 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5334   sw_interface_set_l2_bridge_reply)                                     \
5335 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5336 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5337 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5338 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5339 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5340 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5341 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5342 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5343 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5344 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5345 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5346 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5347 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5348 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5349 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5350 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5351 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5352 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5353 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5354 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5355 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5356 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5357 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5358 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5359 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5360 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5361 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5362 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5363 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5364 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5365   proxy_arp_intfc_enable_disable_reply)                                 \
5366 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5367 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5368   sw_interface_set_unnumbered_reply)                                    \
5369 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5370 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5371 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5372 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5373 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5374 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5375 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5376 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5377 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5378 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5379 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5380   sw_interface_ip6_enable_disable_reply)                                \
5381 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5382 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5383 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5384   sw_interface_ip6nd_ra_prefix_reply)                                   \
5385 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5386   sw_interface_ip6nd_ra_config_reply)                                   \
5387 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5388 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5389 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5390 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5391 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5392 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5393 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5394 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5395 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5396 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5397 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5398 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5399 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5400 classify_set_interface_ip_table_reply)                                  \
5401 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5402   classify_set_interface_l2_tables_reply)                               \
5403 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5404 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5405 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5406 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5407 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5408   l2tpv3_interface_enable_disable_reply)                                \
5409 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5410 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5411 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5412 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5413 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5414 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5415 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5416 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5417 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5418 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5419 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5420 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5421 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5422 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5423 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5424 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5425 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5426 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5427 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5428 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5429 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5430 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5431 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5432 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5433 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5434 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5435 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5436 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5437 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5438 _(L2_MACS_EVENT, l2_macs_event)                                         \
5439 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5440 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5441 _(IP_DETAILS, ip_details)                                               \
5442 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5443 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5444 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5445 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5446 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5447 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5448 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5449 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5450 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5451 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5452 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5453 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5454 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5455 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5456 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5457 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5458 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5459 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5460 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5461 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5462 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5463 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5464 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5465 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5466 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5467 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5468 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5469 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5470 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5471 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5472 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5473   one_map_register_enable_disable_reply)                                \
5474 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5475 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5476 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5477 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5478   one_map_register_fallback_threshold_reply)                            \
5479 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5480   one_rloc_probe_enable_disable_reply)                                  \
5481 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5482 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5483 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5484 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5485 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5486 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5487 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5488 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5489 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5490 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5491 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5492 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5493 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5494 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5495 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5496 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5497   show_one_stats_enable_disable_reply)                                  \
5498 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5499 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5500 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5501 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5502 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5503 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5504 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5505 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5506   one_enable_disable_pitr_mode_reply)                                   \
5507 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5508   one_enable_disable_petr_mode_reply)                                   \
5509 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5510 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5511 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5512 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5513 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5514 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5515 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5516 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5517 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5518 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5519 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5520 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5521   gpe_add_del_native_fwd_rpath_reply)                                   \
5522 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5523   gpe_fwd_entry_path_details)                                           \
5524 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5525 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5526   one_add_del_map_request_itr_rlocs_reply)                              \
5527 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5528   one_get_map_request_itr_rlocs_reply)                                  \
5529 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5530 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5531 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5532 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5533 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5534 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5535   show_one_map_register_state_reply)                                    \
5536 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5537 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5538   show_one_map_register_fallback_threshold_reply)                       \
5539 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5540 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5541 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5542 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5543 _(POLICER_DETAILS, policer_details)                                     \
5544 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5545 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5546 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5547 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5548 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5549 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5550 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5551 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5552 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5553 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5554 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5555 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5556 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5557 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5558 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5559 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5560 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5561 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5562 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5563 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5564 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5565 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5566 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5567 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5568 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5569  ip_source_and_port_range_check_add_del_reply)                          \
5570 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5571  ip_source_and_port_range_check_interface_add_del_reply)                \
5572 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5573 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5574 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5575 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5576 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5577 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5578 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5579 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5580 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5581 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5582 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5583 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5584 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5585 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5586 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5587 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5588 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5589 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5590 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5591 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5592 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5593 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5594 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5595 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5596 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5597 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5598 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5599 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5600
5601 #define foreach_standalone_reply_msg                                    \
5602 _(SW_INTERFACE_EVENT, sw_interface_event)
5603
5604 typedef struct
5605 {
5606   u8 *name;
5607   u32 value;
5608 } name_sort_t;
5609
5610 #define STR_VTR_OP_CASE(op)     \
5611     case L2_VTR_ ## op:         \
5612         return "" # op;
5613
5614 static const char *
5615 str_vtr_op (u32 vtr_op)
5616 {
5617   switch (vtr_op)
5618     {
5619       STR_VTR_OP_CASE (DISABLED);
5620       STR_VTR_OP_CASE (PUSH_1);
5621       STR_VTR_OP_CASE (PUSH_2);
5622       STR_VTR_OP_CASE (POP_1);
5623       STR_VTR_OP_CASE (POP_2);
5624       STR_VTR_OP_CASE (TRANSLATE_1_1);
5625       STR_VTR_OP_CASE (TRANSLATE_1_2);
5626       STR_VTR_OP_CASE (TRANSLATE_2_1);
5627       STR_VTR_OP_CASE (TRANSLATE_2_2);
5628     }
5629
5630   return "UNKNOWN";
5631 }
5632
5633 static int
5634 dump_sub_interface_table (vat_main_t * vam)
5635 {
5636   const sw_interface_subif_t *sub = NULL;
5637
5638   if (vam->json_output)
5639     {
5640       clib_warning
5641         ("JSON output supported only for VPE API calls and dump_stats_table");
5642       return -99;
5643     }
5644
5645   print (vam->ofp,
5646          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5647          "Interface", "sw_if_index",
5648          "sub id", "dot1ad", "tags", "outer id",
5649          "inner id", "exact", "default", "outer any", "inner any");
5650
5651   vec_foreach (sub, vam->sw_if_subif_table)
5652   {
5653     print (vam->ofp,
5654            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5655            sub->interface_name,
5656            sub->sw_if_index,
5657            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5658            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5659            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5660            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5661     if (sub->vtr_op != L2_VTR_DISABLED)
5662       {
5663         print (vam->ofp,
5664                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5665                "tag1: %d tag2: %d ]",
5666                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5667                sub->vtr_tag1, sub->vtr_tag2);
5668       }
5669   }
5670
5671   return 0;
5672 }
5673
5674 static int
5675 name_sort_cmp (void *a1, void *a2)
5676 {
5677   name_sort_t *n1 = a1;
5678   name_sort_t *n2 = a2;
5679
5680   return strcmp ((char *) n1->name, (char *) n2->name);
5681 }
5682
5683 static int
5684 dump_interface_table (vat_main_t * vam)
5685 {
5686   hash_pair_t *p;
5687   name_sort_t *nses = 0, *ns;
5688
5689   if (vam->json_output)
5690     {
5691       clib_warning
5692         ("JSON output supported only for VPE API calls and dump_stats_table");
5693       return -99;
5694     }
5695
5696   /* *INDENT-OFF* */
5697   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5698   ({
5699     vec_add2 (nses, ns, 1);
5700     ns->name = (u8 *)(p->key);
5701     ns->value = (u32) p->value[0];
5702   }));
5703   /* *INDENT-ON* */
5704
5705   vec_sort_with_function (nses, name_sort_cmp);
5706
5707   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5708   vec_foreach (ns, nses)
5709   {
5710     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5711   }
5712   vec_free (nses);
5713   return 0;
5714 }
5715
5716 static int
5717 dump_ip_table (vat_main_t * vam, int is_ipv6)
5718 {
5719   const ip_details_t *det = NULL;
5720   const ip_address_details_t *address = NULL;
5721   u32 i = ~0;
5722
5723   print (vam->ofp, "%-12s", "sw_if_index");
5724
5725   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5726   {
5727     i++;
5728     if (!det->present)
5729       {
5730         continue;
5731       }
5732     print (vam->ofp, "%-12d", i);
5733     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5734     if (!det->addr)
5735       {
5736         continue;
5737       }
5738     vec_foreach (address, det->addr)
5739     {
5740       print (vam->ofp,
5741              "            %-30U%-13d",
5742              is_ipv6 ? format_ip6_address : format_ip4_address,
5743              address->ip, address->prefix_length);
5744     }
5745   }
5746
5747   return 0;
5748 }
5749
5750 static int
5751 dump_ipv4_table (vat_main_t * vam)
5752 {
5753   if (vam->json_output)
5754     {
5755       clib_warning
5756         ("JSON output supported only for VPE API calls and dump_stats_table");
5757       return -99;
5758     }
5759
5760   return dump_ip_table (vam, 0);
5761 }
5762
5763 static int
5764 dump_ipv6_table (vat_main_t * vam)
5765 {
5766   if (vam->json_output)
5767     {
5768       clib_warning
5769         ("JSON output supported only for VPE API calls and dump_stats_table");
5770       return -99;
5771     }
5772
5773   return dump_ip_table (vam, 1);
5774 }
5775
5776 /*
5777  * Pass CLI buffers directly in the CLI_INBAND API message,
5778  * instead of an additional shared memory area.
5779  */
5780 static int
5781 exec_inband (vat_main_t * vam)
5782 {
5783   vl_api_cli_inband_t *mp;
5784   unformat_input_t *i = vam->input;
5785   int ret;
5786
5787   if (vec_len (i->buffer) == 0)
5788     return -1;
5789
5790   if (vam->exec_mode == 0 && unformat (i, "mode"))
5791     {
5792       vam->exec_mode = 1;
5793       return 0;
5794     }
5795   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5796     {
5797       vam->exec_mode = 0;
5798       return 0;
5799     }
5800
5801   /*
5802    * In order for the CLI command to work, it
5803    * must be a vector ending in \n, not a C-string ending
5804    * in \n\0.
5805    */
5806   u32 len = vec_len (vam->input->buffer);
5807   M2 (CLI_INBAND, mp, len);
5808   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5809
5810   S (mp);
5811   W (ret);
5812   /* json responses may or may not include a useful reply... */
5813   if (vec_len (vam->cmd_reply))
5814     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5815   return ret;
5816 }
5817
5818 int
5819 exec (vat_main_t * vam)
5820 {
5821   return exec_inband (vam);
5822 }
5823
5824 static int
5825 api_create_loopback (vat_main_t * vam)
5826 {
5827   unformat_input_t *i = vam->input;
5828   vl_api_create_loopback_t *mp;
5829   vl_api_create_loopback_instance_t *mp_lbi;
5830   u8 mac_address[6];
5831   u8 mac_set = 0;
5832   u8 is_specified = 0;
5833   u32 user_instance = 0;
5834   int ret;
5835
5836   clib_memset (mac_address, 0, sizeof (mac_address));
5837
5838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5839     {
5840       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5841         mac_set = 1;
5842       if (unformat (i, "instance %d", &user_instance))
5843         is_specified = 1;
5844       else
5845         break;
5846     }
5847
5848   if (is_specified)
5849     {
5850       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5851       mp_lbi->is_specified = is_specified;
5852       if (is_specified)
5853         mp_lbi->user_instance = htonl (user_instance);
5854       if (mac_set)
5855         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5856       S (mp_lbi);
5857     }
5858   else
5859     {
5860       /* Construct the API message */
5861       M (CREATE_LOOPBACK, mp);
5862       if (mac_set)
5863         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5864       S (mp);
5865     }
5866
5867   W (ret);
5868   return ret;
5869 }
5870
5871 static int
5872 api_delete_loopback (vat_main_t * vam)
5873 {
5874   unformat_input_t *i = vam->input;
5875   vl_api_delete_loopback_t *mp;
5876   u32 sw_if_index = ~0;
5877   int ret;
5878
5879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5880     {
5881       if (unformat (i, "sw_if_index %d", &sw_if_index))
5882         ;
5883       else
5884         break;
5885     }
5886
5887   if (sw_if_index == ~0)
5888     {
5889       errmsg ("missing sw_if_index");
5890       return -99;
5891     }
5892
5893   /* Construct the API message */
5894   M (DELETE_LOOPBACK, mp);
5895   mp->sw_if_index = ntohl (sw_if_index);
5896
5897   S (mp);
5898   W (ret);
5899   return ret;
5900 }
5901
5902 static int
5903 api_want_interface_events (vat_main_t * vam)
5904 {
5905   unformat_input_t *i = vam->input;
5906   vl_api_want_interface_events_t *mp;
5907   int enable = -1;
5908   int ret;
5909
5910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5911     {
5912       if (unformat (i, "enable"))
5913         enable = 1;
5914       else if (unformat (i, "disable"))
5915         enable = 0;
5916       else
5917         break;
5918     }
5919
5920   if (enable == -1)
5921     {
5922       errmsg ("missing enable|disable");
5923       return -99;
5924     }
5925
5926   M (WANT_INTERFACE_EVENTS, mp);
5927   mp->enable_disable = enable;
5928
5929   vam->interface_event_display = enable;
5930
5931   S (mp);
5932   W (ret);
5933   return ret;
5934 }
5935
5936
5937 /* Note: non-static, called once to set up the initial intfc table */
5938 int
5939 api_sw_interface_dump (vat_main_t * vam)
5940 {
5941   vl_api_sw_interface_dump_t *mp;
5942   vl_api_control_ping_t *mp_ping;
5943   hash_pair_t *p;
5944   name_sort_t *nses = 0, *ns;
5945   sw_interface_subif_t *sub = NULL;
5946   int ret;
5947
5948   /* Toss the old name table */
5949   /* *INDENT-OFF* */
5950   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5951   ({
5952     vec_add2 (nses, ns, 1);
5953     ns->name = (u8 *)(p->key);
5954     ns->value = (u32) p->value[0];
5955   }));
5956   /* *INDENT-ON* */
5957
5958   hash_free (vam->sw_if_index_by_interface_name);
5959
5960   vec_foreach (ns, nses) vec_free (ns->name);
5961
5962   vec_free (nses);
5963
5964   vec_foreach (sub, vam->sw_if_subif_table)
5965   {
5966     vec_free (sub->interface_name);
5967   }
5968   vec_free (vam->sw_if_subif_table);
5969
5970   /* recreate the interface name hash table */
5971   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5972
5973   /*
5974    * Ask for all interface names. Otherwise, the epic catalog of
5975    * name filters becomes ridiculously long, and vat ends up needing
5976    * to be taught about new interface types.
5977    */
5978   M (SW_INTERFACE_DUMP, mp);
5979   S (mp);
5980
5981   /* Use a control ping for synchronization */
5982   MPING (CONTROL_PING, mp_ping);
5983   S (mp_ping);
5984
5985   W (ret);
5986   return ret;
5987 }
5988
5989 static int
5990 api_sw_interface_set_flags (vat_main_t * vam)
5991 {
5992   unformat_input_t *i = vam->input;
5993   vl_api_sw_interface_set_flags_t *mp;
5994   u32 sw_if_index;
5995   u8 sw_if_index_set = 0;
5996   u8 admin_up = 0;
5997   int ret;
5998
5999   /* Parse args required to build the message */
6000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6001     {
6002       if (unformat (i, "admin-up"))
6003         admin_up = 1;
6004       else if (unformat (i, "admin-down"))
6005         admin_up = 0;
6006       else
6007         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6008         sw_if_index_set = 1;
6009       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6010         sw_if_index_set = 1;
6011       else
6012         break;
6013     }
6014
6015   if (sw_if_index_set == 0)
6016     {
6017       errmsg ("missing interface name or sw_if_index");
6018       return -99;
6019     }
6020
6021   /* Construct the API message */
6022   M (SW_INTERFACE_SET_FLAGS, mp);
6023   mp->sw_if_index = ntohl (sw_if_index);
6024   mp->admin_up_down = admin_up;
6025
6026   /* send it... */
6027   S (mp);
6028
6029   /* Wait for a reply, return the good/bad news... */
6030   W (ret);
6031   return ret;
6032 }
6033
6034 static int
6035 api_sw_interface_set_rx_mode (vat_main_t * vam)
6036 {
6037   unformat_input_t *i = vam->input;
6038   vl_api_sw_interface_set_rx_mode_t *mp;
6039   u32 sw_if_index;
6040   u8 sw_if_index_set = 0;
6041   int ret;
6042   u8 queue_id_valid = 0;
6043   u32 queue_id;
6044   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6045
6046   /* Parse args required to build the message */
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "queue %d", &queue_id))
6050         queue_id_valid = 1;
6051       else if (unformat (i, "polling"))
6052         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6053       else if (unformat (i, "interrupt"))
6054         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6055       else if (unformat (i, "adaptive"))
6056         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6057       else
6058         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6059         sw_if_index_set = 1;
6060       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6061         sw_if_index_set = 1;
6062       else
6063         break;
6064     }
6065
6066   if (sw_if_index_set == 0)
6067     {
6068       errmsg ("missing interface name or sw_if_index");
6069       return -99;
6070     }
6071   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6072     {
6073       errmsg ("missing rx-mode");
6074       return -99;
6075     }
6076
6077   /* Construct the API message */
6078   M (SW_INTERFACE_SET_RX_MODE, mp);
6079   mp->sw_if_index = ntohl (sw_if_index);
6080   mp->mode = mode;
6081   mp->queue_id_valid = queue_id_valid;
6082   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6083
6084   /* send it... */
6085   S (mp);
6086
6087   /* Wait for a reply, return the good/bad news... */
6088   W (ret);
6089   return ret;
6090 }
6091
6092 static int
6093 api_sw_interface_set_rx_placement (vat_main_t * vam)
6094 {
6095   unformat_input_t *i = vam->input;
6096   vl_api_sw_interface_set_rx_placement_t *mp;
6097   u32 sw_if_index;
6098   u8 sw_if_index_set = 0;
6099   int ret;
6100   u8 is_main = 0;
6101   u32 queue_id, thread_index;
6102
6103   /* Parse args required to build the message */
6104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6105     {
6106       if (unformat (i, "queue %d", &queue_id))
6107         ;
6108       else if (unformat (i, "main"))
6109         is_main = 1;
6110       else if (unformat (i, "worker %d", &thread_index))
6111         ;
6112       else
6113         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6114         sw_if_index_set = 1;
6115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6116         sw_if_index_set = 1;
6117       else
6118         break;
6119     }
6120
6121   if (sw_if_index_set == 0)
6122     {
6123       errmsg ("missing interface name or sw_if_index");
6124       return -99;
6125     }
6126
6127   if (is_main)
6128     thread_index = 0;
6129   /* Construct the API message */
6130   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6131   mp->sw_if_index = ntohl (sw_if_index);
6132   mp->worker_id = ntohl (thread_index);
6133   mp->queue_id = ntohl (queue_id);
6134   mp->is_main = is_main;
6135
6136   /* send it... */
6137   S (mp);
6138   /* Wait for a reply, return the good/bad news... */
6139   W (ret);
6140   return ret;
6141 }
6142
6143 static void vl_api_sw_interface_rx_placement_details_t_handler
6144   (vl_api_sw_interface_rx_placement_details_t * mp)
6145 {
6146   vat_main_t *vam = &vat_main;
6147   u32 worker_id = ntohl (mp->worker_id);
6148
6149   print (vam->ofp,
6150          "\n%-11d %-11s %-6d %-5d %-9s",
6151          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6152          worker_id, ntohl (mp->queue_id),
6153          (mp->mode ==
6154           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6155 }
6156
6157 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6158   (vl_api_sw_interface_rx_placement_details_t * mp)
6159 {
6160   vat_main_t *vam = &vat_main;
6161   vat_json_node_t *node = NULL;
6162
6163   if (VAT_JSON_ARRAY != vam->json_tree.type)
6164     {
6165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6166       vat_json_init_array (&vam->json_tree);
6167     }
6168   node = vat_json_array_add (&vam->json_tree);
6169
6170   vat_json_init_object (node);
6171   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6172   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6173   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6174   vat_json_object_add_uint (node, "mode", mp->mode);
6175 }
6176
6177 static int
6178 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6179 {
6180   unformat_input_t *i = vam->input;
6181   vl_api_sw_interface_rx_placement_dump_t *mp;
6182   vl_api_control_ping_t *mp_ping;
6183   int ret;
6184   u32 sw_if_index;
6185   u8 sw_if_index_set = 0;
6186
6187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6188     {
6189       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6190         sw_if_index_set++;
6191       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6192         sw_if_index_set++;
6193       else
6194         break;
6195     }
6196
6197   print (vam->ofp,
6198          "\n%-11s %-11s %-6s %-5s %-4s",
6199          "sw_if_index", "main/worker", "thread", "queue", "mode");
6200
6201   /* Dump Interface rx placement */
6202   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6203
6204   if (sw_if_index_set)
6205     mp->sw_if_index = htonl (sw_if_index);
6206   else
6207     mp->sw_if_index = ~0;
6208
6209   S (mp);
6210
6211   /* Use a control ping for synchronization */
6212   MPING (CONTROL_PING, mp_ping);
6213   S (mp_ping);
6214
6215   W (ret);
6216   return ret;
6217 }
6218
6219 static int
6220 api_sw_interface_clear_stats (vat_main_t * vam)
6221 {
6222   unformat_input_t *i = vam->input;
6223   vl_api_sw_interface_clear_stats_t *mp;
6224   u32 sw_if_index;
6225   u8 sw_if_index_set = 0;
6226   int ret;
6227
6228   /* Parse args required to build the message */
6229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6230     {
6231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6232         sw_if_index_set = 1;
6233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else
6236         break;
6237     }
6238
6239   /* Construct the API message */
6240   M (SW_INTERFACE_CLEAR_STATS, mp);
6241
6242   if (sw_if_index_set == 1)
6243     mp->sw_if_index = ntohl (sw_if_index);
6244   else
6245     mp->sw_if_index = ~0;
6246
6247   /* send it... */
6248   S (mp);
6249
6250   /* Wait for a reply, return the good/bad news... */
6251   W (ret);
6252   return ret;
6253 }
6254
6255 static int
6256 api_sw_interface_add_del_address (vat_main_t * vam)
6257 {
6258   unformat_input_t *i = vam->input;
6259   vl_api_sw_interface_add_del_address_t *mp;
6260   u32 sw_if_index;
6261   u8 sw_if_index_set = 0;
6262   u8 is_add = 1, del_all = 0;
6263   u32 address_length = 0;
6264   u8 v4_address_set = 0;
6265   u8 v6_address_set = 0;
6266   ip4_address_t v4address;
6267   ip6_address_t v6address;
6268   int ret;
6269
6270   /* Parse args required to build the message */
6271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6272     {
6273       if (unformat (i, "del-all"))
6274         del_all = 1;
6275       else if (unformat (i, "del"))
6276         is_add = 0;
6277       else
6278         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6279         sw_if_index_set = 1;
6280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6281         sw_if_index_set = 1;
6282       else if (unformat (i, "%U/%d",
6283                          unformat_ip4_address, &v4address, &address_length))
6284         v4_address_set = 1;
6285       else if (unformat (i, "%U/%d",
6286                          unformat_ip6_address, &v6address, &address_length))
6287         v6_address_set = 1;
6288       else
6289         break;
6290     }
6291
6292   if (sw_if_index_set == 0)
6293     {
6294       errmsg ("missing interface name or sw_if_index");
6295       return -99;
6296     }
6297   if (v4_address_set && v6_address_set)
6298     {
6299       errmsg ("both v4 and v6 addresses set");
6300       return -99;
6301     }
6302   if (!v4_address_set && !v6_address_set && !del_all)
6303     {
6304       errmsg ("no addresses set");
6305       return -99;
6306     }
6307
6308   /* Construct the API message */
6309   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6310
6311   mp->sw_if_index = ntohl (sw_if_index);
6312   mp->is_add = is_add;
6313   mp->del_all = del_all;
6314   if (v6_address_set)
6315     {
6316       mp->is_ipv6 = 1;
6317       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6318     }
6319   else
6320     {
6321       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6322     }
6323   mp->address_length = address_length;
6324
6325   /* send it... */
6326   S (mp);
6327
6328   /* Wait for a reply, return good/bad news  */
6329   W (ret);
6330   return ret;
6331 }
6332
6333 static int
6334 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6335 {
6336   unformat_input_t *i = vam->input;
6337   vl_api_sw_interface_set_mpls_enable_t *mp;
6338   u32 sw_if_index;
6339   u8 sw_if_index_set = 0;
6340   u8 enable = 1;
6341   int ret;
6342
6343   /* Parse args required to build the message */
6344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6345     {
6346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6349         sw_if_index_set = 1;
6350       else if (unformat (i, "disable"))
6351         enable = 0;
6352       else if (unformat (i, "dis"))
6353         enable = 0;
6354       else
6355         break;
6356     }
6357
6358   if (sw_if_index_set == 0)
6359     {
6360       errmsg ("missing interface name or sw_if_index");
6361       return -99;
6362     }
6363
6364   /* Construct the API message */
6365   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6366
6367   mp->sw_if_index = ntohl (sw_if_index);
6368   mp->enable = enable;
6369
6370   /* send it... */
6371   S (mp);
6372
6373   /* Wait for a reply... */
6374   W (ret);
6375   return ret;
6376 }
6377
6378 static int
6379 api_sw_interface_set_table (vat_main_t * vam)
6380 {
6381   unformat_input_t *i = vam->input;
6382   vl_api_sw_interface_set_table_t *mp;
6383   u32 sw_if_index, vrf_id = 0;
6384   u8 sw_if_index_set = 0;
6385   u8 is_ipv6 = 0;
6386   int ret;
6387
6388   /* Parse args required to build the message */
6389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6390     {
6391       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6392         sw_if_index_set = 1;
6393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6394         sw_if_index_set = 1;
6395       else if (unformat (i, "vrf %d", &vrf_id))
6396         ;
6397       else if (unformat (i, "ipv6"))
6398         is_ipv6 = 1;
6399       else
6400         break;
6401     }
6402
6403   if (sw_if_index_set == 0)
6404     {
6405       errmsg ("missing interface name or sw_if_index");
6406       return -99;
6407     }
6408
6409   /* Construct the API message */
6410   M (SW_INTERFACE_SET_TABLE, mp);
6411
6412   mp->sw_if_index = ntohl (sw_if_index);
6413   mp->is_ipv6 = is_ipv6;
6414   mp->vrf_id = ntohl (vrf_id);
6415
6416   /* send it... */
6417   S (mp);
6418
6419   /* Wait for a reply... */
6420   W (ret);
6421   return ret;
6422 }
6423
6424 static void vl_api_sw_interface_get_table_reply_t_handler
6425   (vl_api_sw_interface_get_table_reply_t * mp)
6426 {
6427   vat_main_t *vam = &vat_main;
6428
6429   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6430
6431   vam->retval = ntohl (mp->retval);
6432   vam->result_ready = 1;
6433
6434 }
6435
6436 static void vl_api_sw_interface_get_table_reply_t_handler_json
6437   (vl_api_sw_interface_get_table_reply_t * mp)
6438 {
6439   vat_main_t *vam = &vat_main;
6440   vat_json_node_t node;
6441
6442   vat_json_init_object (&node);
6443   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6444   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6445
6446   vat_json_print (vam->ofp, &node);
6447   vat_json_free (&node);
6448
6449   vam->retval = ntohl (mp->retval);
6450   vam->result_ready = 1;
6451 }
6452
6453 static int
6454 api_sw_interface_get_table (vat_main_t * vam)
6455 {
6456   unformat_input_t *i = vam->input;
6457   vl_api_sw_interface_get_table_t *mp;
6458   u32 sw_if_index;
6459   u8 sw_if_index_set = 0;
6460   u8 is_ipv6 = 0;
6461   int ret;
6462
6463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6464     {
6465       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else if (unformat (i, "ipv6"))
6470         is_ipv6 = 1;
6471       else
6472         break;
6473     }
6474
6475   if (sw_if_index_set == 0)
6476     {
6477       errmsg ("missing interface name or sw_if_index");
6478       return -99;
6479     }
6480
6481   M (SW_INTERFACE_GET_TABLE, mp);
6482   mp->sw_if_index = htonl (sw_if_index);
6483   mp->is_ipv6 = is_ipv6;
6484
6485   S (mp);
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static int
6491 api_sw_interface_set_vpath (vat_main_t * vam)
6492 {
6493   unformat_input_t *i = vam->input;
6494   vl_api_sw_interface_set_vpath_t *mp;
6495   u32 sw_if_index = 0;
6496   u8 sw_if_index_set = 0;
6497   u8 is_enable = 0;
6498   int ret;
6499
6500   /* Parse args required to build the message */
6501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6502     {
6503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6504         sw_if_index_set = 1;
6505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6506         sw_if_index_set = 1;
6507       else if (unformat (i, "enable"))
6508         is_enable = 1;
6509       else if (unformat (i, "disable"))
6510         is_enable = 0;
6511       else
6512         break;
6513     }
6514
6515   if (sw_if_index_set == 0)
6516     {
6517       errmsg ("missing interface name or sw_if_index");
6518       return -99;
6519     }
6520
6521   /* Construct the API message */
6522   M (SW_INTERFACE_SET_VPATH, mp);
6523
6524   mp->sw_if_index = ntohl (sw_if_index);
6525   mp->enable = is_enable;
6526
6527   /* send it... */
6528   S (mp);
6529
6530   /* Wait for a reply... */
6531   W (ret);
6532   return ret;
6533 }
6534
6535 static int
6536 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6537 {
6538   unformat_input_t *i = vam->input;
6539   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6540   u32 sw_if_index = 0;
6541   u8 sw_if_index_set = 0;
6542   u8 is_enable = 1;
6543   u8 is_ipv6 = 0;
6544   int ret;
6545
6546   /* Parse args required to build the message */
6547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6548     {
6549       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6550         sw_if_index_set = 1;
6551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6552         sw_if_index_set = 1;
6553       else if (unformat (i, "enable"))
6554         is_enable = 1;
6555       else if (unformat (i, "disable"))
6556         is_enable = 0;
6557       else if (unformat (i, "ip4"))
6558         is_ipv6 = 0;
6559       else if (unformat (i, "ip6"))
6560         is_ipv6 = 1;
6561       else
6562         break;
6563     }
6564
6565   if (sw_if_index_set == 0)
6566     {
6567       errmsg ("missing interface name or sw_if_index");
6568       return -99;
6569     }
6570
6571   /* Construct the API message */
6572   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6573
6574   mp->sw_if_index = ntohl (sw_if_index);
6575   mp->enable = is_enable;
6576   mp->is_ipv6 = is_ipv6;
6577
6578   /* send it... */
6579   S (mp);
6580
6581   /* Wait for a reply... */
6582   W (ret);
6583   return ret;
6584 }
6585
6586 static int
6587 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6588 {
6589   unformat_input_t *i = vam->input;
6590   vl_api_sw_interface_set_geneve_bypass_t *mp;
6591   u32 sw_if_index = 0;
6592   u8 sw_if_index_set = 0;
6593   u8 is_enable = 1;
6594   u8 is_ipv6 = 0;
6595   int ret;
6596
6597   /* Parse args required to build the message */
6598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599     {
6600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6601         sw_if_index_set = 1;
6602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6603         sw_if_index_set = 1;
6604       else if (unformat (i, "enable"))
6605         is_enable = 1;
6606       else if (unformat (i, "disable"))
6607         is_enable = 0;
6608       else if (unformat (i, "ip4"))
6609         is_ipv6 = 0;
6610       else if (unformat (i, "ip6"))
6611         is_ipv6 = 1;
6612       else
6613         break;
6614     }
6615
6616   if (sw_if_index_set == 0)
6617     {
6618       errmsg ("missing interface name or sw_if_index");
6619       return -99;
6620     }
6621
6622   /* Construct the API message */
6623   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6624
6625   mp->sw_if_index = ntohl (sw_if_index);
6626   mp->enable = is_enable;
6627   mp->is_ipv6 = is_ipv6;
6628
6629   /* send it... */
6630   S (mp);
6631
6632   /* Wait for a reply... */
6633   W (ret);
6634   return ret;
6635 }
6636
6637 static int
6638 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6639 {
6640   unformat_input_t *i = vam->input;
6641   vl_api_sw_interface_set_l2_xconnect_t *mp;
6642   u32 rx_sw_if_index;
6643   u8 rx_sw_if_index_set = 0;
6644   u32 tx_sw_if_index;
6645   u8 tx_sw_if_index_set = 0;
6646   u8 enable = 1;
6647   int ret;
6648
6649   /* Parse args required to build the message */
6650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651     {
6652       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6653         rx_sw_if_index_set = 1;
6654       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6655         tx_sw_if_index_set = 1;
6656       else if (unformat (i, "rx"))
6657         {
6658           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659             {
6660               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6661                             &rx_sw_if_index))
6662                 rx_sw_if_index_set = 1;
6663             }
6664           else
6665             break;
6666         }
6667       else if (unformat (i, "tx"))
6668         {
6669           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670             {
6671               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6672                             &tx_sw_if_index))
6673                 tx_sw_if_index_set = 1;
6674             }
6675           else
6676             break;
6677         }
6678       else if (unformat (i, "enable"))
6679         enable = 1;
6680       else if (unformat (i, "disable"))
6681         enable = 0;
6682       else
6683         break;
6684     }
6685
6686   if (rx_sw_if_index_set == 0)
6687     {
6688       errmsg ("missing rx interface name or rx_sw_if_index");
6689       return -99;
6690     }
6691
6692   if (enable && (tx_sw_if_index_set == 0))
6693     {
6694       errmsg ("missing tx interface name or tx_sw_if_index");
6695       return -99;
6696     }
6697
6698   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6699
6700   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6701   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6702   mp->enable = enable;
6703
6704   S (mp);
6705   W (ret);
6706   return ret;
6707 }
6708
6709 static int
6710 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6711 {
6712   unformat_input_t *i = vam->input;
6713   vl_api_sw_interface_set_l2_bridge_t *mp;
6714   vl_api_l2_port_type_t port_type;
6715   u32 rx_sw_if_index;
6716   u8 rx_sw_if_index_set = 0;
6717   u32 bd_id;
6718   u8 bd_id_set = 0;
6719   u32 shg = 0;
6720   u8 enable = 1;
6721   int ret;
6722
6723   port_type = L2_API_PORT_TYPE_NORMAL;
6724
6725   /* Parse args required to build the message */
6726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6727     {
6728       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6729         rx_sw_if_index_set = 1;
6730       else if (unformat (i, "bd_id %d", &bd_id))
6731         bd_id_set = 1;
6732       else
6733         if (unformat
6734             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6735         rx_sw_if_index_set = 1;
6736       else if (unformat (i, "shg %d", &shg))
6737         ;
6738       else if (unformat (i, "bvi"))
6739         port_type = L2_API_PORT_TYPE_BVI;
6740       else if (unformat (i, "uu-fwd"))
6741         port_type = L2_API_PORT_TYPE_UU_FWD;
6742       else if (unformat (i, "enable"))
6743         enable = 1;
6744       else if (unformat (i, "disable"))
6745         enable = 0;
6746       else
6747         break;
6748     }
6749
6750   if (rx_sw_if_index_set == 0)
6751     {
6752       errmsg ("missing rx interface name or sw_if_index");
6753       return -99;
6754     }
6755
6756   if (enable && (bd_id_set == 0))
6757     {
6758       errmsg ("missing bridge domain");
6759       return -99;
6760     }
6761
6762   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6763
6764   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6765   mp->bd_id = ntohl (bd_id);
6766   mp->shg = (u8) shg;
6767   mp->port_type = ntohl (port_type);
6768   mp->enable = enable;
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_bridge_domain_dump (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_bridge_domain_dump_t *mp;
6780   vl_api_control_ping_t *mp_ping;
6781   u32 bd_id = ~0;
6782   int ret;
6783
6784   /* Parse args required to build the message */
6785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6786     {
6787       if (unformat (i, "bd_id %d", &bd_id))
6788         ;
6789       else
6790         break;
6791     }
6792
6793   M (BRIDGE_DOMAIN_DUMP, mp);
6794   mp->bd_id = ntohl (bd_id);
6795   S (mp);
6796
6797   /* Use a control ping for synchronization */
6798   MPING (CONTROL_PING, mp_ping);
6799   S (mp_ping);
6800
6801   W (ret);
6802   return ret;
6803 }
6804
6805 static int
6806 api_bridge_domain_add_del (vat_main_t * vam)
6807 {
6808   unformat_input_t *i = vam->input;
6809   vl_api_bridge_domain_add_del_t *mp;
6810   u32 bd_id = ~0;
6811   u8 is_add = 1;
6812   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6813   u8 *bd_tag = NULL;
6814   u32 mac_age = 0;
6815   int ret;
6816
6817   /* Parse args required to build the message */
6818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6819     {
6820       if (unformat (i, "bd_id %d", &bd_id))
6821         ;
6822       else if (unformat (i, "flood %d", &flood))
6823         ;
6824       else if (unformat (i, "uu-flood %d", &uu_flood))
6825         ;
6826       else if (unformat (i, "forward %d", &forward))
6827         ;
6828       else if (unformat (i, "learn %d", &learn))
6829         ;
6830       else if (unformat (i, "arp-term %d", &arp_term))
6831         ;
6832       else if (unformat (i, "mac-age %d", &mac_age))
6833         ;
6834       else if (unformat (i, "bd-tag %s", &bd_tag))
6835         ;
6836       else if (unformat (i, "del"))
6837         {
6838           is_add = 0;
6839           flood = uu_flood = forward = learn = 0;
6840         }
6841       else
6842         break;
6843     }
6844
6845   if (bd_id == ~0)
6846     {
6847       errmsg ("missing bridge domain");
6848       ret = -99;
6849       goto done;
6850     }
6851
6852   if (mac_age > 255)
6853     {
6854       errmsg ("mac age must be less than 256 ");
6855       ret = -99;
6856       goto done;
6857     }
6858
6859   if ((bd_tag) && (vec_len (bd_tag) > 63))
6860     {
6861       errmsg ("bd-tag cannot be longer than 63");
6862       ret = -99;
6863       goto done;
6864     }
6865
6866   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6867
6868   mp->bd_id = ntohl (bd_id);
6869   mp->flood = flood;
6870   mp->uu_flood = uu_flood;
6871   mp->forward = forward;
6872   mp->learn = learn;
6873   mp->arp_term = arp_term;
6874   mp->is_add = is_add;
6875   mp->mac_age = (u8) mac_age;
6876   if (bd_tag)
6877     {
6878       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6879       mp->bd_tag[vec_len (bd_tag)] = 0;
6880     }
6881   S (mp);
6882   W (ret);
6883
6884 done:
6885   vec_free (bd_tag);
6886   return ret;
6887 }
6888
6889 static int
6890 api_l2fib_flush_bd (vat_main_t * vam)
6891 {
6892   unformat_input_t *i = vam->input;
6893   vl_api_l2fib_flush_bd_t *mp;
6894   u32 bd_id = ~0;
6895   int ret;
6896
6897   /* Parse args required to build the message */
6898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6899     {
6900       if (unformat (i, "bd_id %d", &bd_id));
6901       else
6902         break;
6903     }
6904
6905   if (bd_id == ~0)
6906     {
6907       errmsg ("missing bridge domain");
6908       return -99;
6909     }
6910
6911   M (L2FIB_FLUSH_BD, mp);
6912
6913   mp->bd_id = htonl (bd_id);
6914
6915   S (mp);
6916   W (ret);
6917   return ret;
6918 }
6919
6920 static int
6921 api_l2fib_flush_int (vat_main_t * vam)
6922 {
6923   unformat_input_t *i = vam->input;
6924   vl_api_l2fib_flush_int_t *mp;
6925   u32 sw_if_index = ~0;
6926   int ret;
6927
6928   /* Parse args required to build the message */
6929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6930     {
6931       if (unformat (i, "sw_if_index %d", &sw_if_index));
6932       else
6933         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6934       else
6935         break;
6936     }
6937
6938   if (sw_if_index == ~0)
6939     {
6940       errmsg ("missing interface name or sw_if_index");
6941       return -99;
6942     }
6943
6944   M (L2FIB_FLUSH_INT, mp);
6945
6946   mp->sw_if_index = ntohl (sw_if_index);
6947
6948   S (mp);
6949   W (ret);
6950   return ret;
6951 }
6952
6953 static int
6954 api_l2fib_add_del (vat_main_t * vam)
6955 {
6956   unformat_input_t *i = vam->input;
6957   vl_api_l2fib_add_del_t *mp;
6958   f64 timeout;
6959   u8 mac[6] = { 0 };
6960   u8 mac_set = 0;
6961   u32 bd_id;
6962   u8 bd_id_set = 0;
6963   u32 sw_if_index = 0;
6964   u8 sw_if_index_set = 0;
6965   u8 is_add = 1;
6966   u8 static_mac = 0;
6967   u8 filter_mac = 0;
6968   u8 bvi_mac = 0;
6969   int count = 1;
6970   f64 before = 0;
6971   int j;
6972
6973   /* Parse args required to build the message */
6974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6975     {
6976       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6977         mac_set = 1;
6978       else if (unformat (i, "bd_id %d", &bd_id))
6979         bd_id_set = 1;
6980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6981         sw_if_index_set = 1;
6982       else if (unformat (i, "sw_if"))
6983         {
6984           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6985             {
6986               if (unformat
6987                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6988                 sw_if_index_set = 1;
6989             }
6990           else
6991             break;
6992         }
6993       else if (unformat (i, "static"))
6994         static_mac = 1;
6995       else if (unformat (i, "filter"))
6996         {
6997           filter_mac = 1;
6998           static_mac = 1;
6999         }
7000       else if (unformat (i, "bvi"))
7001         {
7002           bvi_mac = 1;
7003           static_mac = 1;
7004         }
7005       else if (unformat (i, "del"))
7006         is_add = 0;
7007       else if (unformat (i, "count %d", &count))
7008         ;
7009       else
7010         break;
7011     }
7012
7013   if (mac_set == 0)
7014     {
7015       errmsg ("missing mac address");
7016       return -99;
7017     }
7018
7019   if (bd_id_set == 0)
7020     {
7021       errmsg ("missing bridge domain");
7022       return -99;
7023     }
7024
7025   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7026     {
7027       errmsg ("missing interface name or sw_if_index");
7028       return -99;
7029     }
7030
7031   if (count > 1)
7032     {
7033       /* Turn on async mode */
7034       vam->async_mode = 1;
7035       vam->async_errors = 0;
7036       before = vat_time_now (vam);
7037     }
7038
7039   for (j = 0; j < count; j++)
7040     {
7041       M (L2FIB_ADD_DEL, mp);
7042
7043       clib_memcpy (mp->mac, mac, 6);
7044       mp->bd_id = ntohl (bd_id);
7045       mp->is_add = is_add;
7046       mp->sw_if_index = ntohl (sw_if_index);
7047
7048       if (is_add)
7049         {
7050           mp->static_mac = static_mac;
7051           mp->filter_mac = filter_mac;
7052           mp->bvi_mac = bvi_mac;
7053         }
7054       increment_mac_address (mac);
7055       /* send it... */
7056       S (mp);
7057     }
7058
7059   if (count > 1)
7060     {
7061       vl_api_control_ping_t *mp_ping;
7062       f64 after;
7063
7064       /* Shut off async mode */
7065       vam->async_mode = 0;
7066
7067       MPING (CONTROL_PING, mp_ping);
7068       S (mp_ping);
7069
7070       timeout = vat_time_now (vam) + 1.0;
7071       while (vat_time_now (vam) < timeout)
7072         if (vam->result_ready == 1)
7073           goto out;
7074       vam->retval = -99;
7075
7076     out:
7077       if (vam->retval == -99)
7078         errmsg ("timeout");
7079
7080       if (vam->async_errors > 0)
7081         {
7082           errmsg ("%d asynchronous errors", vam->async_errors);
7083           vam->retval = -98;
7084         }
7085       vam->async_errors = 0;
7086       after = vat_time_now (vam);
7087
7088       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7089              count, after - before, count / (after - before));
7090     }
7091   else
7092     {
7093       int ret;
7094
7095       /* Wait for a reply... */
7096       W (ret);
7097       return ret;
7098     }
7099   /* Return the good/bad news */
7100   return (vam->retval);
7101 }
7102
7103 static int
7104 api_bridge_domain_set_mac_age (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_bridge_domain_set_mac_age_t *mp;
7108   u32 bd_id = ~0;
7109   u32 mac_age = 0;
7110   int ret;
7111
7112   /* Parse args required to build the message */
7113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7114     {
7115       if (unformat (i, "bd_id %d", &bd_id));
7116       else if (unformat (i, "mac-age %d", &mac_age));
7117       else
7118         break;
7119     }
7120
7121   if (bd_id == ~0)
7122     {
7123       errmsg ("missing bridge domain");
7124       return -99;
7125     }
7126
7127   if (mac_age > 255)
7128     {
7129       errmsg ("mac age must be less than 256 ");
7130       return -99;
7131     }
7132
7133   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7134
7135   mp->bd_id = htonl (bd_id);
7136   mp->mac_age = (u8) mac_age;
7137
7138   S (mp);
7139   W (ret);
7140   return ret;
7141 }
7142
7143 static int
7144 api_l2_flags (vat_main_t * vam)
7145 {
7146   unformat_input_t *i = vam->input;
7147   vl_api_l2_flags_t *mp;
7148   u32 sw_if_index;
7149   u32 flags = 0;
7150   u8 sw_if_index_set = 0;
7151   u8 is_set = 0;
7152   int ret;
7153
7154   /* Parse args required to build the message */
7155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7156     {
7157       if (unformat (i, "sw_if_index %d", &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "sw_if"))
7160         {
7161           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7162             {
7163               if (unformat
7164                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7165                 sw_if_index_set = 1;
7166             }
7167           else
7168             break;
7169         }
7170       else if (unformat (i, "learn"))
7171         flags |= L2_LEARN;
7172       else if (unformat (i, "forward"))
7173         flags |= L2_FWD;
7174       else if (unformat (i, "flood"))
7175         flags |= L2_FLOOD;
7176       else if (unformat (i, "uu-flood"))
7177         flags |= L2_UU_FLOOD;
7178       else if (unformat (i, "arp-term"))
7179         flags |= L2_ARP_TERM;
7180       else if (unformat (i, "off"))
7181         is_set = 0;
7182       else if (unformat (i, "disable"))
7183         is_set = 0;
7184       else
7185         break;
7186     }
7187
7188   if (sw_if_index_set == 0)
7189     {
7190       errmsg ("missing interface name or sw_if_index");
7191       return -99;
7192     }
7193
7194   M (L2_FLAGS, mp);
7195
7196   mp->sw_if_index = ntohl (sw_if_index);
7197   mp->feature_bitmap = ntohl (flags);
7198   mp->is_set = is_set;
7199
7200   S (mp);
7201   W (ret);
7202   return ret;
7203 }
7204
7205 static int
7206 api_bridge_flags (vat_main_t * vam)
7207 {
7208   unformat_input_t *i = vam->input;
7209   vl_api_bridge_flags_t *mp;
7210   u32 bd_id;
7211   u8 bd_id_set = 0;
7212   u8 is_set = 1;
7213   bd_flags_t flags = 0;
7214   int ret;
7215
7216   /* Parse args required to build the message */
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "bd_id %d", &bd_id))
7220         bd_id_set = 1;
7221       else if (unformat (i, "learn"))
7222         flags |= BRIDGE_API_FLAG_LEARN;
7223       else if (unformat (i, "forward"))
7224         flags |= BRIDGE_API_FLAG_FWD;
7225       else if (unformat (i, "flood"))
7226         flags |= BRIDGE_API_FLAG_FLOOD;
7227       else if (unformat (i, "uu-flood"))
7228         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7229       else if (unformat (i, "arp-term"))
7230         flags |= BRIDGE_API_FLAG_ARP_TERM;
7231       else if (unformat (i, "off"))
7232         is_set = 0;
7233       else if (unformat (i, "disable"))
7234         is_set = 0;
7235       else
7236         break;
7237     }
7238
7239   if (bd_id_set == 0)
7240     {
7241       errmsg ("missing bridge domain");
7242       return -99;
7243     }
7244
7245   M (BRIDGE_FLAGS, mp);
7246
7247   mp->bd_id = ntohl (bd_id);
7248   mp->flags = ntohl (flags);
7249   mp->is_set = is_set;
7250
7251   S (mp);
7252   W (ret);
7253   return ret;
7254 }
7255
7256 static int
7257 api_bd_ip_mac_add_del (vat_main_t * vam)
7258 {
7259   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7260   vl_api_mac_address_t mac = { 0 };
7261   unformat_input_t *i = vam->input;
7262   vl_api_bd_ip_mac_add_del_t *mp;
7263   ip46_type_t type;
7264   u32 bd_id;
7265   u8 is_ipv6 = 0;
7266   u8 is_add = 1;
7267   u8 bd_id_set = 0;
7268   u8 ip_set = 0;
7269   u8 mac_set = 0;
7270   u8 macaddr[6];
7271   int ret;
7272
7273
7274   /* Parse args required to build the message */
7275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7276     {
7277       if (unformat (i, "bd_id %d", &bd_id))
7278         {
7279           bd_id_set++;
7280         }
7281       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7282         {
7283           ip_set++;
7284         }
7285       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7286         {
7287           mac_set++;
7288         }
7289       else if (unformat (i, "del"))
7290         is_add = 0;
7291       else
7292         break;
7293     }
7294
7295   if (bd_id_set == 0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300   else if (ip_set == 0)
7301     {
7302       errmsg ("missing IP address");
7303       return -99;
7304     }
7305   else if (mac_set == 0)
7306     {
7307       errmsg ("missing MAC address");
7308       return -99;
7309     }
7310
7311   M (BD_IP_MAC_ADD_DEL, mp);
7312
7313   mp->bd_id = ntohl (bd_id);
7314   mp->is_add = is_add;
7315
7316   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7317   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7318
7319   S (mp);
7320   W (ret);
7321   return ret;
7322 }
7323
7324 static int
7325 api_bd_ip_mac_flush (vat_main_t * vam)
7326 {
7327   unformat_input_t *i = vam->input;
7328   vl_api_bd_ip_mac_flush_t *mp;
7329   u32 bd_id;
7330   u8 bd_id_set = 0;
7331   int ret;
7332
7333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7334     {
7335       if (unformat (i, "bd_id %d", &bd_id))
7336         {
7337           bd_id_set++;
7338         }
7339       else
7340         break;
7341     }
7342
7343   if (bd_id_set == 0)
7344     {
7345       errmsg ("missing bridge domain");
7346       return -99;
7347     }
7348
7349   M (BD_IP_MAC_FLUSH, mp);
7350
7351   mp->bd_id = ntohl (bd_id);
7352
7353   S (mp);
7354   W (ret);
7355   return ret;
7356 }
7357
7358 static void vl_api_bd_ip_mac_details_t_handler
7359   (vl_api_bd_ip_mac_details_t * mp)
7360 {
7361   vat_main_t *vam = &vat_main;
7362   u8 *ip = 0;
7363
7364   if (!mp->is_ipv6)
7365     ip =
7366       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7367   else
7368     ip =
7369       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7370
7371   print (vam->ofp,
7372          "\n%-5d %-7s %-20U %-30s",
7373          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7374          format_ethernet_address, mp->mac_address, ip);
7375
7376   vec_free (ip);
7377 }
7378
7379 static void vl_api_bd_ip_mac_details_t_handler_json
7380   (vl_api_bd_ip_mac_details_t * mp)
7381 {
7382   vat_main_t *vam = &vat_main;
7383   vat_json_node_t *node = NULL;
7384
7385   if (VAT_JSON_ARRAY != vam->json_tree.type)
7386     {
7387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7388       vat_json_init_array (&vam->json_tree);
7389     }
7390   node = vat_json_array_add (&vam->json_tree);
7391
7392   vat_json_init_object (node);
7393   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7394   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7395   vat_json_object_add_string_copy (node, "mac_address",
7396                                    format (0, "%U", format_ethernet_address,
7397                                            &mp->mac_address));
7398   u8 *ip = 0;
7399
7400   if (!mp->is_ipv6)
7401     ip =
7402       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7403   else
7404     ip =
7405       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7406   vat_json_object_add_string_copy (node, "ip_address", ip);
7407   vec_free (ip);
7408 }
7409
7410 static int
7411 api_bd_ip_mac_dump (vat_main_t * vam)
7412 {
7413   unformat_input_t *i = vam->input;
7414   vl_api_bd_ip_mac_dump_t *mp;
7415   vl_api_control_ping_t *mp_ping;
7416   int ret;
7417   u32 bd_id;
7418   u8 bd_id_set = 0;
7419
7420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7421     {
7422       if (unformat (i, "bd_id %d", &bd_id))
7423         {
7424           bd_id_set++;
7425         }
7426       else
7427         break;
7428     }
7429
7430   print (vam->ofp,
7431          "\n%-5s %-7s %-20s %-30s",
7432          "bd_id", "is_ipv6", "mac_address", "ip_address");
7433
7434   /* Dump Bridge Domain Ip to Mac entries */
7435   M (BD_IP_MAC_DUMP, mp);
7436
7437   if (bd_id_set)
7438     mp->bd_id = htonl (bd_id);
7439   else
7440     mp->bd_id = ~0;
7441
7442   S (mp);
7443
7444   /* Use a control ping for synchronization */
7445   MPING (CONTROL_PING, mp_ping);
7446   S (mp_ping);
7447
7448   W (ret);
7449   return ret;
7450 }
7451
7452 static int
7453 api_tap_create_v2 (vat_main_t * vam)
7454 {
7455   unformat_input_t *i = vam->input;
7456   vl_api_tap_create_v2_t *mp;
7457   u8 mac_address[6];
7458   u8 random_mac = 1;
7459   u32 id = ~0;
7460   u8 *host_if_name = 0;
7461   u8 *host_ns = 0;
7462   u8 host_mac_addr[6];
7463   u8 host_mac_addr_set = 0;
7464   u8 *host_bridge = 0;
7465   ip4_address_t host_ip4_addr;
7466   ip4_address_t host_ip4_gw;
7467   u8 host_ip4_gw_set = 0;
7468   u32 host_ip4_prefix_len = 0;
7469   ip6_address_t host_ip6_addr;
7470   ip6_address_t host_ip6_gw;
7471   u8 host_ip6_gw_set = 0;
7472   u32 host_ip6_prefix_len = 0;
7473   int ret;
7474   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7475
7476   clib_memset (mac_address, 0, sizeof (mac_address));
7477
7478   /* Parse args required to build the message */
7479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7480     {
7481       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7482         {
7483           random_mac = 0;
7484         }
7485       else if (unformat (i, "id %u", &id))
7486         ;
7487       else if (unformat (i, "host-if-name %s", &host_if_name))
7488         ;
7489       else if (unformat (i, "host-ns %s", &host_ns))
7490         ;
7491       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7492                          host_mac_addr))
7493         host_mac_addr_set = 1;
7494       else if (unformat (i, "host-bridge %s", &host_bridge))
7495         ;
7496       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7497                          &host_ip4_addr, &host_ip4_prefix_len))
7498         ;
7499       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7500                          &host_ip6_addr, &host_ip6_prefix_len))
7501         ;
7502       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7503                          &host_ip4_gw))
7504         host_ip4_gw_set = 1;
7505       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7506                          &host_ip6_gw))
7507         host_ip6_gw_set = 1;
7508       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7509         ;
7510       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7511         ;
7512       else
7513         break;
7514     }
7515
7516   if (vec_len (host_if_name) > 63)
7517     {
7518       errmsg ("tap name too long. ");
7519       return -99;
7520     }
7521   if (vec_len (host_ns) > 63)
7522     {
7523       errmsg ("host name space too long. ");
7524       return -99;
7525     }
7526   if (vec_len (host_bridge) > 63)
7527     {
7528       errmsg ("host bridge name too long. ");
7529       return -99;
7530     }
7531   if (host_ip4_prefix_len > 32)
7532     {
7533       errmsg ("host ip4 prefix length not valid. ");
7534       return -99;
7535     }
7536   if (host_ip6_prefix_len > 128)
7537     {
7538       errmsg ("host ip6 prefix length not valid. ");
7539       return -99;
7540     }
7541   if (!is_pow2 (rx_ring_sz))
7542     {
7543       errmsg ("rx ring size must be power of 2. ");
7544       return -99;
7545     }
7546   if (rx_ring_sz > 32768)
7547     {
7548       errmsg ("rx ring size must be 32768 or lower. ");
7549       return -99;
7550     }
7551   if (!is_pow2 (tx_ring_sz))
7552     {
7553       errmsg ("tx ring size must be power of 2. ");
7554       return -99;
7555     }
7556   if (tx_ring_sz > 32768)
7557     {
7558       errmsg ("tx ring size must be 32768 or lower. ");
7559       return -99;
7560     }
7561
7562   /* Construct the API message */
7563   M (TAP_CREATE_V2, mp);
7564
7565   mp->use_random_mac = random_mac;
7566
7567   mp->id = ntohl (id);
7568   mp->host_namespace_set = host_ns != 0;
7569   mp->host_bridge_set = host_bridge != 0;
7570   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7571   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7572   mp->rx_ring_sz = ntohs (rx_ring_sz);
7573   mp->tx_ring_sz = ntohs (tx_ring_sz);
7574
7575   if (random_mac == 0)
7576     clib_memcpy (mp->mac_address, mac_address, 6);
7577   if (host_mac_addr_set)
7578     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7579   if (host_if_name)
7580     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7581   if (host_ns)
7582     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7583   if (host_bridge)
7584     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7585   if (host_ip4_prefix_len)
7586     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7587   if (host_ip6_prefix_len)
7588     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7589   if (host_ip4_gw_set)
7590     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7591   if (host_ip6_gw_set)
7592     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7593
7594   vec_free (host_ns);
7595   vec_free (host_if_name);
7596   vec_free (host_bridge);
7597
7598   /* send it... */
7599   S (mp);
7600
7601   /* Wait for a reply... */
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_tap_delete_v2 (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_tap_delete_v2_t *mp;
7611   u32 sw_if_index = ~0;
7612   u8 sw_if_index_set = 0;
7613   int ret;
7614
7615   /* Parse args required to build the message */
7616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7617     {
7618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7619         sw_if_index_set = 1;
7620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7621         sw_if_index_set = 1;
7622       else
7623         break;
7624     }
7625
7626   if (sw_if_index_set == 0)
7627     {
7628       errmsg ("missing vpp interface name. ");
7629       return -99;
7630     }
7631
7632   /* Construct the API message */
7633   M (TAP_DELETE_V2, mp);
7634
7635   mp->sw_if_index = ntohl (sw_if_index);
7636
7637   /* send it... */
7638   S (mp);
7639
7640   /* Wait for a reply... */
7641   W (ret);
7642   return ret;
7643 }
7644
7645 uword
7646 unformat_pci_addr (unformat_input_t * input, va_list * args)
7647 {
7648   struct pci_addr_t
7649   {
7650     u16 domain;
7651     u8 bus;
7652     u8 slot:5;
7653     u8 function:3;
7654   } *addr;
7655   addr = va_arg (*args, struct pci_addr_t *);
7656   u32 x[4];
7657
7658   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7659     return 0;
7660
7661   addr->domain = x[0];
7662   addr->bus = x[1];
7663   addr->slot = x[2];
7664   addr->function = x[3];
7665
7666   return 1;
7667 }
7668
7669 static int
7670 api_virtio_pci_create (vat_main_t * vam)
7671 {
7672   unformat_input_t *i = vam->input;
7673   vl_api_virtio_pci_create_t *mp;
7674   u8 mac_address[6];
7675   u8 random_mac = 1;
7676   u32 pci_addr = 0;
7677   u64 features = (u64) ~ (0ULL);
7678   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7679   int ret;
7680
7681   clib_memset (mac_address, 0, sizeof (mac_address));
7682
7683   /* Parse args required to build the message */
7684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7685     {
7686       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7687         {
7688           random_mac = 0;
7689         }
7690       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7691         ;
7692       else if (unformat (i, "features 0x%llx", &features))
7693         ;
7694       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7695         ;
7696       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7697         ;
7698       else
7699         break;
7700     }
7701
7702   if (pci_addr == 0)
7703     {
7704       errmsg ("pci address must be non zero. ");
7705       return -99;
7706     }
7707   if (!is_pow2 (rx_ring_sz))
7708     {
7709       errmsg ("rx ring size must be power of 2. ");
7710       return -99;
7711     }
7712   if (rx_ring_sz > 32768)
7713     {
7714       errmsg ("rx ring size must be 32768 or lower. ");
7715       return -99;
7716     }
7717   if (!is_pow2 (tx_ring_sz))
7718     {
7719       errmsg ("tx ring size must be power of 2. ");
7720       return -99;
7721     }
7722   if (tx_ring_sz > 32768)
7723     {
7724       errmsg ("tx ring size must be 32768 or lower. ");
7725       return -99;
7726     }
7727
7728   /* Construct the API message */
7729   M (VIRTIO_PCI_CREATE, mp);
7730
7731   mp->use_random_mac = random_mac;
7732
7733   mp->pci_addr = htonl (pci_addr);
7734   mp->features = clib_host_to_net_u64 (features);
7735
7736   if (random_mac == 0)
7737     clib_memcpy (mp->mac_address, mac_address, 6);
7738
7739   /* send it... */
7740   S (mp);
7741
7742   /* Wait for a reply... */
7743   W (ret);
7744   return ret;
7745 }
7746
7747 static int
7748 api_virtio_pci_delete (vat_main_t * vam)
7749 {
7750   unformat_input_t *i = vam->input;
7751   vl_api_virtio_pci_delete_t *mp;
7752   u32 sw_if_index = ~0;
7753   u8 sw_if_index_set = 0;
7754   int ret;
7755
7756   /* Parse args required to build the message */
7757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7758     {
7759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7760         sw_if_index_set = 1;
7761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7762         sw_if_index_set = 1;
7763       else
7764         break;
7765     }
7766
7767   if (sw_if_index_set == 0)
7768     {
7769       errmsg ("missing vpp interface name. ");
7770       return -99;
7771     }
7772
7773   /* Construct the API message */
7774   M (VIRTIO_PCI_DELETE, mp);
7775
7776   mp->sw_if_index = htonl (sw_if_index);
7777
7778   /* send it... */
7779   S (mp);
7780
7781   /* Wait for a reply... */
7782   W (ret);
7783   return ret;
7784 }
7785
7786 static int
7787 api_bond_create (vat_main_t * vam)
7788 {
7789   unformat_input_t *i = vam->input;
7790   vl_api_bond_create_t *mp;
7791   u8 mac_address[6];
7792   u8 custom_mac = 0;
7793   int ret;
7794   u8 mode;
7795   u8 lb;
7796   u8 mode_is_set = 0;
7797   u32 id = ~0;
7798
7799   clib_memset (mac_address, 0, sizeof (mac_address));
7800   lb = BOND_LB_L2;
7801
7802   /* Parse args required to build the message */
7803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7804     {
7805       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7806         mode_is_set = 1;
7807       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7808                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7809         ;
7810       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7811                          mac_address))
7812         custom_mac = 1;
7813       else if (unformat (i, "id %u", &id))
7814         ;
7815       else
7816         break;
7817     }
7818
7819   if (mode_is_set == 0)
7820     {
7821       errmsg ("Missing bond mode. ");
7822       return -99;
7823     }
7824
7825   /* Construct the API message */
7826   M (BOND_CREATE, mp);
7827
7828   mp->use_custom_mac = custom_mac;
7829
7830   mp->mode = mode;
7831   mp->lb = lb;
7832   mp->id = htonl (id);
7833
7834   if (custom_mac)
7835     clib_memcpy (mp->mac_address, mac_address, 6);
7836
7837   /* send it... */
7838   S (mp);
7839
7840   /* Wait for a reply... */
7841   W (ret);
7842   return ret;
7843 }
7844
7845 static int
7846 api_bond_delete (vat_main_t * vam)
7847 {
7848   unformat_input_t *i = vam->input;
7849   vl_api_bond_delete_t *mp;
7850   u32 sw_if_index = ~0;
7851   u8 sw_if_index_set = 0;
7852   int ret;
7853
7854   /* Parse args required to build the message */
7855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7856     {
7857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7858         sw_if_index_set = 1;
7859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7860         sw_if_index_set = 1;
7861       else
7862         break;
7863     }
7864
7865   if (sw_if_index_set == 0)
7866     {
7867       errmsg ("missing vpp interface name. ");
7868       return -99;
7869     }
7870
7871   /* Construct the API message */
7872   M (BOND_DELETE, mp);
7873
7874   mp->sw_if_index = ntohl (sw_if_index);
7875
7876   /* send it... */
7877   S (mp);
7878
7879   /* Wait for a reply... */
7880   W (ret);
7881   return ret;
7882 }
7883
7884 static int
7885 api_bond_enslave (vat_main_t * vam)
7886 {
7887   unformat_input_t *i = vam->input;
7888   vl_api_bond_enslave_t *mp;
7889   u32 bond_sw_if_index;
7890   int ret;
7891   u8 is_passive;
7892   u8 is_long_timeout;
7893   u32 bond_sw_if_index_is_set = 0;
7894   u32 sw_if_index;
7895   u8 sw_if_index_is_set = 0;
7896
7897   /* Parse args required to build the message */
7898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7899     {
7900       if (unformat (i, "sw_if_index %d", &sw_if_index))
7901         sw_if_index_is_set = 1;
7902       else if (unformat (i, "bond %u", &bond_sw_if_index))
7903         bond_sw_if_index_is_set = 1;
7904       else if (unformat (i, "passive %d", &is_passive))
7905         ;
7906       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7907         ;
7908       else
7909         break;
7910     }
7911
7912   if (bond_sw_if_index_is_set == 0)
7913     {
7914       errmsg ("Missing bond sw_if_index. ");
7915       return -99;
7916     }
7917   if (sw_if_index_is_set == 0)
7918     {
7919       errmsg ("Missing slave sw_if_index. ");
7920       return -99;
7921     }
7922
7923   /* Construct the API message */
7924   M (BOND_ENSLAVE, mp);
7925
7926   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7927   mp->sw_if_index = ntohl (sw_if_index);
7928   mp->is_long_timeout = is_long_timeout;
7929   mp->is_passive = is_passive;
7930
7931   /* send it... */
7932   S (mp);
7933
7934   /* Wait for a reply... */
7935   W (ret);
7936   return ret;
7937 }
7938
7939 static int
7940 api_bond_detach_slave (vat_main_t * vam)
7941 {
7942   unformat_input_t *i = vam->input;
7943   vl_api_bond_detach_slave_t *mp;
7944   u32 sw_if_index = ~0;
7945   u8 sw_if_index_set = 0;
7946   int ret;
7947
7948   /* Parse args required to build the message */
7949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7950     {
7951       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7952         sw_if_index_set = 1;
7953       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7954         sw_if_index_set = 1;
7955       else
7956         break;
7957     }
7958
7959   if (sw_if_index_set == 0)
7960     {
7961       errmsg ("missing vpp interface name. ");
7962       return -99;
7963     }
7964
7965   /* Construct the API message */
7966   M (BOND_DETACH_SLAVE, mp);
7967
7968   mp->sw_if_index = ntohl (sw_if_index);
7969
7970   /* send it... */
7971   S (mp);
7972
7973   /* Wait for a reply... */
7974   W (ret);
7975   return ret;
7976 }
7977
7978 static int
7979 api_ip_table_add_del (vat_main_t * vam)
7980 {
7981   unformat_input_t *i = vam->input;
7982   vl_api_ip_table_add_del_t *mp;
7983   u32 table_id = ~0;
7984   u8 is_ipv6 = 0;
7985   u8 is_add = 1;
7986   int ret = 0;
7987
7988   /* Parse args required to build the message */
7989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7990     {
7991       if (unformat (i, "ipv6"))
7992         is_ipv6 = 1;
7993       else if (unformat (i, "del"))
7994         is_add = 0;
7995       else if (unformat (i, "add"))
7996         is_add = 1;
7997       else if (unformat (i, "table %d", &table_id))
7998         ;
7999       else
8000         {
8001           clib_warning ("parse error '%U'", format_unformat_error, i);
8002           return -99;
8003         }
8004     }
8005
8006   if (~0 == table_id)
8007     {
8008       errmsg ("missing table-ID");
8009       return -99;
8010     }
8011
8012   /* Construct the API message */
8013   M (IP_TABLE_ADD_DEL, mp);
8014
8015   mp->table_id = ntohl (table_id);
8016   mp->is_ipv6 = is_ipv6;
8017   mp->is_add = is_add;
8018
8019   /* send it... */
8020   S (mp);
8021
8022   /* Wait for a reply... */
8023   W (ret);
8024
8025   return ret;
8026 }
8027
8028 static int
8029 api_ip_add_del_route (vat_main_t * vam)
8030 {
8031   unformat_input_t *i = vam->input;
8032   vl_api_ip_add_del_route_t *mp;
8033   u32 sw_if_index = ~0, vrf_id = 0;
8034   u8 is_ipv6 = 0;
8035   u8 is_local = 0, is_drop = 0;
8036   u8 is_unreach = 0, is_prohibit = 0;
8037   u8 is_add = 1;
8038   u32 next_hop_weight = 1;
8039   u8 is_multipath = 0;
8040   u8 address_set = 0;
8041   u8 address_length_set = 0;
8042   u32 next_hop_table_id = 0;
8043   u32 resolve_attempts = 0;
8044   u32 dst_address_length = 0;
8045   u8 next_hop_set = 0;
8046   ip4_address_t v4_dst_address, v4_next_hop_address;
8047   ip6_address_t v6_dst_address, v6_next_hop_address;
8048   int count = 1;
8049   int j;
8050   f64 before = 0;
8051   u32 random_add_del = 0;
8052   u32 *random_vector = 0;
8053   uword *random_hash;
8054   u32 random_seed = 0xdeaddabe;
8055   u32 classify_table_index = ~0;
8056   u8 is_classify = 0;
8057   u8 resolve_host = 0, resolve_attached = 0;
8058   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8059   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8060   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8061
8062   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8063   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8064   /* Parse args required to build the message */
8065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8066     {
8067       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8068         ;
8069       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8070         ;
8071       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8072         {
8073           address_set = 1;
8074           is_ipv6 = 0;
8075         }
8076       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8077         {
8078           address_set = 1;
8079           is_ipv6 = 1;
8080         }
8081       else if (unformat (i, "/%d", &dst_address_length))
8082         {
8083           address_length_set = 1;
8084         }
8085
8086       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8087                                          &v4_next_hop_address))
8088         {
8089           next_hop_set = 1;
8090         }
8091       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8092                                          &v6_next_hop_address))
8093         {
8094           next_hop_set = 1;
8095         }
8096       else
8097         if (unformat
8098             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8099         {
8100           next_hop_set = 1;
8101         }
8102       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8103         {
8104           next_hop_set = 1;
8105         }
8106       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8107         ;
8108       else if (unformat (i, "weight %d", &next_hop_weight))
8109         ;
8110       else if (unformat (i, "drop"))
8111         {
8112           is_drop = 1;
8113         }
8114       else if (unformat (i, "null-send-unreach"))
8115         {
8116           is_unreach = 1;
8117         }
8118       else if (unformat (i, "null-send-prohibit"))
8119         {
8120           is_prohibit = 1;
8121         }
8122       else if (unformat (i, "local"))
8123         {
8124           is_local = 1;
8125         }
8126       else if (unformat (i, "classify %d", &classify_table_index))
8127         {
8128           is_classify = 1;
8129         }
8130       else if (unformat (i, "del"))
8131         is_add = 0;
8132       else if (unformat (i, "add"))
8133         is_add = 1;
8134       else if (unformat (i, "resolve-via-host"))
8135         resolve_host = 1;
8136       else if (unformat (i, "resolve-via-attached"))
8137         resolve_attached = 1;
8138       else if (unformat (i, "multipath"))
8139         is_multipath = 1;
8140       else if (unformat (i, "vrf %d", &vrf_id))
8141         ;
8142       else if (unformat (i, "count %d", &count))
8143         ;
8144       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8145         ;
8146       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8147         ;
8148       else if (unformat (i, "out-label %d", &next_hop_out_label))
8149         {
8150           vl_api_fib_mpls_label_t fib_label = {
8151             .label = ntohl (next_hop_out_label),
8152             .ttl = 64,
8153             .exp = 0,
8154           };
8155           vec_add1 (next_hop_out_label_stack, fib_label);
8156         }
8157       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8158         ;
8159       else if (unformat (i, "random"))
8160         random_add_del = 1;
8161       else if (unformat (i, "seed %d", &random_seed))
8162         ;
8163       else
8164         {
8165           clib_warning ("parse error '%U'", format_unformat_error, i);
8166           return -99;
8167         }
8168     }
8169
8170   if (!next_hop_set && !is_drop && !is_local &&
8171       !is_classify && !is_unreach && !is_prohibit &&
8172       MPLS_LABEL_INVALID == next_hop_via_label)
8173     {
8174       errmsg
8175         ("next hop / local / drop / unreach / prohibit / classify not set");
8176       return -99;
8177     }
8178
8179   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8180     {
8181       errmsg ("next hop and next-hop via label set");
8182       return -99;
8183     }
8184   if (address_set == 0)
8185     {
8186       errmsg ("missing addresses");
8187       return -99;
8188     }
8189
8190   if (address_length_set == 0)
8191     {
8192       errmsg ("missing address length");
8193       return -99;
8194     }
8195
8196   /* Generate a pile of unique, random routes */
8197   if (random_add_del)
8198     {
8199       u32 this_random_address;
8200       random_hash = hash_create (count, sizeof (uword));
8201
8202       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8203       for (j = 0; j <= count; j++)
8204         {
8205           do
8206             {
8207               this_random_address = random_u32 (&random_seed);
8208               this_random_address =
8209                 clib_host_to_net_u32 (this_random_address);
8210             }
8211           while (hash_get (random_hash, this_random_address));
8212           vec_add1 (random_vector, this_random_address);
8213           hash_set (random_hash, this_random_address, 1);
8214         }
8215       hash_free (random_hash);
8216       v4_dst_address.as_u32 = random_vector[0];
8217     }
8218
8219   if (count > 1)
8220     {
8221       /* Turn on async mode */
8222       vam->async_mode = 1;
8223       vam->async_errors = 0;
8224       before = vat_time_now (vam);
8225     }
8226
8227   for (j = 0; j < count; j++)
8228     {
8229       /* Construct the API message */
8230       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8231           vec_len (next_hop_out_label_stack));
8232
8233       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8234       mp->table_id = ntohl (vrf_id);
8235
8236       mp->is_add = is_add;
8237       mp->is_drop = is_drop;
8238       mp->is_unreach = is_unreach;
8239       mp->is_prohibit = is_prohibit;
8240       mp->is_ipv6 = is_ipv6;
8241       mp->is_local = is_local;
8242       mp->is_classify = is_classify;
8243       mp->is_multipath = is_multipath;
8244       mp->is_resolve_host = resolve_host;
8245       mp->is_resolve_attached = resolve_attached;
8246       mp->next_hop_weight = next_hop_weight;
8247       mp->next_hop_preference = 0;
8248       mp->dst_address_length = dst_address_length;
8249       mp->next_hop_table_id = ntohl (next_hop_table_id);
8250       mp->classify_table_index = ntohl (classify_table_index);
8251       mp->next_hop_via_label = ntohl (next_hop_via_label);
8252       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8253       if (0 != mp->next_hop_n_out_labels)
8254         {
8255           memcpy (mp->next_hop_out_label_stack,
8256                   next_hop_out_label_stack,
8257                   (vec_len (next_hop_out_label_stack) *
8258                    sizeof (vl_api_fib_mpls_label_t)));
8259           vec_free (next_hop_out_label_stack);
8260         }
8261
8262       if (is_ipv6)
8263         {
8264           clib_memcpy (mp->dst_address, &v6_dst_address,
8265                        sizeof (v6_dst_address));
8266           if (next_hop_set)
8267             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8268                          sizeof (v6_next_hop_address));
8269           increment_v6_address (&v6_dst_address);
8270         }
8271       else
8272         {
8273           clib_memcpy (mp->dst_address, &v4_dst_address,
8274                        sizeof (v4_dst_address));
8275           if (next_hop_set)
8276             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8277                          sizeof (v4_next_hop_address));
8278           if (random_add_del)
8279             v4_dst_address.as_u32 = random_vector[j + 1];
8280           else
8281             increment_v4_address (&v4_dst_address);
8282         }
8283       /* send it... */
8284       S (mp);
8285       /* If we receive SIGTERM, stop now... */
8286       if (vam->do_exit)
8287         break;
8288     }
8289
8290   /* When testing multiple add/del ops, use a control-ping to sync */
8291   if (count > 1)
8292     {
8293       vl_api_control_ping_t *mp_ping;
8294       f64 after;
8295       f64 timeout;
8296
8297       /* Shut off async mode */
8298       vam->async_mode = 0;
8299
8300       MPING (CONTROL_PING, mp_ping);
8301       S (mp_ping);
8302
8303       timeout = vat_time_now (vam) + 1.0;
8304       while (vat_time_now (vam) < timeout)
8305         if (vam->result_ready == 1)
8306           goto out;
8307       vam->retval = -99;
8308
8309     out:
8310       if (vam->retval == -99)
8311         errmsg ("timeout");
8312
8313       if (vam->async_errors > 0)
8314         {
8315           errmsg ("%d asynchronous errors", vam->async_errors);
8316           vam->retval = -98;
8317         }
8318       vam->async_errors = 0;
8319       after = vat_time_now (vam);
8320
8321       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8322       if (j > 0)
8323         count = j;
8324
8325       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8326              count, after - before, count / (after - before));
8327     }
8328   else
8329     {
8330       int ret;
8331
8332       /* Wait for a reply... */
8333       W (ret);
8334       return ret;
8335     }
8336
8337   /* Return the good/bad news */
8338   return (vam->retval);
8339 }
8340
8341 static int
8342 api_ip_mroute_add_del (vat_main_t * vam)
8343 {
8344   unformat_input_t *i = vam->input;
8345   vl_api_ip_mroute_add_del_t *mp;
8346   u32 sw_if_index = ~0, vrf_id = 0;
8347   u8 is_ipv6 = 0;
8348   u8 is_local = 0;
8349   u8 is_add = 1;
8350   u8 address_set = 0;
8351   u32 grp_address_length = 0;
8352   ip4_address_t v4_grp_address, v4_src_address;
8353   ip6_address_t v6_grp_address, v6_src_address;
8354   mfib_itf_flags_t iflags = 0;
8355   mfib_entry_flags_t eflags = 0;
8356   int ret;
8357
8358   /* Parse args required to build the message */
8359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8360     {
8361       if (unformat (i, "sw_if_index %d", &sw_if_index))
8362         ;
8363       else if (unformat (i, "%U %U",
8364                          unformat_ip4_address, &v4_src_address,
8365                          unformat_ip4_address, &v4_grp_address))
8366         {
8367           grp_address_length = 64;
8368           address_set = 1;
8369           is_ipv6 = 0;
8370         }
8371       else if (unformat (i, "%U %U",
8372                          unformat_ip6_address, &v6_src_address,
8373                          unformat_ip6_address, &v6_grp_address))
8374         {
8375           grp_address_length = 256;
8376           address_set = 1;
8377           is_ipv6 = 1;
8378         }
8379       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8380         {
8381           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8382           grp_address_length = 32;
8383           address_set = 1;
8384           is_ipv6 = 0;
8385         }
8386       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8387         {
8388           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8389           grp_address_length = 128;
8390           address_set = 1;
8391           is_ipv6 = 1;
8392         }
8393       else if (unformat (i, "/%d", &grp_address_length))
8394         ;
8395       else if (unformat (i, "local"))
8396         {
8397           is_local = 1;
8398         }
8399       else if (unformat (i, "del"))
8400         is_add = 0;
8401       else if (unformat (i, "add"))
8402         is_add = 1;
8403       else if (unformat (i, "vrf %d", &vrf_id))
8404         ;
8405       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8406         ;
8407       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8408         ;
8409       else
8410         {
8411           clib_warning ("parse error '%U'", format_unformat_error, i);
8412           return -99;
8413         }
8414     }
8415
8416   if (address_set == 0)
8417     {
8418       errmsg ("missing addresses\n");
8419       return -99;
8420     }
8421
8422   /* Construct the API message */
8423   M (IP_MROUTE_ADD_DEL, mp);
8424
8425   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8426   mp->table_id = ntohl (vrf_id);
8427
8428   mp->is_add = is_add;
8429   mp->is_ipv6 = is_ipv6;
8430   mp->is_local = is_local;
8431   mp->itf_flags = ntohl (iflags);
8432   mp->entry_flags = ntohl (eflags);
8433   mp->grp_address_length = grp_address_length;
8434   mp->grp_address_length = ntohs (mp->grp_address_length);
8435
8436   if (is_ipv6)
8437     {
8438       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8439       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8440     }
8441   else
8442     {
8443       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8444       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8445
8446     }
8447
8448   /* send it... */
8449   S (mp);
8450   /* Wait for a reply... */
8451   W (ret);
8452   return ret;
8453 }
8454
8455 static int
8456 api_mpls_table_add_del (vat_main_t * vam)
8457 {
8458   unformat_input_t *i = vam->input;
8459   vl_api_mpls_table_add_del_t *mp;
8460   u32 table_id = ~0;
8461   u8 is_add = 1;
8462   int ret = 0;
8463
8464   /* Parse args required to build the message */
8465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8466     {
8467       if (unformat (i, "table %d", &table_id))
8468         ;
8469       else if (unformat (i, "del"))
8470         is_add = 0;
8471       else if (unformat (i, "add"))
8472         is_add = 1;
8473       else
8474         {
8475           clib_warning ("parse error '%U'", format_unformat_error, i);
8476           return -99;
8477         }
8478     }
8479
8480   if (~0 == table_id)
8481     {
8482       errmsg ("missing table-ID");
8483       return -99;
8484     }
8485
8486   /* Construct the API message */
8487   M (MPLS_TABLE_ADD_DEL, mp);
8488
8489   mp->mt_table_id = ntohl (table_id);
8490   mp->mt_is_add = is_add;
8491
8492   /* send it... */
8493   S (mp);
8494
8495   /* Wait for a reply... */
8496   W (ret);
8497
8498   return ret;
8499 }
8500
8501 static int
8502 api_mpls_route_add_del (vat_main_t * vam)
8503 {
8504   unformat_input_t *i = vam->input;
8505   vl_api_mpls_route_add_del_t *mp;
8506   u32 sw_if_index = ~0, table_id = 0;
8507   u8 is_add = 1;
8508   u32 next_hop_weight = 1;
8509   u8 is_multipath = 0;
8510   u32 next_hop_table_id = 0;
8511   u8 next_hop_set = 0;
8512   ip4_address_t v4_next_hop_address = {
8513     .as_u32 = 0,
8514   };
8515   ip6_address_t v6_next_hop_address = { {0} };
8516   int count = 1;
8517   int j;
8518   f64 before = 0;
8519   u32 classify_table_index = ~0;
8520   u8 is_classify = 0;
8521   u8 resolve_host = 0, resolve_attached = 0;
8522   u8 is_interface_rx = 0;
8523   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8524   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8525   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8526   mpls_label_t local_label = MPLS_LABEL_INVALID;
8527   u8 is_eos = 0;
8528   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8529
8530   /* Parse args required to build the message */
8531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8532     {
8533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8534         ;
8535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8536         ;
8537       else if (unformat (i, "%d", &local_label))
8538         ;
8539       else if (unformat (i, "eos"))
8540         is_eos = 1;
8541       else if (unformat (i, "non-eos"))
8542         is_eos = 0;
8543       else if (unformat (i, "via %U", unformat_ip4_address,
8544                          &v4_next_hop_address))
8545         {
8546           next_hop_set = 1;
8547           next_hop_proto = DPO_PROTO_IP4;
8548         }
8549       else if (unformat (i, "via %U", unformat_ip6_address,
8550                          &v6_next_hop_address))
8551         {
8552           next_hop_set = 1;
8553           next_hop_proto = DPO_PROTO_IP6;
8554         }
8555       else if (unformat (i, "weight %d", &next_hop_weight))
8556         ;
8557       else if (unformat (i, "classify %d", &classify_table_index))
8558         {
8559           is_classify = 1;
8560         }
8561       else if (unformat (i, "del"))
8562         is_add = 0;
8563       else if (unformat (i, "add"))
8564         is_add = 1;
8565       else if (unformat (i, "resolve-via-host"))
8566         resolve_host = 1;
8567       else if (unformat (i, "resolve-via-attached"))
8568         resolve_attached = 1;
8569       else if (unformat (i, "multipath"))
8570         is_multipath = 1;
8571       else if (unformat (i, "count %d", &count))
8572         ;
8573       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8574         {
8575           next_hop_set = 1;
8576           next_hop_proto = DPO_PROTO_IP4;
8577         }
8578       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8579         {
8580           next_hop_set = 1;
8581           next_hop_proto = DPO_PROTO_IP6;
8582         }
8583       else
8584         if (unformat
8585             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8586              &sw_if_index))
8587         {
8588           next_hop_set = 1;
8589           next_hop_proto = DPO_PROTO_ETHERNET;
8590           is_interface_rx = 1;
8591         }
8592       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8593         {
8594           next_hop_set = 1;
8595           next_hop_proto = DPO_PROTO_ETHERNET;
8596           is_interface_rx = 1;
8597         }
8598       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8599         next_hop_set = 1;
8600       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8601         next_hop_set = 1;
8602       else if (unformat (i, "out-label %d", &next_hop_out_label))
8603         {
8604           vl_api_fib_mpls_label_t fib_label = {
8605             .label = ntohl (next_hop_out_label),
8606             .ttl = 64,
8607             .exp = 0,
8608           };
8609           vec_add1 (next_hop_out_label_stack, fib_label);
8610         }
8611       else
8612         {
8613           clib_warning ("parse error '%U'", format_unformat_error, i);
8614           return -99;
8615         }
8616     }
8617
8618   if (!next_hop_set && !is_classify)
8619     {
8620       errmsg ("next hop / classify not set");
8621       return -99;
8622     }
8623
8624   if (MPLS_LABEL_INVALID == local_label)
8625     {
8626       errmsg ("missing label");
8627       return -99;
8628     }
8629
8630   if (count > 1)
8631     {
8632       /* Turn on async mode */
8633       vam->async_mode = 1;
8634       vam->async_errors = 0;
8635       before = vat_time_now (vam);
8636     }
8637
8638   for (j = 0; j < count; j++)
8639     {
8640       /* Construct the API message */
8641       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8642           vec_len (next_hop_out_label_stack));
8643
8644       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8645       mp->mr_table_id = ntohl (table_id);
8646
8647       mp->mr_is_add = is_add;
8648       mp->mr_next_hop_proto = next_hop_proto;
8649       mp->mr_is_classify = is_classify;
8650       mp->mr_is_multipath = is_multipath;
8651       mp->mr_is_resolve_host = resolve_host;
8652       mp->mr_is_resolve_attached = resolve_attached;
8653       mp->mr_is_interface_rx = is_interface_rx;
8654       mp->mr_next_hop_weight = next_hop_weight;
8655       mp->mr_next_hop_preference = 0;
8656       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8657       mp->mr_classify_table_index = ntohl (classify_table_index);
8658       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8659       mp->mr_label = ntohl (local_label);
8660       mp->mr_eos = is_eos;
8661
8662       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8663       if (0 != mp->mr_next_hop_n_out_labels)
8664         {
8665           memcpy (mp->mr_next_hop_out_label_stack,
8666                   next_hop_out_label_stack,
8667                   vec_len (next_hop_out_label_stack) *
8668                   sizeof (vl_api_fib_mpls_label_t));
8669           vec_free (next_hop_out_label_stack);
8670         }
8671
8672       if (next_hop_set)
8673         {
8674           if (DPO_PROTO_IP4 == next_hop_proto)
8675             {
8676               clib_memcpy (mp->mr_next_hop,
8677                            &v4_next_hop_address,
8678                            sizeof (v4_next_hop_address));
8679             }
8680           else if (DPO_PROTO_IP6 == next_hop_proto)
8681
8682             {
8683               clib_memcpy (mp->mr_next_hop,
8684                            &v6_next_hop_address,
8685                            sizeof (v6_next_hop_address));
8686             }
8687         }
8688       local_label++;
8689
8690       /* send it... */
8691       S (mp);
8692       /* If we receive SIGTERM, stop now... */
8693       if (vam->do_exit)
8694         break;
8695     }
8696
8697   /* When testing multiple add/del ops, use a control-ping to sync */
8698   if (count > 1)
8699     {
8700       vl_api_control_ping_t *mp_ping;
8701       f64 after;
8702       f64 timeout;
8703
8704       /* Shut off async mode */
8705       vam->async_mode = 0;
8706
8707       MPING (CONTROL_PING, mp_ping);
8708       S (mp_ping);
8709
8710       timeout = vat_time_now (vam) + 1.0;
8711       while (vat_time_now (vam) < timeout)
8712         if (vam->result_ready == 1)
8713           goto out;
8714       vam->retval = -99;
8715
8716     out:
8717       if (vam->retval == -99)
8718         errmsg ("timeout");
8719
8720       if (vam->async_errors > 0)
8721         {
8722           errmsg ("%d asynchronous errors", vam->async_errors);
8723           vam->retval = -98;
8724         }
8725       vam->async_errors = 0;
8726       after = vat_time_now (vam);
8727
8728       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8729       if (j > 0)
8730         count = j;
8731
8732       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8733              count, after - before, count / (after - before));
8734     }
8735   else
8736     {
8737       int ret;
8738
8739       /* Wait for a reply... */
8740       W (ret);
8741       return ret;
8742     }
8743
8744   /* Return the good/bad news */
8745   return (vam->retval);
8746 }
8747
8748 static int
8749 api_mpls_ip_bind_unbind (vat_main_t * vam)
8750 {
8751   unformat_input_t *i = vam->input;
8752   vl_api_mpls_ip_bind_unbind_t *mp;
8753   u32 ip_table_id = 0;
8754   u8 is_bind = 1;
8755   u8 is_ip4 = 1;
8756   ip4_address_t v4_address;
8757   ip6_address_t v6_address;
8758   u32 address_length;
8759   u8 address_set = 0;
8760   mpls_label_t local_label = MPLS_LABEL_INVALID;
8761   int ret;
8762
8763   /* Parse args required to build the message */
8764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8765     {
8766       if (unformat (i, "%U/%d", unformat_ip4_address,
8767                     &v4_address, &address_length))
8768         {
8769           is_ip4 = 1;
8770           address_set = 1;
8771         }
8772       else if (unformat (i, "%U/%d", unformat_ip6_address,
8773                          &v6_address, &address_length))
8774         {
8775           is_ip4 = 0;
8776           address_set = 1;
8777         }
8778       else if (unformat (i, "%d", &local_label))
8779         ;
8780       else if (unformat (i, "table-id %d", &ip_table_id))
8781         ;
8782       else if (unformat (i, "unbind"))
8783         is_bind = 0;
8784       else if (unformat (i, "bind"))
8785         is_bind = 1;
8786       else
8787         {
8788           clib_warning ("parse error '%U'", format_unformat_error, i);
8789           return -99;
8790         }
8791     }
8792
8793   if (!address_set)
8794     {
8795       errmsg ("IP address not set");
8796       return -99;
8797     }
8798
8799   if (MPLS_LABEL_INVALID == local_label)
8800     {
8801       errmsg ("missing label");
8802       return -99;
8803     }
8804
8805   /* Construct the API message */
8806   M (MPLS_IP_BIND_UNBIND, mp);
8807
8808   mp->mb_is_bind = is_bind;
8809   mp->mb_is_ip4 = is_ip4;
8810   mp->mb_ip_table_id = ntohl (ip_table_id);
8811   mp->mb_mpls_table_id = 0;
8812   mp->mb_label = ntohl (local_label);
8813   mp->mb_address_length = address_length;
8814
8815   if (is_ip4)
8816     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8817   else
8818     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8819
8820   /* send it... */
8821   S (mp);
8822
8823   /* Wait for a reply... */
8824   W (ret);
8825   return ret;
8826 }
8827
8828 static int
8829 api_sr_mpls_policy_add (vat_main_t * vam)
8830 {
8831   unformat_input_t *i = vam->input;
8832   vl_api_sr_mpls_policy_add_t *mp;
8833   u32 bsid = 0;
8834   u32 weight = 1;
8835   u8 type = 0;
8836   u8 n_segments = 0;
8837   u32 sid;
8838   u32 *segments = NULL;
8839   int ret;
8840
8841   /* Parse args required to build the message */
8842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8843     {
8844       if (unformat (i, "bsid %d", &bsid))
8845         ;
8846       else if (unformat (i, "weight %d", &weight))
8847         ;
8848       else if (unformat (i, "spray"))
8849         type = 1;
8850       else if (unformat (i, "next %d", &sid))
8851         {
8852           n_segments += 1;
8853           vec_add1 (segments, htonl (sid));
8854         }
8855       else
8856         {
8857           clib_warning ("parse error '%U'", format_unformat_error, i);
8858           return -99;
8859         }
8860     }
8861
8862   if (bsid == 0)
8863     {
8864       errmsg ("bsid not set");
8865       return -99;
8866     }
8867
8868   if (n_segments == 0)
8869     {
8870       errmsg ("no sid in segment stack");
8871       return -99;
8872     }
8873
8874   /* Construct the API message */
8875   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8876
8877   mp->bsid = htonl (bsid);
8878   mp->weight = htonl (weight);
8879   mp->type = type;
8880   mp->n_segments = n_segments;
8881   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8882   vec_free (segments);
8883
8884   /* send it... */
8885   S (mp);
8886
8887   /* Wait for a reply... */
8888   W (ret);
8889   return ret;
8890 }
8891
8892 static int
8893 api_sr_mpls_policy_del (vat_main_t * vam)
8894 {
8895   unformat_input_t *i = vam->input;
8896   vl_api_sr_mpls_policy_del_t *mp;
8897   u32 bsid = 0;
8898   int ret;
8899
8900   /* Parse args required to build the message */
8901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8902     {
8903       if (unformat (i, "bsid %d", &bsid))
8904         ;
8905       else
8906         {
8907           clib_warning ("parse error '%U'", format_unformat_error, i);
8908           return -99;
8909         }
8910     }
8911
8912   if (bsid == 0)
8913     {
8914       errmsg ("bsid not set");
8915       return -99;
8916     }
8917
8918   /* Construct the API message */
8919   M (SR_MPLS_POLICY_DEL, mp);
8920
8921   mp->bsid = htonl (bsid);
8922
8923   /* send it... */
8924   S (mp);
8925
8926   /* Wait for a reply... */
8927   W (ret);
8928   return ret;
8929 }
8930
8931 static int
8932 api_bier_table_add_del (vat_main_t * vam)
8933 {
8934   unformat_input_t *i = vam->input;
8935   vl_api_bier_table_add_del_t *mp;
8936   u8 is_add = 1;
8937   u32 set = 0, sub_domain = 0, hdr_len = 3;
8938   mpls_label_t local_label = MPLS_LABEL_INVALID;
8939   int ret;
8940
8941   /* Parse args required to build the message */
8942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (i, "sub-domain %d", &sub_domain))
8945         ;
8946       else if (unformat (i, "set %d", &set))
8947         ;
8948       else if (unformat (i, "label %d", &local_label))
8949         ;
8950       else if (unformat (i, "hdr-len %d", &hdr_len))
8951         ;
8952       else if (unformat (i, "add"))
8953         is_add = 1;
8954       else if (unformat (i, "del"))
8955         is_add = 0;
8956       else
8957         {
8958           clib_warning ("parse error '%U'", format_unformat_error, i);
8959           return -99;
8960         }
8961     }
8962
8963   if (MPLS_LABEL_INVALID == local_label)
8964     {
8965       errmsg ("missing label\n");
8966       return -99;
8967     }
8968
8969   /* Construct the API message */
8970   M (BIER_TABLE_ADD_DEL, mp);
8971
8972   mp->bt_is_add = is_add;
8973   mp->bt_label = ntohl (local_label);
8974   mp->bt_tbl_id.bt_set = set;
8975   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8976   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8977
8978   /* send it... */
8979   S (mp);
8980
8981   /* Wait for a reply... */
8982   W (ret);
8983
8984   return (ret);
8985 }
8986
8987 static int
8988 api_bier_route_add_del (vat_main_t * vam)
8989 {
8990   unformat_input_t *i = vam->input;
8991   vl_api_bier_route_add_del_t *mp;
8992   u8 is_add = 1;
8993   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8994   ip4_address_t v4_next_hop_address;
8995   ip6_address_t v6_next_hop_address;
8996   u8 next_hop_set = 0;
8997   u8 next_hop_proto_is_ip4 = 1;
8998   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8999   int ret;
9000
9001   /* Parse args required to build the message */
9002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9003     {
9004       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9005         {
9006           next_hop_proto_is_ip4 = 1;
9007           next_hop_set = 1;
9008         }
9009       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9010         {
9011           next_hop_proto_is_ip4 = 0;
9012           next_hop_set = 1;
9013         }
9014       if (unformat (i, "sub-domain %d", &sub_domain))
9015         ;
9016       else if (unformat (i, "set %d", &set))
9017         ;
9018       else if (unformat (i, "hdr-len %d", &hdr_len))
9019         ;
9020       else if (unformat (i, "bp %d", &bp))
9021         ;
9022       else if (unformat (i, "add"))
9023         is_add = 1;
9024       else if (unformat (i, "del"))
9025         is_add = 0;
9026       else if (unformat (i, "out-label %d", &next_hop_out_label))
9027         ;
9028       else
9029         {
9030           clib_warning ("parse error '%U'", format_unformat_error, i);
9031           return -99;
9032         }
9033     }
9034
9035   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9036     {
9037       errmsg ("next hop / label set\n");
9038       return -99;
9039     }
9040   if (0 == bp)
9041     {
9042       errmsg ("bit=position not set\n");
9043       return -99;
9044     }
9045
9046   /* Construct the API message */
9047   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9048
9049   mp->br_is_add = is_add;
9050   mp->br_tbl_id.bt_set = set;
9051   mp->br_tbl_id.bt_sub_domain = sub_domain;
9052   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9053   mp->br_bp = ntohs (bp);
9054   mp->br_n_paths = 1;
9055   mp->br_paths[0].n_labels = 1;
9056   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9057   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9058
9059   if (next_hop_proto_is_ip4)
9060     {
9061       clib_memcpy (mp->br_paths[0].next_hop,
9062                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9063     }
9064   else
9065     {
9066       clib_memcpy (mp->br_paths[0].next_hop,
9067                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9068     }
9069
9070   /* send it... */
9071   S (mp);
9072
9073   /* Wait for a reply... */
9074   W (ret);
9075
9076   return (ret);
9077 }
9078
9079 static int
9080 api_proxy_arp_add_del (vat_main_t * vam)
9081 {
9082   unformat_input_t *i = vam->input;
9083   vl_api_proxy_arp_add_del_t *mp;
9084   u32 vrf_id = 0;
9085   u8 is_add = 1;
9086   vl_api_ip4_address_t lo, hi;
9087   u8 range_set = 0;
9088   int ret;
9089
9090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (i, "vrf %d", &vrf_id))
9093         ;
9094       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9095                          unformat_vl_api_ip4_address, &hi))
9096         range_set = 1;
9097       else if (unformat (i, "del"))
9098         is_add = 0;
9099       else
9100         {
9101           clib_warning ("parse error '%U'", format_unformat_error, i);
9102           return -99;
9103         }
9104     }
9105
9106   if (range_set == 0)
9107     {
9108       errmsg ("address range not set");
9109       return -99;
9110     }
9111
9112   M (PROXY_ARP_ADD_DEL, mp);
9113
9114   mp->proxy.table_id = ntohl (vrf_id);
9115   mp->is_add = is_add;
9116   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9117   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9118
9119   S (mp);
9120   W (ret);
9121   return ret;
9122 }
9123
9124 static int
9125 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9126 {
9127   unformat_input_t *i = vam->input;
9128   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9129   u32 sw_if_index;
9130   u8 enable = 1;
9131   u8 sw_if_index_set = 0;
9132   int ret;
9133
9134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9135     {
9136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9137         sw_if_index_set = 1;
9138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9139         sw_if_index_set = 1;
9140       else if (unformat (i, "enable"))
9141         enable = 1;
9142       else if (unformat (i, "disable"))
9143         enable = 0;
9144       else
9145         {
9146           clib_warning ("parse error '%U'", format_unformat_error, i);
9147           return -99;
9148         }
9149     }
9150
9151   if (sw_if_index_set == 0)
9152     {
9153       errmsg ("missing interface name or sw_if_index");
9154       return -99;
9155     }
9156
9157   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9158
9159   mp->sw_if_index = ntohl (sw_if_index);
9160   mp->enable_disable = enable;
9161
9162   S (mp);
9163   W (ret);
9164   return ret;
9165 }
9166
9167 static int
9168 api_mpls_tunnel_add_del (vat_main_t * vam)
9169 {
9170   unformat_input_t *i = vam->input;
9171   vl_api_mpls_tunnel_add_del_t *mp;
9172
9173   u8 is_add = 1;
9174   u8 l2_only = 0;
9175   u32 sw_if_index = ~0;
9176   u32 next_hop_sw_if_index = ~0;
9177   u32 next_hop_proto_is_ip4 = 1;
9178
9179   u32 next_hop_table_id = 0;
9180   ip4_address_t v4_next_hop_address = {
9181     .as_u32 = 0,
9182   };
9183   ip6_address_t v6_next_hop_address = { {0} };
9184   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9185   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9186   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9187   int ret;
9188
9189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9190     {
9191       if (unformat (i, "add"))
9192         is_add = 1;
9193       else
9194         if (unformat
9195             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9196         is_add = 0;
9197       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9198         is_add = 0;
9199       else if (unformat (i, "via %U",
9200                          unformat_ip4_address, &v4_next_hop_address))
9201         {
9202           next_hop_proto_is_ip4 = 1;
9203         }
9204       else if (unformat (i, "via %U",
9205                          unformat_ip6_address, &v6_next_hop_address))
9206         {
9207           next_hop_proto_is_ip4 = 0;
9208         }
9209       else if (unformat (i, "via-label %d", &next_hop_via_label))
9210         ;
9211       else
9212         if (unformat
9213             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9214         ;
9215       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9216         ;
9217       else if (unformat (i, "l2-only"))
9218         l2_only = 1;
9219       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9220         ;
9221       else if (unformat (i, "out-label %d", &next_hop_out_label))
9222         {
9223           vl_api_fib_mpls_label_t fib_label = {
9224             .label = ntohl (next_hop_out_label),
9225             .ttl = 64,
9226             .exp = 0,
9227           };
9228           vec_add1 (next_hop_out_label_stack, fib_label);
9229         }
9230       else
9231         {
9232           clib_warning ("parse error '%U'", format_unformat_error, i);
9233           return -99;
9234         }
9235     }
9236
9237   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9238       vec_len (next_hop_out_label_stack));
9239
9240   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9241   mp->mt_sw_if_index = ntohl (sw_if_index);
9242   mp->mt_is_add = is_add;
9243   mp->mt_l2_only = l2_only;
9244   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9245   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9246   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9247   mp->mt_next_hop_weight = 1;
9248   mp->mt_next_hop_preference = 0;
9249
9250   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9251
9252   if (0 != mp->mt_next_hop_n_out_labels)
9253     {
9254       clib_memcpy (mp->mt_next_hop_out_label_stack,
9255                    next_hop_out_label_stack,
9256                    (vec_len (next_hop_out_label_stack) *
9257                     sizeof (vl_api_fib_mpls_label_t)));
9258       vec_free (next_hop_out_label_stack);
9259     }
9260
9261   if (next_hop_proto_is_ip4)
9262     {
9263       clib_memcpy (mp->mt_next_hop,
9264                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9265     }
9266   else
9267     {
9268       clib_memcpy (mp->mt_next_hop,
9269                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9270     }
9271
9272   S (mp);
9273   W (ret);
9274   return ret;
9275 }
9276
9277 static int
9278 api_sw_interface_set_unnumbered (vat_main_t * vam)
9279 {
9280   unformat_input_t *i = vam->input;
9281   vl_api_sw_interface_set_unnumbered_t *mp;
9282   u32 sw_if_index;
9283   u32 unnum_sw_index = ~0;
9284   u8 is_add = 1;
9285   u8 sw_if_index_set = 0;
9286   int ret;
9287
9288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9289     {
9290       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9291         sw_if_index_set = 1;
9292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9293         sw_if_index_set = 1;
9294       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9295         ;
9296       else if (unformat (i, "del"))
9297         is_add = 0;
9298       else
9299         {
9300           clib_warning ("parse error '%U'", format_unformat_error, i);
9301           return -99;
9302         }
9303     }
9304
9305   if (sw_if_index_set == 0)
9306     {
9307       errmsg ("missing interface name or sw_if_index");
9308       return -99;
9309     }
9310
9311   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9312
9313   mp->sw_if_index = ntohl (sw_if_index);
9314   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9315   mp->is_add = is_add;
9316
9317   S (mp);
9318   W (ret);
9319   return ret;
9320 }
9321
9322 static int
9323 api_ip_neighbor_add_del (vat_main_t * vam)
9324 {
9325   vl_api_mac_address_t mac_address;
9326   unformat_input_t *i = vam->input;
9327   vl_api_ip_neighbor_add_del_t *mp;
9328   vl_api_address_t ip_address;
9329   u32 sw_if_index;
9330   u8 sw_if_index_set = 0;
9331   u8 is_add = 1;
9332   u8 mac_set = 0;
9333   u8 address_set = 0;
9334   int ret;
9335   ip_neighbor_flags_t flags;
9336
9337   flags = IP_NEIGHBOR_FLAG_NONE;
9338   clib_memset (&ip_address, 0, sizeof (ip_address));
9339   clib_memset (&mac_address, 0, sizeof (mac_address));
9340   /* Parse args required to build the message */
9341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9342     {
9343       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9344         {
9345           mac_set = 1;
9346         }
9347       else if (unformat (i, "del"))
9348         is_add = 0;
9349       else
9350         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9351         sw_if_index_set = 1;
9352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9353         sw_if_index_set = 1;
9354       else if (unformat (i, "static"))
9355         flags |= IP_NEIGHBOR_FLAG_STATIC;
9356       else if (unformat (i, "no-fib-entry"))
9357         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9358       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9359         address_set = 1;
9360       else
9361         {
9362           clib_warning ("parse error '%U'", format_unformat_error, i);
9363           return -99;
9364         }
9365     }
9366
9367   if (sw_if_index_set == 0)
9368     {
9369       errmsg ("missing interface name or sw_if_index");
9370       return -99;
9371     }
9372   if (!address_set)
9373     {
9374       errmsg ("no address set");
9375       return -99;
9376     }
9377
9378   /* Construct the API message */
9379   M (IP_NEIGHBOR_ADD_DEL, mp);
9380
9381   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9382   mp->is_add = is_add;
9383   mp->neighbor.flags = htonl (flags);
9384   if (mac_set)
9385     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9386                  sizeof (mac_address));
9387   if (address_set)
9388     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9389
9390   /* send it... */
9391   S (mp);
9392
9393   /* Wait for a reply, return good/bad news  */
9394   W (ret);
9395   return ret;
9396 }
9397
9398 static int
9399 api_create_vlan_subif (vat_main_t * vam)
9400 {
9401   unformat_input_t *i = vam->input;
9402   vl_api_create_vlan_subif_t *mp;
9403   u32 sw_if_index;
9404   u8 sw_if_index_set = 0;
9405   u32 vlan_id;
9406   u8 vlan_id_set = 0;
9407   int ret;
9408
9409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9410     {
9411       if (unformat (i, "sw_if_index %d", &sw_if_index))
9412         sw_if_index_set = 1;
9413       else
9414         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9415         sw_if_index_set = 1;
9416       else if (unformat (i, "vlan %d", &vlan_id))
9417         vlan_id_set = 1;
9418       else
9419         {
9420           clib_warning ("parse error '%U'", format_unformat_error, i);
9421           return -99;
9422         }
9423     }
9424
9425   if (sw_if_index_set == 0)
9426     {
9427       errmsg ("missing interface name or sw_if_index");
9428       return -99;
9429     }
9430
9431   if (vlan_id_set == 0)
9432     {
9433       errmsg ("missing vlan_id");
9434       return -99;
9435     }
9436   M (CREATE_VLAN_SUBIF, mp);
9437
9438   mp->sw_if_index = ntohl (sw_if_index);
9439   mp->vlan_id = ntohl (vlan_id);
9440
9441   S (mp);
9442   W (ret);
9443   return ret;
9444 }
9445
9446 #define foreach_create_subif_bit                \
9447 _(no_tags)                                      \
9448 _(one_tag)                                      \
9449 _(two_tags)                                     \
9450 _(dot1ad)                                       \
9451 _(exact_match)                                  \
9452 _(default_sub)                                  \
9453 _(outer_vlan_id_any)                            \
9454 _(inner_vlan_id_any)
9455
9456 static int
9457 api_create_subif (vat_main_t * vam)
9458 {
9459   unformat_input_t *i = vam->input;
9460   vl_api_create_subif_t *mp;
9461   u32 sw_if_index;
9462   u8 sw_if_index_set = 0;
9463   u32 sub_id;
9464   u8 sub_id_set = 0;
9465   u32 no_tags = 0;
9466   u32 one_tag = 0;
9467   u32 two_tags = 0;
9468   u32 dot1ad = 0;
9469   u32 exact_match = 0;
9470   u32 default_sub = 0;
9471   u32 outer_vlan_id_any = 0;
9472   u32 inner_vlan_id_any = 0;
9473   u32 tmp;
9474   u16 outer_vlan_id = 0;
9475   u16 inner_vlan_id = 0;
9476   int ret;
9477
9478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9479     {
9480       if (unformat (i, "sw_if_index %d", &sw_if_index))
9481         sw_if_index_set = 1;
9482       else
9483         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9484         sw_if_index_set = 1;
9485       else if (unformat (i, "sub_id %d", &sub_id))
9486         sub_id_set = 1;
9487       else if (unformat (i, "outer_vlan_id %d", &tmp))
9488         outer_vlan_id = tmp;
9489       else if (unformat (i, "inner_vlan_id %d", &tmp))
9490         inner_vlan_id = tmp;
9491
9492 #define _(a) else if (unformat (i, #a)) a = 1 ;
9493       foreach_create_subif_bit
9494 #undef _
9495         else
9496         {
9497           clib_warning ("parse error '%U'", format_unformat_error, i);
9498           return -99;
9499         }
9500     }
9501
9502   if (sw_if_index_set == 0)
9503     {
9504       errmsg ("missing interface name or sw_if_index");
9505       return -99;
9506     }
9507
9508   if (sub_id_set == 0)
9509     {
9510       errmsg ("missing sub_id");
9511       return -99;
9512     }
9513   M (CREATE_SUBIF, mp);
9514
9515   mp->sw_if_index = ntohl (sw_if_index);
9516   mp->sub_id = ntohl (sub_id);
9517
9518 #define _(a) mp->a = a;
9519   foreach_create_subif_bit;
9520 #undef _
9521
9522   mp->outer_vlan_id = ntohs (outer_vlan_id);
9523   mp->inner_vlan_id = ntohs (inner_vlan_id);
9524
9525   S (mp);
9526   W (ret);
9527   return ret;
9528 }
9529
9530 static int
9531 api_oam_add_del (vat_main_t * vam)
9532 {
9533   unformat_input_t *i = vam->input;
9534   vl_api_oam_add_del_t *mp;
9535   u32 vrf_id = 0;
9536   u8 is_add = 1;
9537   ip4_address_t src, dst;
9538   u8 src_set = 0;
9539   u8 dst_set = 0;
9540   int ret;
9541
9542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9543     {
9544       if (unformat (i, "vrf %d", &vrf_id))
9545         ;
9546       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9547         src_set = 1;
9548       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9549         dst_set = 1;
9550       else if (unformat (i, "del"))
9551         is_add = 0;
9552       else
9553         {
9554           clib_warning ("parse error '%U'", format_unformat_error, i);
9555           return -99;
9556         }
9557     }
9558
9559   if (src_set == 0)
9560     {
9561       errmsg ("missing src addr");
9562       return -99;
9563     }
9564
9565   if (dst_set == 0)
9566     {
9567       errmsg ("missing dst addr");
9568       return -99;
9569     }
9570
9571   M (OAM_ADD_DEL, mp);
9572
9573   mp->vrf_id = ntohl (vrf_id);
9574   mp->is_add = is_add;
9575   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9576   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9577
9578   S (mp);
9579   W (ret);
9580   return ret;
9581 }
9582
9583 static int
9584 api_reset_fib (vat_main_t * vam)
9585 {
9586   unformat_input_t *i = vam->input;
9587   vl_api_reset_fib_t *mp;
9588   u32 vrf_id = 0;
9589   u8 is_ipv6 = 0;
9590   u8 vrf_id_set = 0;
9591
9592   int ret;
9593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9594     {
9595       if (unformat (i, "vrf %d", &vrf_id))
9596         vrf_id_set = 1;
9597       else if (unformat (i, "ipv6"))
9598         is_ipv6 = 1;
9599       else
9600         {
9601           clib_warning ("parse error '%U'", format_unformat_error, i);
9602           return -99;
9603         }
9604     }
9605
9606   if (vrf_id_set == 0)
9607     {
9608       errmsg ("missing vrf id");
9609       return -99;
9610     }
9611
9612   M (RESET_FIB, mp);
9613
9614   mp->vrf_id = ntohl (vrf_id);
9615   mp->is_ipv6 = is_ipv6;
9616
9617   S (mp);
9618   W (ret);
9619   return ret;
9620 }
9621
9622 static int
9623 api_dhcp_proxy_config (vat_main_t * vam)
9624 {
9625   unformat_input_t *i = vam->input;
9626   vl_api_dhcp_proxy_config_t *mp;
9627   u32 rx_vrf_id = 0;
9628   u32 server_vrf_id = 0;
9629   u8 is_add = 1;
9630   u8 v4_address_set = 0;
9631   u8 v6_address_set = 0;
9632   ip4_address_t v4address;
9633   ip6_address_t v6address;
9634   u8 v4_src_address_set = 0;
9635   u8 v6_src_address_set = 0;
9636   ip4_address_t v4srcaddress;
9637   ip6_address_t v6srcaddress;
9638   int ret;
9639
9640   /* Parse args required to build the message */
9641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (i, "del"))
9644         is_add = 0;
9645       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9646         ;
9647       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9648         ;
9649       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9650         v4_address_set = 1;
9651       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9652         v6_address_set = 1;
9653       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9654         v4_src_address_set = 1;
9655       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9656         v6_src_address_set = 1;
9657       else
9658         break;
9659     }
9660
9661   if (v4_address_set && v6_address_set)
9662     {
9663       errmsg ("both v4 and v6 server addresses set");
9664       return -99;
9665     }
9666   if (!v4_address_set && !v6_address_set)
9667     {
9668       errmsg ("no server addresses set");
9669       return -99;
9670     }
9671
9672   if (v4_src_address_set && v6_src_address_set)
9673     {
9674       errmsg ("both v4 and v6  src addresses set");
9675       return -99;
9676     }
9677   if (!v4_src_address_set && !v6_src_address_set)
9678     {
9679       errmsg ("no src addresses set");
9680       return -99;
9681     }
9682
9683   if (!(v4_src_address_set && v4_address_set) &&
9684       !(v6_src_address_set && v6_address_set))
9685     {
9686       errmsg ("no matching server and src addresses set");
9687       return -99;
9688     }
9689
9690   /* Construct the API message */
9691   M (DHCP_PROXY_CONFIG, mp);
9692
9693   mp->is_add = is_add;
9694   mp->rx_vrf_id = ntohl (rx_vrf_id);
9695   mp->server_vrf_id = ntohl (server_vrf_id);
9696   if (v6_address_set)
9697     {
9698       mp->is_ipv6 = 1;
9699       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9700       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9701     }
9702   else
9703     {
9704       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9705       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9706     }
9707
9708   /* send it... */
9709   S (mp);
9710
9711   /* Wait for a reply, return good/bad news  */
9712   W (ret);
9713   return ret;
9714 }
9715
9716 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9717 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9718
9719 static void
9720 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9721 {
9722   vat_main_t *vam = &vat_main;
9723   u32 i, count = mp->count;
9724   vl_api_dhcp_server_t *s;
9725
9726   if (mp->is_ipv6)
9727     print (vam->ofp,
9728            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9729            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9730            ntohl (mp->rx_vrf_id),
9731            format_ip6_address, mp->dhcp_src_address,
9732            mp->vss_type, mp->vss_vpn_ascii_id,
9733            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9734   else
9735     print (vam->ofp,
9736            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9737            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9738            ntohl (mp->rx_vrf_id),
9739            format_ip4_address, mp->dhcp_src_address,
9740            mp->vss_type, mp->vss_vpn_ascii_id,
9741            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9742
9743   for (i = 0; i < count; i++)
9744     {
9745       s = &mp->servers[i];
9746
9747       if (mp->is_ipv6)
9748         print (vam->ofp,
9749                " Server Table-ID %d, Server Address %U",
9750                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9751       else
9752         print (vam->ofp,
9753                " Server Table-ID %d, Server Address %U",
9754                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9755     }
9756 }
9757
9758 static void vl_api_dhcp_proxy_details_t_handler_json
9759   (vl_api_dhcp_proxy_details_t * mp)
9760 {
9761   vat_main_t *vam = &vat_main;
9762   vat_json_node_t *node = NULL;
9763   u32 i, count = mp->count;
9764   struct in_addr ip4;
9765   struct in6_addr ip6;
9766   vl_api_dhcp_server_t *s;
9767
9768   if (VAT_JSON_ARRAY != vam->json_tree.type)
9769     {
9770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9771       vat_json_init_array (&vam->json_tree);
9772     }
9773   node = vat_json_array_add (&vam->json_tree);
9774
9775   vat_json_init_object (node);
9776   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9777   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9778                              sizeof (mp->vss_type));
9779   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9780                                    mp->vss_vpn_ascii_id);
9781   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9782   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9783
9784   if (mp->is_ipv6)
9785     {
9786       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9787       vat_json_object_add_ip6 (node, "src_address", ip6);
9788     }
9789   else
9790     {
9791       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9792       vat_json_object_add_ip4 (node, "src_address", ip4);
9793     }
9794
9795   for (i = 0; i < count; i++)
9796     {
9797       s = &mp->servers[i];
9798
9799       vat_json_object_add_uint (node, "server-table-id",
9800                                 ntohl (s->server_vrf_id));
9801
9802       if (mp->is_ipv6)
9803         {
9804           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9805           vat_json_object_add_ip4 (node, "src_address", ip4);
9806         }
9807       else
9808         {
9809           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9810           vat_json_object_add_ip6 (node, "server_address", ip6);
9811         }
9812     }
9813 }
9814
9815 static int
9816 api_dhcp_proxy_dump (vat_main_t * vam)
9817 {
9818   unformat_input_t *i = vam->input;
9819   vl_api_control_ping_t *mp_ping;
9820   vl_api_dhcp_proxy_dump_t *mp;
9821   u8 is_ipv6 = 0;
9822   int ret;
9823
9824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9825     {
9826       if (unformat (i, "ipv6"))
9827         is_ipv6 = 1;
9828       else
9829         {
9830           clib_warning ("parse error '%U'", format_unformat_error, i);
9831           return -99;
9832         }
9833     }
9834
9835   M (DHCP_PROXY_DUMP, mp);
9836
9837   mp->is_ip6 = is_ipv6;
9838   S (mp);
9839
9840   /* Use a control ping for synchronization */
9841   MPING (CONTROL_PING, mp_ping);
9842   S (mp_ping);
9843
9844   W (ret);
9845   return ret;
9846 }
9847
9848 static int
9849 api_dhcp_proxy_set_vss (vat_main_t * vam)
9850 {
9851   unformat_input_t *i = vam->input;
9852   vl_api_dhcp_proxy_set_vss_t *mp;
9853   u8 is_ipv6 = 0;
9854   u8 is_add = 1;
9855   u32 tbl_id = ~0;
9856   u8 vss_type = VSS_TYPE_DEFAULT;
9857   u8 *vpn_ascii_id = 0;
9858   u32 oui = 0;
9859   u32 fib_id = 0;
9860   int ret;
9861
9862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9863     {
9864       if (unformat (i, "tbl_id %d", &tbl_id))
9865         ;
9866       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9867         vss_type = VSS_TYPE_ASCII;
9868       else if (unformat (i, "fib_id %d", &fib_id))
9869         vss_type = VSS_TYPE_VPN_ID;
9870       else if (unformat (i, "oui %d", &oui))
9871         vss_type = VSS_TYPE_VPN_ID;
9872       else if (unformat (i, "ipv6"))
9873         is_ipv6 = 1;
9874       else if (unformat (i, "del"))
9875         is_add = 0;
9876       else
9877         break;
9878     }
9879
9880   if (tbl_id == ~0)
9881     {
9882       errmsg ("missing tbl_id ");
9883       vec_free (vpn_ascii_id);
9884       return -99;
9885     }
9886
9887   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9888     {
9889       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9890       vec_free (vpn_ascii_id);
9891       return -99;
9892     }
9893
9894   M (DHCP_PROXY_SET_VSS, mp);
9895   mp->tbl_id = ntohl (tbl_id);
9896   mp->vss_type = vss_type;
9897   if (vpn_ascii_id)
9898     {
9899       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9900       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9901     }
9902   mp->vpn_index = ntohl (fib_id);
9903   mp->oui = ntohl (oui);
9904   mp->is_ipv6 = is_ipv6;
9905   mp->is_add = is_add;
9906
9907   S (mp);
9908   W (ret);
9909
9910   vec_free (vpn_ascii_id);
9911   return ret;
9912 }
9913
9914 static int
9915 api_dhcp_client_config (vat_main_t * vam)
9916 {
9917   unformat_input_t *i = vam->input;
9918   vl_api_dhcp_client_config_t *mp;
9919   u32 sw_if_index;
9920   u8 sw_if_index_set = 0;
9921   u8 is_add = 1;
9922   u8 *hostname = 0;
9923   u8 disable_event = 0;
9924   int ret;
9925
9926   /* Parse args required to build the message */
9927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9928     {
9929       if (unformat (i, "del"))
9930         is_add = 0;
9931       else
9932         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9933         sw_if_index_set = 1;
9934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9935         sw_if_index_set = 1;
9936       else if (unformat (i, "hostname %s", &hostname))
9937         ;
9938       else if (unformat (i, "disable_event"))
9939         disable_event = 1;
9940       else
9941         break;
9942     }
9943
9944   if (sw_if_index_set == 0)
9945     {
9946       errmsg ("missing interface name or sw_if_index");
9947       return -99;
9948     }
9949
9950   if (vec_len (hostname) > 63)
9951     {
9952       errmsg ("hostname too long");
9953     }
9954   vec_add1 (hostname, 0);
9955
9956   /* Construct the API message */
9957   M (DHCP_CLIENT_CONFIG, mp);
9958
9959   mp->is_add = is_add;
9960   mp->client.sw_if_index = htonl (sw_if_index);
9961   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9962   vec_free (hostname);
9963   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9964   mp->client.pid = htonl (getpid ());
9965
9966   /* send it... */
9967   S (mp);
9968
9969   /* Wait for a reply, return good/bad news  */
9970   W (ret);
9971   return ret;
9972 }
9973
9974 static int
9975 api_set_ip_flow_hash (vat_main_t * vam)
9976 {
9977   unformat_input_t *i = vam->input;
9978   vl_api_set_ip_flow_hash_t *mp;
9979   u32 vrf_id = 0;
9980   u8 is_ipv6 = 0;
9981   u8 vrf_id_set = 0;
9982   u8 src = 0;
9983   u8 dst = 0;
9984   u8 sport = 0;
9985   u8 dport = 0;
9986   u8 proto = 0;
9987   u8 reverse = 0;
9988   int ret;
9989
9990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9991     {
9992       if (unformat (i, "vrf %d", &vrf_id))
9993         vrf_id_set = 1;
9994       else if (unformat (i, "ipv6"))
9995         is_ipv6 = 1;
9996       else if (unformat (i, "src"))
9997         src = 1;
9998       else if (unformat (i, "dst"))
9999         dst = 1;
10000       else if (unformat (i, "sport"))
10001         sport = 1;
10002       else if (unformat (i, "dport"))
10003         dport = 1;
10004       else if (unformat (i, "proto"))
10005         proto = 1;
10006       else if (unformat (i, "reverse"))
10007         reverse = 1;
10008
10009       else
10010         {
10011           clib_warning ("parse error '%U'", format_unformat_error, i);
10012           return -99;
10013         }
10014     }
10015
10016   if (vrf_id_set == 0)
10017     {
10018       errmsg ("missing vrf id");
10019       return -99;
10020     }
10021
10022   M (SET_IP_FLOW_HASH, mp);
10023   mp->src = src;
10024   mp->dst = dst;
10025   mp->sport = sport;
10026   mp->dport = dport;
10027   mp->proto = proto;
10028   mp->reverse = reverse;
10029   mp->vrf_id = ntohl (vrf_id);
10030   mp->is_ipv6 = is_ipv6;
10031
10032   S (mp);
10033   W (ret);
10034   return ret;
10035 }
10036
10037 static int
10038 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10039 {
10040   unformat_input_t *i = vam->input;
10041   vl_api_sw_interface_ip6_enable_disable_t *mp;
10042   u32 sw_if_index;
10043   u8 sw_if_index_set = 0;
10044   u8 enable = 0;
10045   int ret;
10046
10047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10048     {
10049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10050         sw_if_index_set = 1;
10051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10052         sw_if_index_set = 1;
10053       else if (unformat (i, "enable"))
10054         enable = 1;
10055       else if (unformat (i, "disable"))
10056         enable = 0;
10057       else
10058         {
10059           clib_warning ("parse error '%U'", format_unformat_error, i);
10060           return -99;
10061         }
10062     }
10063
10064   if (sw_if_index_set == 0)
10065     {
10066       errmsg ("missing interface name or sw_if_index");
10067       return -99;
10068     }
10069
10070   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10071
10072   mp->sw_if_index = ntohl (sw_if_index);
10073   mp->enable = enable;
10074
10075   S (mp);
10076   W (ret);
10077   return ret;
10078 }
10079
10080 static int
10081 api_ip6nd_proxy_add_del (vat_main_t * vam)
10082 {
10083   unformat_input_t *i = vam->input;
10084   vl_api_ip6nd_proxy_add_del_t *mp;
10085   u32 sw_if_index = ~0;
10086   u8 v6_address_set = 0;
10087   vl_api_ip6_address_t v6address;
10088   u8 is_del = 0;
10089   int ret;
10090
10091   /* Parse args required to build the message */
10092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10093     {
10094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10095         ;
10096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10097         ;
10098       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10099         v6_address_set = 1;
10100       if (unformat (i, "del"))
10101         is_del = 1;
10102       else
10103         {
10104           clib_warning ("parse error '%U'", format_unformat_error, i);
10105           return -99;
10106         }
10107     }
10108
10109   if (sw_if_index == ~0)
10110     {
10111       errmsg ("missing interface name or sw_if_index");
10112       return -99;
10113     }
10114   if (!v6_address_set)
10115     {
10116       errmsg ("no address set");
10117       return -99;
10118     }
10119
10120   /* Construct the API message */
10121   M (IP6ND_PROXY_ADD_DEL, mp);
10122
10123   mp->is_del = is_del;
10124   mp->sw_if_index = ntohl (sw_if_index);
10125   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10126
10127   /* send it... */
10128   S (mp);
10129
10130   /* Wait for a reply, return good/bad news  */
10131   W (ret);
10132   return ret;
10133 }
10134
10135 static int
10136 api_ip6nd_proxy_dump (vat_main_t * vam)
10137 {
10138   vl_api_ip6nd_proxy_dump_t *mp;
10139   vl_api_control_ping_t *mp_ping;
10140   int ret;
10141
10142   M (IP6ND_PROXY_DUMP, mp);
10143
10144   S (mp);
10145
10146   /* Use a control ping for synchronization */
10147   MPING (CONTROL_PING, mp_ping);
10148   S (mp_ping);
10149
10150   W (ret);
10151   return ret;
10152 }
10153
10154 static void vl_api_ip6nd_proxy_details_t_handler
10155   (vl_api_ip6nd_proxy_details_t * mp)
10156 {
10157   vat_main_t *vam = &vat_main;
10158
10159   print (vam->ofp, "host %U sw_if_index %d",
10160          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10161 }
10162
10163 static void vl_api_ip6nd_proxy_details_t_handler_json
10164   (vl_api_ip6nd_proxy_details_t * mp)
10165 {
10166   vat_main_t *vam = &vat_main;
10167   struct in6_addr ip6;
10168   vat_json_node_t *node = NULL;
10169
10170   if (VAT_JSON_ARRAY != vam->json_tree.type)
10171     {
10172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10173       vat_json_init_array (&vam->json_tree);
10174     }
10175   node = vat_json_array_add (&vam->json_tree);
10176
10177   vat_json_init_object (node);
10178   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10179
10180   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10181   vat_json_object_add_ip6 (node, "host", ip6);
10182 }
10183
10184 static int
10185 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10186 {
10187   unformat_input_t *i = vam->input;
10188   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10189   u32 sw_if_index;
10190   u8 sw_if_index_set = 0;
10191   u32 address_length = 0;
10192   u8 v6_address_set = 0;
10193   vl_api_prefix_t pfx;
10194   u8 use_default = 0;
10195   u8 no_advertise = 0;
10196   u8 off_link = 0;
10197   u8 no_autoconfig = 0;
10198   u8 no_onlink = 0;
10199   u8 is_no = 0;
10200   u32 val_lifetime = 0;
10201   u32 pref_lifetime = 0;
10202   int ret;
10203
10204   /* Parse args required to build the message */
10205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10206     {
10207       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10208         sw_if_index_set = 1;
10209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10210         sw_if_index_set = 1;
10211       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10212         v6_address_set = 1;
10213       else if (unformat (i, "val_life %d", &val_lifetime))
10214         ;
10215       else if (unformat (i, "pref_life %d", &pref_lifetime))
10216         ;
10217       else if (unformat (i, "def"))
10218         use_default = 1;
10219       else if (unformat (i, "noadv"))
10220         no_advertise = 1;
10221       else if (unformat (i, "offl"))
10222         off_link = 1;
10223       else if (unformat (i, "noauto"))
10224         no_autoconfig = 1;
10225       else if (unformat (i, "nolink"))
10226         no_onlink = 1;
10227       else if (unformat (i, "isno"))
10228         is_no = 1;
10229       else
10230         {
10231           clib_warning ("parse error '%U'", format_unformat_error, i);
10232           return -99;
10233         }
10234     }
10235
10236   if (sw_if_index_set == 0)
10237     {
10238       errmsg ("missing interface name or sw_if_index");
10239       return -99;
10240     }
10241   if (!v6_address_set)
10242     {
10243       errmsg ("no address set");
10244       return -99;
10245     }
10246
10247   /* Construct the API message */
10248   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10249
10250   mp->sw_if_index = ntohl (sw_if_index);
10251   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10252   mp->use_default = use_default;
10253   mp->no_advertise = no_advertise;
10254   mp->off_link = off_link;
10255   mp->no_autoconfig = no_autoconfig;
10256   mp->no_onlink = no_onlink;
10257   mp->is_no = is_no;
10258   mp->val_lifetime = ntohl (val_lifetime);
10259   mp->pref_lifetime = ntohl (pref_lifetime);
10260
10261   /* send it... */
10262   S (mp);
10263
10264   /* Wait for a reply, return good/bad news  */
10265   W (ret);
10266   return ret;
10267 }
10268
10269 static int
10270 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10271 {
10272   unformat_input_t *i = vam->input;
10273   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10274   u32 sw_if_index;
10275   u8 sw_if_index_set = 0;
10276   u8 suppress = 0;
10277   u8 managed = 0;
10278   u8 other = 0;
10279   u8 ll_option = 0;
10280   u8 send_unicast = 0;
10281   u8 cease = 0;
10282   u8 is_no = 0;
10283   u8 default_router = 0;
10284   u32 max_interval = 0;
10285   u32 min_interval = 0;
10286   u32 lifetime = 0;
10287   u32 initial_count = 0;
10288   u32 initial_interval = 0;
10289   int ret;
10290
10291
10292   /* Parse args required to build the message */
10293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10294     {
10295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10296         sw_if_index_set = 1;
10297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10298         sw_if_index_set = 1;
10299       else if (unformat (i, "maxint %d", &max_interval))
10300         ;
10301       else if (unformat (i, "minint %d", &min_interval))
10302         ;
10303       else if (unformat (i, "life %d", &lifetime))
10304         ;
10305       else if (unformat (i, "count %d", &initial_count))
10306         ;
10307       else if (unformat (i, "interval %d", &initial_interval))
10308         ;
10309       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10310         suppress = 1;
10311       else if (unformat (i, "managed"))
10312         managed = 1;
10313       else if (unformat (i, "other"))
10314         other = 1;
10315       else if (unformat (i, "ll"))
10316         ll_option = 1;
10317       else if (unformat (i, "send"))
10318         send_unicast = 1;
10319       else if (unformat (i, "cease"))
10320         cease = 1;
10321       else if (unformat (i, "isno"))
10322         is_no = 1;
10323       else if (unformat (i, "def"))
10324         default_router = 1;
10325       else
10326         {
10327           clib_warning ("parse error '%U'", format_unformat_error, i);
10328           return -99;
10329         }
10330     }
10331
10332   if (sw_if_index_set == 0)
10333     {
10334       errmsg ("missing interface name or sw_if_index");
10335       return -99;
10336     }
10337
10338   /* Construct the API message */
10339   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10340
10341   mp->sw_if_index = ntohl (sw_if_index);
10342   mp->max_interval = ntohl (max_interval);
10343   mp->min_interval = ntohl (min_interval);
10344   mp->lifetime = ntohl (lifetime);
10345   mp->initial_count = ntohl (initial_count);
10346   mp->initial_interval = ntohl (initial_interval);
10347   mp->suppress = suppress;
10348   mp->managed = managed;
10349   mp->other = other;
10350   mp->ll_option = ll_option;
10351   mp->send_unicast = send_unicast;
10352   mp->cease = cease;
10353   mp->is_no = is_no;
10354   mp->default_router = default_router;
10355
10356   /* send it... */
10357   S (mp);
10358
10359   /* Wait for a reply, return good/bad news  */
10360   W (ret);
10361   return ret;
10362 }
10363
10364 static int
10365 api_set_arp_neighbor_limit (vat_main_t * vam)
10366 {
10367   unformat_input_t *i = vam->input;
10368   vl_api_set_arp_neighbor_limit_t *mp;
10369   u32 arp_nbr_limit;
10370   u8 limit_set = 0;
10371   u8 is_ipv6 = 0;
10372   int ret;
10373
10374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10375     {
10376       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10377         limit_set = 1;
10378       else if (unformat (i, "ipv6"))
10379         is_ipv6 = 1;
10380       else
10381         {
10382           clib_warning ("parse error '%U'", format_unformat_error, i);
10383           return -99;
10384         }
10385     }
10386
10387   if (limit_set == 0)
10388     {
10389       errmsg ("missing limit value");
10390       return -99;
10391     }
10392
10393   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10394
10395   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10396   mp->is_ipv6 = is_ipv6;
10397
10398   S (mp);
10399   W (ret);
10400   return ret;
10401 }
10402
10403 static int
10404 api_l2_patch_add_del (vat_main_t * vam)
10405 {
10406   unformat_input_t *i = vam->input;
10407   vl_api_l2_patch_add_del_t *mp;
10408   u32 rx_sw_if_index;
10409   u8 rx_sw_if_index_set = 0;
10410   u32 tx_sw_if_index;
10411   u8 tx_sw_if_index_set = 0;
10412   u8 is_add = 1;
10413   int ret;
10414
10415   /* Parse args required to build the message */
10416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10417     {
10418       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10419         rx_sw_if_index_set = 1;
10420       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10421         tx_sw_if_index_set = 1;
10422       else if (unformat (i, "rx"))
10423         {
10424           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10425             {
10426               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10427                             &rx_sw_if_index))
10428                 rx_sw_if_index_set = 1;
10429             }
10430           else
10431             break;
10432         }
10433       else if (unformat (i, "tx"))
10434         {
10435           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10436             {
10437               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10438                             &tx_sw_if_index))
10439                 tx_sw_if_index_set = 1;
10440             }
10441           else
10442             break;
10443         }
10444       else if (unformat (i, "del"))
10445         is_add = 0;
10446       else
10447         break;
10448     }
10449
10450   if (rx_sw_if_index_set == 0)
10451     {
10452       errmsg ("missing rx interface name or rx_sw_if_index");
10453       return -99;
10454     }
10455
10456   if (tx_sw_if_index_set == 0)
10457     {
10458       errmsg ("missing tx interface name or tx_sw_if_index");
10459       return -99;
10460     }
10461
10462   M (L2_PATCH_ADD_DEL, mp);
10463
10464   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10465   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10466   mp->is_add = is_add;
10467
10468   S (mp);
10469   W (ret);
10470   return ret;
10471 }
10472
10473 u8 is_del;
10474 u8 localsid_addr[16];
10475 u8 end_psp;
10476 u8 behavior;
10477 u32 sw_if_index;
10478 u32 vlan_index;
10479 u32 fib_table;
10480 u8 nh_addr[16];
10481
10482 static int
10483 api_sr_localsid_add_del (vat_main_t * vam)
10484 {
10485   unformat_input_t *i = vam->input;
10486   vl_api_sr_localsid_add_del_t *mp;
10487
10488   u8 is_del;
10489   ip6_address_t localsid;
10490   u8 end_psp = 0;
10491   u8 behavior = ~0;
10492   u32 sw_if_index;
10493   u32 fib_table = ~(u32) 0;
10494   ip6_address_t nh_addr6;
10495   ip4_address_t nh_addr4;
10496   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10497   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10498
10499   bool nexthop_set = 0;
10500
10501   int ret;
10502
10503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10504     {
10505       if (unformat (i, "del"))
10506         is_del = 1;
10507       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10508       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10509         nexthop_set = 1;
10510       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10511         nexthop_set = 1;
10512       else if (unformat (i, "behavior %u", &behavior));
10513       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10514       else if (unformat (i, "fib-table %u", &fib_table));
10515       else if (unformat (i, "end.psp %u", &behavior));
10516       else
10517         break;
10518     }
10519
10520   M (SR_LOCALSID_ADD_DEL, mp);
10521
10522   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10523   if (nexthop_set)
10524     {
10525       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10526       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10527     }
10528   mp->behavior = behavior;
10529   mp->sw_if_index = ntohl (sw_if_index);
10530   mp->fib_table = ntohl (fib_table);
10531   mp->end_psp = end_psp;
10532   mp->is_del = is_del;
10533
10534   S (mp);
10535   W (ret);
10536   return ret;
10537 }
10538
10539 static int
10540 api_ioam_enable (vat_main_t * vam)
10541 {
10542   unformat_input_t *input = vam->input;
10543   vl_api_ioam_enable_t *mp;
10544   u32 id = 0;
10545   int has_trace_option = 0;
10546   int has_pot_option = 0;
10547   int has_seqno_option = 0;
10548   int has_analyse_option = 0;
10549   int ret;
10550
10551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10552     {
10553       if (unformat (input, "trace"))
10554         has_trace_option = 1;
10555       else if (unformat (input, "pot"))
10556         has_pot_option = 1;
10557       else if (unformat (input, "seqno"))
10558         has_seqno_option = 1;
10559       else if (unformat (input, "analyse"))
10560         has_analyse_option = 1;
10561       else
10562         break;
10563     }
10564   M (IOAM_ENABLE, mp);
10565   mp->id = htons (id);
10566   mp->seqno = has_seqno_option;
10567   mp->analyse = has_analyse_option;
10568   mp->pot_enable = has_pot_option;
10569   mp->trace_enable = has_trace_option;
10570
10571   S (mp);
10572   W (ret);
10573   return ret;
10574 }
10575
10576
10577 static int
10578 api_ioam_disable (vat_main_t * vam)
10579 {
10580   vl_api_ioam_disable_t *mp;
10581   int ret;
10582
10583   M (IOAM_DISABLE, mp);
10584   S (mp);
10585   W (ret);
10586   return ret;
10587 }
10588
10589 #define foreach_tcp_proto_field                 \
10590 _(src_port)                                     \
10591 _(dst_port)
10592
10593 #define foreach_udp_proto_field                 \
10594 _(src_port)                                     \
10595 _(dst_port)
10596
10597 #define foreach_ip4_proto_field                 \
10598 _(src_address)                                  \
10599 _(dst_address)                                  \
10600 _(tos)                                          \
10601 _(length)                                       \
10602 _(fragment_id)                                  \
10603 _(ttl)                                          \
10604 _(protocol)                                     \
10605 _(checksum)
10606
10607 typedef struct
10608 {
10609   u16 src_port, dst_port;
10610 } tcpudp_header_t;
10611
10612 #if VPP_API_TEST_BUILTIN == 0
10613 uword
10614 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10615 {
10616   u8 **maskp = va_arg (*args, u8 **);
10617   u8 *mask = 0;
10618   u8 found_something = 0;
10619   tcp_header_t *tcp;
10620
10621 #define _(a) u8 a=0;
10622   foreach_tcp_proto_field;
10623 #undef _
10624
10625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10626     {
10627       if (0);
10628 #define _(a) else if (unformat (input, #a)) a=1;
10629       foreach_tcp_proto_field
10630 #undef _
10631         else
10632         break;
10633     }
10634
10635 #define _(a) found_something += a;
10636   foreach_tcp_proto_field;
10637 #undef _
10638
10639   if (found_something == 0)
10640     return 0;
10641
10642   vec_validate (mask, sizeof (*tcp) - 1);
10643
10644   tcp = (tcp_header_t *) mask;
10645
10646 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10647   foreach_tcp_proto_field;
10648 #undef _
10649
10650   *maskp = mask;
10651   return 1;
10652 }
10653
10654 uword
10655 unformat_udp_mask (unformat_input_t * input, va_list * args)
10656 {
10657   u8 **maskp = va_arg (*args, u8 **);
10658   u8 *mask = 0;
10659   u8 found_something = 0;
10660   udp_header_t *udp;
10661
10662 #define _(a) u8 a=0;
10663   foreach_udp_proto_field;
10664 #undef _
10665
10666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10667     {
10668       if (0);
10669 #define _(a) else if (unformat (input, #a)) a=1;
10670       foreach_udp_proto_field
10671 #undef _
10672         else
10673         break;
10674     }
10675
10676 #define _(a) found_something += a;
10677   foreach_udp_proto_field;
10678 #undef _
10679
10680   if (found_something == 0)
10681     return 0;
10682
10683   vec_validate (mask, sizeof (*udp) - 1);
10684
10685   udp = (udp_header_t *) mask;
10686
10687 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10688   foreach_udp_proto_field;
10689 #undef _
10690
10691   *maskp = mask;
10692   return 1;
10693 }
10694
10695 uword
10696 unformat_l4_mask (unformat_input_t * input, va_list * args)
10697 {
10698   u8 **maskp = va_arg (*args, u8 **);
10699   u16 src_port = 0, dst_port = 0;
10700   tcpudp_header_t *tcpudp;
10701
10702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10705         return 1;
10706       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10707         return 1;
10708       else if (unformat (input, "src_port"))
10709         src_port = 0xFFFF;
10710       else if (unformat (input, "dst_port"))
10711         dst_port = 0xFFFF;
10712       else
10713         return 0;
10714     }
10715
10716   if (!src_port && !dst_port)
10717     return 0;
10718
10719   u8 *mask = 0;
10720   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10721
10722   tcpudp = (tcpudp_header_t *) mask;
10723   tcpudp->src_port = src_port;
10724   tcpudp->dst_port = dst_port;
10725
10726   *maskp = mask;
10727
10728   return 1;
10729 }
10730
10731 uword
10732 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10733 {
10734   u8 **maskp = va_arg (*args, u8 **);
10735   u8 *mask = 0;
10736   u8 found_something = 0;
10737   ip4_header_t *ip;
10738
10739 #define _(a) u8 a=0;
10740   foreach_ip4_proto_field;
10741 #undef _
10742   u8 version = 0;
10743   u8 hdr_length = 0;
10744
10745
10746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10747     {
10748       if (unformat (input, "version"))
10749         version = 1;
10750       else if (unformat (input, "hdr_length"))
10751         hdr_length = 1;
10752       else if (unformat (input, "src"))
10753         src_address = 1;
10754       else if (unformat (input, "dst"))
10755         dst_address = 1;
10756       else if (unformat (input, "proto"))
10757         protocol = 1;
10758
10759 #define _(a) else if (unformat (input, #a)) a=1;
10760       foreach_ip4_proto_field
10761 #undef _
10762         else
10763         break;
10764     }
10765
10766 #define _(a) found_something += a;
10767   foreach_ip4_proto_field;
10768 #undef _
10769
10770   if (found_something == 0)
10771     return 0;
10772
10773   vec_validate (mask, sizeof (*ip) - 1);
10774
10775   ip = (ip4_header_t *) mask;
10776
10777 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10778   foreach_ip4_proto_field;
10779 #undef _
10780
10781   ip->ip_version_and_header_length = 0;
10782
10783   if (version)
10784     ip->ip_version_and_header_length |= 0xF0;
10785
10786   if (hdr_length)
10787     ip->ip_version_and_header_length |= 0x0F;
10788
10789   *maskp = mask;
10790   return 1;
10791 }
10792
10793 #define foreach_ip6_proto_field                 \
10794 _(src_address)                                  \
10795 _(dst_address)                                  \
10796 _(payload_length)                               \
10797 _(hop_limit)                                    \
10798 _(protocol)
10799
10800 uword
10801 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10802 {
10803   u8 **maskp = va_arg (*args, u8 **);
10804   u8 *mask = 0;
10805   u8 found_something = 0;
10806   ip6_header_t *ip;
10807   u32 ip_version_traffic_class_and_flow_label;
10808
10809 #define _(a) u8 a=0;
10810   foreach_ip6_proto_field;
10811 #undef _
10812   u8 version = 0;
10813   u8 traffic_class = 0;
10814   u8 flow_label = 0;
10815
10816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10817     {
10818       if (unformat (input, "version"))
10819         version = 1;
10820       else if (unformat (input, "traffic-class"))
10821         traffic_class = 1;
10822       else if (unformat (input, "flow-label"))
10823         flow_label = 1;
10824       else if (unformat (input, "src"))
10825         src_address = 1;
10826       else if (unformat (input, "dst"))
10827         dst_address = 1;
10828       else if (unformat (input, "proto"))
10829         protocol = 1;
10830
10831 #define _(a) else if (unformat (input, #a)) a=1;
10832       foreach_ip6_proto_field
10833 #undef _
10834         else
10835         break;
10836     }
10837
10838 #define _(a) found_something += a;
10839   foreach_ip6_proto_field;
10840 #undef _
10841
10842   if (found_something == 0)
10843     return 0;
10844
10845   vec_validate (mask, sizeof (*ip) - 1);
10846
10847   ip = (ip6_header_t *) mask;
10848
10849 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10850   foreach_ip6_proto_field;
10851 #undef _
10852
10853   ip_version_traffic_class_and_flow_label = 0;
10854
10855   if (version)
10856     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10857
10858   if (traffic_class)
10859     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10860
10861   if (flow_label)
10862     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10863
10864   ip->ip_version_traffic_class_and_flow_label =
10865     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10866
10867   *maskp = mask;
10868   return 1;
10869 }
10870
10871 uword
10872 unformat_l3_mask (unformat_input_t * input, va_list * args)
10873 {
10874   u8 **maskp = va_arg (*args, u8 **);
10875
10876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10879         return 1;
10880       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10881         return 1;
10882       else
10883         break;
10884     }
10885   return 0;
10886 }
10887
10888 uword
10889 unformat_l2_mask (unformat_input_t * input, va_list * args)
10890 {
10891   u8 **maskp = va_arg (*args, u8 **);
10892   u8 *mask = 0;
10893   u8 src = 0;
10894   u8 dst = 0;
10895   u8 proto = 0;
10896   u8 tag1 = 0;
10897   u8 tag2 = 0;
10898   u8 ignore_tag1 = 0;
10899   u8 ignore_tag2 = 0;
10900   u8 cos1 = 0;
10901   u8 cos2 = 0;
10902   u8 dot1q = 0;
10903   u8 dot1ad = 0;
10904   int len = 14;
10905
10906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10907     {
10908       if (unformat (input, "src"))
10909         src = 1;
10910       else if (unformat (input, "dst"))
10911         dst = 1;
10912       else if (unformat (input, "proto"))
10913         proto = 1;
10914       else if (unformat (input, "tag1"))
10915         tag1 = 1;
10916       else if (unformat (input, "tag2"))
10917         tag2 = 1;
10918       else if (unformat (input, "ignore-tag1"))
10919         ignore_tag1 = 1;
10920       else if (unformat (input, "ignore-tag2"))
10921         ignore_tag2 = 1;
10922       else if (unformat (input, "cos1"))
10923         cos1 = 1;
10924       else if (unformat (input, "cos2"))
10925         cos2 = 1;
10926       else if (unformat (input, "dot1q"))
10927         dot1q = 1;
10928       else if (unformat (input, "dot1ad"))
10929         dot1ad = 1;
10930       else
10931         break;
10932     }
10933   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10934        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10935     return 0;
10936
10937   if (tag1 || ignore_tag1 || cos1 || dot1q)
10938     len = 18;
10939   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10940     len = 22;
10941
10942   vec_validate (mask, len - 1);
10943
10944   if (dst)
10945     clib_memset (mask, 0xff, 6);
10946
10947   if (src)
10948     clib_memset (mask + 6, 0xff, 6);
10949
10950   if (tag2 || dot1ad)
10951     {
10952       /* inner vlan tag */
10953       if (tag2)
10954         {
10955           mask[19] = 0xff;
10956           mask[18] = 0x0f;
10957         }
10958       if (cos2)
10959         mask[18] |= 0xe0;
10960       if (proto)
10961         mask[21] = mask[20] = 0xff;
10962       if (tag1)
10963         {
10964           mask[15] = 0xff;
10965           mask[14] = 0x0f;
10966         }
10967       if (cos1)
10968         mask[14] |= 0xe0;
10969       *maskp = mask;
10970       return 1;
10971     }
10972   if (tag1 | dot1q)
10973     {
10974       if (tag1)
10975         {
10976           mask[15] = 0xff;
10977           mask[14] = 0x0f;
10978         }
10979       if (cos1)
10980         mask[14] |= 0xe0;
10981       if (proto)
10982         mask[16] = mask[17] = 0xff;
10983
10984       *maskp = mask;
10985       return 1;
10986     }
10987   if (cos2)
10988     mask[18] |= 0xe0;
10989   if (cos1)
10990     mask[14] |= 0xe0;
10991   if (proto)
10992     mask[12] = mask[13] = 0xff;
10993
10994   *maskp = mask;
10995   return 1;
10996 }
10997
10998 uword
10999 unformat_classify_mask (unformat_input_t * input, va_list * args)
11000 {
11001   u8 **maskp = va_arg (*args, u8 **);
11002   u32 *skipp = va_arg (*args, u32 *);
11003   u32 *matchp = va_arg (*args, u32 *);
11004   u32 match;
11005   u8 *mask = 0;
11006   u8 *l2 = 0;
11007   u8 *l3 = 0;
11008   u8 *l4 = 0;
11009   int i;
11010
11011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11012     {
11013       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11014         ;
11015       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11016         ;
11017       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11018         ;
11019       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11020         ;
11021       else
11022         break;
11023     }
11024
11025   if (l4 && !l3)
11026     {
11027       vec_free (mask);
11028       vec_free (l2);
11029       vec_free (l4);
11030       return 0;
11031     }
11032
11033   if (mask || l2 || l3 || l4)
11034     {
11035       if (l2 || l3 || l4)
11036         {
11037           /* "With a free Ethernet header in every package" */
11038           if (l2 == 0)
11039             vec_validate (l2, 13);
11040           mask = l2;
11041           if (vec_len (l3))
11042             {
11043               vec_append (mask, l3);
11044               vec_free (l3);
11045             }
11046           if (vec_len (l4))
11047             {
11048               vec_append (mask, l4);
11049               vec_free (l4);
11050             }
11051         }
11052
11053       /* Scan forward looking for the first significant mask octet */
11054       for (i = 0; i < vec_len (mask); i++)
11055         if (mask[i])
11056           break;
11057
11058       /* compute (skip, match) params */
11059       *skipp = i / sizeof (u32x4);
11060       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11061
11062       /* Pad mask to an even multiple of the vector size */
11063       while (vec_len (mask) % sizeof (u32x4))
11064         vec_add1 (mask, 0);
11065
11066       match = vec_len (mask) / sizeof (u32x4);
11067
11068       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11069         {
11070           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11071           if (*tmp || *(tmp + 1))
11072             break;
11073           match--;
11074         }
11075       if (match == 0)
11076         clib_warning ("BUG: match 0");
11077
11078       _vec_len (mask) = match * sizeof (u32x4);
11079
11080       *matchp = match;
11081       *maskp = mask;
11082
11083       return 1;
11084     }
11085
11086   return 0;
11087 }
11088 #endif /* VPP_API_TEST_BUILTIN */
11089
11090 #define foreach_l2_next                         \
11091 _(drop, DROP)                                   \
11092 _(ethernet, ETHERNET_INPUT)                     \
11093 _(ip4, IP4_INPUT)                               \
11094 _(ip6, IP6_INPUT)
11095
11096 uword
11097 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11098 {
11099   u32 *miss_next_indexp = va_arg (*args, u32 *);
11100   u32 next_index = 0;
11101   u32 tmp;
11102
11103 #define _(n,N) \
11104   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11105   foreach_l2_next;
11106 #undef _
11107
11108   if (unformat (input, "%d", &tmp))
11109     {
11110       next_index = tmp;
11111       goto out;
11112     }
11113
11114   return 0;
11115
11116 out:
11117   *miss_next_indexp = next_index;
11118   return 1;
11119 }
11120
11121 #define foreach_ip_next                         \
11122 _(drop, DROP)                                   \
11123 _(local, LOCAL)                                 \
11124 _(rewrite, REWRITE)
11125
11126 uword
11127 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11128 {
11129   u32 *miss_next_indexp = va_arg (*args, u32 *);
11130   u32 next_index = 0;
11131   u32 tmp;
11132
11133 #define _(n,N) \
11134   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11135   foreach_ip_next;
11136 #undef _
11137
11138   if (unformat (input, "%d", &tmp))
11139     {
11140       next_index = tmp;
11141       goto out;
11142     }
11143
11144   return 0;
11145
11146 out:
11147   *miss_next_indexp = next_index;
11148   return 1;
11149 }
11150
11151 #define foreach_acl_next                        \
11152 _(deny, DENY)
11153
11154 uword
11155 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11156 {
11157   u32 *miss_next_indexp = va_arg (*args, u32 *);
11158   u32 next_index = 0;
11159   u32 tmp;
11160
11161 #define _(n,N) \
11162   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11163   foreach_acl_next;
11164 #undef _
11165
11166   if (unformat (input, "permit"))
11167     {
11168       next_index = ~0;
11169       goto out;
11170     }
11171   else if (unformat (input, "%d", &tmp))
11172     {
11173       next_index = tmp;
11174       goto out;
11175     }
11176
11177   return 0;
11178
11179 out:
11180   *miss_next_indexp = next_index;
11181   return 1;
11182 }
11183
11184 uword
11185 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11186 {
11187   u32 *r = va_arg (*args, u32 *);
11188
11189   if (unformat (input, "conform-color"))
11190     *r = POLICE_CONFORM;
11191   else if (unformat (input, "exceed-color"))
11192     *r = POLICE_EXCEED;
11193   else
11194     return 0;
11195
11196   return 1;
11197 }
11198
11199 static int
11200 api_classify_add_del_table (vat_main_t * vam)
11201 {
11202   unformat_input_t *i = vam->input;
11203   vl_api_classify_add_del_table_t *mp;
11204
11205   u32 nbuckets = 2;
11206   u32 skip = ~0;
11207   u32 match = ~0;
11208   int is_add = 1;
11209   int del_chain = 0;
11210   u32 table_index = ~0;
11211   u32 next_table_index = ~0;
11212   u32 miss_next_index = ~0;
11213   u32 memory_size = 32 << 20;
11214   u8 *mask = 0;
11215   u32 current_data_flag = 0;
11216   int current_data_offset = 0;
11217   int ret;
11218
11219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (i, "del"))
11222         is_add = 0;
11223       else if (unformat (i, "del-chain"))
11224         {
11225           is_add = 0;
11226           del_chain = 1;
11227         }
11228       else if (unformat (i, "buckets %d", &nbuckets))
11229         ;
11230       else if (unformat (i, "memory_size %d", &memory_size))
11231         ;
11232       else if (unformat (i, "skip %d", &skip))
11233         ;
11234       else if (unformat (i, "match %d", &match))
11235         ;
11236       else if (unformat (i, "table %d", &table_index))
11237         ;
11238       else if (unformat (i, "mask %U", unformat_classify_mask,
11239                          &mask, &skip, &match))
11240         ;
11241       else if (unformat (i, "next-table %d", &next_table_index))
11242         ;
11243       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11244                          &miss_next_index))
11245         ;
11246       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11247                          &miss_next_index))
11248         ;
11249       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11250                          &miss_next_index))
11251         ;
11252       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11253         ;
11254       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11255         ;
11256       else
11257         break;
11258     }
11259
11260   if (is_add && mask == 0)
11261     {
11262       errmsg ("Mask required");
11263       return -99;
11264     }
11265
11266   if (is_add && skip == ~0)
11267     {
11268       errmsg ("skip count required");
11269       return -99;
11270     }
11271
11272   if (is_add && match == ~0)
11273     {
11274       errmsg ("match count required");
11275       return -99;
11276     }
11277
11278   if (!is_add && table_index == ~0)
11279     {
11280       errmsg ("table index required for delete");
11281       return -99;
11282     }
11283
11284   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11285
11286   mp->is_add = is_add;
11287   mp->del_chain = del_chain;
11288   mp->table_index = ntohl (table_index);
11289   mp->nbuckets = ntohl (nbuckets);
11290   mp->memory_size = ntohl (memory_size);
11291   mp->skip_n_vectors = ntohl (skip);
11292   mp->match_n_vectors = ntohl (match);
11293   mp->next_table_index = ntohl (next_table_index);
11294   mp->miss_next_index = ntohl (miss_next_index);
11295   mp->current_data_flag = ntohl (current_data_flag);
11296   mp->current_data_offset = ntohl (current_data_offset);
11297   mp->mask_len = ntohl (vec_len (mask));
11298   clib_memcpy (mp->mask, mask, vec_len (mask));
11299
11300   vec_free (mask);
11301
11302   S (mp);
11303   W (ret);
11304   return ret;
11305 }
11306
11307 #if VPP_API_TEST_BUILTIN == 0
11308 uword
11309 unformat_l4_match (unformat_input_t * input, va_list * args)
11310 {
11311   u8 **matchp = va_arg (*args, u8 **);
11312
11313   u8 *proto_header = 0;
11314   int src_port = 0;
11315   int dst_port = 0;
11316
11317   tcpudp_header_t h;
11318
11319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (input, "src_port %d", &src_port))
11322         ;
11323       else if (unformat (input, "dst_port %d", &dst_port))
11324         ;
11325       else
11326         return 0;
11327     }
11328
11329   h.src_port = clib_host_to_net_u16 (src_port);
11330   h.dst_port = clib_host_to_net_u16 (dst_port);
11331   vec_validate (proto_header, sizeof (h) - 1);
11332   memcpy (proto_header, &h, sizeof (h));
11333
11334   *matchp = proto_header;
11335
11336   return 1;
11337 }
11338
11339 uword
11340 unformat_ip4_match (unformat_input_t * input, va_list * args)
11341 {
11342   u8 **matchp = va_arg (*args, u8 **);
11343   u8 *match = 0;
11344   ip4_header_t *ip;
11345   int version = 0;
11346   u32 version_val;
11347   int hdr_length = 0;
11348   u32 hdr_length_val;
11349   int src = 0, dst = 0;
11350   ip4_address_t src_val, dst_val;
11351   int proto = 0;
11352   u32 proto_val;
11353   int tos = 0;
11354   u32 tos_val;
11355   int length = 0;
11356   u32 length_val;
11357   int fragment_id = 0;
11358   u32 fragment_id_val;
11359   int ttl = 0;
11360   int ttl_val;
11361   int checksum = 0;
11362   u32 checksum_val;
11363
11364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11365     {
11366       if (unformat (input, "version %d", &version_val))
11367         version = 1;
11368       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11369         hdr_length = 1;
11370       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11371         src = 1;
11372       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11373         dst = 1;
11374       else if (unformat (input, "proto %d", &proto_val))
11375         proto = 1;
11376       else if (unformat (input, "tos %d", &tos_val))
11377         tos = 1;
11378       else if (unformat (input, "length %d", &length_val))
11379         length = 1;
11380       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11381         fragment_id = 1;
11382       else if (unformat (input, "ttl %d", &ttl_val))
11383         ttl = 1;
11384       else if (unformat (input, "checksum %d", &checksum_val))
11385         checksum = 1;
11386       else
11387         break;
11388     }
11389
11390   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11391       + ttl + checksum == 0)
11392     return 0;
11393
11394   /*
11395    * Aligned because we use the real comparison functions
11396    */
11397   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11398
11399   ip = (ip4_header_t *) match;
11400
11401   /* These are realistically matched in practice */
11402   if (src)
11403     ip->src_address.as_u32 = src_val.as_u32;
11404
11405   if (dst)
11406     ip->dst_address.as_u32 = dst_val.as_u32;
11407
11408   if (proto)
11409     ip->protocol = proto_val;
11410
11411
11412   /* These are not, but they're included for completeness */
11413   if (version)
11414     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11415
11416   if (hdr_length)
11417     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11418
11419   if (tos)
11420     ip->tos = tos_val;
11421
11422   if (length)
11423     ip->length = clib_host_to_net_u16 (length_val);
11424
11425   if (ttl)
11426     ip->ttl = ttl_val;
11427
11428   if (checksum)
11429     ip->checksum = clib_host_to_net_u16 (checksum_val);
11430
11431   *matchp = match;
11432   return 1;
11433 }
11434
11435 uword
11436 unformat_ip6_match (unformat_input_t * input, va_list * args)
11437 {
11438   u8 **matchp = va_arg (*args, u8 **);
11439   u8 *match = 0;
11440   ip6_header_t *ip;
11441   int version = 0;
11442   u32 version_val;
11443   u8 traffic_class = 0;
11444   u32 traffic_class_val = 0;
11445   u8 flow_label = 0;
11446   u8 flow_label_val;
11447   int src = 0, dst = 0;
11448   ip6_address_t src_val, dst_val;
11449   int proto = 0;
11450   u32 proto_val;
11451   int payload_length = 0;
11452   u32 payload_length_val;
11453   int hop_limit = 0;
11454   int hop_limit_val;
11455   u32 ip_version_traffic_class_and_flow_label;
11456
11457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11458     {
11459       if (unformat (input, "version %d", &version_val))
11460         version = 1;
11461       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11462         traffic_class = 1;
11463       else if (unformat (input, "flow_label %d", &flow_label_val))
11464         flow_label = 1;
11465       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11466         src = 1;
11467       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11468         dst = 1;
11469       else if (unformat (input, "proto %d", &proto_val))
11470         proto = 1;
11471       else if (unformat (input, "payload_length %d", &payload_length_val))
11472         payload_length = 1;
11473       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11474         hop_limit = 1;
11475       else
11476         break;
11477     }
11478
11479   if (version + traffic_class + flow_label + src + dst + proto +
11480       payload_length + hop_limit == 0)
11481     return 0;
11482
11483   /*
11484    * Aligned because we use the real comparison functions
11485    */
11486   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11487
11488   ip = (ip6_header_t *) match;
11489
11490   if (src)
11491     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11492
11493   if (dst)
11494     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11495
11496   if (proto)
11497     ip->protocol = proto_val;
11498
11499   ip_version_traffic_class_and_flow_label = 0;
11500
11501   if (version)
11502     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11503
11504   if (traffic_class)
11505     ip_version_traffic_class_and_flow_label |=
11506       (traffic_class_val & 0xFF) << 20;
11507
11508   if (flow_label)
11509     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11510
11511   ip->ip_version_traffic_class_and_flow_label =
11512     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11513
11514   if (payload_length)
11515     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11516
11517   if (hop_limit)
11518     ip->hop_limit = hop_limit_val;
11519
11520   *matchp = match;
11521   return 1;
11522 }
11523
11524 uword
11525 unformat_l3_match (unformat_input_t * input, va_list * args)
11526 {
11527   u8 **matchp = va_arg (*args, u8 **);
11528
11529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11530     {
11531       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11532         return 1;
11533       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11534         return 1;
11535       else
11536         break;
11537     }
11538   return 0;
11539 }
11540
11541 uword
11542 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11543 {
11544   u8 *tagp = va_arg (*args, u8 *);
11545   u32 tag;
11546
11547   if (unformat (input, "%d", &tag))
11548     {
11549       tagp[0] = (tag >> 8) & 0x0F;
11550       tagp[1] = tag & 0xFF;
11551       return 1;
11552     }
11553
11554   return 0;
11555 }
11556
11557 uword
11558 unformat_l2_match (unformat_input_t * input, va_list * args)
11559 {
11560   u8 **matchp = va_arg (*args, u8 **);
11561   u8 *match = 0;
11562   u8 src = 0;
11563   u8 src_val[6];
11564   u8 dst = 0;
11565   u8 dst_val[6];
11566   u8 proto = 0;
11567   u16 proto_val;
11568   u8 tag1 = 0;
11569   u8 tag1_val[2];
11570   u8 tag2 = 0;
11571   u8 tag2_val[2];
11572   int len = 14;
11573   u8 ignore_tag1 = 0;
11574   u8 ignore_tag2 = 0;
11575   u8 cos1 = 0;
11576   u8 cos2 = 0;
11577   u32 cos1_val = 0;
11578   u32 cos2_val = 0;
11579
11580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11581     {
11582       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11583         src = 1;
11584       else
11585         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11586         dst = 1;
11587       else if (unformat (input, "proto %U",
11588                          unformat_ethernet_type_host_byte_order, &proto_val))
11589         proto = 1;
11590       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11591         tag1 = 1;
11592       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11593         tag2 = 1;
11594       else if (unformat (input, "ignore-tag1"))
11595         ignore_tag1 = 1;
11596       else if (unformat (input, "ignore-tag2"))
11597         ignore_tag2 = 1;
11598       else if (unformat (input, "cos1 %d", &cos1_val))
11599         cos1 = 1;
11600       else if (unformat (input, "cos2 %d", &cos2_val))
11601         cos2 = 1;
11602       else
11603         break;
11604     }
11605   if ((src + dst + proto + tag1 + tag2 +
11606        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11607     return 0;
11608
11609   if (tag1 || ignore_tag1 || cos1)
11610     len = 18;
11611   if (tag2 || ignore_tag2 || cos2)
11612     len = 22;
11613
11614   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11615
11616   if (dst)
11617     clib_memcpy (match, dst_val, 6);
11618
11619   if (src)
11620     clib_memcpy (match + 6, src_val, 6);
11621
11622   if (tag2)
11623     {
11624       /* inner vlan tag */
11625       match[19] = tag2_val[1];
11626       match[18] = tag2_val[0];
11627       if (cos2)
11628         match[18] |= (cos2_val & 0x7) << 5;
11629       if (proto)
11630         {
11631           match[21] = proto_val & 0xff;
11632           match[20] = proto_val >> 8;
11633         }
11634       if (tag1)
11635         {
11636           match[15] = tag1_val[1];
11637           match[14] = tag1_val[0];
11638         }
11639       if (cos1)
11640         match[14] |= (cos1_val & 0x7) << 5;
11641       *matchp = match;
11642       return 1;
11643     }
11644   if (tag1)
11645     {
11646       match[15] = tag1_val[1];
11647       match[14] = tag1_val[0];
11648       if (proto)
11649         {
11650           match[17] = proto_val & 0xff;
11651           match[16] = proto_val >> 8;
11652         }
11653       if (cos1)
11654         match[14] |= (cos1_val & 0x7) << 5;
11655
11656       *matchp = match;
11657       return 1;
11658     }
11659   if (cos2)
11660     match[18] |= (cos2_val & 0x7) << 5;
11661   if (cos1)
11662     match[14] |= (cos1_val & 0x7) << 5;
11663   if (proto)
11664     {
11665       match[13] = proto_val & 0xff;
11666       match[12] = proto_val >> 8;
11667     }
11668
11669   *matchp = match;
11670   return 1;
11671 }
11672
11673 uword
11674 unformat_qos_source (unformat_input_t * input, va_list * args)
11675 {
11676   int *qs = va_arg (*args, int *);
11677
11678   if (unformat (input, "ip"))
11679     *qs = QOS_SOURCE_IP;
11680   else if (unformat (input, "mpls"))
11681     *qs = QOS_SOURCE_MPLS;
11682   else if (unformat (input, "ext"))
11683     *qs = QOS_SOURCE_EXT;
11684   else if (unformat (input, "vlan"))
11685     *qs = QOS_SOURCE_VLAN;
11686   else
11687     return 0;
11688
11689   return 1;
11690 }
11691 #endif
11692
11693 uword
11694 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11695 {
11696   u8 **matchp = va_arg (*args, u8 **);
11697   u32 skip_n_vectors = va_arg (*args, u32);
11698   u32 match_n_vectors = va_arg (*args, u32);
11699
11700   u8 *match = 0;
11701   u8 *l2 = 0;
11702   u8 *l3 = 0;
11703   u8 *l4 = 0;
11704
11705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11706     {
11707       if (unformat (input, "hex %U", unformat_hex_string, &match))
11708         ;
11709       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11710         ;
11711       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11712         ;
11713       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11714         ;
11715       else
11716         break;
11717     }
11718
11719   if (l4 && !l3)
11720     {
11721       vec_free (match);
11722       vec_free (l2);
11723       vec_free (l4);
11724       return 0;
11725     }
11726
11727   if (match || l2 || l3 || l4)
11728     {
11729       if (l2 || l3 || l4)
11730         {
11731           /* "Win a free Ethernet header in every packet" */
11732           if (l2 == 0)
11733             vec_validate_aligned (l2, 13, sizeof (u32x4));
11734           match = l2;
11735           if (vec_len (l3))
11736             {
11737               vec_append_aligned (match, l3, sizeof (u32x4));
11738               vec_free (l3);
11739             }
11740           if (vec_len (l4))
11741             {
11742               vec_append_aligned (match, l4, sizeof (u32x4));
11743               vec_free (l4);
11744             }
11745         }
11746
11747       /* Make sure the vector is big enough even if key is all 0's */
11748       vec_validate_aligned
11749         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11750          sizeof (u32x4));
11751
11752       /* Set size, include skipped vectors */
11753       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11754
11755       *matchp = match;
11756
11757       return 1;
11758     }
11759
11760   return 0;
11761 }
11762
11763 static int
11764 api_classify_add_del_session (vat_main_t * vam)
11765 {
11766   unformat_input_t *i = vam->input;
11767   vl_api_classify_add_del_session_t *mp;
11768   int is_add = 1;
11769   u32 table_index = ~0;
11770   u32 hit_next_index = ~0;
11771   u32 opaque_index = ~0;
11772   u8 *match = 0;
11773   i32 advance = 0;
11774   u32 skip_n_vectors = 0;
11775   u32 match_n_vectors = 0;
11776   u32 action = 0;
11777   u32 metadata = 0;
11778   int ret;
11779
11780   /*
11781    * Warning: you have to supply skip_n and match_n
11782    * because the API client cant simply look at the classify
11783    * table object.
11784    */
11785
11786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11787     {
11788       if (unformat (i, "del"))
11789         is_add = 0;
11790       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11791                          &hit_next_index))
11792         ;
11793       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11794                          &hit_next_index))
11795         ;
11796       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11797                          &hit_next_index))
11798         ;
11799       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11800         ;
11801       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11802         ;
11803       else if (unformat (i, "opaque-index %d", &opaque_index))
11804         ;
11805       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11806         ;
11807       else if (unformat (i, "match_n %d", &match_n_vectors))
11808         ;
11809       else if (unformat (i, "match %U", api_unformat_classify_match,
11810                          &match, skip_n_vectors, match_n_vectors))
11811         ;
11812       else if (unformat (i, "advance %d", &advance))
11813         ;
11814       else if (unformat (i, "table-index %d", &table_index))
11815         ;
11816       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11817         action = 1;
11818       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11819         action = 2;
11820       else if (unformat (i, "action %d", &action))
11821         ;
11822       else if (unformat (i, "metadata %d", &metadata))
11823         ;
11824       else
11825         break;
11826     }
11827
11828   if (table_index == ~0)
11829     {
11830       errmsg ("Table index required");
11831       return -99;
11832     }
11833
11834   if (is_add && match == 0)
11835     {
11836       errmsg ("Match value required");
11837       return -99;
11838     }
11839
11840   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11841
11842   mp->is_add = is_add;
11843   mp->table_index = ntohl (table_index);
11844   mp->hit_next_index = ntohl (hit_next_index);
11845   mp->opaque_index = ntohl (opaque_index);
11846   mp->advance = ntohl (advance);
11847   mp->action = action;
11848   mp->metadata = ntohl (metadata);
11849   mp->match_len = ntohl (vec_len (match));
11850   clib_memcpy (mp->match, match, vec_len (match));
11851   vec_free (match);
11852
11853   S (mp);
11854   W (ret);
11855   return ret;
11856 }
11857
11858 static int
11859 api_classify_set_interface_ip_table (vat_main_t * vam)
11860 {
11861   unformat_input_t *i = vam->input;
11862   vl_api_classify_set_interface_ip_table_t *mp;
11863   u32 sw_if_index;
11864   int sw_if_index_set;
11865   u32 table_index = ~0;
11866   u8 is_ipv6 = 0;
11867   int ret;
11868
11869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11870     {
11871       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11872         sw_if_index_set = 1;
11873       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11874         sw_if_index_set = 1;
11875       else if (unformat (i, "table %d", &table_index))
11876         ;
11877       else
11878         {
11879           clib_warning ("parse error '%U'", format_unformat_error, i);
11880           return -99;
11881         }
11882     }
11883
11884   if (sw_if_index_set == 0)
11885     {
11886       errmsg ("missing interface name or sw_if_index");
11887       return -99;
11888     }
11889
11890
11891   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11892
11893   mp->sw_if_index = ntohl (sw_if_index);
11894   mp->table_index = ntohl (table_index);
11895   mp->is_ipv6 = is_ipv6;
11896
11897   S (mp);
11898   W (ret);
11899   return ret;
11900 }
11901
11902 static int
11903 api_classify_set_interface_l2_tables (vat_main_t * vam)
11904 {
11905   unformat_input_t *i = vam->input;
11906   vl_api_classify_set_interface_l2_tables_t *mp;
11907   u32 sw_if_index;
11908   int sw_if_index_set;
11909   u32 ip4_table_index = ~0;
11910   u32 ip6_table_index = ~0;
11911   u32 other_table_index = ~0;
11912   u32 is_input = 1;
11913   int ret;
11914
11915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11916     {
11917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11918         sw_if_index_set = 1;
11919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11920         sw_if_index_set = 1;
11921       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11922         ;
11923       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11924         ;
11925       else if (unformat (i, "other-table %d", &other_table_index))
11926         ;
11927       else if (unformat (i, "is-input %d", &is_input))
11928         ;
11929       else
11930         {
11931           clib_warning ("parse error '%U'", format_unformat_error, i);
11932           return -99;
11933         }
11934     }
11935
11936   if (sw_if_index_set == 0)
11937     {
11938       errmsg ("missing interface name or sw_if_index");
11939       return -99;
11940     }
11941
11942
11943   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11944
11945   mp->sw_if_index = ntohl (sw_if_index);
11946   mp->ip4_table_index = ntohl (ip4_table_index);
11947   mp->ip6_table_index = ntohl (ip6_table_index);
11948   mp->other_table_index = ntohl (other_table_index);
11949   mp->is_input = (u8) is_input;
11950
11951   S (mp);
11952   W (ret);
11953   return ret;
11954 }
11955
11956 static int
11957 api_set_ipfix_exporter (vat_main_t * vam)
11958 {
11959   unformat_input_t *i = vam->input;
11960   vl_api_set_ipfix_exporter_t *mp;
11961   ip4_address_t collector_address;
11962   u8 collector_address_set = 0;
11963   u32 collector_port = ~0;
11964   ip4_address_t src_address;
11965   u8 src_address_set = 0;
11966   u32 vrf_id = ~0;
11967   u32 path_mtu = ~0;
11968   u32 template_interval = ~0;
11969   u8 udp_checksum = 0;
11970   int ret;
11971
11972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11973     {
11974       if (unformat (i, "collector_address %U", unformat_ip4_address,
11975                     &collector_address))
11976         collector_address_set = 1;
11977       else if (unformat (i, "collector_port %d", &collector_port))
11978         ;
11979       else if (unformat (i, "src_address %U", unformat_ip4_address,
11980                          &src_address))
11981         src_address_set = 1;
11982       else if (unformat (i, "vrf_id %d", &vrf_id))
11983         ;
11984       else if (unformat (i, "path_mtu %d", &path_mtu))
11985         ;
11986       else if (unformat (i, "template_interval %d", &template_interval))
11987         ;
11988       else if (unformat (i, "udp_checksum"))
11989         udp_checksum = 1;
11990       else
11991         break;
11992     }
11993
11994   if (collector_address_set == 0)
11995     {
11996       errmsg ("collector_address required");
11997       return -99;
11998     }
11999
12000   if (src_address_set == 0)
12001     {
12002       errmsg ("src_address required");
12003       return -99;
12004     }
12005
12006   M (SET_IPFIX_EXPORTER, mp);
12007
12008   memcpy (mp->collector_address, collector_address.data,
12009           sizeof (collector_address.data));
12010   mp->collector_port = htons ((u16) collector_port);
12011   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12012   mp->vrf_id = htonl (vrf_id);
12013   mp->path_mtu = htonl (path_mtu);
12014   mp->template_interval = htonl (template_interval);
12015   mp->udp_checksum = udp_checksum;
12016
12017   S (mp);
12018   W (ret);
12019   return ret;
12020 }
12021
12022 static int
12023 api_set_ipfix_classify_stream (vat_main_t * vam)
12024 {
12025   unformat_input_t *i = vam->input;
12026   vl_api_set_ipfix_classify_stream_t *mp;
12027   u32 domain_id = 0;
12028   u32 src_port = UDP_DST_PORT_ipfix;
12029   int ret;
12030
12031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12032     {
12033       if (unformat (i, "domain %d", &domain_id))
12034         ;
12035       else if (unformat (i, "src_port %d", &src_port))
12036         ;
12037       else
12038         {
12039           errmsg ("unknown input `%U'", format_unformat_error, i);
12040           return -99;
12041         }
12042     }
12043
12044   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12045
12046   mp->domain_id = htonl (domain_id);
12047   mp->src_port = htons ((u16) src_port);
12048
12049   S (mp);
12050   W (ret);
12051   return ret;
12052 }
12053
12054 static int
12055 api_ipfix_classify_table_add_del (vat_main_t * vam)
12056 {
12057   unformat_input_t *i = vam->input;
12058   vl_api_ipfix_classify_table_add_del_t *mp;
12059   int is_add = -1;
12060   u32 classify_table_index = ~0;
12061   u8 ip_version = 0;
12062   u8 transport_protocol = 255;
12063   int ret;
12064
12065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12066     {
12067       if (unformat (i, "add"))
12068         is_add = 1;
12069       else if (unformat (i, "del"))
12070         is_add = 0;
12071       else if (unformat (i, "table %d", &classify_table_index))
12072         ;
12073       else if (unformat (i, "ip4"))
12074         ip_version = 4;
12075       else if (unformat (i, "ip6"))
12076         ip_version = 6;
12077       else if (unformat (i, "tcp"))
12078         transport_protocol = 6;
12079       else if (unformat (i, "udp"))
12080         transport_protocol = 17;
12081       else
12082         {
12083           errmsg ("unknown input `%U'", format_unformat_error, i);
12084           return -99;
12085         }
12086     }
12087
12088   if (is_add == -1)
12089     {
12090       errmsg ("expecting: add|del");
12091       return -99;
12092     }
12093   if (classify_table_index == ~0)
12094     {
12095       errmsg ("classifier table not specified");
12096       return -99;
12097     }
12098   if (ip_version == 0)
12099     {
12100       errmsg ("IP version not specified");
12101       return -99;
12102     }
12103
12104   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12105
12106   mp->is_add = is_add;
12107   mp->table_id = htonl (classify_table_index);
12108   mp->ip_version = ip_version;
12109   mp->transport_protocol = transport_protocol;
12110
12111   S (mp);
12112   W (ret);
12113   return ret;
12114 }
12115
12116 static int
12117 api_get_node_index (vat_main_t * vam)
12118 {
12119   unformat_input_t *i = vam->input;
12120   vl_api_get_node_index_t *mp;
12121   u8 *name = 0;
12122   int ret;
12123
12124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12125     {
12126       if (unformat (i, "node %s", &name))
12127         ;
12128       else
12129         break;
12130     }
12131   if (name == 0)
12132     {
12133       errmsg ("node name required");
12134       return -99;
12135     }
12136   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12137     {
12138       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12139       return -99;
12140     }
12141
12142   M (GET_NODE_INDEX, mp);
12143   clib_memcpy (mp->node_name, name, vec_len (name));
12144   vec_free (name);
12145
12146   S (mp);
12147   W (ret);
12148   return ret;
12149 }
12150
12151 static int
12152 api_get_next_index (vat_main_t * vam)
12153 {
12154   unformat_input_t *i = vam->input;
12155   vl_api_get_next_index_t *mp;
12156   u8 *node_name = 0, *next_node_name = 0;
12157   int ret;
12158
12159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12160     {
12161       if (unformat (i, "node-name %s", &node_name))
12162         ;
12163       else if (unformat (i, "next-node-name %s", &next_node_name))
12164         break;
12165     }
12166
12167   if (node_name == 0)
12168     {
12169       errmsg ("node name required");
12170       return -99;
12171     }
12172   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12173     {
12174       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12175       return -99;
12176     }
12177
12178   if (next_node_name == 0)
12179     {
12180       errmsg ("next node name required");
12181       return -99;
12182     }
12183   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12184     {
12185       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12186       return -99;
12187     }
12188
12189   M (GET_NEXT_INDEX, mp);
12190   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12191   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12192   vec_free (node_name);
12193   vec_free (next_node_name);
12194
12195   S (mp);
12196   W (ret);
12197   return ret;
12198 }
12199
12200 static int
12201 api_add_node_next (vat_main_t * vam)
12202 {
12203   unformat_input_t *i = vam->input;
12204   vl_api_add_node_next_t *mp;
12205   u8 *name = 0;
12206   u8 *next = 0;
12207   int ret;
12208
12209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12210     {
12211       if (unformat (i, "node %s", &name))
12212         ;
12213       else if (unformat (i, "next %s", &next))
12214         ;
12215       else
12216         break;
12217     }
12218   if (name == 0)
12219     {
12220       errmsg ("node name required");
12221       return -99;
12222     }
12223   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12224     {
12225       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12226       return -99;
12227     }
12228   if (next == 0)
12229     {
12230       errmsg ("next node required");
12231       return -99;
12232     }
12233   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12234     {
12235       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12236       return -99;
12237     }
12238
12239   M (ADD_NODE_NEXT, mp);
12240   clib_memcpy (mp->node_name, name, vec_len (name));
12241   clib_memcpy (mp->next_name, next, vec_len (next));
12242   vec_free (name);
12243   vec_free (next);
12244
12245   S (mp);
12246   W (ret);
12247   return ret;
12248 }
12249
12250 static int
12251 api_l2tpv3_create_tunnel (vat_main_t * vam)
12252 {
12253   unformat_input_t *i = vam->input;
12254   ip6_address_t client_address, our_address;
12255   int client_address_set = 0;
12256   int our_address_set = 0;
12257   u32 local_session_id = 0;
12258   u32 remote_session_id = 0;
12259   u64 local_cookie = 0;
12260   u64 remote_cookie = 0;
12261   u8 l2_sublayer_present = 0;
12262   vl_api_l2tpv3_create_tunnel_t *mp;
12263   int ret;
12264
12265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12266     {
12267       if (unformat (i, "client_address %U", unformat_ip6_address,
12268                     &client_address))
12269         client_address_set = 1;
12270       else if (unformat (i, "our_address %U", unformat_ip6_address,
12271                          &our_address))
12272         our_address_set = 1;
12273       else if (unformat (i, "local_session_id %d", &local_session_id))
12274         ;
12275       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12276         ;
12277       else if (unformat (i, "local_cookie %lld", &local_cookie))
12278         ;
12279       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12280         ;
12281       else if (unformat (i, "l2-sublayer-present"))
12282         l2_sublayer_present = 1;
12283       else
12284         break;
12285     }
12286
12287   if (client_address_set == 0)
12288     {
12289       errmsg ("client_address required");
12290       return -99;
12291     }
12292
12293   if (our_address_set == 0)
12294     {
12295       errmsg ("our_address required");
12296       return -99;
12297     }
12298
12299   M (L2TPV3_CREATE_TUNNEL, mp);
12300
12301   clib_memcpy (mp->client_address, client_address.as_u8,
12302                sizeof (mp->client_address));
12303
12304   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12305
12306   mp->local_session_id = ntohl (local_session_id);
12307   mp->remote_session_id = ntohl (remote_session_id);
12308   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12309   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12310   mp->l2_sublayer_present = l2_sublayer_present;
12311   mp->is_ipv6 = 1;
12312
12313   S (mp);
12314   W (ret);
12315   return ret;
12316 }
12317
12318 static int
12319 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12320 {
12321   unformat_input_t *i = vam->input;
12322   u32 sw_if_index;
12323   u8 sw_if_index_set = 0;
12324   u64 new_local_cookie = 0;
12325   u64 new_remote_cookie = 0;
12326   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12327   int ret;
12328
12329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12332         sw_if_index_set = 1;
12333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12334         sw_if_index_set = 1;
12335       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12336         ;
12337       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12338         ;
12339       else
12340         break;
12341     }
12342
12343   if (sw_if_index_set == 0)
12344     {
12345       errmsg ("missing interface name or sw_if_index");
12346       return -99;
12347     }
12348
12349   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12350
12351   mp->sw_if_index = ntohl (sw_if_index);
12352   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12353   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12354
12355   S (mp);
12356   W (ret);
12357   return ret;
12358 }
12359
12360 static int
12361 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12362 {
12363   unformat_input_t *i = vam->input;
12364   vl_api_l2tpv3_interface_enable_disable_t *mp;
12365   u32 sw_if_index;
12366   u8 sw_if_index_set = 0;
12367   u8 enable_disable = 1;
12368   int ret;
12369
12370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12373         sw_if_index_set = 1;
12374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12375         sw_if_index_set = 1;
12376       else if (unformat (i, "enable"))
12377         enable_disable = 1;
12378       else if (unformat (i, "disable"))
12379         enable_disable = 0;
12380       else
12381         break;
12382     }
12383
12384   if (sw_if_index_set == 0)
12385     {
12386       errmsg ("missing interface name or sw_if_index");
12387       return -99;
12388     }
12389
12390   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12391
12392   mp->sw_if_index = ntohl (sw_if_index);
12393   mp->enable_disable = enable_disable;
12394
12395   S (mp);
12396   W (ret);
12397   return ret;
12398 }
12399
12400 static int
12401 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12402 {
12403   unformat_input_t *i = vam->input;
12404   vl_api_l2tpv3_set_lookup_key_t *mp;
12405   u8 key = ~0;
12406   int ret;
12407
12408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12409     {
12410       if (unformat (i, "lookup_v6_src"))
12411         key = L2T_LOOKUP_SRC_ADDRESS;
12412       else if (unformat (i, "lookup_v6_dst"))
12413         key = L2T_LOOKUP_DST_ADDRESS;
12414       else if (unformat (i, "lookup_session_id"))
12415         key = L2T_LOOKUP_SESSION_ID;
12416       else
12417         break;
12418     }
12419
12420   if (key == (u8) ~ 0)
12421     {
12422       errmsg ("l2tp session lookup key unset");
12423       return -99;
12424     }
12425
12426   M (L2TPV3_SET_LOOKUP_KEY, mp);
12427
12428   mp->key = key;
12429
12430   S (mp);
12431   W (ret);
12432   return ret;
12433 }
12434
12435 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12436   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12437 {
12438   vat_main_t *vam = &vat_main;
12439
12440   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12441          format_ip6_address, mp->our_address,
12442          format_ip6_address, mp->client_address,
12443          clib_net_to_host_u32 (mp->sw_if_index));
12444
12445   print (vam->ofp,
12446          "   local cookies %016llx %016llx remote cookie %016llx",
12447          clib_net_to_host_u64 (mp->local_cookie[0]),
12448          clib_net_to_host_u64 (mp->local_cookie[1]),
12449          clib_net_to_host_u64 (mp->remote_cookie));
12450
12451   print (vam->ofp, "   local session-id %d remote session-id %d",
12452          clib_net_to_host_u32 (mp->local_session_id),
12453          clib_net_to_host_u32 (mp->remote_session_id));
12454
12455   print (vam->ofp, "   l2 specific sublayer %s\n",
12456          mp->l2_sublayer_present ? "preset" : "absent");
12457
12458 }
12459
12460 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12461   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12462 {
12463   vat_main_t *vam = &vat_main;
12464   vat_json_node_t *node = NULL;
12465   struct in6_addr addr;
12466
12467   if (VAT_JSON_ARRAY != vam->json_tree.type)
12468     {
12469       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12470       vat_json_init_array (&vam->json_tree);
12471     }
12472   node = vat_json_array_add (&vam->json_tree);
12473
12474   vat_json_init_object (node);
12475
12476   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12477   vat_json_object_add_ip6 (node, "our_address", addr);
12478   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12479   vat_json_object_add_ip6 (node, "client_address", addr);
12480
12481   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12482   vat_json_init_array (lc);
12483   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12484   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12485   vat_json_object_add_uint (node, "remote_cookie",
12486                             clib_net_to_host_u64 (mp->remote_cookie));
12487
12488   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12489   vat_json_object_add_uint (node, "local_session_id",
12490                             clib_net_to_host_u32 (mp->local_session_id));
12491   vat_json_object_add_uint (node, "remote_session_id",
12492                             clib_net_to_host_u32 (mp->remote_session_id));
12493   vat_json_object_add_string_copy (node, "l2_sublayer",
12494                                    mp->l2_sublayer_present ? (u8 *) "present"
12495                                    : (u8 *) "absent");
12496 }
12497
12498 static int
12499 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12500 {
12501   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12502   vl_api_control_ping_t *mp_ping;
12503   int ret;
12504
12505   /* Get list of l2tpv3-tunnel interfaces */
12506   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12507   S (mp);
12508
12509   /* Use a control ping for synchronization */
12510   MPING (CONTROL_PING, mp_ping);
12511   S (mp_ping);
12512
12513   W (ret);
12514   return ret;
12515 }
12516
12517
12518 static void vl_api_sw_interface_tap_v2_details_t_handler
12519   (vl_api_sw_interface_tap_v2_details_t * mp)
12520 {
12521   vat_main_t *vam = &vat_main;
12522
12523   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12524                     mp->host_ip4_prefix_len);
12525   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12526                     mp->host_ip6_prefix_len);
12527
12528   print (vam->ofp,
12529          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12530          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12531          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12532          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12533          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12534
12535   vec_free (ip4);
12536   vec_free (ip6);
12537 }
12538
12539 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12540   (vl_api_sw_interface_tap_v2_details_t * mp)
12541 {
12542   vat_main_t *vam = &vat_main;
12543   vat_json_node_t *node = NULL;
12544
12545   if (VAT_JSON_ARRAY != vam->json_tree.type)
12546     {
12547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12548       vat_json_init_array (&vam->json_tree);
12549     }
12550   node = vat_json_array_add (&vam->json_tree);
12551
12552   vat_json_init_object (node);
12553   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12554   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12555   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12556   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12557   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12558   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12559   vat_json_object_add_string_copy (node, "host_mac_addr",
12560                                    format (0, "%U", format_ethernet_address,
12561                                            &mp->host_mac_addr));
12562   vat_json_object_add_string_copy (node, "host_namespace",
12563                                    mp->host_namespace);
12564   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12565   vat_json_object_add_string_copy (node, "host_ip4_addr",
12566                                    format (0, "%U/%d", format_ip4_address,
12567                                            mp->host_ip4_addr,
12568                                            mp->host_ip4_prefix_len));
12569   vat_json_object_add_string_copy (node, "host_ip6_addr",
12570                                    format (0, "%U/%d", format_ip6_address,
12571                                            mp->host_ip6_addr,
12572                                            mp->host_ip6_prefix_len));
12573
12574 }
12575
12576 static int
12577 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12578 {
12579   vl_api_sw_interface_tap_v2_dump_t *mp;
12580   vl_api_control_ping_t *mp_ping;
12581   int ret;
12582
12583   print (vam->ofp,
12584          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12585          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12586          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12587          "host_ip6_addr");
12588
12589   /* Get list of tap interfaces */
12590   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12591   S (mp);
12592
12593   /* Use a control ping for synchronization */
12594   MPING (CONTROL_PING, mp_ping);
12595   S (mp_ping);
12596
12597   W (ret);
12598   return ret;
12599 }
12600
12601 static void vl_api_sw_interface_virtio_pci_details_t_handler
12602   (vl_api_sw_interface_virtio_pci_details_t * mp)
12603 {
12604   vat_main_t *vam = &vat_main;
12605
12606   typedef union
12607   {
12608     struct
12609     {
12610       u16 domain;
12611       u8 bus;
12612       u8 slot:5;
12613       u8 function:3;
12614     };
12615     u32 as_u32;
12616   } pci_addr_t;
12617   pci_addr_t addr;
12618   addr.as_u32 = ntohl (mp->pci_addr);
12619   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12620                          addr.slot, addr.function);
12621
12622   print (vam->ofp,
12623          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12624          pci_addr, ntohl (mp->sw_if_index),
12625          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12626          format_ethernet_address, mp->mac_addr,
12627          clib_net_to_host_u64 (mp->features));
12628   vec_free (pci_addr);
12629 }
12630
12631 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12632   (vl_api_sw_interface_virtio_pci_details_t * mp)
12633 {
12634   vat_main_t *vam = &vat_main;
12635   vat_json_node_t *node = NULL;
12636
12637   if (VAT_JSON_ARRAY != vam->json_tree.type)
12638     {
12639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12640       vat_json_init_array (&vam->json_tree);
12641     }
12642   node = vat_json_array_add (&vam->json_tree);
12643
12644   vat_json_init_object (node);
12645   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12646   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12647   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12648   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12649   vat_json_object_add_uint (node, "features",
12650                             clib_net_to_host_u64 (mp->features));
12651   vat_json_object_add_string_copy (node, "mac_addr",
12652                                    format (0, "%U", format_ethernet_address,
12653                                            &mp->mac_addr));
12654 }
12655
12656 static int
12657 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12658 {
12659   vl_api_sw_interface_virtio_pci_dump_t *mp;
12660   vl_api_control_ping_t *mp_ping;
12661   int ret;
12662
12663   print (vam->ofp,
12664          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12665          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12666          "mac_addr", "features");
12667
12668   /* Get list of tap interfaces */
12669   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12670   S (mp);
12671
12672   /* Use a control ping for synchronization */
12673   MPING (CONTROL_PING, mp_ping);
12674   S (mp_ping);
12675
12676   W (ret);
12677   return ret;
12678 }
12679
12680 static int
12681 api_vxlan_offload_rx (vat_main_t * vam)
12682 {
12683   unformat_input_t *line_input = vam->input;
12684   vl_api_vxlan_offload_rx_t *mp;
12685   u32 hw_if_index = ~0, rx_if_index = ~0;
12686   u8 is_add = 1;
12687   int ret;
12688
12689   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12690     {
12691       if (unformat (line_input, "del"))
12692         is_add = 0;
12693       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12694                          &hw_if_index))
12695         ;
12696       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12697         ;
12698       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12699                          &rx_if_index))
12700         ;
12701       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12702         ;
12703       else
12704         {
12705           errmsg ("parse error '%U'", format_unformat_error, line_input);
12706           return -99;
12707         }
12708     }
12709
12710   if (hw_if_index == ~0)
12711     {
12712       errmsg ("no hw interface");
12713       return -99;
12714     }
12715
12716   if (rx_if_index == ~0)
12717     {
12718       errmsg ("no rx tunnel");
12719       return -99;
12720     }
12721
12722   M (VXLAN_OFFLOAD_RX, mp);
12723
12724   mp->hw_if_index = ntohl (hw_if_index);
12725   mp->sw_if_index = ntohl (rx_if_index);
12726   mp->enable = is_add;
12727
12728   S (mp);
12729   W (ret);
12730   return ret;
12731 }
12732
12733 static uword unformat_vxlan_decap_next
12734   (unformat_input_t * input, va_list * args)
12735 {
12736   u32 *result = va_arg (*args, u32 *);
12737   u32 tmp;
12738
12739   if (unformat (input, "l2"))
12740     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12741   else if (unformat (input, "%d", &tmp))
12742     *result = tmp;
12743   else
12744     return 0;
12745   return 1;
12746 }
12747
12748 static int
12749 api_vxlan_add_del_tunnel (vat_main_t * vam)
12750 {
12751   unformat_input_t *line_input = vam->input;
12752   vl_api_vxlan_add_del_tunnel_t *mp;
12753   ip46_address_t src, dst;
12754   u8 is_add = 1;
12755   u8 ipv4_set = 0, ipv6_set = 0;
12756   u8 src_set = 0;
12757   u8 dst_set = 0;
12758   u8 grp_set = 0;
12759   u32 instance = ~0;
12760   u32 mcast_sw_if_index = ~0;
12761   u32 encap_vrf_id = 0;
12762   u32 decap_next_index = ~0;
12763   u32 vni = 0;
12764   int ret;
12765
12766   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12767   clib_memset (&src, 0, sizeof src);
12768   clib_memset (&dst, 0, sizeof dst);
12769
12770   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12771     {
12772       if (unformat (line_input, "del"))
12773         is_add = 0;
12774       else if (unformat (line_input, "instance %d", &instance))
12775         ;
12776       else
12777         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12778         {
12779           ipv4_set = 1;
12780           src_set = 1;
12781         }
12782       else
12783         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12784         {
12785           ipv4_set = 1;
12786           dst_set = 1;
12787         }
12788       else
12789         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12790         {
12791           ipv6_set = 1;
12792           src_set = 1;
12793         }
12794       else
12795         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12796         {
12797           ipv6_set = 1;
12798           dst_set = 1;
12799         }
12800       else if (unformat (line_input, "group %U %U",
12801                          unformat_ip4_address, &dst.ip4,
12802                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12803         {
12804           grp_set = dst_set = 1;
12805           ipv4_set = 1;
12806         }
12807       else if (unformat (line_input, "group %U",
12808                          unformat_ip4_address, &dst.ip4))
12809         {
12810           grp_set = dst_set = 1;
12811           ipv4_set = 1;
12812         }
12813       else if (unformat (line_input, "group %U %U",
12814                          unformat_ip6_address, &dst.ip6,
12815                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12816         {
12817           grp_set = dst_set = 1;
12818           ipv6_set = 1;
12819         }
12820       else if (unformat (line_input, "group %U",
12821                          unformat_ip6_address, &dst.ip6))
12822         {
12823           grp_set = dst_set = 1;
12824           ipv6_set = 1;
12825         }
12826       else
12827         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12828         ;
12829       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12830         ;
12831       else if (unformat (line_input, "decap-next %U",
12832                          unformat_vxlan_decap_next, &decap_next_index))
12833         ;
12834       else if (unformat (line_input, "vni %d", &vni))
12835         ;
12836       else
12837         {
12838           errmsg ("parse error '%U'", format_unformat_error, line_input);
12839           return -99;
12840         }
12841     }
12842
12843   if (src_set == 0)
12844     {
12845       errmsg ("tunnel src address not specified");
12846       return -99;
12847     }
12848   if (dst_set == 0)
12849     {
12850       errmsg ("tunnel dst address not specified");
12851       return -99;
12852     }
12853
12854   if (grp_set && !ip46_address_is_multicast (&dst))
12855     {
12856       errmsg ("tunnel group address not multicast");
12857       return -99;
12858     }
12859   if (grp_set && mcast_sw_if_index == ~0)
12860     {
12861       errmsg ("tunnel nonexistent multicast device");
12862       return -99;
12863     }
12864   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12865     {
12866       errmsg ("tunnel dst address must be unicast");
12867       return -99;
12868     }
12869
12870
12871   if (ipv4_set && ipv6_set)
12872     {
12873       errmsg ("both IPv4 and IPv6 addresses specified");
12874       return -99;
12875     }
12876
12877   if ((vni == 0) || (vni >> 24))
12878     {
12879       errmsg ("vni not specified or out of range");
12880       return -99;
12881     }
12882
12883   M (VXLAN_ADD_DEL_TUNNEL, mp);
12884
12885   if (ipv6_set)
12886     {
12887       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12888       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12889     }
12890   else
12891     {
12892       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12893       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12894     }
12895
12896   mp->instance = htonl (instance);
12897   mp->encap_vrf_id = ntohl (encap_vrf_id);
12898   mp->decap_next_index = ntohl (decap_next_index);
12899   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12900   mp->vni = ntohl (vni);
12901   mp->is_add = is_add;
12902   mp->is_ipv6 = ipv6_set;
12903
12904   S (mp);
12905   W (ret);
12906   return ret;
12907 }
12908
12909 static void vl_api_vxlan_tunnel_details_t_handler
12910   (vl_api_vxlan_tunnel_details_t * mp)
12911 {
12912   vat_main_t *vam = &vat_main;
12913   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12914   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12915
12916   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12917          ntohl (mp->sw_if_index),
12918          ntohl (mp->instance),
12919          format_ip46_address, &src, IP46_TYPE_ANY,
12920          format_ip46_address, &dst, IP46_TYPE_ANY,
12921          ntohl (mp->encap_vrf_id),
12922          ntohl (mp->decap_next_index), ntohl (mp->vni),
12923          ntohl (mp->mcast_sw_if_index));
12924 }
12925
12926 static void vl_api_vxlan_tunnel_details_t_handler_json
12927   (vl_api_vxlan_tunnel_details_t * mp)
12928 {
12929   vat_main_t *vam = &vat_main;
12930   vat_json_node_t *node = NULL;
12931
12932   if (VAT_JSON_ARRAY != vam->json_tree.type)
12933     {
12934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12935       vat_json_init_array (&vam->json_tree);
12936     }
12937   node = vat_json_array_add (&vam->json_tree);
12938
12939   vat_json_init_object (node);
12940   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12941
12942   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12943
12944   if (mp->is_ipv6)
12945     {
12946       struct in6_addr ip6;
12947
12948       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12949       vat_json_object_add_ip6 (node, "src_address", ip6);
12950       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12951       vat_json_object_add_ip6 (node, "dst_address", ip6);
12952     }
12953   else
12954     {
12955       struct in_addr ip4;
12956
12957       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12958       vat_json_object_add_ip4 (node, "src_address", ip4);
12959       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12960       vat_json_object_add_ip4 (node, "dst_address", ip4);
12961     }
12962   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12963   vat_json_object_add_uint (node, "decap_next_index",
12964                             ntohl (mp->decap_next_index));
12965   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12966   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12967   vat_json_object_add_uint (node, "mcast_sw_if_index",
12968                             ntohl (mp->mcast_sw_if_index));
12969 }
12970
12971 static int
12972 api_vxlan_tunnel_dump (vat_main_t * vam)
12973 {
12974   unformat_input_t *i = vam->input;
12975   vl_api_vxlan_tunnel_dump_t *mp;
12976   vl_api_control_ping_t *mp_ping;
12977   u32 sw_if_index;
12978   u8 sw_if_index_set = 0;
12979   int ret;
12980
12981   /* Parse args required to build the message */
12982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12983     {
12984       if (unformat (i, "sw_if_index %d", &sw_if_index))
12985         sw_if_index_set = 1;
12986       else
12987         break;
12988     }
12989
12990   if (sw_if_index_set == 0)
12991     {
12992       sw_if_index = ~0;
12993     }
12994
12995   if (!vam->json_output)
12996     {
12997       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12998              "sw_if_index", "instance", "src_address", "dst_address",
12999              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13000     }
13001
13002   /* Get list of vxlan-tunnel interfaces */
13003   M (VXLAN_TUNNEL_DUMP, mp);
13004
13005   mp->sw_if_index = htonl (sw_if_index);
13006
13007   S (mp);
13008
13009   /* Use a control ping for synchronization */
13010   MPING (CONTROL_PING, mp_ping);
13011   S (mp_ping);
13012
13013   W (ret);
13014   return ret;
13015 }
13016
13017 static uword unformat_geneve_decap_next
13018   (unformat_input_t * input, va_list * args)
13019 {
13020   u32 *result = va_arg (*args, u32 *);
13021   u32 tmp;
13022
13023   if (unformat (input, "l2"))
13024     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13025   else if (unformat (input, "%d", &tmp))
13026     *result = tmp;
13027   else
13028     return 0;
13029   return 1;
13030 }
13031
13032 static int
13033 api_geneve_add_del_tunnel (vat_main_t * vam)
13034 {
13035   unformat_input_t *line_input = vam->input;
13036   vl_api_geneve_add_del_tunnel_t *mp;
13037   ip46_address_t src, dst;
13038   u8 is_add = 1;
13039   u8 ipv4_set = 0, ipv6_set = 0;
13040   u8 src_set = 0;
13041   u8 dst_set = 0;
13042   u8 grp_set = 0;
13043   u32 mcast_sw_if_index = ~0;
13044   u32 encap_vrf_id = 0;
13045   u32 decap_next_index = ~0;
13046   u32 vni = 0;
13047   int ret;
13048
13049   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13050   clib_memset (&src, 0, sizeof src);
13051   clib_memset (&dst, 0, sizeof dst);
13052
13053   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13054     {
13055       if (unformat (line_input, "del"))
13056         is_add = 0;
13057       else
13058         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13059         {
13060           ipv4_set = 1;
13061           src_set = 1;
13062         }
13063       else
13064         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13065         {
13066           ipv4_set = 1;
13067           dst_set = 1;
13068         }
13069       else
13070         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13071         {
13072           ipv6_set = 1;
13073           src_set = 1;
13074         }
13075       else
13076         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13077         {
13078           ipv6_set = 1;
13079           dst_set = 1;
13080         }
13081       else if (unformat (line_input, "group %U %U",
13082                          unformat_ip4_address, &dst.ip4,
13083                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13084         {
13085           grp_set = dst_set = 1;
13086           ipv4_set = 1;
13087         }
13088       else if (unformat (line_input, "group %U",
13089                          unformat_ip4_address, &dst.ip4))
13090         {
13091           grp_set = dst_set = 1;
13092           ipv4_set = 1;
13093         }
13094       else if (unformat (line_input, "group %U %U",
13095                          unformat_ip6_address, &dst.ip6,
13096                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13097         {
13098           grp_set = dst_set = 1;
13099           ipv6_set = 1;
13100         }
13101       else if (unformat (line_input, "group %U",
13102                          unformat_ip6_address, &dst.ip6))
13103         {
13104           grp_set = dst_set = 1;
13105           ipv6_set = 1;
13106         }
13107       else
13108         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13109         ;
13110       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13111         ;
13112       else if (unformat (line_input, "decap-next %U",
13113                          unformat_geneve_decap_next, &decap_next_index))
13114         ;
13115       else if (unformat (line_input, "vni %d", &vni))
13116         ;
13117       else
13118         {
13119           errmsg ("parse error '%U'", format_unformat_error, line_input);
13120           return -99;
13121         }
13122     }
13123
13124   if (src_set == 0)
13125     {
13126       errmsg ("tunnel src address not specified");
13127       return -99;
13128     }
13129   if (dst_set == 0)
13130     {
13131       errmsg ("tunnel dst address not specified");
13132       return -99;
13133     }
13134
13135   if (grp_set && !ip46_address_is_multicast (&dst))
13136     {
13137       errmsg ("tunnel group address not multicast");
13138       return -99;
13139     }
13140   if (grp_set && mcast_sw_if_index == ~0)
13141     {
13142       errmsg ("tunnel nonexistent multicast device");
13143       return -99;
13144     }
13145   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13146     {
13147       errmsg ("tunnel dst address must be unicast");
13148       return -99;
13149     }
13150
13151
13152   if (ipv4_set && ipv6_set)
13153     {
13154       errmsg ("both IPv4 and IPv6 addresses specified");
13155       return -99;
13156     }
13157
13158   if ((vni == 0) || (vni >> 24))
13159     {
13160       errmsg ("vni not specified or out of range");
13161       return -99;
13162     }
13163
13164   M (GENEVE_ADD_DEL_TUNNEL, mp);
13165
13166   if (ipv6_set)
13167     {
13168       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13169       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13170     }
13171   else
13172     {
13173       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13174       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13175     }
13176   mp->encap_vrf_id = ntohl (encap_vrf_id);
13177   mp->decap_next_index = ntohl (decap_next_index);
13178   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13179   mp->vni = ntohl (vni);
13180   mp->is_add = is_add;
13181   mp->is_ipv6 = ipv6_set;
13182
13183   S (mp);
13184   W (ret);
13185   return ret;
13186 }
13187
13188 static void vl_api_geneve_tunnel_details_t_handler
13189   (vl_api_geneve_tunnel_details_t * mp)
13190 {
13191   vat_main_t *vam = &vat_main;
13192   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13193   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13194
13195   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13196          ntohl (mp->sw_if_index),
13197          format_ip46_address, &src, IP46_TYPE_ANY,
13198          format_ip46_address, &dst, IP46_TYPE_ANY,
13199          ntohl (mp->encap_vrf_id),
13200          ntohl (mp->decap_next_index), ntohl (mp->vni),
13201          ntohl (mp->mcast_sw_if_index));
13202 }
13203
13204 static void vl_api_geneve_tunnel_details_t_handler_json
13205   (vl_api_geneve_tunnel_details_t * mp)
13206 {
13207   vat_main_t *vam = &vat_main;
13208   vat_json_node_t *node = NULL;
13209
13210   if (VAT_JSON_ARRAY != vam->json_tree.type)
13211     {
13212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13213       vat_json_init_array (&vam->json_tree);
13214     }
13215   node = vat_json_array_add (&vam->json_tree);
13216
13217   vat_json_init_object (node);
13218   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13219   if (mp->is_ipv6)
13220     {
13221       struct in6_addr ip6;
13222
13223       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13224       vat_json_object_add_ip6 (node, "src_address", ip6);
13225       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13226       vat_json_object_add_ip6 (node, "dst_address", ip6);
13227     }
13228   else
13229     {
13230       struct in_addr ip4;
13231
13232       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13233       vat_json_object_add_ip4 (node, "src_address", ip4);
13234       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13235       vat_json_object_add_ip4 (node, "dst_address", ip4);
13236     }
13237   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13238   vat_json_object_add_uint (node, "decap_next_index",
13239                             ntohl (mp->decap_next_index));
13240   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13241   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13242   vat_json_object_add_uint (node, "mcast_sw_if_index",
13243                             ntohl (mp->mcast_sw_if_index));
13244 }
13245
13246 static int
13247 api_geneve_tunnel_dump (vat_main_t * vam)
13248 {
13249   unformat_input_t *i = vam->input;
13250   vl_api_geneve_tunnel_dump_t *mp;
13251   vl_api_control_ping_t *mp_ping;
13252   u32 sw_if_index;
13253   u8 sw_if_index_set = 0;
13254   int ret;
13255
13256   /* Parse args required to build the message */
13257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13258     {
13259       if (unformat (i, "sw_if_index %d", &sw_if_index))
13260         sw_if_index_set = 1;
13261       else
13262         break;
13263     }
13264
13265   if (sw_if_index_set == 0)
13266     {
13267       sw_if_index = ~0;
13268     }
13269
13270   if (!vam->json_output)
13271     {
13272       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13273              "sw_if_index", "local_address", "remote_address",
13274              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13275     }
13276
13277   /* Get list of geneve-tunnel interfaces */
13278   M (GENEVE_TUNNEL_DUMP, mp);
13279
13280   mp->sw_if_index = htonl (sw_if_index);
13281
13282   S (mp);
13283
13284   /* Use a control ping for synchronization */
13285   M (CONTROL_PING, mp_ping);
13286   S (mp_ping);
13287
13288   W (ret);
13289   return ret;
13290 }
13291
13292 static int
13293 api_gre_tunnel_add_del (vat_main_t * vam)
13294 {
13295   unformat_input_t *line_input = vam->input;
13296   vl_api_address_t src = { }, dst =
13297   {
13298   };
13299   vl_api_gre_tunnel_add_del_t *mp;
13300   vl_api_gre_tunnel_type_t t_type;
13301   u8 is_add = 1;
13302   u8 ipv4_set = 0;
13303   u8 ipv6_set = 0;
13304   u8 src_set = 0;
13305   u8 dst_set = 0;
13306   u32 outer_fib_id = 0;
13307   u32 session_id = 0;
13308   u32 instance = ~0;
13309   int ret;
13310
13311   t_type = GRE_API_TUNNEL_TYPE_L3;
13312
13313   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13314     {
13315       if (unformat (line_input, "del"))
13316         is_add = 0;
13317       else if (unformat (line_input, "instance %d", &instance))
13318         ;
13319       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13320         {
13321           src_set = 1;
13322         }
13323       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13324         {
13325           dst_set = 1;
13326         }
13327       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13328         ;
13329       else if (unformat (line_input, "teb"))
13330         t_type = GRE_API_TUNNEL_TYPE_TEB;
13331       else if (unformat (line_input, "erspan %d", &session_id))
13332         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13333       else
13334         {
13335           errmsg ("parse error '%U'", format_unformat_error, line_input);
13336           return -99;
13337         }
13338     }
13339
13340   if (src_set == 0)
13341     {
13342       errmsg ("tunnel src address not specified");
13343       return -99;
13344     }
13345   if (dst_set == 0)
13346     {
13347       errmsg ("tunnel dst address not specified");
13348       return -99;
13349     }
13350
13351   M (GRE_TUNNEL_ADD_DEL, mp);
13352
13353   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13354   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13355
13356   mp->tunnel.instance = htonl (instance);
13357   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13358   mp->is_add = is_add;
13359   mp->tunnel.session_id = htons ((u16) session_id);
13360   mp->tunnel.type = htonl (t_type);
13361
13362   S (mp);
13363   W (ret);
13364   return ret;
13365 }
13366
13367 static void vl_api_gre_tunnel_details_t_handler
13368   (vl_api_gre_tunnel_details_t * mp)
13369 {
13370   vat_main_t *vam = &vat_main;
13371
13372   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13373          ntohl (mp->tunnel.sw_if_index),
13374          ntohl (mp->tunnel.instance),
13375          format_vl_api_address, &mp->tunnel.src,
13376          format_vl_api_address, &mp->tunnel.dst,
13377          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13378          ntohl (mp->tunnel.session_id));
13379 }
13380
13381 static void
13382 vat_json_object_add_address (vat_json_node_t * node,
13383                              const char *str, const vl_api_address_t * addr)
13384 {
13385   if (ADDRESS_IP6 == addr->af)
13386     {
13387       struct in6_addr ip6;
13388
13389       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13390       vat_json_object_add_ip6 (node, str, ip6);
13391     }
13392   else
13393     {
13394       struct in_addr ip4;
13395
13396       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13397       vat_json_object_add_ip4 (node, str, ip4);
13398     }
13399 }
13400
13401 static void vl_api_gre_tunnel_details_t_handler_json
13402   (vl_api_gre_tunnel_details_t * mp)
13403 {
13404   vat_main_t *vam = &vat_main;
13405   vat_json_node_t *node = NULL;
13406   struct in_addr ip4;
13407   struct in6_addr ip6;
13408
13409   if (VAT_JSON_ARRAY != vam->json_tree.type)
13410     {
13411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13412       vat_json_init_array (&vam->json_tree);
13413     }
13414   node = vat_json_array_add (&vam->json_tree);
13415
13416   vat_json_init_object (node);
13417   vat_json_object_add_uint (node, "sw_if_index",
13418                             ntohl (mp->tunnel.sw_if_index));
13419   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13420
13421   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13422   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13423   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13424   vat_json_object_add_uint (node, "outer_fib_id",
13425                             ntohl (mp->tunnel.outer_fib_id));
13426   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13427 }
13428
13429 static int
13430 api_gre_tunnel_dump (vat_main_t * vam)
13431 {
13432   unformat_input_t *i = vam->input;
13433   vl_api_gre_tunnel_dump_t *mp;
13434   vl_api_control_ping_t *mp_ping;
13435   u32 sw_if_index;
13436   u8 sw_if_index_set = 0;
13437   int ret;
13438
13439   /* Parse args required to build the message */
13440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13441     {
13442       if (unformat (i, "sw_if_index %d", &sw_if_index))
13443         sw_if_index_set = 1;
13444       else
13445         break;
13446     }
13447
13448   if (sw_if_index_set == 0)
13449     {
13450       sw_if_index = ~0;
13451     }
13452
13453   if (!vam->json_output)
13454     {
13455       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13456              "sw_if_index", "instance", "src_address", "dst_address",
13457              "tunnel_type", "outer_fib_id", "session_id");
13458     }
13459
13460   /* Get list of gre-tunnel interfaces */
13461   M (GRE_TUNNEL_DUMP, mp);
13462
13463   mp->sw_if_index = htonl (sw_if_index);
13464
13465   S (mp);
13466
13467   /* Use a control ping for synchronization */
13468   MPING (CONTROL_PING, mp_ping);
13469   S (mp_ping);
13470
13471   W (ret);
13472   return ret;
13473 }
13474
13475 static int
13476 api_l2_fib_clear_table (vat_main_t * vam)
13477 {
13478 //  unformat_input_t * i = vam->input;
13479   vl_api_l2_fib_clear_table_t *mp;
13480   int ret;
13481
13482   M (L2_FIB_CLEAR_TABLE, mp);
13483
13484   S (mp);
13485   W (ret);
13486   return ret;
13487 }
13488
13489 static int
13490 api_l2_interface_efp_filter (vat_main_t * vam)
13491 {
13492   unformat_input_t *i = vam->input;
13493   vl_api_l2_interface_efp_filter_t *mp;
13494   u32 sw_if_index;
13495   u8 enable = 1;
13496   u8 sw_if_index_set = 0;
13497   int ret;
13498
13499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13500     {
13501       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13502         sw_if_index_set = 1;
13503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13504         sw_if_index_set = 1;
13505       else if (unformat (i, "enable"))
13506         enable = 1;
13507       else if (unformat (i, "disable"))
13508         enable = 0;
13509       else
13510         {
13511           clib_warning ("parse error '%U'", format_unformat_error, i);
13512           return -99;
13513         }
13514     }
13515
13516   if (sw_if_index_set == 0)
13517     {
13518       errmsg ("missing sw_if_index");
13519       return -99;
13520     }
13521
13522   M (L2_INTERFACE_EFP_FILTER, mp);
13523
13524   mp->sw_if_index = ntohl (sw_if_index);
13525   mp->enable_disable = enable;
13526
13527   S (mp);
13528   W (ret);
13529   return ret;
13530 }
13531
13532 #define foreach_vtr_op                          \
13533 _("disable",  L2_VTR_DISABLED)                  \
13534 _("push-1",  L2_VTR_PUSH_1)                     \
13535 _("push-2",  L2_VTR_PUSH_2)                     \
13536 _("pop-1",  L2_VTR_POP_1)                       \
13537 _("pop-2",  L2_VTR_POP_2)                       \
13538 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13539 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13540 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13541 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13542
13543 static int
13544 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13545 {
13546   unformat_input_t *i = vam->input;
13547   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13548   u32 sw_if_index;
13549   u8 sw_if_index_set = 0;
13550   u8 vtr_op_set = 0;
13551   u32 vtr_op = 0;
13552   u32 push_dot1q = 1;
13553   u32 tag1 = ~0;
13554   u32 tag2 = ~0;
13555   int ret;
13556
13557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13558     {
13559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13560         sw_if_index_set = 1;
13561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13562         sw_if_index_set = 1;
13563       else if (unformat (i, "vtr_op %d", &vtr_op))
13564         vtr_op_set = 1;
13565 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13566       foreach_vtr_op
13567 #undef _
13568         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13569         ;
13570       else if (unformat (i, "tag1 %d", &tag1))
13571         ;
13572       else if (unformat (i, "tag2 %d", &tag2))
13573         ;
13574       else
13575         {
13576           clib_warning ("parse error '%U'", format_unformat_error, i);
13577           return -99;
13578         }
13579     }
13580
13581   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13582     {
13583       errmsg ("missing vtr operation or sw_if_index");
13584       return -99;
13585     }
13586
13587   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13588   mp->sw_if_index = ntohl (sw_if_index);
13589   mp->vtr_op = ntohl (vtr_op);
13590   mp->push_dot1q = ntohl (push_dot1q);
13591   mp->tag1 = ntohl (tag1);
13592   mp->tag2 = ntohl (tag2);
13593
13594   S (mp);
13595   W (ret);
13596   return ret;
13597 }
13598
13599 static int
13600 api_create_vhost_user_if (vat_main_t * vam)
13601 {
13602   unformat_input_t *i = vam->input;
13603   vl_api_create_vhost_user_if_t *mp;
13604   u8 *file_name;
13605   u8 is_server = 0;
13606   u8 file_name_set = 0;
13607   u32 custom_dev_instance = ~0;
13608   u8 hwaddr[6];
13609   u8 use_custom_mac = 0;
13610   u8 disable_mrg_rxbuf = 0;
13611   u8 disable_indirect_desc = 0;
13612   u8 *tag = 0;
13613   int ret;
13614
13615   /* Shut up coverity */
13616   clib_memset (hwaddr, 0, sizeof (hwaddr));
13617
13618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13619     {
13620       if (unformat (i, "socket %s", &file_name))
13621         {
13622           file_name_set = 1;
13623         }
13624       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13625         ;
13626       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13627         use_custom_mac = 1;
13628       else if (unformat (i, "server"))
13629         is_server = 1;
13630       else if (unformat (i, "disable_mrg_rxbuf"))
13631         disable_mrg_rxbuf = 1;
13632       else if (unformat (i, "disable_indirect_desc"))
13633         disable_indirect_desc = 1;
13634       else if (unformat (i, "tag %s", &tag))
13635         ;
13636       else
13637         break;
13638     }
13639
13640   if (file_name_set == 0)
13641     {
13642       errmsg ("missing socket file name");
13643       return -99;
13644     }
13645
13646   if (vec_len (file_name) > 255)
13647     {
13648       errmsg ("socket file name too long");
13649       return -99;
13650     }
13651   vec_add1 (file_name, 0);
13652
13653   M (CREATE_VHOST_USER_IF, mp);
13654
13655   mp->is_server = is_server;
13656   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13657   mp->disable_indirect_desc = disable_indirect_desc;
13658   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13659   vec_free (file_name);
13660   if (custom_dev_instance != ~0)
13661     {
13662       mp->renumber = 1;
13663       mp->custom_dev_instance = ntohl (custom_dev_instance);
13664     }
13665
13666   mp->use_custom_mac = use_custom_mac;
13667   clib_memcpy (mp->mac_address, hwaddr, 6);
13668   if (tag)
13669     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13670   vec_free (tag);
13671
13672   S (mp);
13673   W (ret);
13674   return ret;
13675 }
13676
13677 static int
13678 api_modify_vhost_user_if (vat_main_t * vam)
13679 {
13680   unformat_input_t *i = vam->input;
13681   vl_api_modify_vhost_user_if_t *mp;
13682   u8 *file_name;
13683   u8 is_server = 0;
13684   u8 file_name_set = 0;
13685   u32 custom_dev_instance = ~0;
13686   u8 sw_if_index_set = 0;
13687   u32 sw_if_index = (u32) ~ 0;
13688   int ret;
13689
13690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13691     {
13692       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13693         sw_if_index_set = 1;
13694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13695         sw_if_index_set = 1;
13696       else if (unformat (i, "socket %s", &file_name))
13697         {
13698           file_name_set = 1;
13699         }
13700       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13701         ;
13702       else if (unformat (i, "server"))
13703         is_server = 1;
13704       else
13705         break;
13706     }
13707
13708   if (sw_if_index_set == 0)
13709     {
13710       errmsg ("missing sw_if_index or interface name");
13711       return -99;
13712     }
13713
13714   if (file_name_set == 0)
13715     {
13716       errmsg ("missing socket file name");
13717       return -99;
13718     }
13719
13720   if (vec_len (file_name) > 255)
13721     {
13722       errmsg ("socket file name too long");
13723       return -99;
13724     }
13725   vec_add1 (file_name, 0);
13726
13727   M (MODIFY_VHOST_USER_IF, mp);
13728
13729   mp->sw_if_index = ntohl (sw_if_index);
13730   mp->is_server = is_server;
13731   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13732   vec_free (file_name);
13733   if (custom_dev_instance != ~0)
13734     {
13735       mp->renumber = 1;
13736       mp->custom_dev_instance = ntohl (custom_dev_instance);
13737     }
13738
13739   S (mp);
13740   W (ret);
13741   return ret;
13742 }
13743
13744 static int
13745 api_delete_vhost_user_if (vat_main_t * vam)
13746 {
13747   unformat_input_t *i = vam->input;
13748   vl_api_delete_vhost_user_if_t *mp;
13749   u32 sw_if_index = ~0;
13750   u8 sw_if_index_set = 0;
13751   int ret;
13752
13753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13754     {
13755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13756         sw_if_index_set = 1;
13757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13758         sw_if_index_set = 1;
13759       else
13760         break;
13761     }
13762
13763   if (sw_if_index_set == 0)
13764     {
13765       errmsg ("missing sw_if_index or interface name");
13766       return -99;
13767     }
13768
13769
13770   M (DELETE_VHOST_USER_IF, mp);
13771
13772   mp->sw_if_index = ntohl (sw_if_index);
13773
13774   S (mp);
13775   W (ret);
13776   return ret;
13777 }
13778
13779 static void vl_api_sw_interface_vhost_user_details_t_handler
13780   (vl_api_sw_interface_vhost_user_details_t * mp)
13781 {
13782   vat_main_t *vam = &vat_main;
13783
13784   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13785          (char *) mp->interface_name,
13786          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13787          clib_net_to_host_u64 (mp->features), mp->is_server,
13788          ntohl (mp->num_regions), (char *) mp->sock_filename);
13789   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13790 }
13791
13792 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13793   (vl_api_sw_interface_vhost_user_details_t * mp)
13794 {
13795   vat_main_t *vam = &vat_main;
13796   vat_json_node_t *node = NULL;
13797
13798   if (VAT_JSON_ARRAY != vam->json_tree.type)
13799     {
13800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13801       vat_json_init_array (&vam->json_tree);
13802     }
13803   node = vat_json_array_add (&vam->json_tree);
13804
13805   vat_json_init_object (node);
13806   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13807   vat_json_object_add_string_copy (node, "interface_name",
13808                                    mp->interface_name);
13809   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13810                             ntohl (mp->virtio_net_hdr_sz));
13811   vat_json_object_add_uint (node, "features",
13812                             clib_net_to_host_u64 (mp->features));
13813   vat_json_object_add_uint (node, "is_server", mp->is_server);
13814   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13815   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13816   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13817 }
13818
13819 static int
13820 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13821 {
13822   vl_api_sw_interface_vhost_user_dump_t *mp;
13823   vl_api_control_ping_t *mp_ping;
13824   int ret;
13825   print (vam->ofp,
13826          "Interface name            idx hdr_sz features server regions filename");
13827
13828   /* Get list of vhost-user interfaces */
13829   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13830   S (mp);
13831
13832   /* Use a control ping for synchronization */
13833   MPING (CONTROL_PING, mp_ping);
13834   S (mp_ping);
13835
13836   W (ret);
13837   return ret;
13838 }
13839
13840 static int
13841 api_show_version (vat_main_t * vam)
13842 {
13843   vl_api_show_version_t *mp;
13844   int ret;
13845
13846   M (SHOW_VERSION, mp);
13847
13848   S (mp);
13849   W (ret);
13850   return ret;
13851 }
13852
13853
13854 static int
13855 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13856 {
13857   unformat_input_t *line_input = vam->input;
13858   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13859   ip4_address_t local4, remote4;
13860   ip6_address_t local6, remote6;
13861   u8 is_add = 1;
13862   u8 ipv4_set = 0, ipv6_set = 0;
13863   u8 local_set = 0;
13864   u8 remote_set = 0;
13865   u8 grp_set = 0;
13866   u32 mcast_sw_if_index = ~0;
13867   u32 encap_vrf_id = 0;
13868   u32 decap_vrf_id = 0;
13869   u8 protocol = ~0;
13870   u32 vni;
13871   u8 vni_set = 0;
13872   int ret;
13873
13874   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13875   clib_memset (&local4, 0, sizeof local4);
13876   clib_memset (&remote4, 0, sizeof remote4);
13877   clib_memset (&local6, 0, sizeof local6);
13878   clib_memset (&remote6, 0, sizeof remote6);
13879
13880   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13881     {
13882       if (unformat (line_input, "del"))
13883         is_add = 0;
13884       else if (unformat (line_input, "local %U",
13885                          unformat_ip4_address, &local4))
13886         {
13887           local_set = 1;
13888           ipv4_set = 1;
13889         }
13890       else if (unformat (line_input, "remote %U",
13891                          unformat_ip4_address, &remote4))
13892         {
13893           remote_set = 1;
13894           ipv4_set = 1;
13895         }
13896       else if (unformat (line_input, "local %U",
13897                          unformat_ip6_address, &local6))
13898         {
13899           local_set = 1;
13900           ipv6_set = 1;
13901         }
13902       else if (unformat (line_input, "remote %U",
13903                          unformat_ip6_address, &remote6))
13904         {
13905           remote_set = 1;
13906           ipv6_set = 1;
13907         }
13908       else if (unformat (line_input, "group %U %U",
13909                          unformat_ip4_address, &remote4,
13910                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13911         {
13912           grp_set = remote_set = 1;
13913           ipv4_set = 1;
13914         }
13915       else if (unformat (line_input, "group %U",
13916                          unformat_ip4_address, &remote4))
13917         {
13918           grp_set = remote_set = 1;
13919           ipv4_set = 1;
13920         }
13921       else if (unformat (line_input, "group %U %U",
13922                          unformat_ip6_address, &remote6,
13923                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13924         {
13925           grp_set = remote_set = 1;
13926           ipv6_set = 1;
13927         }
13928       else if (unformat (line_input, "group %U",
13929                          unformat_ip6_address, &remote6))
13930         {
13931           grp_set = remote_set = 1;
13932           ipv6_set = 1;
13933         }
13934       else
13935         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13936         ;
13937       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13938         ;
13939       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13940         ;
13941       else if (unformat (line_input, "vni %d", &vni))
13942         vni_set = 1;
13943       else if (unformat (line_input, "next-ip4"))
13944         protocol = 1;
13945       else if (unformat (line_input, "next-ip6"))
13946         protocol = 2;
13947       else if (unformat (line_input, "next-ethernet"))
13948         protocol = 3;
13949       else if (unformat (line_input, "next-nsh"))
13950         protocol = 4;
13951       else
13952         {
13953           errmsg ("parse error '%U'", format_unformat_error, line_input);
13954           return -99;
13955         }
13956     }
13957
13958   if (local_set == 0)
13959     {
13960       errmsg ("tunnel local address not specified");
13961       return -99;
13962     }
13963   if (remote_set == 0)
13964     {
13965       errmsg ("tunnel remote address not specified");
13966       return -99;
13967     }
13968   if (grp_set && mcast_sw_if_index == ~0)
13969     {
13970       errmsg ("tunnel nonexistent multicast device");
13971       return -99;
13972     }
13973   if (ipv4_set && ipv6_set)
13974     {
13975       errmsg ("both IPv4 and IPv6 addresses specified");
13976       return -99;
13977     }
13978
13979   if (vni_set == 0)
13980     {
13981       errmsg ("vni not specified");
13982       return -99;
13983     }
13984
13985   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13986
13987
13988   if (ipv6_set)
13989     {
13990       clib_memcpy (&mp->local, &local6, sizeof (local6));
13991       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13992     }
13993   else
13994     {
13995       clib_memcpy (&mp->local, &local4, sizeof (local4));
13996       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13997     }
13998
13999   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14000   mp->encap_vrf_id = ntohl (encap_vrf_id);
14001   mp->decap_vrf_id = ntohl (decap_vrf_id);
14002   mp->protocol = protocol;
14003   mp->vni = ntohl (vni);
14004   mp->is_add = is_add;
14005   mp->is_ipv6 = ipv6_set;
14006
14007   S (mp);
14008   W (ret);
14009   return ret;
14010 }
14011
14012 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14013   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14014 {
14015   vat_main_t *vam = &vat_main;
14016   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14017   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14018
14019   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14020          ntohl (mp->sw_if_index),
14021          format_ip46_address, &local, IP46_TYPE_ANY,
14022          format_ip46_address, &remote, IP46_TYPE_ANY,
14023          ntohl (mp->vni), mp->protocol,
14024          ntohl (mp->mcast_sw_if_index),
14025          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14026 }
14027
14028
14029 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14030   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14031 {
14032   vat_main_t *vam = &vat_main;
14033   vat_json_node_t *node = NULL;
14034   struct in_addr ip4;
14035   struct in6_addr ip6;
14036
14037   if (VAT_JSON_ARRAY != vam->json_tree.type)
14038     {
14039       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14040       vat_json_init_array (&vam->json_tree);
14041     }
14042   node = vat_json_array_add (&vam->json_tree);
14043
14044   vat_json_init_object (node);
14045   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14046   if (mp->is_ipv6)
14047     {
14048       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14049       vat_json_object_add_ip6 (node, "local", ip6);
14050       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14051       vat_json_object_add_ip6 (node, "remote", ip6);
14052     }
14053   else
14054     {
14055       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14056       vat_json_object_add_ip4 (node, "local", ip4);
14057       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14058       vat_json_object_add_ip4 (node, "remote", ip4);
14059     }
14060   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14061   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14062   vat_json_object_add_uint (node, "mcast_sw_if_index",
14063                             ntohl (mp->mcast_sw_if_index));
14064   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14065   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14066   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14067 }
14068
14069 static int
14070 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14071 {
14072   unformat_input_t *i = vam->input;
14073   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14074   vl_api_control_ping_t *mp_ping;
14075   u32 sw_if_index;
14076   u8 sw_if_index_set = 0;
14077   int ret;
14078
14079   /* Parse args required to build the message */
14080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (i, "sw_if_index %d", &sw_if_index))
14083         sw_if_index_set = 1;
14084       else
14085         break;
14086     }
14087
14088   if (sw_if_index_set == 0)
14089     {
14090       sw_if_index = ~0;
14091     }
14092
14093   if (!vam->json_output)
14094     {
14095       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14096              "sw_if_index", "local", "remote", "vni",
14097              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14098     }
14099
14100   /* Get list of vxlan-tunnel interfaces */
14101   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14102
14103   mp->sw_if_index = htonl (sw_if_index);
14104
14105   S (mp);
14106
14107   /* Use a control ping for synchronization */
14108   MPING (CONTROL_PING, mp_ping);
14109   S (mp_ping);
14110
14111   W (ret);
14112   return ret;
14113 }
14114
14115 static void vl_api_l2_fib_table_details_t_handler
14116   (vl_api_l2_fib_table_details_t * mp)
14117 {
14118   vat_main_t *vam = &vat_main;
14119
14120   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14121          "       %d       %d     %d",
14122          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14123          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14124          mp->bvi_mac);
14125 }
14126
14127 static void vl_api_l2_fib_table_details_t_handler_json
14128   (vl_api_l2_fib_table_details_t * mp)
14129 {
14130   vat_main_t *vam = &vat_main;
14131   vat_json_node_t *node = NULL;
14132
14133   if (VAT_JSON_ARRAY != vam->json_tree.type)
14134     {
14135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14136       vat_json_init_array (&vam->json_tree);
14137     }
14138   node = vat_json_array_add (&vam->json_tree);
14139
14140   vat_json_init_object (node);
14141   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14142   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14143   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14144   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14145   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14146   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14147 }
14148
14149 static int
14150 api_l2_fib_table_dump (vat_main_t * vam)
14151 {
14152   unformat_input_t *i = vam->input;
14153   vl_api_l2_fib_table_dump_t *mp;
14154   vl_api_control_ping_t *mp_ping;
14155   u32 bd_id;
14156   u8 bd_id_set = 0;
14157   int ret;
14158
14159   /* Parse args required to build the message */
14160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14161     {
14162       if (unformat (i, "bd_id %d", &bd_id))
14163         bd_id_set = 1;
14164       else
14165         break;
14166     }
14167
14168   if (bd_id_set == 0)
14169     {
14170       errmsg ("missing bridge domain");
14171       return -99;
14172     }
14173
14174   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14175
14176   /* Get list of l2 fib entries */
14177   M (L2_FIB_TABLE_DUMP, mp);
14178
14179   mp->bd_id = ntohl (bd_id);
14180   S (mp);
14181
14182   /* Use a control ping for synchronization */
14183   MPING (CONTROL_PING, mp_ping);
14184   S (mp_ping);
14185
14186   W (ret);
14187   return ret;
14188 }
14189
14190
14191 static int
14192 api_interface_name_renumber (vat_main_t * vam)
14193 {
14194   unformat_input_t *line_input = vam->input;
14195   vl_api_interface_name_renumber_t *mp;
14196   u32 sw_if_index = ~0;
14197   u32 new_show_dev_instance = ~0;
14198   int ret;
14199
14200   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14201     {
14202       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14203                     &sw_if_index))
14204         ;
14205       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14206         ;
14207       else if (unformat (line_input, "new_show_dev_instance %d",
14208                          &new_show_dev_instance))
14209         ;
14210       else
14211         break;
14212     }
14213
14214   if (sw_if_index == ~0)
14215     {
14216       errmsg ("missing interface name or sw_if_index");
14217       return -99;
14218     }
14219
14220   if (new_show_dev_instance == ~0)
14221     {
14222       errmsg ("missing new_show_dev_instance");
14223       return -99;
14224     }
14225
14226   M (INTERFACE_NAME_RENUMBER, mp);
14227
14228   mp->sw_if_index = ntohl (sw_if_index);
14229   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14230
14231   S (mp);
14232   W (ret);
14233   return ret;
14234 }
14235
14236 static int
14237 api_ip_probe_neighbor (vat_main_t * vam)
14238 {
14239   unformat_input_t *i = vam->input;
14240   vl_api_ip_probe_neighbor_t *mp;
14241   vl_api_address_t dst_adr;
14242   u8 int_set = 0;
14243   u8 adr_set = 0;
14244   u32 sw_if_index;
14245   int ret;
14246
14247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14248     {
14249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14250         int_set = 1;
14251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14252         int_set = 1;
14253       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14254         adr_set = 1;
14255       else
14256         break;
14257     }
14258
14259   if (int_set == 0)
14260     {
14261       errmsg ("missing interface");
14262       return -99;
14263     }
14264
14265   if (adr_set == 0)
14266     {
14267       errmsg ("missing addresses");
14268       return -99;
14269     }
14270
14271   M (IP_PROBE_NEIGHBOR, mp);
14272
14273   mp->sw_if_index = ntohl (sw_if_index);
14274   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14275
14276   S (mp);
14277   W (ret);
14278   return ret;
14279 }
14280
14281 static int
14282 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14283 {
14284   unformat_input_t *i = vam->input;
14285   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14286   u8 mode = IP_SCAN_V46_NEIGHBORS;
14287   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14288   int ret;
14289
14290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (unformat (i, "ip4"))
14293         mode = IP_SCAN_V4_NEIGHBORS;
14294       else if (unformat (i, "ip6"))
14295         mode = IP_SCAN_V6_NEIGHBORS;
14296       if (unformat (i, "both"))
14297         mode = IP_SCAN_V46_NEIGHBORS;
14298       else if (unformat (i, "disable"))
14299         mode = IP_SCAN_DISABLED;
14300       else if (unformat (i, "interval %d", &interval))
14301         ;
14302       else if (unformat (i, "max-time %d", &time))
14303         ;
14304       else if (unformat (i, "max-update %d", &update))
14305         ;
14306       else if (unformat (i, "delay %d", &delay))
14307         ;
14308       else if (unformat (i, "stale %d", &stale))
14309         ;
14310       else
14311         break;
14312     }
14313
14314   if (interval > 255)
14315     {
14316       errmsg ("interval cannot exceed 255 minutes.");
14317       return -99;
14318     }
14319   if (time > 255)
14320     {
14321       errmsg ("max-time cannot exceed 255 usec.");
14322       return -99;
14323     }
14324   if (update > 255)
14325     {
14326       errmsg ("max-update cannot exceed 255.");
14327       return -99;
14328     }
14329   if (delay > 255)
14330     {
14331       errmsg ("delay cannot exceed 255 msec.");
14332       return -99;
14333     }
14334   if (stale > 255)
14335     {
14336       errmsg ("stale cannot exceed 255 minutes.");
14337       return -99;
14338     }
14339
14340   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14341   mp->mode = mode;
14342   mp->scan_interval = interval;
14343   mp->max_proc_time = time;
14344   mp->max_update = update;
14345   mp->scan_int_delay = delay;
14346   mp->stale_threshold = stale;
14347
14348   S (mp);
14349   W (ret);
14350   return ret;
14351 }
14352
14353 static int
14354 api_want_ip4_arp_events (vat_main_t * vam)
14355 {
14356   unformat_input_t *line_input = vam->input;
14357   vl_api_want_ip4_arp_events_t *mp;
14358   ip4_address_t address;
14359   int address_set = 0;
14360   u32 enable_disable = 1;
14361   int ret;
14362
14363   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14364     {
14365       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14366         address_set = 1;
14367       else if (unformat (line_input, "del"))
14368         enable_disable = 0;
14369       else
14370         break;
14371     }
14372
14373   if (address_set == 0)
14374     {
14375       errmsg ("missing addresses");
14376       return -99;
14377     }
14378
14379   M (WANT_IP4_ARP_EVENTS, mp);
14380   mp->enable_disable = enable_disable;
14381   mp->pid = htonl (getpid ());
14382   clib_memcpy (mp->ip, &address, sizeof (address));
14383
14384   S (mp);
14385   W (ret);
14386   return ret;
14387 }
14388
14389 static int
14390 api_want_ip6_nd_events (vat_main_t * vam)
14391 {
14392   unformat_input_t *line_input = vam->input;
14393   vl_api_want_ip6_nd_events_t *mp;
14394   vl_api_ip6_address_t address;
14395   int address_set = 0;
14396   u32 enable_disable = 1;
14397   int ret;
14398
14399   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14400     {
14401       if (unformat
14402           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14403         address_set = 1;
14404       else if (unformat (line_input, "del"))
14405         enable_disable = 0;
14406       else
14407         break;
14408     }
14409
14410   if (address_set == 0)
14411     {
14412       errmsg ("missing addresses");
14413       return -99;
14414     }
14415
14416   M (WANT_IP6_ND_EVENTS, mp);
14417   mp->enable_disable = enable_disable;
14418   mp->pid = htonl (getpid ());
14419   clib_memcpy (&mp->ip, &address, sizeof (address));
14420
14421   S (mp);
14422   W (ret);
14423   return ret;
14424 }
14425
14426 static int
14427 api_want_l2_macs_events (vat_main_t * vam)
14428 {
14429   unformat_input_t *line_input = vam->input;
14430   vl_api_want_l2_macs_events_t *mp;
14431   u8 enable_disable = 1;
14432   u32 scan_delay = 0;
14433   u32 max_macs_in_event = 0;
14434   u32 learn_limit = 0;
14435   int ret;
14436
14437   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14438     {
14439       if (unformat (line_input, "learn-limit %d", &learn_limit))
14440         ;
14441       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14442         ;
14443       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14444         ;
14445       else if (unformat (line_input, "disable"))
14446         enable_disable = 0;
14447       else
14448         break;
14449     }
14450
14451   M (WANT_L2_MACS_EVENTS, mp);
14452   mp->enable_disable = enable_disable;
14453   mp->pid = htonl (getpid ());
14454   mp->learn_limit = htonl (learn_limit);
14455   mp->scan_delay = (u8) scan_delay;
14456   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14457   S (mp);
14458   W (ret);
14459   return ret;
14460 }
14461
14462 static int
14463 api_input_acl_set_interface (vat_main_t * vam)
14464 {
14465   unformat_input_t *i = vam->input;
14466   vl_api_input_acl_set_interface_t *mp;
14467   u32 sw_if_index;
14468   int sw_if_index_set;
14469   u32 ip4_table_index = ~0;
14470   u32 ip6_table_index = ~0;
14471   u32 l2_table_index = ~0;
14472   u8 is_add = 1;
14473   int ret;
14474
14475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14476     {
14477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14478         sw_if_index_set = 1;
14479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14480         sw_if_index_set = 1;
14481       else if (unformat (i, "del"))
14482         is_add = 0;
14483       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14484         ;
14485       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14486         ;
14487       else if (unformat (i, "l2-table %d", &l2_table_index))
14488         ;
14489       else
14490         {
14491           clib_warning ("parse error '%U'", format_unformat_error, i);
14492           return -99;
14493         }
14494     }
14495
14496   if (sw_if_index_set == 0)
14497     {
14498       errmsg ("missing interface name or sw_if_index");
14499       return -99;
14500     }
14501
14502   M (INPUT_ACL_SET_INTERFACE, mp);
14503
14504   mp->sw_if_index = ntohl (sw_if_index);
14505   mp->ip4_table_index = ntohl (ip4_table_index);
14506   mp->ip6_table_index = ntohl (ip6_table_index);
14507   mp->l2_table_index = ntohl (l2_table_index);
14508   mp->is_add = is_add;
14509
14510   S (mp);
14511   W (ret);
14512   return ret;
14513 }
14514
14515 static int
14516 api_output_acl_set_interface (vat_main_t * vam)
14517 {
14518   unformat_input_t *i = vam->input;
14519   vl_api_output_acl_set_interface_t *mp;
14520   u32 sw_if_index;
14521   int sw_if_index_set;
14522   u32 ip4_table_index = ~0;
14523   u32 ip6_table_index = ~0;
14524   u32 l2_table_index = ~0;
14525   u8 is_add = 1;
14526   int ret;
14527
14528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14529     {
14530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14531         sw_if_index_set = 1;
14532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14533         sw_if_index_set = 1;
14534       else if (unformat (i, "del"))
14535         is_add = 0;
14536       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14537         ;
14538       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14539         ;
14540       else if (unformat (i, "l2-table %d", &l2_table_index))
14541         ;
14542       else
14543         {
14544           clib_warning ("parse error '%U'", format_unformat_error, i);
14545           return -99;
14546         }
14547     }
14548
14549   if (sw_if_index_set == 0)
14550     {
14551       errmsg ("missing interface name or sw_if_index");
14552       return -99;
14553     }
14554
14555   M (OUTPUT_ACL_SET_INTERFACE, mp);
14556
14557   mp->sw_if_index = ntohl (sw_if_index);
14558   mp->ip4_table_index = ntohl (ip4_table_index);
14559   mp->ip6_table_index = ntohl (ip6_table_index);
14560   mp->l2_table_index = ntohl (l2_table_index);
14561   mp->is_add = is_add;
14562
14563   S (mp);
14564   W (ret);
14565   return ret;
14566 }
14567
14568 static int
14569 api_ip_address_dump (vat_main_t * vam)
14570 {
14571   unformat_input_t *i = vam->input;
14572   vl_api_ip_address_dump_t *mp;
14573   vl_api_control_ping_t *mp_ping;
14574   u32 sw_if_index = ~0;
14575   u8 sw_if_index_set = 0;
14576   u8 ipv4_set = 0;
14577   u8 ipv6_set = 0;
14578   int ret;
14579
14580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14581     {
14582       if (unformat (i, "sw_if_index %d", &sw_if_index))
14583         sw_if_index_set = 1;
14584       else
14585         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14586         sw_if_index_set = 1;
14587       else if (unformat (i, "ipv4"))
14588         ipv4_set = 1;
14589       else if (unformat (i, "ipv6"))
14590         ipv6_set = 1;
14591       else
14592         break;
14593     }
14594
14595   if (ipv4_set && ipv6_set)
14596     {
14597       errmsg ("ipv4 and ipv6 flags cannot be both set");
14598       return -99;
14599     }
14600
14601   if ((!ipv4_set) && (!ipv6_set))
14602     {
14603       errmsg ("no ipv4 nor ipv6 flag set");
14604       return -99;
14605     }
14606
14607   if (sw_if_index_set == 0)
14608     {
14609       errmsg ("missing interface name or sw_if_index");
14610       return -99;
14611     }
14612
14613   vam->current_sw_if_index = sw_if_index;
14614   vam->is_ipv6 = ipv6_set;
14615
14616   M (IP_ADDRESS_DUMP, mp);
14617   mp->sw_if_index = ntohl (sw_if_index);
14618   mp->is_ipv6 = ipv6_set;
14619   S (mp);
14620
14621   /* Use a control ping for synchronization */
14622   MPING (CONTROL_PING, mp_ping);
14623   S (mp_ping);
14624
14625   W (ret);
14626   return ret;
14627 }
14628
14629 static int
14630 api_ip_dump (vat_main_t * vam)
14631 {
14632   vl_api_ip_dump_t *mp;
14633   vl_api_control_ping_t *mp_ping;
14634   unformat_input_t *in = vam->input;
14635   int ipv4_set = 0;
14636   int ipv6_set = 0;
14637   int is_ipv6;
14638   int i;
14639   int ret;
14640
14641   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14642     {
14643       if (unformat (in, "ipv4"))
14644         ipv4_set = 1;
14645       else if (unformat (in, "ipv6"))
14646         ipv6_set = 1;
14647       else
14648         break;
14649     }
14650
14651   if (ipv4_set && ipv6_set)
14652     {
14653       errmsg ("ipv4 and ipv6 flags cannot be both set");
14654       return -99;
14655     }
14656
14657   if ((!ipv4_set) && (!ipv6_set))
14658     {
14659       errmsg ("no ipv4 nor ipv6 flag set");
14660       return -99;
14661     }
14662
14663   is_ipv6 = ipv6_set;
14664   vam->is_ipv6 = is_ipv6;
14665
14666   /* free old data */
14667   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14668     {
14669       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14670     }
14671   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14672
14673   M (IP_DUMP, mp);
14674   mp->is_ipv6 = ipv6_set;
14675   S (mp);
14676
14677   /* Use a control ping for synchronization */
14678   MPING (CONTROL_PING, mp_ping);
14679   S (mp_ping);
14680
14681   W (ret);
14682   return ret;
14683 }
14684
14685 static int
14686 api_ipsec_spd_add_del (vat_main_t * vam)
14687 {
14688   unformat_input_t *i = vam->input;
14689   vl_api_ipsec_spd_add_del_t *mp;
14690   u32 spd_id = ~0;
14691   u8 is_add = 1;
14692   int ret;
14693
14694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14695     {
14696       if (unformat (i, "spd_id %d", &spd_id))
14697         ;
14698       else if (unformat (i, "del"))
14699         is_add = 0;
14700       else
14701         {
14702           clib_warning ("parse error '%U'", format_unformat_error, i);
14703           return -99;
14704         }
14705     }
14706   if (spd_id == ~0)
14707     {
14708       errmsg ("spd_id must be set");
14709       return -99;
14710     }
14711
14712   M (IPSEC_SPD_ADD_DEL, mp);
14713
14714   mp->spd_id = ntohl (spd_id);
14715   mp->is_add = is_add;
14716
14717   S (mp);
14718   W (ret);
14719   return ret;
14720 }
14721
14722 static int
14723 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14724 {
14725   unformat_input_t *i = vam->input;
14726   vl_api_ipsec_interface_add_del_spd_t *mp;
14727   u32 sw_if_index;
14728   u8 sw_if_index_set = 0;
14729   u32 spd_id = (u32) ~ 0;
14730   u8 is_add = 1;
14731   int ret;
14732
14733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14734     {
14735       if (unformat (i, "del"))
14736         is_add = 0;
14737       else if (unformat (i, "spd_id %d", &spd_id))
14738         ;
14739       else
14740         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14741         sw_if_index_set = 1;
14742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14743         sw_if_index_set = 1;
14744       else
14745         {
14746           clib_warning ("parse error '%U'", format_unformat_error, i);
14747           return -99;
14748         }
14749
14750     }
14751
14752   if (spd_id == (u32) ~ 0)
14753     {
14754       errmsg ("spd_id must be set");
14755       return -99;
14756     }
14757
14758   if (sw_if_index_set == 0)
14759     {
14760       errmsg ("missing interface name or sw_if_index");
14761       return -99;
14762     }
14763
14764   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14765
14766   mp->spd_id = ntohl (spd_id);
14767   mp->sw_if_index = ntohl (sw_if_index);
14768   mp->is_add = is_add;
14769
14770   S (mp);
14771   W (ret);
14772   return ret;
14773 }
14774
14775 static int
14776 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14777 {
14778   unformat_input_t *i = vam->input;
14779   vl_api_ipsec_spd_entry_add_del_t *mp;
14780   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14781   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14782   i32 priority = 0;
14783   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14784   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14785   vl_api_address_t laddr_start = { }, laddr_stop =
14786   {
14787   }, raddr_start =
14788   {
14789   }, raddr_stop =
14790   {
14791   };
14792   int ret;
14793
14794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14795     {
14796       if (unformat (i, "del"))
14797         is_add = 0;
14798       if (unformat (i, "outbound"))
14799         is_outbound = 1;
14800       if (unformat (i, "inbound"))
14801         is_outbound = 0;
14802       else if (unformat (i, "spd_id %d", &spd_id))
14803         ;
14804       else if (unformat (i, "sa_id %d", &sa_id))
14805         ;
14806       else if (unformat (i, "priority %d", &priority))
14807         ;
14808       else if (unformat (i, "protocol %d", &protocol))
14809         ;
14810       else if (unformat (i, "lport_start %d", &lport_start))
14811         ;
14812       else if (unformat (i, "lport_stop %d", &lport_stop))
14813         ;
14814       else if (unformat (i, "rport_start %d", &rport_start))
14815         ;
14816       else if (unformat (i, "rport_stop %d", &rport_stop))
14817         ;
14818       else if (unformat (i, "laddr_start %U",
14819                          unformat_vl_api_address, &laddr_start))
14820         is_ip_any = 0;
14821       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14822                          &laddr_stop))
14823         is_ip_any = 0;
14824       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14825                          &raddr_start))
14826         is_ip_any = 0;
14827       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14828                          &raddr_stop))
14829         is_ip_any = 0;
14830       else
14831         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14832         {
14833           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14834             {
14835               clib_warning ("unsupported action: 'resolve'");
14836               return -99;
14837             }
14838         }
14839       else
14840         {
14841           clib_warning ("parse error '%U'", format_unformat_error, i);
14842           return -99;
14843         }
14844
14845     }
14846
14847   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14848
14849   mp->is_add = is_add;
14850
14851   mp->entry.spd_id = ntohl (spd_id);
14852   mp->entry.priority = ntohl (priority);
14853   mp->entry.is_outbound = is_outbound;
14854
14855   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14856                sizeof (vl_api_address_t));
14857   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14858                sizeof (vl_api_address_t));
14859   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14860                sizeof (vl_api_address_t));
14861   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14862                sizeof (vl_api_address_t));
14863
14864   mp->entry.protocol = (u8) protocol;
14865   mp->entry.local_port_start = ntohs ((u16) lport_start);
14866   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14867   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14868   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14869   mp->entry.policy = (u8) policy;
14870   mp->entry.sa_id = ntohl (sa_id);
14871
14872   S (mp);
14873   W (ret);
14874   return ret;
14875 }
14876
14877 static int
14878 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14879 {
14880   unformat_input_t *i = vam->input;
14881   vl_api_ipsec_sad_entry_add_del_t *mp;
14882   u32 sad_id = 0, spi = 0;
14883   u8 *ck = 0, *ik = 0;
14884   u8 is_add = 1;
14885
14886   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14887   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14888   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14889   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14890   vl_api_address_t tun_src, tun_dst;
14891   int ret;
14892
14893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14894     {
14895       if (unformat (i, "del"))
14896         is_add = 0;
14897       else if (unformat (i, "sad_id %d", &sad_id))
14898         ;
14899       else if (unformat (i, "spi %d", &spi))
14900         ;
14901       else if (unformat (i, "esp"))
14902         protocol = IPSEC_API_PROTO_ESP;
14903       else
14904         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14905         {
14906           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14907           if (ADDRESS_IP6 == tun_src.af)
14908             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14909         }
14910       else
14911         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14912         {
14913           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14914           if (ADDRESS_IP6 == tun_src.af)
14915             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14916         }
14917       else
14918         if (unformat (i, "crypto_alg %U",
14919                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14920         ;
14921       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14922         ;
14923       else if (unformat (i, "integ_alg %U",
14924                          unformat_ipsec_api_integ_alg, &integ_alg))
14925         ;
14926       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14927         ;
14928       else
14929         {
14930           clib_warning ("parse error '%U'", format_unformat_error, i);
14931           return -99;
14932         }
14933
14934     }
14935
14936   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14937
14938   mp->is_add = is_add;
14939   mp->entry.sad_id = ntohl (sad_id);
14940   mp->entry.protocol = protocol;
14941   mp->entry.spi = ntohl (spi);
14942   mp->entry.flags = flags;
14943
14944   mp->entry.crypto_algorithm = crypto_alg;
14945   mp->entry.integrity_algorithm = integ_alg;
14946   mp->entry.crypto_key.length = vec_len (ck);
14947   mp->entry.integrity_key.length = vec_len (ik);
14948
14949   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14950     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14951
14952   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14953     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14954
14955   if (ck)
14956     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14957   if (ik)
14958     clib_memcpy (mp->entry.integrity_key.data, ik,
14959                  mp->entry.integrity_key.length);
14960
14961   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14962     {
14963       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14964                    sizeof (mp->entry.tunnel_src));
14965       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14966                    sizeof (mp->entry.tunnel_dst));
14967     }
14968
14969   S (mp);
14970   W (ret);
14971   return ret;
14972 }
14973
14974 static int
14975 api_ipsec_sa_set_key (vat_main_t * vam)
14976 {
14977   unformat_input_t *i = vam->input;
14978   vl_api_ipsec_sa_set_key_t *mp;
14979   u32 sa_id;
14980   u8 *ck = 0, *ik = 0;
14981   int ret;
14982
14983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (i, "sa_id %d", &sa_id))
14986         ;
14987       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14988         ;
14989       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14990         ;
14991       else
14992         {
14993           clib_warning ("parse error '%U'", format_unformat_error, i);
14994           return -99;
14995         }
14996     }
14997
14998   M (IPSEC_SA_SET_KEY, mp);
14999
15000   mp->sa_id = ntohl (sa_id);
15001   mp->crypto_key.length = vec_len (ck);
15002   mp->integrity_key.length = vec_len (ik);
15003
15004   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15005     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15006
15007   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15008     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15009
15010   if (ck)
15011     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15012   if (ik)
15013     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15014
15015   S (mp);
15016   W (ret);
15017   return ret;
15018 }
15019
15020 static int
15021 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15022 {
15023   unformat_input_t *i = vam->input;
15024   vl_api_ipsec_tunnel_if_add_del_t *mp;
15025   u32 local_spi = 0, remote_spi = 0;
15026   u32 crypto_alg = 0, integ_alg = 0;
15027   u8 *lck = NULL, *rck = NULL;
15028   u8 *lik = NULL, *rik = NULL;
15029   vl_api_address_t local_ip = { 0 };
15030   vl_api_address_t remote_ip = { 0 };
15031   f64 before = 0;
15032   u8 is_add = 1;
15033   u8 esn = 0;
15034   u8 anti_replay = 0;
15035   u8 renumber = 0;
15036   u32 instance = ~0;
15037   u32 count = 1, jj;
15038   int ret;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "del"))
15043         is_add = 0;
15044       else if (unformat (i, "esn"))
15045         esn = 1;
15046       else if (unformat (i, "anti-replay"))
15047         anti_replay = 1;
15048       else if (unformat (i, "count %d", &count))
15049         ;
15050       else if (unformat (i, "local_spi %d", &local_spi))
15051         ;
15052       else if (unformat (i, "remote_spi %d", &remote_spi))
15053         ;
15054       else
15055         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15056         ;
15057       else
15058         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15059         ;
15060       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15061         ;
15062       else
15063         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15064         ;
15065       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15066         ;
15067       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15068         ;
15069       else
15070         if (unformat
15071             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15072         {
15073           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15074             {
15075               errmsg ("unsupported crypto-alg: '%U'\n",
15076                       format_ipsec_crypto_alg, crypto_alg);
15077               return -99;
15078             }
15079         }
15080       else
15081         if (unformat
15082             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15083         {
15084           if (integ_alg >= IPSEC_INTEG_N_ALG)
15085             {
15086               errmsg ("unsupported integ-alg: '%U'\n",
15087                       format_ipsec_integ_alg, integ_alg);
15088               return -99;
15089             }
15090         }
15091       else if (unformat (i, "instance %u", &instance))
15092         renumber = 1;
15093       else
15094         {
15095           errmsg ("parse error '%U'\n", format_unformat_error, i);
15096           return -99;
15097         }
15098     }
15099
15100   if (count > 1)
15101     {
15102       /* Turn on async mode */
15103       vam->async_mode = 1;
15104       vam->async_errors = 0;
15105       before = vat_time_now (vam);
15106     }
15107
15108   for (jj = 0; jj < count; jj++)
15109     {
15110       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15111
15112       mp->is_add = is_add;
15113       mp->esn = esn;
15114       mp->anti_replay = anti_replay;
15115
15116       if (jj > 0)
15117         increment_vl_address (&remote_ip);
15118
15119       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15120       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15121
15122       mp->local_spi = htonl (local_spi + jj);
15123       mp->remote_spi = htonl (remote_spi + jj);
15124       mp->crypto_alg = (u8) crypto_alg;
15125
15126       mp->local_crypto_key_len = 0;
15127       if (lck)
15128         {
15129           mp->local_crypto_key_len = vec_len (lck);
15130           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15131             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15132           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15133         }
15134
15135       mp->remote_crypto_key_len = 0;
15136       if (rck)
15137         {
15138           mp->remote_crypto_key_len = vec_len (rck);
15139           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15140             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15141           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15142         }
15143
15144       mp->integ_alg = (u8) integ_alg;
15145
15146       mp->local_integ_key_len = 0;
15147       if (lik)
15148         {
15149           mp->local_integ_key_len = vec_len (lik);
15150           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15151             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15152           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15153         }
15154
15155       mp->remote_integ_key_len = 0;
15156       if (rik)
15157         {
15158           mp->remote_integ_key_len = vec_len (rik);
15159           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15160             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15161           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15162         }
15163
15164       if (renumber)
15165         {
15166           mp->renumber = renumber;
15167           mp->show_instance = ntohl (instance);
15168         }
15169       S (mp);
15170     }
15171
15172   /* When testing multiple add/del ops, use a control-ping to sync */
15173   if (count > 1)
15174     {
15175       vl_api_control_ping_t *mp_ping;
15176       f64 after;
15177       f64 timeout;
15178
15179       /* Shut off async mode */
15180       vam->async_mode = 0;
15181
15182       MPING (CONTROL_PING, mp_ping);
15183       S (mp_ping);
15184
15185       timeout = vat_time_now (vam) + 1.0;
15186       while (vat_time_now (vam) < timeout)
15187         if (vam->result_ready == 1)
15188           goto out;
15189       vam->retval = -99;
15190
15191     out:
15192       if (vam->retval == -99)
15193         errmsg ("timeout");
15194
15195       if (vam->async_errors > 0)
15196         {
15197           errmsg ("%d asynchronous errors", vam->async_errors);
15198           vam->retval = -98;
15199         }
15200       vam->async_errors = 0;
15201       after = vat_time_now (vam);
15202
15203       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15204       if (jj > 0)
15205         count = jj;
15206
15207       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15208              count, after - before, count / (after - before));
15209     }
15210   else
15211     {
15212       /* Wait for a reply... */
15213       W (ret);
15214       return ret;
15215     }
15216
15217   return ret;
15218 }
15219
15220 static void
15221 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15222 {
15223   vat_main_t *vam = &vat_main;
15224
15225   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15226          "crypto_key %U integ_alg %u integ_key %U flags %x "
15227          "tunnel_src_addr %U tunnel_dst_addr %U "
15228          "salt %u seq_outbound %lu last_seq_inbound %lu "
15229          "replay_window %lu\n",
15230          ntohl (mp->entry.sad_id),
15231          ntohl (mp->sw_if_index),
15232          ntohl (mp->entry.spi),
15233          ntohl (mp->entry.protocol),
15234          ntohl (mp->entry.crypto_algorithm),
15235          format_hex_bytes, mp->entry.crypto_key.data,
15236          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15237          format_hex_bytes, mp->entry.integrity_key.data,
15238          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15239          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15240          &mp->entry.tunnel_dst, ntohl (mp->salt),
15241          clib_net_to_host_u64 (mp->seq_outbound),
15242          clib_net_to_host_u64 (mp->last_seq_inbound),
15243          clib_net_to_host_u64 (mp->replay_window));
15244 }
15245
15246 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15247 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15248
15249 static void vl_api_ipsec_sa_details_t_handler_json
15250   (vl_api_ipsec_sa_details_t * mp)
15251 {
15252   vat_main_t *vam = &vat_main;
15253   vat_json_node_t *node = NULL;
15254   vl_api_ipsec_sad_flags_t flags;
15255
15256   if (VAT_JSON_ARRAY != vam->json_tree.type)
15257     {
15258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15259       vat_json_init_array (&vam->json_tree);
15260     }
15261   node = vat_json_array_add (&vam->json_tree);
15262
15263   vat_json_init_object (node);
15264   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15265   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15266   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15267   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15268   vat_json_object_add_uint (node, "crypto_alg",
15269                             ntohl (mp->entry.crypto_algorithm));
15270   vat_json_object_add_uint (node, "integ_alg",
15271                             ntohl (mp->entry.integrity_algorithm));
15272   flags = ntohl (mp->entry.flags);
15273   vat_json_object_add_uint (node, "use_esn",
15274                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15275   vat_json_object_add_uint (node, "use_anti_replay",
15276                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15277   vat_json_object_add_uint (node, "is_tunnel",
15278                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15279   vat_json_object_add_uint (node, "is_tunnel_ip6",
15280                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15281   vat_json_object_add_uint (node, "udp_encap",
15282                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15283   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15284                              mp->entry.crypto_key.length);
15285   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15286                              mp->entry.integrity_key.length);
15287   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15288   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15289   vat_json_object_add_uint (node, "replay_window",
15290                             clib_net_to_host_u64 (mp->replay_window));
15291 }
15292
15293 static int
15294 api_ipsec_sa_dump (vat_main_t * vam)
15295 {
15296   unformat_input_t *i = vam->input;
15297   vl_api_ipsec_sa_dump_t *mp;
15298   vl_api_control_ping_t *mp_ping;
15299   u32 sa_id = ~0;
15300   int ret;
15301
15302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15303     {
15304       if (unformat (i, "sa_id %d", &sa_id))
15305         ;
15306       else
15307         {
15308           clib_warning ("parse error '%U'", format_unformat_error, i);
15309           return -99;
15310         }
15311     }
15312
15313   M (IPSEC_SA_DUMP, mp);
15314
15315   mp->sa_id = ntohl (sa_id);
15316
15317   S (mp);
15318
15319   /* Use a control ping for synchronization */
15320   M (CONTROL_PING, mp_ping);
15321   S (mp_ping);
15322
15323   W (ret);
15324   return ret;
15325 }
15326
15327 static int
15328 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15329 {
15330   unformat_input_t *i = vam->input;
15331   vl_api_ipsec_tunnel_if_set_key_t *mp;
15332   u32 sw_if_index = ~0;
15333   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15334   u8 *key = 0;
15335   u32 alg = ~0;
15336   int ret;
15337
15338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15339     {
15340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15341         ;
15342       else
15343         if (unformat
15344             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15345         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15346       else
15347         if (unformat
15348             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15349         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15350       else
15351         if (unformat
15352             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15353         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15354       else
15355         if (unformat
15356             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15357         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15358       else if (unformat (i, "%U", unformat_hex_string, &key))
15359         ;
15360       else
15361         {
15362           clib_warning ("parse error '%U'", format_unformat_error, i);
15363           return -99;
15364         }
15365     }
15366
15367   if (sw_if_index == ~0)
15368     {
15369       errmsg ("interface must be specified");
15370       return -99;
15371     }
15372
15373   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15374     {
15375       errmsg ("key type must be specified");
15376       return -99;
15377     }
15378
15379   if (alg == ~0)
15380     {
15381       errmsg ("algorithm must be specified");
15382       return -99;
15383     }
15384
15385   if (vec_len (key) == 0)
15386     {
15387       errmsg ("key must be specified");
15388       return -99;
15389     }
15390
15391   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15392
15393   mp->sw_if_index = htonl (sw_if_index);
15394   mp->alg = alg;
15395   mp->key_type = key_type;
15396   mp->key_len = vec_len (key);
15397   clib_memcpy (mp->key, key, vec_len (key));
15398
15399   S (mp);
15400   W (ret);
15401
15402   return ret;
15403 }
15404
15405 static int
15406 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15407 {
15408   unformat_input_t *i = vam->input;
15409   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15410   u32 sw_if_index = ~0;
15411   u32 sa_id = ~0;
15412   u8 is_outbound = (u8) ~ 0;
15413   int ret;
15414
15415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15418         ;
15419       else if (unformat (i, "sa_id %d", &sa_id))
15420         ;
15421       else if (unformat (i, "outbound"))
15422         is_outbound = 1;
15423       else if (unformat (i, "inbound"))
15424         is_outbound = 0;
15425       else
15426         {
15427           clib_warning ("parse error '%U'", format_unformat_error, i);
15428           return -99;
15429         }
15430     }
15431
15432   if (sw_if_index == ~0)
15433     {
15434       errmsg ("interface must be specified");
15435       return -99;
15436     }
15437
15438   if (sa_id == ~0)
15439     {
15440       errmsg ("SA ID must be specified");
15441       return -99;
15442     }
15443
15444   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15445
15446   mp->sw_if_index = htonl (sw_if_index);
15447   mp->sa_id = htonl (sa_id);
15448   mp->is_outbound = is_outbound;
15449
15450   S (mp);
15451   W (ret);
15452
15453   return ret;
15454 }
15455
15456 static int
15457 api_get_first_msg_id (vat_main_t * vam)
15458 {
15459   vl_api_get_first_msg_id_t *mp;
15460   unformat_input_t *i = vam->input;
15461   u8 *name;
15462   u8 name_set = 0;
15463   int ret;
15464
15465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15466     {
15467       if (unformat (i, "client %s", &name))
15468         name_set = 1;
15469       else
15470         break;
15471     }
15472
15473   if (name_set == 0)
15474     {
15475       errmsg ("missing client name");
15476       return -99;
15477     }
15478   vec_add1 (name, 0);
15479
15480   if (vec_len (name) > 63)
15481     {
15482       errmsg ("client name too long");
15483       return -99;
15484     }
15485
15486   M (GET_FIRST_MSG_ID, mp);
15487   clib_memcpy (mp->name, name, vec_len (name));
15488   S (mp);
15489   W (ret);
15490   return ret;
15491 }
15492
15493 static int
15494 api_cop_interface_enable_disable (vat_main_t * vam)
15495 {
15496   unformat_input_t *line_input = vam->input;
15497   vl_api_cop_interface_enable_disable_t *mp;
15498   u32 sw_if_index = ~0;
15499   u8 enable_disable = 1;
15500   int ret;
15501
15502   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15503     {
15504       if (unformat (line_input, "disable"))
15505         enable_disable = 0;
15506       if (unformat (line_input, "enable"))
15507         enable_disable = 1;
15508       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15509                          vam, &sw_if_index))
15510         ;
15511       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15512         ;
15513       else
15514         break;
15515     }
15516
15517   if (sw_if_index == ~0)
15518     {
15519       errmsg ("missing interface name or sw_if_index");
15520       return -99;
15521     }
15522
15523   /* Construct the API message */
15524   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15525   mp->sw_if_index = ntohl (sw_if_index);
15526   mp->enable_disable = enable_disable;
15527
15528   /* send it... */
15529   S (mp);
15530   /* Wait for the reply */
15531   W (ret);
15532   return ret;
15533 }
15534
15535 static int
15536 api_cop_whitelist_enable_disable (vat_main_t * vam)
15537 {
15538   unformat_input_t *line_input = vam->input;
15539   vl_api_cop_whitelist_enable_disable_t *mp;
15540   u32 sw_if_index = ~0;
15541   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15542   u32 fib_id = 0;
15543   int ret;
15544
15545   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15546     {
15547       if (unformat (line_input, "ip4"))
15548         ip4 = 1;
15549       else if (unformat (line_input, "ip6"))
15550         ip6 = 1;
15551       else if (unformat (line_input, "default"))
15552         default_cop = 1;
15553       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15554                          vam, &sw_if_index))
15555         ;
15556       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15557         ;
15558       else if (unformat (line_input, "fib-id %d", &fib_id))
15559         ;
15560       else
15561         break;
15562     }
15563
15564   if (sw_if_index == ~0)
15565     {
15566       errmsg ("missing interface name or sw_if_index");
15567       return -99;
15568     }
15569
15570   /* Construct the API message */
15571   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15572   mp->sw_if_index = ntohl (sw_if_index);
15573   mp->fib_id = ntohl (fib_id);
15574   mp->ip4 = ip4;
15575   mp->ip6 = ip6;
15576   mp->default_cop = default_cop;
15577
15578   /* send it... */
15579   S (mp);
15580   /* Wait for the reply */
15581   W (ret);
15582   return ret;
15583 }
15584
15585 static int
15586 api_get_node_graph (vat_main_t * vam)
15587 {
15588   vl_api_get_node_graph_t *mp;
15589   int ret;
15590
15591   M (GET_NODE_GRAPH, mp);
15592
15593   /* send it... */
15594   S (mp);
15595   /* Wait for the reply */
15596   W (ret);
15597   return ret;
15598 }
15599
15600 /* *INDENT-OFF* */
15601 /** Used for parsing LISP eids */
15602 typedef CLIB_PACKED(struct{
15603   u8 addr[16];   /**< eid address */
15604   u32 len;       /**< prefix length if IP */
15605   u8 type;      /**< type of eid */
15606 }) lisp_eid_vat_t;
15607 /* *INDENT-ON* */
15608
15609 static uword
15610 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15611 {
15612   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15613
15614   clib_memset (a, 0, sizeof (a[0]));
15615
15616   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15617     {
15618       a->type = 0;              /* ipv4 type */
15619     }
15620   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15621     {
15622       a->type = 1;              /* ipv6 type */
15623     }
15624   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15625     {
15626       a->type = 2;              /* mac type */
15627     }
15628   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15629     {
15630       a->type = 3;              /* NSH type */
15631       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15632       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15633     }
15634   else
15635     {
15636       return 0;
15637     }
15638
15639   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15640     {
15641       return 0;
15642     }
15643
15644   return 1;
15645 }
15646
15647 static int
15648 lisp_eid_size_vat (u8 type)
15649 {
15650   switch (type)
15651     {
15652     case 0:
15653       return 4;
15654     case 1:
15655       return 16;
15656     case 2:
15657       return 6;
15658     case 3:
15659       return 5;
15660     }
15661   return 0;
15662 }
15663
15664 static void
15665 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15666 {
15667   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15668 }
15669
15670 static int
15671 api_one_add_del_locator_set (vat_main_t * vam)
15672 {
15673   unformat_input_t *input = vam->input;
15674   vl_api_one_add_del_locator_set_t *mp;
15675   u8 is_add = 1;
15676   u8 *locator_set_name = NULL;
15677   u8 locator_set_name_set = 0;
15678   vl_api_local_locator_t locator, *locators = 0;
15679   u32 sw_if_index, priority, weight;
15680   u32 data_len = 0;
15681
15682   int ret;
15683   /* Parse args required to build the message */
15684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15685     {
15686       if (unformat (input, "del"))
15687         {
15688           is_add = 0;
15689         }
15690       else if (unformat (input, "locator-set %s", &locator_set_name))
15691         {
15692           locator_set_name_set = 1;
15693         }
15694       else if (unformat (input, "sw_if_index %u p %u w %u",
15695                          &sw_if_index, &priority, &weight))
15696         {
15697           locator.sw_if_index = htonl (sw_if_index);
15698           locator.priority = priority;
15699           locator.weight = weight;
15700           vec_add1 (locators, locator);
15701         }
15702       else
15703         if (unformat
15704             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15705              &sw_if_index, &priority, &weight))
15706         {
15707           locator.sw_if_index = htonl (sw_if_index);
15708           locator.priority = priority;
15709           locator.weight = weight;
15710           vec_add1 (locators, locator);
15711         }
15712       else
15713         break;
15714     }
15715
15716   if (locator_set_name_set == 0)
15717     {
15718       errmsg ("missing locator-set name");
15719       vec_free (locators);
15720       return -99;
15721     }
15722
15723   if (vec_len (locator_set_name) > 64)
15724     {
15725       errmsg ("locator-set name too long");
15726       vec_free (locator_set_name);
15727       vec_free (locators);
15728       return -99;
15729     }
15730   vec_add1 (locator_set_name, 0);
15731
15732   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15733
15734   /* Construct the API message */
15735   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15736
15737   mp->is_add = is_add;
15738   clib_memcpy (mp->locator_set_name, locator_set_name,
15739                vec_len (locator_set_name));
15740   vec_free (locator_set_name);
15741
15742   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15743   if (locators)
15744     clib_memcpy (mp->locators, locators, data_len);
15745   vec_free (locators);
15746
15747   /* send it... */
15748   S (mp);
15749
15750   /* Wait for a reply... */
15751   W (ret);
15752   return ret;
15753 }
15754
15755 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15756
15757 static int
15758 api_one_add_del_locator (vat_main_t * vam)
15759 {
15760   unformat_input_t *input = vam->input;
15761   vl_api_one_add_del_locator_t *mp;
15762   u32 tmp_if_index = ~0;
15763   u32 sw_if_index = ~0;
15764   u8 sw_if_index_set = 0;
15765   u8 sw_if_index_if_name_set = 0;
15766   u32 priority = ~0;
15767   u8 priority_set = 0;
15768   u32 weight = ~0;
15769   u8 weight_set = 0;
15770   u8 is_add = 1;
15771   u8 *locator_set_name = NULL;
15772   u8 locator_set_name_set = 0;
15773   int ret;
15774
15775   /* Parse args required to build the message */
15776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15777     {
15778       if (unformat (input, "del"))
15779         {
15780           is_add = 0;
15781         }
15782       else if (unformat (input, "locator-set %s", &locator_set_name))
15783         {
15784           locator_set_name_set = 1;
15785         }
15786       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15787                          &tmp_if_index))
15788         {
15789           sw_if_index_if_name_set = 1;
15790           sw_if_index = tmp_if_index;
15791         }
15792       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15793         {
15794           sw_if_index_set = 1;
15795           sw_if_index = tmp_if_index;
15796         }
15797       else if (unformat (input, "p %d", &priority))
15798         {
15799           priority_set = 1;
15800         }
15801       else if (unformat (input, "w %d", &weight))
15802         {
15803           weight_set = 1;
15804         }
15805       else
15806         break;
15807     }
15808
15809   if (locator_set_name_set == 0)
15810     {
15811       errmsg ("missing locator-set name");
15812       return -99;
15813     }
15814
15815   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15816     {
15817       errmsg ("missing sw_if_index");
15818       vec_free (locator_set_name);
15819       return -99;
15820     }
15821
15822   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15823     {
15824       errmsg ("cannot use both params interface name and sw_if_index");
15825       vec_free (locator_set_name);
15826       return -99;
15827     }
15828
15829   if (priority_set == 0)
15830     {
15831       errmsg ("missing locator-set priority");
15832       vec_free (locator_set_name);
15833       return -99;
15834     }
15835
15836   if (weight_set == 0)
15837     {
15838       errmsg ("missing locator-set weight");
15839       vec_free (locator_set_name);
15840       return -99;
15841     }
15842
15843   if (vec_len (locator_set_name) > 64)
15844     {
15845       errmsg ("locator-set name too long");
15846       vec_free (locator_set_name);
15847       return -99;
15848     }
15849   vec_add1 (locator_set_name, 0);
15850
15851   /* Construct the API message */
15852   M (ONE_ADD_DEL_LOCATOR, mp);
15853
15854   mp->is_add = is_add;
15855   mp->sw_if_index = ntohl (sw_if_index);
15856   mp->priority = priority;
15857   mp->weight = weight;
15858   clib_memcpy (mp->locator_set_name, locator_set_name,
15859                vec_len (locator_set_name));
15860   vec_free (locator_set_name);
15861
15862   /* send it... */
15863   S (mp);
15864
15865   /* Wait for a reply... */
15866   W (ret);
15867   return ret;
15868 }
15869
15870 #define api_lisp_add_del_locator api_one_add_del_locator
15871
15872 uword
15873 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15874 {
15875   u32 *key_id = va_arg (*args, u32 *);
15876   u8 *s = 0;
15877
15878   if (unformat (input, "%s", &s))
15879     {
15880       if (!strcmp ((char *) s, "sha1"))
15881         key_id[0] = HMAC_SHA_1_96;
15882       else if (!strcmp ((char *) s, "sha256"))
15883         key_id[0] = HMAC_SHA_256_128;
15884       else
15885         {
15886           clib_warning ("invalid key_id: '%s'", s);
15887           key_id[0] = HMAC_NO_KEY;
15888         }
15889     }
15890   else
15891     return 0;
15892
15893   vec_free (s);
15894   return 1;
15895 }
15896
15897 static int
15898 api_one_add_del_local_eid (vat_main_t * vam)
15899 {
15900   unformat_input_t *input = vam->input;
15901   vl_api_one_add_del_local_eid_t *mp;
15902   u8 is_add = 1;
15903   u8 eid_set = 0;
15904   lisp_eid_vat_t _eid, *eid = &_eid;
15905   u8 *locator_set_name = 0;
15906   u8 locator_set_name_set = 0;
15907   u32 vni = 0;
15908   u16 key_id = 0;
15909   u8 *key = 0;
15910   int ret;
15911
15912   /* Parse args required to build the message */
15913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15914     {
15915       if (unformat (input, "del"))
15916         {
15917           is_add = 0;
15918         }
15919       else if (unformat (input, "vni %d", &vni))
15920         {
15921           ;
15922         }
15923       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15924         {
15925           eid_set = 1;
15926         }
15927       else if (unformat (input, "locator-set %s", &locator_set_name))
15928         {
15929           locator_set_name_set = 1;
15930         }
15931       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15932         ;
15933       else if (unformat (input, "secret-key %_%v%_", &key))
15934         ;
15935       else
15936         break;
15937     }
15938
15939   if (locator_set_name_set == 0)
15940     {
15941       errmsg ("missing locator-set name");
15942       return -99;
15943     }
15944
15945   if (0 == eid_set)
15946     {
15947       errmsg ("EID address not set!");
15948       vec_free (locator_set_name);
15949       return -99;
15950     }
15951
15952   if (key && (0 == key_id))
15953     {
15954       errmsg ("invalid key_id!");
15955       return -99;
15956     }
15957
15958   if (vec_len (key) > 64)
15959     {
15960       errmsg ("key too long");
15961       vec_free (key);
15962       return -99;
15963     }
15964
15965   if (vec_len (locator_set_name) > 64)
15966     {
15967       errmsg ("locator-set name too long");
15968       vec_free (locator_set_name);
15969       return -99;
15970     }
15971   vec_add1 (locator_set_name, 0);
15972
15973   /* Construct the API message */
15974   M (ONE_ADD_DEL_LOCAL_EID, mp);
15975
15976   mp->is_add = is_add;
15977   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15978   mp->eid_type = eid->type;
15979   mp->prefix_len = eid->len;
15980   mp->vni = clib_host_to_net_u32 (vni);
15981   mp->key_id = clib_host_to_net_u16 (key_id);
15982   clib_memcpy (mp->locator_set_name, locator_set_name,
15983                vec_len (locator_set_name));
15984   clib_memcpy (mp->key, key, vec_len (key));
15985
15986   vec_free (locator_set_name);
15987   vec_free (key);
15988
15989   /* send it... */
15990   S (mp);
15991
15992   /* Wait for a reply... */
15993   W (ret);
15994   return ret;
15995 }
15996
15997 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15998
15999 static int
16000 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16001 {
16002   u32 dp_table = 0, vni = 0;;
16003   unformat_input_t *input = vam->input;
16004   vl_api_gpe_add_del_fwd_entry_t *mp;
16005   u8 is_add = 1;
16006   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16007   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16008   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16009   u32 action = ~0, w;
16010   ip4_address_t rmt_rloc4, lcl_rloc4;
16011   ip6_address_t rmt_rloc6, lcl_rloc6;
16012   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16013   int ret;
16014
16015   clib_memset (&rloc, 0, sizeof (rloc));
16016
16017   /* Parse args required to build the message */
16018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16019     {
16020       if (unformat (input, "del"))
16021         is_add = 0;
16022       else if (unformat (input, "add"))
16023         is_add = 1;
16024       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16025         {
16026           rmt_eid_set = 1;
16027         }
16028       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16029         {
16030           lcl_eid_set = 1;
16031         }
16032       else if (unformat (input, "vrf %d", &dp_table))
16033         ;
16034       else if (unformat (input, "bd %d", &dp_table))
16035         ;
16036       else if (unformat (input, "vni %d", &vni))
16037         ;
16038       else if (unformat (input, "w %d", &w))
16039         {
16040           if (!curr_rloc)
16041             {
16042               errmsg ("No RLOC configured for setting priority/weight!");
16043               return -99;
16044             }
16045           curr_rloc->weight = w;
16046         }
16047       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16048                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16049         {
16050           rloc.is_ip4 = 1;
16051
16052           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16053           rloc.weight = 0;
16054           vec_add1 (lcl_locs, rloc);
16055
16056           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16057           vec_add1 (rmt_locs, rloc);
16058           /* weight saved in rmt loc */
16059           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16060         }
16061       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16062                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16063         {
16064           rloc.is_ip4 = 0;
16065           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16066           rloc.weight = 0;
16067           vec_add1 (lcl_locs, rloc);
16068
16069           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16070           vec_add1 (rmt_locs, rloc);
16071           /* weight saved in rmt loc */
16072           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16073         }
16074       else if (unformat (input, "action %d", &action))
16075         {
16076           ;
16077         }
16078       else
16079         {
16080           clib_warning ("parse error '%U'", format_unformat_error, input);
16081           return -99;
16082         }
16083     }
16084
16085   if (!rmt_eid_set)
16086     {
16087       errmsg ("remote eid addresses not set");
16088       return -99;
16089     }
16090
16091   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16092     {
16093       errmsg ("eid types don't match");
16094       return -99;
16095     }
16096
16097   if (0 == rmt_locs && (u32) ~ 0 == action)
16098     {
16099       errmsg ("action not set for negative mapping");
16100       return -99;
16101     }
16102
16103   /* Construct the API message */
16104   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16105       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16106
16107   mp->is_add = is_add;
16108   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16109   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16110   mp->eid_type = rmt_eid->type;
16111   mp->dp_table = clib_host_to_net_u32 (dp_table);
16112   mp->vni = clib_host_to_net_u32 (vni);
16113   mp->rmt_len = rmt_eid->len;
16114   mp->lcl_len = lcl_eid->len;
16115   mp->action = action;
16116
16117   if (0 != rmt_locs && 0 != lcl_locs)
16118     {
16119       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16120       clib_memcpy (mp->locs, lcl_locs,
16121                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16122
16123       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16124       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16125                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16126     }
16127   vec_free (lcl_locs);
16128   vec_free (rmt_locs);
16129
16130   /* send it... */
16131   S (mp);
16132
16133   /* Wait for a reply... */
16134   W (ret);
16135   return ret;
16136 }
16137
16138 static int
16139 api_one_add_del_map_server (vat_main_t * vam)
16140 {
16141   unformat_input_t *input = vam->input;
16142   vl_api_one_add_del_map_server_t *mp;
16143   u8 is_add = 1;
16144   u8 ipv4_set = 0;
16145   u8 ipv6_set = 0;
16146   ip4_address_t ipv4;
16147   ip6_address_t ipv6;
16148   int ret;
16149
16150   /* Parse args required to build the message */
16151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16152     {
16153       if (unformat (input, "del"))
16154         {
16155           is_add = 0;
16156         }
16157       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16158         {
16159           ipv4_set = 1;
16160         }
16161       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16162         {
16163           ipv6_set = 1;
16164         }
16165       else
16166         break;
16167     }
16168
16169   if (ipv4_set && ipv6_set)
16170     {
16171       errmsg ("both eid v4 and v6 addresses set");
16172       return -99;
16173     }
16174
16175   if (!ipv4_set && !ipv6_set)
16176     {
16177       errmsg ("eid addresses not set");
16178       return -99;
16179     }
16180
16181   /* Construct the API message */
16182   M (ONE_ADD_DEL_MAP_SERVER, mp);
16183
16184   mp->is_add = is_add;
16185   if (ipv6_set)
16186     {
16187       mp->is_ipv6 = 1;
16188       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16189     }
16190   else
16191     {
16192       mp->is_ipv6 = 0;
16193       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16194     }
16195
16196   /* send it... */
16197   S (mp);
16198
16199   /* Wait for a reply... */
16200   W (ret);
16201   return ret;
16202 }
16203
16204 #define api_lisp_add_del_map_server api_one_add_del_map_server
16205
16206 static int
16207 api_one_add_del_map_resolver (vat_main_t * vam)
16208 {
16209   unformat_input_t *input = vam->input;
16210   vl_api_one_add_del_map_resolver_t *mp;
16211   u8 is_add = 1;
16212   u8 ipv4_set = 0;
16213   u8 ipv6_set = 0;
16214   ip4_address_t ipv4;
16215   ip6_address_t ipv6;
16216   int ret;
16217
16218   /* Parse args required to build the message */
16219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16220     {
16221       if (unformat (input, "del"))
16222         {
16223           is_add = 0;
16224         }
16225       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16226         {
16227           ipv4_set = 1;
16228         }
16229       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16230         {
16231           ipv6_set = 1;
16232         }
16233       else
16234         break;
16235     }
16236
16237   if (ipv4_set && ipv6_set)
16238     {
16239       errmsg ("both eid v4 and v6 addresses set");
16240       return -99;
16241     }
16242
16243   if (!ipv4_set && !ipv6_set)
16244     {
16245       errmsg ("eid addresses not set");
16246       return -99;
16247     }
16248
16249   /* Construct the API message */
16250   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16251
16252   mp->is_add = is_add;
16253   if (ipv6_set)
16254     {
16255       mp->is_ipv6 = 1;
16256       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16257     }
16258   else
16259     {
16260       mp->is_ipv6 = 0;
16261       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16262     }
16263
16264   /* send it... */
16265   S (mp);
16266
16267   /* Wait for a reply... */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16273
16274 static int
16275 api_lisp_gpe_enable_disable (vat_main_t * vam)
16276 {
16277   unformat_input_t *input = vam->input;
16278   vl_api_gpe_enable_disable_t *mp;
16279   u8 is_set = 0;
16280   u8 is_en = 1;
16281   int ret;
16282
16283   /* Parse args required to build the message */
16284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16285     {
16286       if (unformat (input, "enable"))
16287         {
16288           is_set = 1;
16289           is_en = 1;
16290         }
16291       else if (unformat (input, "disable"))
16292         {
16293           is_set = 1;
16294           is_en = 0;
16295         }
16296       else
16297         break;
16298     }
16299
16300   if (is_set == 0)
16301     {
16302       errmsg ("Value not set");
16303       return -99;
16304     }
16305
16306   /* Construct the API message */
16307   M (GPE_ENABLE_DISABLE, mp);
16308
16309   mp->is_en = is_en;
16310
16311   /* send it... */
16312   S (mp);
16313
16314   /* Wait for a reply... */
16315   W (ret);
16316   return ret;
16317 }
16318
16319 static int
16320 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16321 {
16322   unformat_input_t *input = vam->input;
16323   vl_api_one_rloc_probe_enable_disable_t *mp;
16324   u8 is_set = 0;
16325   u8 is_en = 0;
16326   int ret;
16327
16328   /* Parse args required to build the message */
16329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16330     {
16331       if (unformat (input, "enable"))
16332         {
16333           is_set = 1;
16334           is_en = 1;
16335         }
16336       else if (unformat (input, "disable"))
16337         is_set = 1;
16338       else
16339         break;
16340     }
16341
16342   if (!is_set)
16343     {
16344       errmsg ("Value not set");
16345       return -99;
16346     }
16347
16348   /* Construct the API message */
16349   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16350
16351   mp->is_enabled = is_en;
16352
16353   /* send it... */
16354   S (mp);
16355
16356   /* Wait for a reply... */
16357   W (ret);
16358   return ret;
16359 }
16360
16361 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16362
16363 static int
16364 api_one_map_register_enable_disable (vat_main_t * vam)
16365 {
16366   unformat_input_t *input = vam->input;
16367   vl_api_one_map_register_enable_disable_t *mp;
16368   u8 is_set = 0;
16369   u8 is_en = 0;
16370   int ret;
16371
16372   /* Parse args required to build the message */
16373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (input, "enable"))
16376         {
16377           is_set = 1;
16378           is_en = 1;
16379         }
16380       else if (unformat (input, "disable"))
16381         is_set = 1;
16382       else
16383         break;
16384     }
16385
16386   if (!is_set)
16387     {
16388       errmsg ("Value not set");
16389       return -99;
16390     }
16391
16392   /* Construct the API message */
16393   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16394
16395   mp->is_enabled = is_en;
16396
16397   /* send it... */
16398   S (mp);
16399
16400   /* Wait for a reply... */
16401   W (ret);
16402   return ret;
16403 }
16404
16405 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16406
16407 static int
16408 api_one_enable_disable (vat_main_t * vam)
16409 {
16410   unformat_input_t *input = vam->input;
16411   vl_api_one_enable_disable_t *mp;
16412   u8 is_set = 0;
16413   u8 is_en = 0;
16414   int ret;
16415
16416   /* Parse args required to build the message */
16417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16418     {
16419       if (unformat (input, "enable"))
16420         {
16421           is_set = 1;
16422           is_en = 1;
16423         }
16424       else if (unformat (input, "disable"))
16425         {
16426           is_set = 1;
16427         }
16428       else
16429         break;
16430     }
16431
16432   if (!is_set)
16433     {
16434       errmsg ("Value not set");
16435       return -99;
16436     }
16437
16438   /* Construct the API message */
16439   M (ONE_ENABLE_DISABLE, mp);
16440
16441   mp->is_en = is_en;
16442
16443   /* send it... */
16444   S (mp);
16445
16446   /* Wait for a reply... */
16447   W (ret);
16448   return ret;
16449 }
16450
16451 #define api_lisp_enable_disable api_one_enable_disable
16452
16453 static int
16454 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16455 {
16456   unformat_input_t *input = vam->input;
16457   vl_api_one_enable_disable_xtr_mode_t *mp;
16458   u8 is_set = 0;
16459   u8 is_en = 0;
16460   int ret;
16461
16462   /* Parse args required to build the message */
16463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16464     {
16465       if (unformat (input, "enable"))
16466         {
16467           is_set = 1;
16468           is_en = 1;
16469         }
16470       else if (unformat (input, "disable"))
16471         {
16472           is_set = 1;
16473         }
16474       else
16475         break;
16476     }
16477
16478   if (!is_set)
16479     {
16480       errmsg ("Value not set");
16481       return -99;
16482     }
16483
16484   /* Construct the API message */
16485   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16486
16487   mp->is_en = is_en;
16488
16489   /* send it... */
16490   S (mp);
16491
16492   /* Wait for a reply... */
16493   W (ret);
16494   return ret;
16495 }
16496
16497 static int
16498 api_one_show_xtr_mode (vat_main_t * vam)
16499 {
16500   vl_api_one_show_xtr_mode_t *mp;
16501   int ret;
16502
16503   /* Construct the API message */
16504   M (ONE_SHOW_XTR_MODE, mp);
16505
16506   /* send it... */
16507   S (mp);
16508
16509   /* Wait for a reply... */
16510   W (ret);
16511   return ret;
16512 }
16513
16514 static int
16515 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16516 {
16517   unformat_input_t *input = vam->input;
16518   vl_api_one_enable_disable_pitr_mode_t *mp;
16519   u8 is_set = 0;
16520   u8 is_en = 0;
16521   int ret;
16522
16523   /* Parse args required to build the message */
16524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16525     {
16526       if (unformat (input, "enable"))
16527         {
16528           is_set = 1;
16529           is_en = 1;
16530         }
16531       else if (unformat (input, "disable"))
16532         {
16533           is_set = 1;
16534         }
16535       else
16536         break;
16537     }
16538
16539   if (!is_set)
16540     {
16541       errmsg ("Value not set");
16542       return -99;
16543     }
16544
16545   /* Construct the API message */
16546   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16547
16548   mp->is_en = is_en;
16549
16550   /* send it... */
16551   S (mp);
16552
16553   /* Wait for a reply... */
16554   W (ret);
16555   return ret;
16556 }
16557
16558 static int
16559 api_one_show_pitr_mode (vat_main_t * vam)
16560 {
16561   vl_api_one_show_pitr_mode_t *mp;
16562   int ret;
16563
16564   /* Construct the API message */
16565   M (ONE_SHOW_PITR_MODE, mp);
16566
16567   /* send it... */
16568   S (mp);
16569
16570   /* Wait for a reply... */
16571   W (ret);
16572   return ret;
16573 }
16574
16575 static int
16576 api_one_enable_disable_petr_mode (vat_main_t * vam)
16577 {
16578   unformat_input_t *input = vam->input;
16579   vl_api_one_enable_disable_petr_mode_t *mp;
16580   u8 is_set = 0;
16581   u8 is_en = 0;
16582   int ret;
16583
16584   /* Parse args required to build the message */
16585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16586     {
16587       if (unformat (input, "enable"))
16588         {
16589           is_set = 1;
16590           is_en = 1;
16591         }
16592       else if (unformat (input, "disable"))
16593         {
16594           is_set = 1;
16595         }
16596       else
16597         break;
16598     }
16599
16600   if (!is_set)
16601     {
16602       errmsg ("Value not set");
16603       return -99;
16604     }
16605
16606   /* Construct the API message */
16607   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16608
16609   mp->is_en = is_en;
16610
16611   /* send it... */
16612   S (mp);
16613
16614   /* Wait for a reply... */
16615   W (ret);
16616   return ret;
16617 }
16618
16619 static int
16620 api_one_show_petr_mode (vat_main_t * vam)
16621 {
16622   vl_api_one_show_petr_mode_t *mp;
16623   int ret;
16624
16625   /* Construct the API message */
16626   M (ONE_SHOW_PETR_MODE, mp);
16627
16628   /* send it... */
16629   S (mp);
16630
16631   /* Wait for a reply... */
16632   W (ret);
16633   return ret;
16634 }
16635
16636 static int
16637 api_show_one_map_register_state (vat_main_t * vam)
16638 {
16639   vl_api_show_one_map_register_state_t *mp;
16640   int ret;
16641
16642   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16643
16644   /* send */
16645   S (mp);
16646
16647   /* wait for reply */
16648   W (ret);
16649   return ret;
16650 }
16651
16652 #define api_show_lisp_map_register_state api_show_one_map_register_state
16653
16654 static int
16655 api_show_one_rloc_probe_state (vat_main_t * vam)
16656 {
16657   vl_api_show_one_rloc_probe_state_t *mp;
16658   int ret;
16659
16660   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16661
16662   /* send */
16663   S (mp);
16664
16665   /* wait for reply */
16666   W (ret);
16667   return ret;
16668 }
16669
16670 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16671
16672 static int
16673 api_one_add_del_ndp_entry (vat_main_t * vam)
16674 {
16675   vl_api_one_add_del_ndp_entry_t *mp;
16676   unformat_input_t *input = vam->input;
16677   u8 is_add = 1;
16678   u8 mac_set = 0;
16679   u8 bd_set = 0;
16680   u8 ip_set = 0;
16681   u8 mac[6] = { 0, };
16682   u8 ip6[16] = { 0, };
16683   u32 bd = ~0;
16684   int ret;
16685
16686   /* Parse args required to build the message */
16687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16688     {
16689       if (unformat (input, "del"))
16690         is_add = 0;
16691       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16692         mac_set = 1;
16693       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16694         ip_set = 1;
16695       else if (unformat (input, "bd %d", &bd))
16696         bd_set = 1;
16697       else
16698         {
16699           errmsg ("parse error '%U'", format_unformat_error, input);
16700           return -99;
16701         }
16702     }
16703
16704   if (!bd_set || !ip_set || (!mac_set && is_add))
16705     {
16706       errmsg ("Missing BD, IP or MAC!");
16707       return -99;
16708     }
16709
16710   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16711   mp->is_add = is_add;
16712   clib_memcpy (mp->mac, mac, 6);
16713   mp->bd = clib_host_to_net_u32 (bd);
16714   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16715
16716   /* send */
16717   S (mp);
16718
16719   /* wait for reply */
16720   W (ret);
16721   return ret;
16722 }
16723
16724 static int
16725 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16726 {
16727   vl_api_one_add_del_l2_arp_entry_t *mp;
16728   unformat_input_t *input = vam->input;
16729   u8 is_add = 1;
16730   u8 mac_set = 0;
16731   u8 bd_set = 0;
16732   u8 ip_set = 0;
16733   u8 mac[6] = { 0, };
16734   u32 ip4 = 0, bd = ~0;
16735   int ret;
16736
16737   /* Parse args required to build the message */
16738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16739     {
16740       if (unformat (input, "del"))
16741         is_add = 0;
16742       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16743         mac_set = 1;
16744       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16745         ip_set = 1;
16746       else if (unformat (input, "bd %d", &bd))
16747         bd_set = 1;
16748       else
16749         {
16750           errmsg ("parse error '%U'", format_unformat_error, input);
16751           return -99;
16752         }
16753     }
16754
16755   if (!bd_set || !ip_set || (!mac_set && is_add))
16756     {
16757       errmsg ("Missing BD, IP or MAC!");
16758       return -99;
16759     }
16760
16761   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16762   mp->is_add = is_add;
16763   clib_memcpy (mp->mac, mac, 6);
16764   mp->bd = clib_host_to_net_u32 (bd);
16765   mp->ip4 = ip4;
16766
16767   /* send */
16768   S (mp);
16769
16770   /* wait for reply */
16771   W (ret);
16772   return ret;
16773 }
16774
16775 static int
16776 api_one_ndp_bd_get (vat_main_t * vam)
16777 {
16778   vl_api_one_ndp_bd_get_t *mp;
16779   int ret;
16780
16781   M (ONE_NDP_BD_GET, mp);
16782
16783   /* send */
16784   S (mp);
16785
16786   /* wait for reply */
16787   W (ret);
16788   return ret;
16789 }
16790
16791 static int
16792 api_one_ndp_entries_get (vat_main_t * vam)
16793 {
16794   vl_api_one_ndp_entries_get_t *mp;
16795   unformat_input_t *input = vam->input;
16796   u8 bd_set = 0;
16797   u32 bd = ~0;
16798   int ret;
16799
16800   /* Parse args required to build the message */
16801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16802     {
16803       if (unformat (input, "bd %d", &bd))
16804         bd_set = 1;
16805       else
16806         {
16807           errmsg ("parse error '%U'", format_unformat_error, input);
16808           return -99;
16809         }
16810     }
16811
16812   if (!bd_set)
16813     {
16814       errmsg ("Expected bridge domain!");
16815       return -99;
16816     }
16817
16818   M (ONE_NDP_ENTRIES_GET, mp);
16819   mp->bd = clib_host_to_net_u32 (bd);
16820
16821   /* send */
16822   S (mp);
16823
16824   /* wait for reply */
16825   W (ret);
16826   return ret;
16827 }
16828
16829 static int
16830 api_one_l2_arp_bd_get (vat_main_t * vam)
16831 {
16832   vl_api_one_l2_arp_bd_get_t *mp;
16833   int ret;
16834
16835   M (ONE_L2_ARP_BD_GET, mp);
16836
16837   /* send */
16838   S (mp);
16839
16840   /* wait for reply */
16841   W (ret);
16842   return ret;
16843 }
16844
16845 static int
16846 api_one_l2_arp_entries_get (vat_main_t * vam)
16847 {
16848   vl_api_one_l2_arp_entries_get_t *mp;
16849   unformat_input_t *input = vam->input;
16850   u8 bd_set = 0;
16851   u32 bd = ~0;
16852   int ret;
16853
16854   /* Parse args required to build the message */
16855   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16856     {
16857       if (unformat (input, "bd %d", &bd))
16858         bd_set = 1;
16859       else
16860         {
16861           errmsg ("parse error '%U'", format_unformat_error, input);
16862           return -99;
16863         }
16864     }
16865
16866   if (!bd_set)
16867     {
16868       errmsg ("Expected bridge domain!");
16869       return -99;
16870     }
16871
16872   M (ONE_L2_ARP_ENTRIES_GET, mp);
16873   mp->bd = clib_host_to_net_u32 (bd);
16874
16875   /* send */
16876   S (mp);
16877
16878   /* wait for reply */
16879   W (ret);
16880   return ret;
16881 }
16882
16883 static int
16884 api_one_stats_enable_disable (vat_main_t * vam)
16885 {
16886   vl_api_one_stats_enable_disable_t *mp;
16887   unformat_input_t *input = vam->input;
16888   u8 is_set = 0;
16889   u8 is_en = 0;
16890   int ret;
16891
16892   /* Parse args required to build the message */
16893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16894     {
16895       if (unformat (input, "enable"))
16896         {
16897           is_set = 1;
16898           is_en = 1;
16899         }
16900       else if (unformat (input, "disable"))
16901         {
16902           is_set = 1;
16903         }
16904       else
16905         break;
16906     }
16907
16908   if (!is_set)
16909     {
16910       errmsg ("Value not set");
16911       return -99;
16912     }
16913
16914   M (ONE_STATS_ENABLE_DISABLE, mp);
16915   mp->is_en = is_en;
16916
16917   /* send */
16918   S (mp);
16919
16920   /* wait for reply */
16921   W (ret);
16922   return ret;
16923 }
16924
16925 static int
16926 api_show_one_stats_enable_disable (vat_main_t * vam)
16927 {
16928   vl_api_show_one_stats_enable_disable_t *mp;
16929   int ret;
16930
16931   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16932
16933   /* send */
16934   S (mp);
16935
16936   /* wait for reply */
16937   W (ret);
16938   return ret;
16939 }
16940
16941 static int
16942 api_show_one_map_request_mode (vat_main_t * vam)
16943 {
16944   vl_api_show_one_map_request_mode_t *mp;
16945   int ret;
16946
16947   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16948
16949   /* send */
16950   S (mp);
16951
16952   /* wait for reply */
16953   W (ret);
16954   return ret;
16955 }
16956
16957 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16958
16959 static int
16960 api_one_map_request_mode (vat_main_t * vam)
16961 {
16962   unformat_input_t *input = vam->input;
16963   vl_api_one_map_request_mode_t *mp;
16964   u8 mode = 0;
16965   int ret;
16966
16967   /* Parse args required to build the message */
16968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16969     {
16970       if (unformat (input, "dst-only"))
16971         mode = 0;
16972       else if (unformat (input, "src-dst"))
16973         mode = 1;
16974       else
16975         {
16976           errmsg ("parse error '%U'", format_unformat_error, input);
16977           return -99;
16978         }
16979     }
16980
16981   M (ONE_MAP_REQUEST_MODE, mp);
16982
16983   mp->mode = mode;
16984
16985   /* send */
16986   S (mp);
16987
16988   /* wait for reply */
16989   W (ret);
16990   return ret;
16991 }
16992
16993 #define api_lisp_map_request_mode api_one_map_request_mode
16994
16995 /**
16996  * Enable/disable ONE proxy ITR.
16997  *
16998  * @param vam vpp API test context
16999  * @return return code
17000  */
17001 static int
17002 api_one_pitr_set_locator_set (vat_main_t * vam)
17003 {
17004   u8 ls_name_set = 0;
17005   unformat_input_t *input = vam->input;
17006   vl_api_one_pitr_set_locator_set_t *mp;
17007   u8 is_add = 1;
17008   u8 *ls_name = 0;
17009   int ret;
17010
17011   /* Parse args required to build the message */
17012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17013     {
17014       if (unformat (input, "del"))
17015         is_add = 0;
17016       else if (unformat (input, "locator-set %s", &ls_name))
17017         ls_name_set = 1;
17018       else
17019         {
17020           errmsg ("parse error '%U'", format_unformat_error, input);
17021           return -99;
17022         }
17023     }
17024
17025   if (!ls_name_set)
17026     {
17027       errmsg ("locator-set name not set!");
17028       return -99;
17029     }
17030
17031   M (ONE_PITR_SET_LOCATOR_SET, mp);
17032
17033   mp->is_add = is_add;
17034   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17035   vec_free (ls_name);
17036
17037   /* send */
17038   S (mp);
17039
17040   /* wait for reply */
17041   W (ret);
17042   return ret;
17043 }
17044
17045 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17046
17047 static int
17048 api_one_nsh_set_locator_set (vat_main_t * vam)
17049 {
17050   u8 ls_name_set = 0;
17051   unformat_input_t *input = vam->input;
17052   vl_api_one_nsh_set_locator_set_t *mp;
17053   u8 is_add = 1;
17054   u8 *ls_name = 0;
17055   int ret;
17056
17057   /* Parse args required to build the message */
17058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17059     {
17060       if (unformat (input, "del"))
17061         is_add = 0;
17062       else if (unformat (input, "ls %s", &ls_name))
17063         ls_name_set = 1;
17064       else
17065         {
17066           errmsg ("parse error '%U'", format_unformat_error, input);
17067           return -99;
17068         }
17069     }
17070
17071   if (!ls_name_set && is_add)
17072     {
17073       errmsg ("locator-set name not set!");
17074       return -99;
17075     }
17076
17077   M (ONE_NSH_SET_LOCATOR_SET, mp);
17078
17079   mp->is_add = is_add;
17080   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17081   vec_free (ls_name);
17082
17083   /* send */
17084   S (mp);
17085
17086   /* wait for reply */
17087   W (ret);
17088   return ret;
17089 }
17090
17091 static int
17092 api_show_one_pitr (vat_main_t * vam)
17093 {
17094   vl_api_show_one_pitr_t *mp;
17095   int ret;
17096
17097   if (!vam->json_output)
17098     {
17099       print (vam->ofp, "%=20s", "lisp status:");
17100     }
17101
17102   M (SHOW_ONE_PITR, mp);
17103   /* send it... */
17104   S (mp);
17105
17106   /* Wait for a reply... */
17107   W (ret);
17108   return ret;
17109 }
17110
17111 #define api_show_lisp_pitr api_show_one_pitr
17112
17113 static int
17114 api_one_use_petr (vat_main_t * vam)
17115 {
17116   unformat_input_t *input = vam->input;
17117   vl_api_one_use_petr_t *mp;
17118   u8 is_add = 0;
17119   ip_address_t ip;
17120   int ret;
17121
17122   clib_memset (&ip, 0, sizeof (ip));
17123
17124   /* Parse args required to build the message */
17125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17126     {
17127       if (unformat (input, "disable"))
17128         is_add = 0;
17129       else
17130         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17131         {
17132           is_add = 1;
17133           ip_addr_version (&ip) = IP4;
17134         }
17135       else
17136         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17137         {
17138           is_add = 1;
17139           ip_addr_version (&ip) = IP6;
17140         }
17141       else
17142         {
17143           errmsg ("parse error '%U'", format_unformat_error, input);
17144           return -99;
17145         }
17146     }
17147
17148   M (ONE_USE_PETR, mp);
17149
17150   mp->is_add = is_add;
17151   if (is_add)
17152     {
17153       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17154       if (mp->is_ip4)
17155         clib_memcpy (mp->address, &ip, 4);
17156       else
17157         clib_memcpy (mp->address, &ip, 16);
17158     }
17159
17160   /* send */
17161   S (mp);
17162
17163   /* wait for reply */
17164   W (ret);
17165   return ret;
17166 }
17167
17168 #define api_lisp_use_petr api_one_use_petr
17169
17170 static int
17171 api_show_one_nsh_mapping (vat_main_t * vam)
17172 {
17173   vl_api_show_one_use_petr_t *mp;
17174   int ret;
17175
17176   if (!vam->json_output)
17177     {
17178       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17179     }
17180
17181   M (SHOW_ONE_NSH_MAPPING, mp);
17182   /* send it... */
17183   S (mp);
17184
17185   /* Wait for a reply... */
17186   W (ret);
17187   return ret;
17188 }
17189
17190 static int
17191 api_show_one_use_petr (vat_main_t * vam)
17192 {
17193   vl_api_show_one_use_petr_t *mp;
17194   int ret;
17195
17196   if (!vam->json_output)
17197     {
17198       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17199     }
17200
17201   M (SHOW_ONE_USE_PETR, mp);
17202   /* send it... */
17203   S (mp);
17204
17205   /* Wait for a reply... */
17206   W (ret);
17207   return ret;
17208 }
17209
17210 #define api_show_lisp_use_petr api_show_one_use_petr
17211
17212 /**
17213  * Add/delete mapping between vni and vrf
17214  */
17215 static int
17216 api_one_eid_table_add_del_map (vat_main_t * vam)
17217 {
17218   unformat_input_t *input = vam->input;
17219   vl_api_one_eid_table_add_del_map_t *mp;
17220   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17221   u32 vni, vrf, bd_index;
17222   int ret;
17223
17224   /* Parse args required to build the message */
17225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17226     {
17227       if (unformat (input, "del"))
17228         is_add = 0;
17229       else if (unformat (input, "vrf %d", &vrf))
17230         vrf_set = 1;
17231       else if (unformat (input, "bd_index %d", &bd_index))
17232         bd_index_set = 1;
17233       else if (unformat (input, "vni %d", &vni))
17234         vni_set = 1;
17235       else
17236         break;
17237     }
17238
17239   if (!vni_set || (!vrf_set && !bd_index_set))
17240     {
17241       errmsg ("missing arguments!");
17242       return -99;
17243     }
17244
17245   if (vrf_set && bd_index_set)
17246     {
17247       errmsg ("error: both vrf and bd entered!");
17248       return -99;
17249     }
17250
17251   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17252
17253   mp->is_add = is_add;
17254   mp->vni = htonl (vni);
17255   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17256   mp->is_l2 = bd_index_set;
17257
17258   /* send */
17259   S (mp);
17260
17261   /* wait for reply */
17262   W (ret);
17263   return ret;
17264 }
17265
17266 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17267
17268 uword
17269 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17270 {
17271   u32 *action = va_arg (*args, u32 *);
17272   u8 *s = 0;
17273
17274   if (unformat (input, "%s", &s))
17275     {
17276       if (!strcmp ((char *) s, "no-action"))
17277         action[0] = 0;
17278       else if (!strcmp ((char *) s, "natively-forward"))
17279         action[0] = 1;
17280       else if (!strcmp ((char *) s, "send-map-request"))
17281         action[0] = 2;
17282       else if (!strcmp ((char *) s, "drop"))
17283         action[0] = 3;
17284       else
17285         {
17286           clib_warning ("invalid action: '%s'", s);
17287           action[0] = 3;
17288         }
17289     }
17290   else
17291     return 0;
17292
17293   vec_free (s);
17294   return 1;
17295 }
17296
17297 /**
17298  * Add/del remote mapping to/from ONE control plane
17299  *
17300  * @param vam vpp API test context
17301  * @return return code
17302  */
17303 static int
17304 api_one_add_del_remote_mapping (vat_main_t * vam)
17305 {
17306   unformat_input_t *input = vam->input;
17307   vl_api_one_add_del_remote_mapping_t *mp;
17308   u32 vni = 0;
17309   lisp_eid_vat_t _eid, *eid = &_eid;
17310   lisp_eid_vat_t _seid, *seid = &_seid;
17311   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17312   u32 action = ~0, p, w, data_len;
17313   ip4_address_t rloc4;
17314   ip6_address_t rloc6;
17315   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17316   int ret;
17317
17318   clib_memset (&rloc, 0, sizeof (rloc));
17319
17320   /* Parse args required to build the message */
17321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17322     {
17323       if (unformat (input, "del-all"))
17324         {
17325           del_all = 1;
17326         }
17327       else if (unformat (input, "del"))
17328         {
17329           is_add = 0;
17330         }
17331       else if (unformat (input, "add"))
17332         {
17333           is_add = 1;
17334         }
17335       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17336         {
17337           eid_set = 1;
17338         }
17339       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17340         {
17341           seid_set = 1;
17342         }
17343       else if (unformat (input, "vni %d", &vni))
17344         {
17345           ;
17346         }
17347       else if (unformat (input, "p %d w %d", &p, &w))
17348         {
17349           if (!curr_rloc)
17350             {
17351               errmsg ("No RLOC configured for setting priority/weight!");
17352               return -99;
17353             }
17354           curr_rloc->priority = p;
17355           curr_rloc->weight = w;
17356         }
17357       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17358         {
17359           rloc.is_ip4 = 1;
17360           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17361           vec_add1 (rlocs, rloc);
17362           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17363         }
17364       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17365         {
17366           rloc.is_ip4 = 0;
17367           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17368           vec_add1 (rlocs, rloc);
17369           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17370         }
17371       else if (unformat (input, "action %U",
17372                          unformat_negative_mapping_action, &action))
17373         {
17374           ;
17375         }
17376       else
17377         {
17378           clib_warning ("parse error '%U'", format_unformat_error, input);
17379           return -99;
17380         }
17381     }
17382
17383   if (0 == eid_set)
17384     {
17385       errmsg ("missing params!");
17386       return -99;
17387     }
17388
17389   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17390     {
17391       errmsg ("no action set for negative map-reply!");
17392       return -99;
17393     }
17394
17395   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17396
17397   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17398   mp->is_add = is_add;
17399   mp->vni = htonl (vni);
17400   mp->action = (u8) action;
17401   mp->is_src_dst = seid_set;
17402   mp->eid_len = eid->len;
17403   mp->seid_len = seid->len;
17404   mp->del_all = del_all;
17405   mp->eid_type = eid->type;
17406   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17407   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17408
17409   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17410   clib_memcpy (mp->rlocs, rlocs, data_len);
17411   vec_free (rlocs);
17412
17413   /* send it... */
17414   S (mp);
17415
17416   /* Wait for a reply... */
17417   W (ret);
17418   return ret;
17419 }
17420
17421 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17422
17423 /**
17424  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17425  * forwarding entries in data-plane accordingly.
17426  *
17427  * @param vam vpp API test context
17428  * @return return code
17429  */
17430 static int
17431 api_one_add_del_adjacency (vat_main_t * vam)
17432 {
17433   unformat_input_t *input = vam->input;
17434   vl_api_one_add_del_adjacency_t *mp;
17435   u32 vni = 0;
17436   ip4_address_t leid4, reid4;
17437   ip6_address_t leid6, reid6;
17438   u8 reid_mac[6] = { 0 };
17439   u8 leid_mac[6] = { 0 };
17440   u8 reid_type, leid_type;
17441   u32 leid_len = 0, reid_len = 0, len;
17442   u8 is_add = 1;
17443   int ret;
17444
17445   leid_type = reid_type = (u8) ~ 0;
17446
17447   /* Parse args required to build the message */
17448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17449     {
17450       if (unformat (input, "del"))
17451         {
17452           is_add = 0;
17453         }
17454       else if (unformat (input, "add"))
17455         {
17456           is_add = 1;
17457         }
17458       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17459                          &reid4, &len))
17460         {
17461           reid_type = 0;        /* ipv4 */
17462           reid_len = len;
17463         }
17464       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17465                          &reid6, &len))
17466         {
17467           reid_type = 1;        /* ipv6 */
17468           reid_len = len;
17469         }
17470       else if (unformat (input, "reid %U", unformat_ethernet_address,
17471                          reid_mac))
17472         {
17473           reid_type = 2;        /* mac */
17474         }
17475       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17476                          &leid4, &len))
17477         {
17478           leid_type = 0;        /* ipv4 */
17479           leid_len = len;
17480         }
17481       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17482                          &leid6, &len))
17483         {
17484           leid_type = 1;        /* ipv6 */
17485           leid_len = len;
17486         }
17487       else if (unformat (input, "leid %U", unformat_ethernet_address,
17488                          leid_mac))
17489         {
17490           leid_type = 2;        /* mac */
17491         }
17492       else if (unformat (input, "vni %d", &vni))
17493         {
17494           ;
17495         }
17496       else
17497         {
17498           errmsg ("parse error '%U'", format_unformat_error, input);
17499           return -99;
17500         }
17501     }
17502
17503   if ((u8) ~ 0 == reid_type)
17504     {
17505       errmsg ("missing params!");
17506       return -99;
17507     }
17508
17509   if (leid_type != reid_type)
17510     {
17511       errmsg ("remote and local EIDs are of different types!");
17512       return -99;
17513     }
17514
17515   M (ONE_ADD_DEL_ADJACENCY, mp);
17516   mp->is_add = is_add;
17517   mp->vni = htonl (vni);
17518   mp->leid_len = leid_len;
17519   mp->reid_len = reid_len;
17520   mp->eid_type = reid_type;
17521
17522   switch (mp->eid_type)
17523     {
17524     case 0:
17525       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17526       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17527       break;
17528     case 1:
17529       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17530       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17531       break;
17532     case 2:
17533       clib_memcpy (mp->leid, leid_mac, 6);
17534       clib_memcpy (mp->reid, reid_mac, 6);
17535       break;
17536     default:
17537       errmsg ("unknown EID type %d!", mp->eid_type);
17538       return 0;
17539     }
17540
17541   /* send it... */
17542   S (mp);
17543
17544   /* Wait for a reply... */
17545   W (ret);
17546   return ret;
17547 }
17548
17549 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17550
17551 uword
17552 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17553 {
17554   u32 *mode = va_arg (*args, u32 *);
17555
17556   if (unformat (input, "lisp"))
17557     *mode = 0;
17558   else if (unformat (input, "vxlan"))
17559     *mode = 1;
17560   else
17561     return 0;
17562
17563   return 1;
17564 }
17565
17566 static int
17567 api_gpe_get_encap_mode (vat_main_t * vam)
17568 {
17569   vl_api_gpe_get_encap_mode_t *mp;
17570   int ret;
17571
17572   /* Construct the API message */
17573   M (GPE_GET_ENCAP_MODE, mp);
17574
17575   /* send it... */
17576   S (mp);
17577
17578   /* Wait for a reply... */
17579   W (ret);
17580   return ret;
17581 }
17582
17583 static int
17584 api_gpe_set_encap_mode (vat_main_t * vam)
17585 {
17586   unformat_input_t *input = vam->input;
17587   vl_api_gpe_set_encap_mode_t *mp;
17588   int ret;
17589   u32 mode = 0;
17590
17591   /* Parse args required to build the message */
17592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17593     {
17594       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17595         ;
17596       else
17597         break;
17598     }
17599
17600   /* Construct the API message */
17601   M (GPE_SET_ENCAP_MODE, mp);
17602
17603   mp->mode = mode;
17604
17605   /* send it... */
17606   S (mp);
17607
17608   /* Wait for a reply... */
17609   W (ret);
17610   return ret;
17611 }
17612
17613 static int
17614 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17615 {
17616   unformat_input_t *input = vam->input;
17617   vl_api_gpe_add_del_iface_t *mp;
17618   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17619   u32 dp_table = 0, vni = 0;
17620   int ret;
17621
17622   /* Parse args required to build the message */
17623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17624     {
17625       if (unformat (input, "up"))
17626         {
17627           action_set = 1;
17628           is_add = 1;
17629         }
17630       else if (unformat (input, "down"))
17631         {
17632           action_set = 1;
17633           is_add = 0;
17634         }
17635       else if (unformat (input, "table_id %d", &dp_table))
17636         {
17637           dp_table_set = 1;
17638         }
17639       else if (unformat (input, "bd_id %d", &dp_table))
17640         {
17641           dp_table_set = 1;
17642           is_l2 = 1;
17643         }
17644       else if (unformat (input, "vni %d", &vni))
17645         {
17646           vni_set = 1;
17647         }
17648       else
17649         break;
17650     }
17651
17652   if (action_set == 0)
17653     {
17654       errmsg ("Action not set");
17655       return -99;
17656     }
17657   if (dp_table_set == 0 || vni_set == 0)
17658     {
17659       errmsg ("vni and dp_table must be set");
17660       return -99;
17661     }
17662
17663   /* Construct the API message */
17664   M (GPE_ADD_DEL_IFACE, mp);
17665
17666   mp->is_add = is_add;
17667   mp->dp_table = clib_host_to_net_u32 (dp_table);
17668   mp->is_l2 = is_l2;
17669   mp->vni = clib_host_to_net_u32 (vni);
17670
17671   /* send it... */
17672   S (mp);
17673
17674   /* Wait for a reply... */
17675   W (ret);
17676   return ret;
17677 }
17678
17679 static int
17680 api_one_map_register_fallback_threshold (vat_main_t * vam)
17681 {
17682   unformat_input_t *input = vam->input;
17683   vl_api_one_map_register_fallback_threshold_t *mp;
17684   u32 value = 0;
17685   u8 is_set = 0;
17686   int ret;
17687
17688   /* Parse args required to build the message */
17689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17690     {
17691       if (unformat (input, "%u", &value))
17692         is_set = 1;
17693       else
17694         {
17695           clib_warning ("parse error '%U'", format_unformat_error, input);
17696           return -99;
17697         }
17698     }
17699
17700   if (!is_set)
17701     {
17702       errmsg ("fallback threshold value is missing!");
17703       return -99;
17704     }
17705
17706   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17707   mp->value = clib_host_to_net_u32 (value);
17708
17709   /* send it... */
17710   S (mp);
17711
17712   /* Wait for a reply... */
17713   W (ret);
17714   return ret;
17715 }
17716
17717 static int
17718 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17719 {
17720   vl_api_show_one_map_register_fallback_threshold_t *mp;
17721   int ret;
17722
17723   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17724
17725   /* send it... */
17726   S (mp);
17727
17728   /* Wait for a reply... */
17729   W (ret);
17730   return ret;
17731 }
17732
17733 uword
17734 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17735 {
17736   u32 *proto = va_arg (*args, u32 *);
17737
17738   if (unformat (input, "udp"))
17739     *proto = 1;
17740   else if (unformat (input, "api"))
17741     *proto = 2;
17742   else
17743     return 0;
17744
17745   return 1;
17746 }
17747
17748 static int
17749 api_one_set_transport_protocol (vat_main_t * vam)
17750 {
17751   unformat_input_t *input = vam->input;
17752   vl_api_one_set_transport_protocol_t *mp;
17753   u8 is_set = 0;
17754   u32 protocol = 0;
17755   int ret;
17756
17757   /* Parse args required to build the message */
17758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17759     {
17760       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17761         is_set = 1;
17762       else
17763         {
17764           clib_warning ("parse error '%U'", format_unformat_error, input);
17765           return -99;
17766         }
17767     }
17768
17769   if (!is_set)
17770     {
17771       errmsg ("Transport protocol missing!");
17772       return -99;
17773     }
17774
17775   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17776   mp->protocol = (u8) protocol;
17777
17778   /* send it... */
17779   S (mp);
17780
17781   /* Wait for a reply... */
17782   W (ret);
17783   return ret;
17784 }
17785
17786 static int
17787 api_one_get_transport_protocol (vat_main_t * vam)
17788 {
17789   vl_api_one_get_transport_protocol_t *mp;
17790   int ret;
17791
17792   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17793
17794   /* send it... */
17795   S (mp);
17796
17797   /* Wait for a reply... */
17798   W (ret);
17799   return ret;
17800 }
17801
17802 static int
17803 api_one_map_register_set_ttl (vat_main_t * vam)
17804 {
17805   unformat_input_t *input = vam->input;
17806   vl_api_one_map_register_set_ttl_t *mp;
17807   u32 ttl = 0;
17808   u8 is_set = 0;
17809   int ret;
17810
17811   /* Parse args required to build the message */
17812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17813     {
17814       if (unformat (input, "%u", &ttl))
17815         is_set = 1;
17816       else
17817         {
17818           clib_warning ("parse error '%U'", format_unformat_error, input);
17819           return -99;
17820         }
17821     }
17822
17823   if (!is_set)
17824     {
17825       errmsg ("TTL value missing!");
17826       return -99;
17827     }
17828
17829   M (ONE_MAP_REGISTER_SET_TTL, mp);
17830   mp->ttl = clib_host_to_net_u32 (ttl);
17831
17832   /* send it... */
17833   S (mp);
17834
17835   /* Wait for a reply... */
17836   W (ret);
17837   return ret;
17838 }
17839
17840 static int
17841 api_show_one_map_register_ttl (vat_main_t * vam)
17842 {
17843   vl_api_show_one_map_register_ttl_t *mp;
17844   int ret;
17845
17846   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17847
17848   /* send it... */
17849   S (mp);
17850
17851   /* Wait for a reply... */
17852   W (ret);
17853   return ret;
17854 }
17855
17856 /**
17857  * Add/del map request itr rlocs from ONE control plane and updates
17858  *
17859  * @param vam vpp API test context
17860  * @return return code
17861  */
17862 static int
17863 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17864 {
17865   unformat_input_t *input = vam->input;
17866   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17867   u8 *locator_set_name = 0;
17868   u8 locator_set_name_set = 0;
17869   u8 is_add = 1;
17870   int ret;
17871
17872   /* Parse args required to build the message */
17873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (input, "del"))
17876         {
17877           is_add = 0;
17878         }
17879       else if (unformat (input, "%_%v%_", &locator_set_name))
17880         {
17881           locator_set_name_set = 1;
17882         }
17883       else
17884         {
17885           clib_warning ("parse error '%U'", format_unformat_error, input);
17886           return -99;
17887         }
17888     }
17889
17890   if (is_add && !locator_set_name_set)
17891     {
17892       errmsg ("itr-rloc is not set!");
17893       return -99;
17894     }
17895
17896   if (is_add && vec_len (locator_set_name) > 64)
17897     {
17898       errmsg ("itr-rloc locator-set name too long");
17899       vec_free (locator_set_name);
17900       return -99;
17901     }
17902
17903   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17904   mp->is_add = is_add;
17905   if (is_add)
17906     {
17907       clib_memcpy (mp->locator_set_name, locator_set_name,
17908                    vec_len (locator_set_name));
17909     }
17910   else
17911     {
17912       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17913     }
17914   vec_free (locator_set_name);
17915
17916   /* send it... */
17917   S (mp);
17918
17919   /* Wait for a reply... */
17920   W (ret);
17921   return ret;
17922 }
17923
17924 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17925
17926 static int
17927 api_one_locator_dump (vat_main_t * vam)
17928 {
17929   unformat_input_t *input = vam->input;
17930   vl_api_one_locator_dump_t *mp;
17931   vl_api_control_ping_t *mp_ping;
17932   u8 is_index_set = 0, is_name_set = 0;
17933   u8 *ls_name = 0;
17934   u32 ls_index = ~0;
17935   int ret;
17936
17937   /* Parse args required to build the message */
17938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17939     {
17940       if (unformat (input, "ls_name %_%v%_", &ls_name))
17941         {
17942           is_name_set = 1;
17943         }
17944       else if (unformat (input, "ls_index %d", &ls_index))
17945         {
17946           is_index_set = 1;
17947         }
17948       else
17949         {
17950           errmsg ("parse error '%U'", format_unformat_error, input);
17951           return -99;
17952         }
17953     }
17954
17955   if (!is_index_set && !is_name_set)
17956     {
17957       errmsg ("error: expected one of index or name!");
17958       return -99;
17959     }
17960
17961   if (is_index_set && is_name_set)
17962     {
17963       errmsg ("error: only one param expected!");
17964       return -99;
17965     }
17966
17967   if (vec_len (ls_name) > 62)
17968     {
17969       errmsg ("error: locator set name too long!");
17970       return -99;
17971     }
17972
17973   if (!vam->json_output)
17974     {
17975       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17976     }
17977
17978   M (ONE_LOCATOR_DUMP, mp);
17979   mp->is_index_set = is_index_set;
17980
17981   if (is_index_set)
17982     mp->ls_index = clib_host_to_net_u32 (ls_index);
17983   else
17984     {
17985       vec_add1 (ls_name, 0);
17986       strncpy ((char *) mp->ls_name, (char *) ls_name,
17987                sizeof (mp->ls_name) - 1);
17988     }
17989
17990   /* send it... */
17991   S (mp);
17992
17993   /* Use a control ping for synchronization */
17994   MPING (CONTROL_PING, mp_ping);
17995   S (mp_ping);
17996
17997   /* Wait for a reply... */
17998   W (ret);
17999   return ret;
18000 }
18001
18002 #define api_lisp_locator_dump api_one_locator_dump
18003
18004 static int
18005 api_one_locator_set_dump (vat_main_t * vam)
18006 {
18007   vl_api_one_locator_set_dump_t *mp;
18008   vl_api_control_ping_t *mp_ping;
18009   unformat_input_t *input = vam->input;
18010   u8 filter = 0;
18011   int ret;
18012
18013   /* Parse args required to build the message */
18014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18015     {
18016       if (unformat (input, "local"))
18017         {
18018           filter = 1;
18019         }
18020       else if (unformat (input, "remote"))
18021         {
18022           filter = 2;
18023         }
18024       else
18025         {
18026           errmsg ("parse error '%U'", format_unformat_error, input);
18027           return -99;
18028         }
18029     }
18030
18031   if (!vam->json_output)
18032     {
18033       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18034     }
18035
18036   M (ONE_LOCATOR_SET_DUMP, mp);
18037
18038   mp->filter = filter;
18039
18040   /* send it... */
18041   S (mp);
18042
18043   /* Use a control ping for synchronization */
18044   MPING (CONTROL_PING, mp_ping);
18045   S (mp_ping);
18046
18047   /* Wait for a reply... */
18048   W (ret);
18049   return ret;
18050 }
18051
18052 #define api_lisp_locator_set_dump api_one_locator_set_dump
18053
18054 static int
18055 api_one_eid_table_map_dump (vat_main_t * vam)
18056 {
18057   u8 is_l2 = 0;
18058   u8 mode_set = 0;
18059   unformat_input_t *input = vam->input;
18060   vl_api_one_eid_table_map_dump_t *mp;
18061   vl_api_control_ping_t *mp_ping;
18062   int ret;
18063
18064   /* Parse args required to build the message */
18065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18066     {
18067       if (unformat (input, "l2"))
18068         {
18069           is_l2 = 1;
18070           mode_set = 1;
18071         }
18072       else if (unformat (input, "l3"))
18073         {
18074           is_l2 = 0;
18075           mode_set = 1;
18076         }
18077       else
18078         {
18079           errmsg ("parse error '%U'", format_unformat_error, input);
18080           return -99;
18081         }
18082     }
18083
18084   if (!mode_set)
18085     {
18086       errmsg ("expected one of 'l2' or 'l3' parameter!");
18087       return -99;
18088     }
18089
18090   if (!vam->json_output)
18091     {
18092       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18093     }
18094
18095   M (ONE_EID_TABLE_MAP_DUMP, mp);
18096   mp->is_l2 = is_l2;
18097
18098   /* send it... */
18099   S (mp);
18100
18101   /* Use a control ping for synchronization */
18102   MPING (CONTROL_PING, mp_ping);
18103   S (mp_ping);
18104
18105   /* Wait for a reply... */
18106   W (ret);
18107   return ret;
18108 }
18109
18110 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18111
18112 static int
18113 api_one_eid_table_vni_dump (vat_main_t * vam)
18114 {
18115   vl_api_one_eid_table_vni_dump_t *mp;
18116   vl_api_control_ping_t *mp_ping;
18117   int ret;
18118
18119   if (!vam->json_output)
18120     {
18121       print (vam->ofp, "VNI");
18122     }
18123
18124   M (ONE_EID_TABLE_VNI_DUMP, mp);
18125
18126   /* send it... */
18127   S (mp);
18128
18129   /* Use a control ping for synchronization */
18130   MPING (CONTROL_PING, mp_ping);
18131   S (mp_ping);
18132
18133   /* Wait for a reply... */
18134   W (ret);
18135   return ret;
18136 }
18137
18138 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18139
18140 static int
18141 api_one_eid_table_dump (vat_main_t * vam)
18142 {
18143   unformat_input_t *i = vam->input;
18144   vl_api_one_eid_table_dump_t *mp;
18145   vl_api_control_ping_t *mp_ping;
18146   struct in_addr ip4;
18147   struct in6_addr ip6;
18148   u8 mac[6];
18149   u8 eid_type = ~0, eid_set = 0;
18150   u32 prefix_length = ~0, t, vni = 0;
18151   u8 filter = 0;
18152   int ret;
18153   lisp_nsh_api_t nsh;
18154
18155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18156     {
18157       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18158         {
18159           eid_set = 1;
18160           eid_type = 0;
18161           prefix_length = t;
18162         }
18163       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18164         {
18165           eid_set = 1;
18166           eid_type = 1;
18167           prefix_length = t;
18168         }
18169       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18170         {
18171           eid_set = 1;
18172           eid_type = 2;
18173         }
18174       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18175         {
18176           eid_set = 1;
18177           eid_type = 3;
18178         }
18179       else if (unformat (i, "vni %d", &t))
18180         {
18181           vni = t;
18182         }
18183       else if (unformat (i, "local"))
18184         {
18185           filter = 1;
18186         }
18187       else if (unformat (i, "remote"))
18188         {
18189           filter = 2;
18190         }
18191       else
18192         {
18193           errmsg ("parse error '%U'", format_unformat_error, i);
18194           return -99;
18195         }
18196     }
18197
18198   if (!vam->json_output)
18199     {
18200       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18201              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18202     }
18203
18204   M (ONE_EID_TABLE_DUMP, mp);
18205
18206   mp->filter = filter;
18207   if (eid_set)
18208     {
18209       mp->eid_set = 1;
18210       mp->vni = htonl (vni);
18211       mp->eid_type = eid_type;
18212       switch (eid_type)
18213         {
18214         case 0:
18215           mp->prefix_length = prefix_length;
18216           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18217           break;
18218         case 1:
18219           mp->prefix_length = prefix_length;
18220           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18221           break;
18222         case 2:
18223           clib_memcpy (mp->eid, mac, sizeof (mac));
18224           break;
18225         case 3:
18226           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18227           break;
18228         default:
18229           errmsg ("unknown EID type %d!", eid_type);
18230           return -99;
18231         }
18232     }
18233
18234   /* send it... */
18235   S (mp);
18236
18237   /* Use a control ping for synchronization */
18238   MPING (CONTROL_PING, mp_ping);
18239   S (mp_ping);
18240
18241   /* Wait for a reply... */
18242   W (ret);
18243   return ret;
18244 }
18245
18246 #define api_lisp_eid_table_dump api_one_eid_table_dump
18247
18248 static int
18249 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18250 {
18251   unformat_input_t *i = vam->input;
18252   vl_api_gpe_fwd_entries_get_t *mp;
18253   u8 vni_set = 0;
18254   u32 vni = ~0;
18255   int ret;
18256
18257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18258     {
18259       if (unformat (i, "vni %d", &vni))
18260         {
18261           vni_set = 1;
18262         }
18263       else
18264         {
18265           errmsg ("parse error '%U'", format_unformat_error, i);
18266           return -99;
18267         }
18268     }
18269
18270   if (!vni_set)
18271     {
18272       errmsg ("vni not set!");
18273       return -99;
18274     }
18275
18276   if (!vam->json_output)
18277     {
18278       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18279              "leid", "reid");
18280     }
18281
18282   M (GPE_FWD_ENTRIES_GET, mp);
18283   mp->vni = clib_host_to_net_u32 (vni);
18284
18285   /* send it... */
18286   S (mp);
18287
18288   /* Wait for a reply... */
18289   W (ret);
18290   return ret;
18291 }
18292
18293 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18294 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18295 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18296 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18297 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18298 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18299 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18300 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18301
18302 static int
18303 api_one_adjacencies_get (vat_main_t * vam)
18304 {
18305   unformat_input_t *i = vam->input;
18306   vl_api_one_adjacencies_get_t *mp;
18307   u8 vni_set = 0;
18308   u32 vni = ~0;
18309   int ret;
18310
18311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18312     {
18313       if (unformat (i, "vni %d", &vni))
18314         {
18315           vni_set = 1;
18316         }
18317       else
18318         {
18319           errmsg ("parse error '%U'", format_unformat_error, i);
18320           return -99;
18321         }
18322     }
18323
18324   if (!vni_set)
18325     {
18326       errmsg ("vni not set!");
18327       return -99;
18328     }
18329
18330   if (!vam->json_output)
18331     {
18332       print (vam->ofp, "%s %40s", "leid", "reid");
18333     }
18334
18335   M (ONE_ADJACENCIES_GET, mp);
18336   mp->vni = clib_host_to_net_u32 (vni);
18337
18338   /* send it... */
18339   S (mp);
18340
18341   /* Wait for a reply... */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 #define api_lisp_adjacencies_get api_one_adjacencies_get
18347
18348 static int
18349 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18350 {
18351   unformat_input_t *i = vam->input;
18352   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18353   int ret;
18354   u8 ip_family_set = 0, is_ip4 = 1;
18355
18356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18357     {
18358       if (unformat (i, "ip4"))
18359         {
18360           ip_family_set = 1;
18361           is_ip4 = 1;
18362         }
18363       else if (unformat (i, "ip6"))
18364         {
18365           ip_family_set = 1;
18366           is_ip4 = 0;
18367         }
18368       else
18369         {
18370           errmsg ("parse error '%U'", format_unformat_error, i);
18371           return -99;
18372         }
18373     }
18374
18375   if (!ip_family_set)
18376     {
18377       errmsg ("ip family not set!");
18378       return -99;
18379     }
18380
18381   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18382   mp->is_ip4 = is_ip4;
18383
18384   /* send it... */
18385   S (mp);
18386
18387   /* Wait for a reply... */
18388   W (ret);
18389   return ret;
18390 }
18391
18392 static int
18393 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18394 {
18395   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18396   int ret;
18397
18398   if (!vam->json_output)
18399     {
18400       print (vam->ofp, "VNIs");
18401     }
18402
18403   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18404
18405   /* send it... */
18406   S (mp);
18407
18408   /* Wait for a reply... */
18409   W (ret);
18410   return ret;
18411 }
18412
18413 static int
18414 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18415 {
18416   unformat_input_t *i = vam->input;
18417   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18418   int ret = 0;
18419   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18420   struct in_addr ip4;
18421   struct in6_addr ip6;
18422   u32 table_id = 0, nh_sw_if_index = ~0;
18423
18424   clib_memset (&ip4, 0, sizeof (ip4));
18425   clib_memset (&ip6, 0, sizeof (ip6));
18426
18427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18428     {
18429       if (unformat (i, "del"))
18430         is_add = 0;
18431       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18432                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18433         {
18434           ip_set = 1;
18435           is_ip4 = 1;
18436         }
18437       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18438                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18439         {
18440           ip_set = 1;
18441           is_ip4 = 0;
18442         }
18443       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18444         {
18445           ip_set = 1;
18446           is_ip4 = 1;
18447           nh_sw_if_index = ~0;
18448         }
18449       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18450         {
18451           ip_set = 1;
18452           is_ip4 = 0;
18453           nh_sw_if_index = ~0;
18454         }
18455       else if (unformat (i, "table %d", &table_id))
18456         ;
18457       else
18458         {
18459           errmsg ("parse error '%U'", format_unformat_error, i);
18460           return -99;
18461         }
18462     }
18463
18464   if (!ip_set)
18465     {
18466       errmsg ("nh addr not set!");
18467       return -99;
18468     }
18469
18470   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18471   mp->is_add = is_add;
18472   mp->table_id = clib_host_to_net_u32 (table_id);
18473   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18474   mp->is_ip4 = is_ip4;
18475   if (is_ip4)
18476     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18477   else
18478     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18479
18480   /* send it... */
18481   S (mp);
18482
18483   /* Wait for a reply... */
18484   W (ret);
18485   return ret;
18486 }
18487
18488 static int
18489 api_one_map_server_dump (vat_main_t * vam)
18490 {
18491   vl_api_one_map_server_dump_t *mp;
18492   vl_api_control_ping_t *mp_ping;
18493   int ret;
18494
18495   if (!vam->json_output)
18496     {
18497       print (vam->ofp, "%=20s", "Map server");
18498     }
18499
18500   M (ONE_MAP_SERVER_DUMP, mp);
18501   /* send it... */
18502   S (mp);
18503
18504   /* Use a control ping for synchronization */
18505   MPING (CONTROL_PING, mp_ping);
18506   S (mp_ping);
18507
18508   /* Wait for a reply... */
18509   W (ret);
18510   return ret;
18511 }
18512
18513 #define api_lisp_map_server_dump api_one_map_server_dump
18514
18515 static int
18516 api_one_map_resolver_dump (vat_main_t * vam)
18517 {
18518   vl_api_one_map_resolver_dump_t *mp;
18519   vl_api_control_ping_t *mp_ping;
18520   int ret;
18521
18522   if (!vam->json_output)
18523     {
18524       print (vam->ofp, "%=20s", "Map resolver");
18525     }
18526
18527   M (ONE_MAP_RESOLVER_DUMP, mp);
18528   /* send it... */
18529   S (mp);
18530
18531   /* Use a control ping for synchronization */
18532   MPING (CONTROL_PING, mp_ping);
18533   S (mp_ping);
18534
18535   /* Wait for a reply... */
18536   W (ret);
18537   return ret;
18538 }
18539
18540 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18541
18542 static int
18543 api_one_stats_flush (vat_main_t * vam)
18544 {
18545   vl_api_one_stats_flush_t *mp;
18546   int ret = 0;
18547
18548   M (ONE_STATS_FLUSH, mp);
18549   S (mp);
18550   W (ret);
18551   return ret;
18552 }
18553
18554 static int
18555 api_one_stats_dump (vat_main_t * vam)
18556 {
18557   vl_api_one_stats_dump_t *mp;
18558   vl_api_control_ping_t *mp_ping;
18559   int ret;
18560
18561   M (ONE_STATS_DUMP, mp);
18562   /* send it... */
18563   S (mp);
18564
18565   /* Use a control ping for synchronization */
18566   MPING (CONTROL_PING, mp_ping);
18567   S (mp_ping);
18568
18569   /* Wait for a reply... */
18570   W (ret);
18571   return ret;
18572 }
18573
18574 static int
18575 api_show_one_status (vat_main_t * vam)
18576 {
18577   vl_api_show_one_status_t *mp;
18578   int ret;
18579
18580   if (!vam->json_output)
18581     {
18582       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18583     }
18584
18585   M (SHOW_ONE_STATUS, mp);
18586   /* send it... */
18587   S (mp);
18588   /* Wait for a reply... */
18589   W (ret);
18590   return ret;
18591 }
18592
18593 #define api_show_lisp_status api_show_one_status
18594
18595 static int
18596 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18597 {
18598   vl_api_gpe_fwd_entry_path_dump_t *mp;
18599   vl_api_control_ping_t *mp_ping;
18600   unformat_input_t *i = vam->input;
18601   u32 fwd_entry_index = ~0;
18602   int ret;
18603
18604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18605     {
18606       if (unformat (i, "index %d", &fwd_entry_index))
18607         ;
18608       else
18609         break;
18610     }
18611
18612   if (~0 == fwd_entry_index)
18613     {
18614       errmsg ("no index specified!");
18615       return -99;
18616     }
18617
18618   if (!vam->json_output)
18619     {
18620       print (vam->ofp, "first line");
18621     }
18622
18623   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18624
18625   /* send it... */
18626   S (mp);
18627   /* Use a control ping for synchronization */
18628   MPING (CONTROL_PING, mp_ping);
18629   S (mp_ping);
18630
18631   /* Wait for a reply... */
18632   W (ret);
18633   return ret;
18634 }
18635
18636 static int
18637 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18638 {
18639   vl_api_one_get_map_request_itr_rlocs_t *mp;
18640   int ret;
18641
18642   if (!vam->json_output)
18643     {
18644       print (vam->ofp, "%=20s", "itr-rlocs:");
18645     }
18646
18647   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18648   /* send it... */
18649   S (mp);
18650   /* Wait for a reply... */
18651   W (ret);
18652   return ret;
18653 }
18654
18655 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18656
18657 static int
18658 api_af_packet_create (vat_main_t * vam)
18659 {
18660   unformat_input_t *i = vam->input;
18661   vl_api_af_packet_create_t *mp;
18662   u8 *host_if_name = 0;
18663   u8 hw_addr[6];
18664   u8 random_hw_addr = 1;
18665   int ret;
18666
18667   clib_memset (hw_addr, 0, sizeof (hw_addr));
18668
18669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18670     {
18671       if (unformat (i, "name %s", &host_if_name))
18672         vec_add1 (host_if_name, 0);
18673       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18674         random_hw_addr = 0;
18675       else
18676         break;
18677     }
18678
18679   if (!vec_len (host_if_name))
18680     {
18681       errmsg ("host-interface name must be specified");
18682       return -99;
18683     }
18684
18685   if (vec_len (host_if_name) > 64)
18686     {
18687       errmsg ("host-interface name too long");
18688       return -99;
18689     }
18690
18691   M (AF_PACKET_CREATE, mp);
18692
18693   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18694   clib_memcpy (mp->hw_addr, hw_addr, 6);
18695   mp->use_random_hw_addr = random_hw_addr;
18696   vec_free (host_if_name);
18697
18698   S (mp);
18699
18700   /* *INDENT-OFF* */
18701   W2 (ret,
18702       ({
18703         if (ret == 0)
18704           fprintf (vam->ofp ? vam->ofp : stderr,
18705                    " new sw_if_index = %d\n", vam->sw_if_index);
18706       }));
18707   /* *INDENT-ON* */
18708   return ret;
18709 }
18710
18711 static int
18712 api_af_packet_delete (vat_main_t * vam)
18713 {
18714   unformat_input_t *i = vam->input;
18715   vl_api_af_packet_delete_t *mp;
18716   u8 *host_if_name = 0;
18717   int ret;
18718
18719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18720     {
18721       if (unformat (i, "name %s", &host_if_name))
18722         vec_add1 (host_if_name, 0);
18723       else
18724         break;
18725     }
18726
18727   if (!vec_len (host_if_name))
18728     {
18729       errmsg ("host-interface name must be specified");
18730       return -99;
18731     }
18732
18733   if (vec_len (host_if_name) > 64)
18734     {
18735       errmsg ("host-interface name too long");
18736       return -99;
18737     }
18738
18739   M (AF_PACKET_DELETE, mp);
18740
18741   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18742   vec_free (host_if_name);
18743
18744   S (mp);
18745   W (ret);
18746   return ret;
18747 }
18748
18749 static void vl_api_af_packet_details_t_handler
18750   (vl_api_af_packet_details_t * mp)
18751 {
18752   vat_main_t *vam = &vat_main;
18753
18754   print (vam->ofp, "%-16s %d",
18755          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18756 }
18757
18758 static void vl_api_af_packet_details_t_handler_json
18759   (vl_api_af_packet_details_t * mp)
18760 {
18761   vat_main_t *vam = &vat_main;
18762   vat_json_node_t *node = NULL;
18763
18764   if (VAT_JSON_ARRAY != vam->json_tree.type)
18765     {
18766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18767       vat_json_init_array (&vam->json_tree);
18768     }
18769   node = vat_json_array_add (&vam->json_tree);
18770
18771   vat_json_init_object (node);
18772   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18773   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18774 }
18775
18776 static int
18777 api_af_packet_dump (vat_main_t * vam)
18778 {
18779   vl_api_af_packet_dump_t *mp;
18780   vl_api_control_ping_t *mp_ping;
18781   int ret;
18782
18783   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18784   /* Get list of tap interfaces */
18785   M (AF_PACKET_DUMP, mp);
18786   S (mp);
18787
18788   /* Use a control ping for synchronization */
18789   MPING (CONTROL_PING, mp_ping);
18790   S (mp_ping);
18791
18792   W (ret);
18793   return ret;
18794 }
18795
18796 static int
18797 api_policer_add_del (vat_main_t * vam)
18798 {
18799   unformat_input_t *i = vam->input;
18800   vl_api_policer_add_del_t *mp;
18801   u8 is_add = 1;
18802   u8 *name = 0;
18803   u32 cir = 0;
18804   u32 eir = 0;
18805   u64 cb = 0;
18806   u64 eb = 0;
18807   u8 rate_type = 0;
18808   u8 round_type = 0;
18809   u8 type = 0;
18810   u8 color_aware = 0;
18811   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18812   int ret;
18813
18814   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18815   conform_action.dscp = 0;
18816   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18817   exceed_action.dscp = 0;
18818   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18819   violate_action.dscp = 0;
18820
18821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18822     {
18823       if (unformat (i, "del"))
18824         is_add = 0;
18825       else if (unformat (i, "name %s", &name))
18826         vec_add1 (name, 0);
18827       else if (unformat (i, "cir %u", &cir))
18828         ;
18829       else if (unformat (i, "eir %u", &eir))
18830         ;
18831       else if (unformat (i, "cb %u", &cb))
18832         ;
18833       else if (unformat (i, "eb %u", &eb))
18834         ;
18835       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18836                          &rate_type))
18837         ;
18838       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18839                          &round_type))
18840         ;
18841       else if (unformat (i, "type %U", unformat_policer_type, &type))
18842         ;
18843       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18844                          &conform_action))
18845         ;
18846       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18847                          &exceed_action))
18848         ;
18849       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18850                          &violate_action))
18851         ;
18852       else if (unformat (i, "color-aware"))
18853         color_aware = 1;
18854       else
18855         break;
18856     }
18857
18858   if (!vec_len (name))
18859     {
18860       errmsg ("policer name must be specified");
18861       return -99;
18862     }
18863
18864   if (vec_len (name) > 64)
18865     {
18866       errmsg ("policer name too long");
18867       return -99;
18868     }
18869
18870   M (POLICER_ADD_DEL, mp);
18871
18872   clib_memcpy (mp->name, name, vec_len (name));
18873   vec_free (name);
18874   mp->is_add = is_add;
18875   mp->cir = ntohl (cir);
18876   mp->eir = ntohl (eir);
18877   mp->cb = clib_net_to_host_u64 (cb);
18878   mp->eb = clib_net_to_host_u64 (eb);
18879   mp->rate_type = rate_type;
18880   mp->round_type = round_type;
18881   mp->type = type;
18882   mp->conform_action_type = conform_action.action_type;
18883   mp->conform_dscp = conform_action.dscp;
18884   mp->exceed_action_type = exceed_action.action_type;
18885   mp->exceed_dscp = exceed_action.dscp;
18886   mp->violate_action_type = violate_action.action_type;
18887   mp->violate_dscp = violate_action.dscp;
18888   mp->color_aware = color_aware;
18889
18890   S (mp);
18891   W (ret);
18892   return ret;
18893 }
18894
18895 static int
18896 api_policer_dump (vat_main_t * vam)
18897 {
18898   unformat_input_t *i = vam->input;
18899   vl_api_policer_dump_t *mp;
18900   vl_api_control_ping_t *mp_ping;
18901   u8 *match_name = 0;
18902   u8 match_name_valid = 0;
18903   int ret;
18904
18905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18906     {
18907       if (unformat (i, "name %s", &match_name))
18908         {
18909           vec_add1 (match_name, 0);
18910           match_name_valid = 1;
18911         }
18912       else
18913         break;
18914     }
18915
18916   M (POLICER_DUMP, mp);
18917   mp->match_name_valid = match_name_valid;
18918   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18919   vec_free (match_name);
18920   /* send it... */
18921   S (mp);
18922
18923   /* Use a control ping for synchronization */
18924   MPING (CONTROL_PING, mp_ping);
18925   S (mp_ping);
18926
18927   /* Wait for a reply... */
18928   W (ret);
18929   return ret;
18930 }
18931
18932 static int
18933 api_policer_classify_set_interface (vat_main_t * vam)
18934 {
18935   unformat_input_t *i = vam->input;
18936   vl_api_policer_classify_set_interface_t *mp;
18937   u32 sw_if_index;
18938   int sw_if_index_set;
18939   u32 ip4_table_index = ~0;
18940   u32 ip6_table_index = ~0;
18941   u32 l2_table_index = ~0;
18942   u8 is_add = 1;
18943   int ret;
18944
18945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18946     {
18947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18948         sw_if_index_set = 1;
18949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18950         sw_if_index_set = 1;
18951       else if (unformat (i, "del"))
18952         is_add = 0;
18953       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18954         ;
18955       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18956         ;
18957       else if (unformat (i, "l2-table %d", &l2_table_index))
18958         ;
18959       else
18960         {
18961           clib_warning ("parse error '%U'", format_unformat_error, i);
18962           return -99;
18963         }
18964     }
18965
18966   if (sw_if_index_set == 0)
18967     {
18968       errmsg ("missing interface name or sw_if_index");
18969       return -99;
18970     }
18971
18972   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18973
18974   mp->sw_if_index = ntohl (sw_if_index);
18975   mp->ip4_table_index = ntohl (ip4_table_index);
18976   mp->ip6_table_index = ntohl (ip6_table_index);
18977   mp->l2_table_index = ntohl (l2_table_index);
18978   mp->is_add = is_add;
18979
18980   S (mp);
18981   W (ret);
18982   return ret;
18983 }
18984
18985 static int
18986 api_policer_classify_dump (vat_main_t * vam)
18987 {
18988   unformat_input_t *i = vam->input;
18989   vl_api_policer_classify_dump_t *mp;
18990   vl_api_control_ping_t *mp_ping;
18991   u8 type = POLICER_CLASSIFY_N_TABLES;
18992   int ret;
18993
18994   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18995     ;
18996   else
18997     {
18998       errmsg ("classify table type must be specified");
18999       return -99;
19000     }
19001
19002   if (!vam->json_output)
19003     {
19004       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19005     }
19006
19007   M (POLICER_CLASSIFY_DUMP, mp);
19008   mp->type = type;
19009   /* send it... */
19010   S (mp);
19011
19012   /* Use a control ping for synchronization */
19013   MPING (CONTROL_PING, mp_ping);
19014   S (mp_ping);
19015
19016   /* Wait for a reply... */
19017   W (ret);
19018   return ret;
19019 }
19020
19021 static int
19022 api_netmap_create (vat_main_t * vam)
19023 {
19024   unformat_input_t *i = vam->input;
19025   vl_api_netmap_create_t *mp;
19026   u8 *if_name = 0;
19027   u8 hw_addr[6];
19028   u8 random_hw_addr = 1;
19029   u8 is_pipe = 0;
19030   u8 is_master = 0;
19031   int ret;
19032
19033   clib_memset (hw_addr, 0, sizeof (hw_addr));
19034
19035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19036     {
19037       if (unformat (i, "name %s", &if_name))
19038         vec_add1 (if_name, 0);
19039       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19040         random_hw_addr = 0;
19041       else if (unformat (i, "pipe"))
19042         is_pipe = 1;
19043       else if (unformat (i, "master"))
19044         is_master = 1;
19045       else if (unformat (i, "slave"))
19046         is_master = 0;
19047       else
19048         break;
19049     }
19050
19051   if (!vec_len (if_name))
19052     {
19053       errmsg ("interface name must be specified");
19054       return -99;
19055     }
19056
19057   if (vec_len (if_name) > 64)
19058     {
19059       errmsg ("interface name too long");
19060       return -99;
19061     }
19062
19063   M (NETMAP_CREATE, mp);
19064
19065   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19066   clib_memcpy (mp->hw_addr, hw_addr, 6);
19067   mp->use_random_hw_addr = random_hw_addr;
19068   mp->is_pipe = is_pipe;
19069   mp->is_master = is_master;
19070   vec_free (if_name);
19071
19072   S (mp);
19073   W (ret);
19074   return ret;
19075 }
19076
19077 static int
19078 api_netmap_delete (vat_main_t * vam)
19079 {
19080   unformat_input_t *i = vam->input;
19081   vl_api_netmap_delete_t *mp;
19082   u8 *if_name = 0;
19083   int ret;
19084
19085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19086     {
19087       if (unformat (i, "name %s", &if_name))
19088         vec_add1 (if_name, 0);
19089       else
19090         break;
19091     }
19092
19093   if (!vec_len (if_name))
19094     {
19095       errmsg ("interface name must be specified");
19096       return -99;
19097     }
19098
19099   if (vec_len (if_name) > 64)
19100     {
19101       errmsg ("interface name too long");
19102       return -99;
19103     }
19104
19105   M (NETMAP_DELETE, mp);
19106
19107   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19108   vec_free (if_name);
19109
19110   S (mp);
19111   W (ret);
19112   return ret;
19113 }
19114
19115 static void
19116 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19117 {
19118   if (fp->afi == IP46_TYPE_IP6)
19119     print (vam->ofp,
19120            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19121            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19122            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19123            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19124            format_ip6_address, fp->next_hop);
19125   else if (fp->afi == IP46_TYPE_IP4)
19126     print (vam->ofp,
19127            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19128            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19129            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19130            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19131            format_ip4_address, fp->next_hop);
19132 }
19133
19134 static void
19135 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19136                                  vl_api_fib_path_t * fp)
19137 {
19138   struct in_addr ip4;
19139   struct in6_addr ip6;
19140
19141   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19142   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19143   vat_json_object_add_uint (node, "is_local", fp->is_local);
19144   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19145   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19146   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19147   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19148   if (fp->afi == IP46_TYPE_IP4)
19149     {
19150       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19151       vat_json_object_add_ip4 (node, "next_hop", ip4);
19152     }
19153   else if (fp->afi == IP46_TYPE_IP6)
19154     {
19155       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19156       vat_json_object_add_ip6 (node, "next_hop", ip6);
19157     }
19158 }
19159
19160 static void
19161 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19162 {
19163   vat_main_t *vam = &vat_main;
19164   int count = ntohl (mp->mt_count);
19165   vl_api_fib_path_t *fp;
19166   i32 i;
19167
19168   print (vam->ofp, "[%d]: sw_if_index %d via:",
19169          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19170   fp = mp->mt_paths;
19171   for (i = 0; i < count; i++)
19172     {
19173       vl_api_mpls_fib_path_print (vam, fp);
19174       fp++;
19175     }
19176
19177   print (vam->ofp, "");
19178 }
19179
19180 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19181 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19182
19183 static void
19184 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19185 {
19186   vat_main_t *vam = &vat_main;
19187   vat_json_node_t *node = NULL;
19188   int count = ntohl (mp->mt_count);
19189   vl_api_fib_path_t *fp;
19190   i32 i;
19191
19192   if (VAT_JSON_ARRAY != vam->json_tree.type)
19193     {
19194       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19195       vat_json_init_array (&vam->json_tree);
19196     }
19197   node = vat_json_array_add (&vam->json_tree);
19198
19199   vat_json_init_object (node);
19200   vat_json_object_add_uint (node, "tunnel_index",
19201                             ntohl (mp->mt_tunnel_index));
19202   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19203
19204   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19205
19206   fp = mp->mt_paths;
19207   for (i = 0; i < count; i++)
19208     {
19209       vl_api_mpls_fib_path_json_print (node, fp);
19210       fp++;
19211     }
19212 }
19213
19214 static int
19215 api_mpls_tunnel_dump (vat_main_t * vam)
19216 {
19217   vl_api_mpls_tunnel_dump_t *mp;
19218   vl_api_control_ping_t *mp_ping;
19219   u32 sw_if_index = ~0;
19220   int ret;
19221
19222   /* Parse args required to build the message */
19223   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19224     {
19225       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19226         ;
19227     }
19228
19229   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19230
19231   M (MPLS_TUNNEL_DUMP, mp);
19232   mp->sw_if_index = htonl (sw_if_index);
19233   S (mp);
19234
19235   /* Use a control ping for synchronization */
19236   MPING (CONTROL_PING, mp_ping);
19237   S (mp_ping);
19238
19239   W (ret);
19240   return ret;
19241 }
19242
19243 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19244 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19245
19246
19247 static void
19248 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19249 {
19250   vat_main_t *vam = &vat_main;
19251   int count = ntohl (mp->count);
19252   vl_api_fib_path_t *fp;
19253   int i;
19254
19255   print (vam->ofp,
19256          "table-id %d, label %u, ess_bit %u",
19257          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19258   fp = mp->path;
19259   for (i = 0; i < count; i++)
19260     {
19261       vl_api_mpls_fib_path_print (vam, fp);
19262       fp++;
19263     }
19264 }
19265
19266 static void vl_api_mpls_fib_details_t_handler_json
19267   (vl_api_mpls_fib_details_t * mp)
19268 {
19269   vat_main_t *vam = &vat_main;
19270   int count = ntohl (mp->count);
19271   vat_json_node_t *node = NULL;
19272   vl_api_fib_path_t *fp;
19273   int i;
19274
19275   if (VAT_JSON_ARRAY != vam->json_tree.type)
19276     {
19277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19278       vat_json_init_array (&vam->json_tree);
19279     }
19280   node = vat_json_array_add (&vam->json_tree);
19281
19282   vat_json_init_object (node);
19283   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19284   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19285   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19286   vat_json_object_add_uint (node, "path_count", count);
19287   fp = mp->path;
19288   for (i = 0; i < count; i++)
19289     {
19290       vl_api_mpls_fib_path_json_print (node, fp);
19291       fp++;
19292     }
19293 }
19294
19295 static int
19296 api_mpls_fib_dump (vat_main_t * vam)
19297 {
19298   vl_api_mpls_fib_dump_t *mp;
19299   vl_api_control_ping_t *mp_ping;
19300   int ret;
19301
19302   M (MPLS_FIB_DUMP, mp);
19303   S (mp);
19304
19305   /* Use a control ping for synchronization */
19306   MPING (CONTROL_PING, mp_ping);
19307   S (mp_ping);
19308
19309   W (ret);
19310   return ret;
19311 }
19312
19313 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19314 #define vl_api_ip_fib_details_t_print vl_noop_handler
19315
19316 static void
19317 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19318 {
19319   vat_main_t *vam = &vat_main;
19320   int count = ntohl (mp->count);
19321   vl_api_fib_path_t *fp;
19322   int i;
19323
19324   print (vam->ofp,
19325          "table-id %d, prefix %U/%d stats-index %d",
19326          ntohl (mp->table_id), format_ip4_address, mp->address,
19327          mp->address_length, ntohl (mp->stats_index));
19328   fp = mp->path;
19329   for (i = 0; i < count; i++)
19330     {
19331       if (fp->afi == IP46_TYPE_IP6)
19332         print (vam->ofp,
19333                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19334                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19335                "next_hop_table %d",
19336                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19337                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19338                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19339       else if (fp->afi == IP46_TYPE_IP4)
19340         print (vam->ofp,
19341                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19342                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19343                "next_hop_table %d",
19344                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19345                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19346                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19347       fp++;
19348     }
19349 }
19350
19351 static void vl_api_ip_fib_details_t_handler_json
19352   (vl_api_ip_fib_details_t * mp)
19353 {
19354   vat_main_t *vam = &vat_main;
19355   int count = ntohl (mp->count);
19356   vat_json_node_t *node = NULL;
19357   struct in_addr ip4;
19358   struct in6_addr ip6;
19359   vl_api_fib_path_t *fp;
19360   int i;
19361
19362   if (VAT_JSON_ARRAY != vam->json_tree.type)
19363     {
19364       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19365       vat_json_init_array (&vam->json_tree);
19366     }
19367   node = vat_json_array_add (&vam->json_tree);
19368
19369   vat_json_init_object (node);
19370   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19371   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19372   vat_json_object_add_ip4 (node, "prefix", ip4);
19373   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19374   vat_json_object_add_uint (node, "path_count", count);
19375   fp = mp->path;
19376   for (i = 0; i < count; i++)
19377     {
19378       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19379       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19380       vat_json_object_add_uint (node, "is_local", fp->is_local);
19381       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19382       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19383       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19384       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19385       if (fp->afi == IP46_TYPE_IP4)
19386         {
19387           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19388           vat_json_object_add_ip4 (node, "next_hop", ip4);
19389         }
19390       else if (fp->afi == IP46_TYPE_IP6)
19391         {
19392           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19393           vat_json_object_add_ip6 (node, "next_hop", ip6);
19394         }
19395     }
19396 }
19397
19398 static int
19399 api_ip_fib_dump (vat_main_t * vam)
19400 {
19401   vl_api_ip_fib_dump_t *mp;
19402   vl_api_control_ping_t *mp_ping;
19403   int ret;
19404
19405   M (IP_FIB_DUMP, mp);
19406   S (mp);
19407
19408   /* Use a control ping for synchronization */
19409   MPING (CONTROL_PING, mp_ping);
19410   S (mp_ping);
19411
19412   W (ret);
19413   return ret;
19414 }
19415
19416 static int
19417 api_ip_mfib_dump (vat_main_t * vam)
19418 {
19419   vl_api_ip_mfib_dump_t *mp;
19420   vl_api_control_ping_t *mp_ping;
19421   int ret;
19422
19423   M (IP_MFIB_DUMP, mp);
19424   S (mp);
19425
19426   /* Use a control ping for synchronization */
19427   MPING (CONTROL_PING, mp_ping);
19428   S (mp_ping);
19429
19430   W (ret);
19431   return ret;
19432 }
19433
19434 static void vl_api_ip_neighbor_details_t_handler
19435   (vl_api_ip_neighbor_details_t * mp)
19436 {
19437   vat_main_t *vam = &vat_main;
19438
19439   print (vam->ofp, "%c %U %U",
19440          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19441          format_vl_api_mac_address, &mp->neighbor.mac_address,
19442          format_vl_api_address, &mp->neighbor.ip_address);
19443 }
19444
19445 static void vl_api_ip_neighbor_details_t_handler_json
19446   (vl_api_ip_neighbor_details_t * mp)
19447 {
19448
19449   vat_main_t *vam = &vat_main;
19450   vat_json_node_t *node;
19451
19452   if (VAT_JSON_ARRAY != vam->json_tree.type)
19453     {
19454       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19455       vat_json_init_array (&vam->json_tree);
19456     }
19457   node = vat_json_array_add (&vam->json_tree);
19458
19459   vat_json_init_object (node);
19460   vat_json_object_add_string_copy
19461     (node, "flag",
19462      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19463       (u8 *) "static" : (u8 *) "dynamic"));
19464
19465   vat_json_object_add_string_copy (node, "link_layer",
19466                                    format (0, "%U", format_vl_api_mac_address,
19467                                            &mp->neighbor.mac_address));
19468   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19469 }
19470
19471 static int
19472 api_ip_neighbor_dump (vat_main_t * vam)
19473 {
19474   unformat_input_t *i = vam->input;
19475   vl_api_ip_neighbor_dump_t *mp;
19476   vl_api_control_ping_t *mp_ping;
19477   u8 is_ipv6 = 0;
19478   u32 sw_if_index = ~0;
19479   int ret;
19480
19481   /* Parse args required to build the message */
19482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19483     {
19484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19485         ;
19486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19487         ;
19488       else if (unformat (i, "ip6"))
19489         is_ipv6 = 1;
19490       else
19491         break;
19492     }
19493
19494   if (sw_if_index == ~0)
19495     {
19496       errmsg ("missing interface name or sw_if_index");
19497       return -99;
19498     }
19499
19500   M (IP_NEIGHBOR_DUMP, mp);
19501   mp->is_ipv6 = (u8) is_ipv6;
19502   mp->sw_if_index = ntohl (sw_if_index);
19503   S (mp);
19504
19505   /* Use a control ping for synchronization */
19506   MPING (CONTROL_PING, mp_ping);
19507   S (mp_ping);
19508
19509   W (ret);
19510   return ret;
19511 }
19512
19513 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19514 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19515
19516 static void
19517 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19518 {
19519   vat_main_t *vam = &vat_main;
19520   int count = ntohl (mp->count);
19521   vl_api_fib_path_t *fp;
19522   int i;
19523
19524   print (vam->ofp,
19525          "table-id %d, prefix %U/%d stats-index %d",
19526          ntohl (mp->table_id), format_ip6_address, mp->address,
19527          mp->address_length, ntohl (mp->stats_index));
19528   fp = mp->path;
19529   for (i = 0; i < count; i++)
19530     {
19531       if (fp->afi == IP46_TYPE_IP6)
19532         print (vam->ofp,
19533                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19534                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19535                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19536                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19537                format_ip6_address, fp->next_hop);
19538       else if (fp->afi == IP46_TYPE_IP4)
19539         print (vam->ofp,
19540                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19541                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19542                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19543                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19544                format_ip4_address, fp->next_hop);
19545       fp++;
19546     }
19547 }
19548
19549 static void vl_api_ip6_fib_details_t_handler_json
19550   (vl_api_ip6_fib_details_t * mp)
19551 {
19552   vat_main_t *vam = &vat_main;
19553   int count = ntohl (mp->count);
19554   vat_json_node_t *node = NULL;
19555   struct in_addr ip4;
19556   struct in6_addr ip6;
19557   vl_api_fib_path_t *fp;
19558   int i;
19559
19560   if (VAT_JSON_ARRAY != vam->json_tree.type)
19561     {
19562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19563       vat_json_init_array (&vam->json_tree);
19564     }
19565   node = vat_json_array_add (&vam->json_tree);
19566
19567   vat_json_init_object (node);
19568   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19569   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19570   vat_json_object_add_ip6 (node, "prefix", ip6);
19571   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19572   vat_json_object_add_uint (node, "path_count", count);
19573   fp = mp->path;
19574   for (i = 0; i < count; i++)
19575     {
19576       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19577       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19578       vat_json_object_add_uint (node, "is_local", fp->is_local);
19579       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19580       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19581       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19582       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19583       if (fp->afi == IP46_TYPE_IP4)
19584         {
19585           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19586           vat_json_object_add_ip4 (node, "next_hop", ip4);
19587         }
19588       else if (fp->afi == IP46_TYPE_IP6)
19589         {
19590           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19591           vat_json_object_add_ip6 (node, "next_hop", ip6);
19592         }
19593     }
19594 }
19595
19596 static int
19597 api_ip6_fib_dump (vat_main_t * vam)
19598 {
19599   vl_api_ip6_fib_dump_t *mp;
19600   vl_api_control_ping_t *mp_ping;
19601   int ret;
19602
19603   M (IP6_FIB_DUMP, mp);
19604   S (mp);
19605
19606   /* Use a control ping for synchronization */
19607   MPING (CONTROL_PING, mp_ping);
19608   S (mp_ping);
19609
19610   W (ret);
19611   return ret;
19612 }
19613
19614 static int
19615 api_ip6_mfib_dump (vat_main_t * vam)
19616 {
19617   vl_api_ip6_mfib_dump_t *mp;
19618   vl_api_control_ping_t *mp_ping;
19619   int ret;
19620
19621   M (IP6_MFIB_DUMP, mp);
19622   S (mp);
19623
19624   /* Use a control ping for synchronization */
19625   MPING (CONTROL_PING, mp_ping);
19626   S (mp_ping);
19627
19628   W (ret);
19629   return ret;
19630 }
19631
19632 int
19633 api_classify_table_ids (vat_main_t * vam)
19634 {
19635   vl_api_classify_table_ids_t *mp;
19636   int ret;
19637
19638   /* Construct the API message */
19639   M (CLASSIFY_TABLE_IDS, mp);
19640   mp->context = 0;
19641
19642   S (mp);
19643   W (ret);
19644   return ret;
19645 }
19646
19647 int
19648 api_classify_table_by_interface (vat_main_t * vam)
19649 {
19650   unformat_input_t *input = vam->input;
19651   vl_api_classify_table_by_interface_t *mp;
19652
19653   u32 sw_if_index = ~0;
19654   int ret;
19655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19656     {
19657       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19658         ;
19659       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19660         ;
19661       else
19662         break;
19663     }
19664   if (sw_if_index == ~0)
19665     {
19666       errmsg ("missing interface name or sw_if_index");
19667       return -99;
19668     }
19669
19670   /* Construct the API message */
19671   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19672   mp->context = 0;
19673   mp->sw_if_index = ntohl (sw_if_index);
19674
19675   S (mp);
19676   W (ret);
19677   return ret;
19678 }
19679
19680 int
19681 api_classify_table_info (vat_main_t * vam)
19682 {
19683   unformat_input_t *input = vam->input;
19684   vl_api_classify_table_info_t *mp;
19685
19686   u32 table_id = ~0;
19687   int ret;
19688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19689     {
19690       if (unformat (input, "table_id %d", &table_id))
19691         ;
19692       else
19693         break;
19694     }
19695   if (table_id == ~0)
19696     {
19697       errmsg ("missing table id");
19698       return -99;
19699     }
19700
19701   /* Construct the API message */
19702   M (CLASSIFY_TABLE_INFO, mp);
19703   mp->context = 0;
19704   mp->table_id = ntohl (table_id);
19705
19706   S (mp);
19707   W (ret);
19708   return ret;
19709 }
19710
19711 int
19712 api_classify_session_dump (vat_main_t * vam)
19713 {
19714   unformat_input_t *input = vam->input;
19715   vl_api_classify_session_dump_t *mp;
19716   vl_api_control_ping_t *mp_ping;
19717
19718   u32 table_id = ~0;
19719   int ret;
19720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19721     {
19722       if (unformat (input, "table_id %d", &table_id))
19723         ;
19724       else
19725         break;
19726     }
19727   if (table_id == ~0)
19728     {
19729       errmsg ("missing table id");
19730       return -99;
19731     }
19732
19733   /* Construct the API message */
19734   M (CLASSIFY_SESSION_DUMP, mp);
19735   mp->context = 0;
19736   mp->table_id = ntohl (table_id);
19737   S (mp);
19738
19739   /* Use a control ping for synchronization */
19740   MPING (CONTROL_PING, mp_ping);
19741   S (mp_ping);
19742
19743   W (ret);
19744   return ret;
19745 }
19746
19747 static void
19748 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19749 {
19750   vat_main_t *vam = &vat_main;
19751
19752   print (vam->ofp, "collector_address %U, collector_port %d, "
19753          "src_address %U, vrf_id %d, path_mtu %u, "
19754          "template_interval %u, udp_checksum %d",
19755          format_ip4_address, mp->collector_address,
19756          ntohs (mp->collector_port),
19757          format_ip4_address, mp->src_address,
19758          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19759          ntohl (mp->template_interval), mp->udp_checksum);
19760
19761   vam->retval = 0;
19762   vam->result_ready = 1;
19763 }
19764
19765 static void
19766   vl_api_ipfix_exporter_details_t_handler_json
19767   (vl_api_ipfix_exporter_details_t * mp)
19768 {
19769   vat_main_t *vam = &vat_main;
19770   vat_json_node_t node;
19771   struct in_addr collector_address;
19772   struct in_addr src_address;
19773
19774   vat_json_init_object (&node);
19775   clib_memcpy (&collector_address, &mp->collector_address,
19776                sizeof (collector_address));
19777   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19778   vat_json_object_add_uint (&node, "collector_port",
19779                             ntohs (mp->collector_port));
19780   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19781   vat_json_object_add_ip4 (&node, "src_address", src_address);
19782   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19783   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19784   vat_json_object_add_uint (&node, "template_interval",
19785                             ntohl (mp->template_interval));
19786   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19787
19788   vat_json_print (vam->ofp, &node);
19789   vat_json_free (&node);
19790   vam->retval = 0;
19791   vam->result_ready = 1;
19792 }
19793
19794 int
19795 api_ipfix_exporter_dump (vat_main_t * vam)
19796 {
19797   vl_api_ipfix_exporter_dump_t *mp;
19798   int ret;
19799
19800   /* Construct the API message */
19801   M (IPFIX_EXPORTER_DUMP, mp);
19802   mp->context = 0;
19803
19804   S (mp);
19805   W (ret);
19806   return ret;
19807 }
19808
19809 static int
19810 api_ipfix_classify_stream_dump (vat_main_t * vam)
19811 {
19812   vl_api_ipfix_classify_stream_dump_t *mp;
19813   int ret;
19814
19815   /* Construct the API message */
19816   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19817   mp->context = 0;
19818
19819   S (mp);
19820   W (ret);
19821   return ret;
19822   /* NOTREACHED */
19823   return 0;
19824 }
19825
19826 static void
19827   vl_api_ipfix_classify_stream_details_t_handler
19828   (vl_api_ipfix_classify_stream_details_t * mp)
19829 {
19830   vat_main_t *vam = &vat_main;
19831   print (vam->ofp, "domain_id %d, src_port %d",
19832          ntohl (mp->domain_id), ntohs (mp->src_port));
19833   vam->retval = 0;
19834   vam->result_ready = 1;
19835 }
19836
19837 static void
19838   vl_api_ipfix_classify_stream_details_t_handler_json
19839   (vl_api_ipfix_classify_stream_details_t * mp)
19840 {
19841   vat_main_t *vam = &vat_main;
19842   vat_json_node_t node;
19843
19844   vat_json_init_object (&node);
19845   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19846   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19847
19848   vat_json_print (vam->ofp, &node);
19849   vat_json_free (&node);
19850   vam->retval = 0;
19851   vam->result_ready = 1;
19852 }
19853
19854 static int
19855 api_ipfix_classify_table_dump (vat_main_t * vam)
19856 {
19857   vl_api_ipfix_classify_table_dump_t *mp;
19858   vl_api_control_ping_t *mp_ping;
19859   int ret;
19860
19861   if (!vam->json_output)
19862     {
19863       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19864              "transport_protocol");
19865     }
19866
19867   /* Construct the API message */
19868   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19869
19870   /* send it... */
19871   S (mp);
19872
19873   /* Use a control ping for synchronization */
19874   MPING (CONTROL_PING, mp_ping);
19875   S (mp_ping);
19876
19877   W (ret);
19878   return ret;
19879 }
19880
19881 static void
19882   vl_api_ipfix_classify_table_details_t_handler
19883   (vl_api_ipfix_classify_table_details_t * mp)
19884 {
19885   vat_main_t *vam = &vat_main;
19886   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19887          mp->transport_protocol);
19888 }
19889
19890 static void
19891   vl_api_ipfix_classify_table_details_t_handler_json
19892   (vl_api_ipfix_classify_table_details_t * mp)
19893 {
19894   vat_json_node_t *node = NULL;
19895   vat_main_t *vam = &vat_main;
19896
19897   if (VAT_JSON_ARRAY != vam->json_tree.type)
19898     {
19899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19900       vat_json_init_array (&vam->json_tree);
19901     }
19902
19903   node = vat_json_array_add (&vam->json_tree);
19904   vat_json_init_object (node);
19905
19906   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19907   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19908   vat_json_object_add_uint (node, "transport_protocol",
19909                             mp->transport_protocol);
19910 }
19911
19912 static int
19913 api_sw_interface_span_enable_disable (vat_main_t * vam)
19914 {
19915   unformat_input_t *i = vam->input;
19916   vl_api_sw_interface_span_enable_disable_t *mp;
19917   u32 src_sw_if_index = ~0;
19918   u32 dst_sw_if_index = ~0;
19919   u8 state = 3;
19920   int ret;
19921   u8 is_l2 = 0;
19922
19923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19924     {
19925       if (unformat
19926           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19927         ;
19928       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19929         ;
19930       else
19931         if (unformat
19932             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19933         ;
19934       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19935         ;
19936       else if (unformat (i, "disable"))
19937         state = 0;
19938       else if (unformat (i, "rx"))
19939         state = 1;
19940       else if (unformat (i, "tx"))
19941         state = 2;
19942       else if (unformat (i, "both"))
19943         state = 3;
19944       else if (unformat (i, "l2"))
19945         is_l2 = 1;
19946       else
19947         break;
19948     }
19949
19950   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19951
19952   mp->sw_if_index_from = htonl (src_sw_if_index);
19953   mp->sw_if_index_to = htonl (dst_sw_if_index);
19954   mp->state = state;
19955   mp->is_l2 = is_l2;
19956
19957   S (mp);
19958   W (ret);
19959   return ret;
19960 }
19961
19962 static void
19963 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19964                                             * mp)
19965 {
19966   vat_main_t *vam = &vat_main;
19967   u8 *sw_if_from_name = 0;
19968   u8 *sw_if_to_name = 0;
19969   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19970   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19971   char *states[] = { "none", "rx", "tx", "both" };
19972   hash_pair_t *p;
19973
19974   /* *INDENT-OFF* */
19975   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19976   ({
19977     if ((u32) p->value[0] == sw_if_index_from)
19978       {
19979         sw_if_from_name = (u8 *)(p->key);
19980         if (sw_if_to_name)
19981           break;
19982       }
19983     if ((u32) p->value[0] == sw_if_index_to)
19984       {
19985         sw_if_to_name = (u8 *)(p->key);
19986         if (sw_if_from_name)
19987           break;
19988       }
19989   }));
19990   /* *INDENT-ON* */
19991   print (vam->ofp, "%20s => %20s (%s) %s",
19992          sw_if_from_name, sw_if_to_name, states[mp->state],
19993          mp->is_l2 ? "l2" : "device");
19994 }
19995
19996 static void
19997   vl_api_sw_interface_span_details_t_handler_json
19998   (vl_api_sw_interface_span_details_t * mp)
19999 {
20000   vat_main_t *vam = &vat_main;
20001   vat_json_node_t *node = NULL;
20002   u8 *sw_if_from_name = 0;
20003   u8 *sw_if_to_name = 0;
20004   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20005   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20006   hash_pair_t *p;
20007
20008   /* *INDENT-OFF* */
20009   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20010   ({
20011     if ((u32) p->value[0] == sw_if_index_from)
20012       {
20013         sw_if_from_name = (u8 *)(p->key);
20014         if (sw_if_to_name)
20015           break;
20016       }
20017     if ((u32) p->value[0] == sw_if_index_to)
20018       {
20019         sw_if_to_name = (u8 *)(p->key);
20020         if (sw_if_from_name)
20021           break;
20022       }
20023   }));
20024   /* *INDENT-ON* */
20025
20026   if (VAT_JSON_ARRAY != vam->json_tree.type)
20027     {
20028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20029       vat_json_init_array (&vam->json_tree);
20030     }
20031   node = vat_json_array_add (&vam->json_tree);
20032
20033   vat_json_init_object (node);
20034   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20035   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20036   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20037   if (0 != sw_if_to_name)
20038     {
20039       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20040     }
20041   vat_json_object_add_uint (node, "state", mp->state);
20042   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20043 }
20044
20045 static int
20046 api_sw_interface_span_dump (vat_main_t * vam)
20047 {
20048   unformat_input_t *input = vam->input;
20049   vl_api_sw_interface_span_dump_t *mp;
20050   vl_api_control_ping_t *mp_ping;
20051   u8 is_l2 = 0;
20052   int ret;
20053
20054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20055     {
20056       if (unformat (input, "l2"))
20057         is_l2 = 1;
20058       else
20059         break;
20060     }
20061
20062   M (SW_INTERFACE_SPAN_DUMP, mp);
20063   mp->is_l2 = is_l2;
20064   S (mp);
20065
20066   /* Use a control ping for synchronization */
20067   MPING (CONTROL_PING, mp_ping);
20068   S (mp_ping);
20069
20070   W (ret);
20071   return ret;
20072 }
20073
20074 int
20075 api_pg_create_interface (vat_main_t * vam)
20076 {
20077   unformat_input_t *input = vam->input;
20078   vl_api_pg_create_interface_t *mp;
20079
20080   u32 if_id = ~0;
20081   int ret;
20082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20083     {
20084       if (unformat (input, "if_id %d", &if_id))
20085         ;
20086       else
20087         break;
20088     }
20089   if (if_id == ~0)
20090     {
20091       errmsg ("missing pg interface index");
20092       return -99;
20093     }
20094
20095   /* Construct the API message */
20096   M (PG_CREATE_INTERFACE, mp);
20097   mp->context = 0;
20098   mp->interface_id = ntohl (if_id);
20099
20100   S (mp);
20101   W (ret);
20102   return ret;
20103 }
20104
20105 int
20106 api_pg_capture (vat_main_t * vam)
20107 {
20108   unformat_input_t *input = vam->input;
20109   vl_api_pg_capture_t *mp;
20110
20111   u32 if_id = ~0;
20112   u8 enable = 1;
20113   u32 count = 1;
20114   u8 pcap_file_set = 0;
20115   u8 *pcap_file = 0;
20116   int ret;
20117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20118     {
20119       if (unformat (input, "if_id %d", &if_id))
20120         ;
20121       else if (unformat (input, "pcap %s", &pcap_file))
20122         pcap_file_set = 1;
20123       else if (unformat (input, "count %d", &count))
20124         ;
20125       else if (unformat (input, "disable"))
20126         enable = 0;
20127       else
20128         break;
20129     }
20130   if (if_id == ~0)
20131     {
20132       errmsg ("missing pg interface index");
20133       return -99;
20134     }
20135   if (pcap_file_set > 0)
20136     {
20137       if (vec_len (pcap_file) > 255)
20138         {
20139           errmsg ("pcap file name is too long");
20140           return -99;
20141         }
20142     }
20143
20144   u32 name_len = vec_len (pcap_file);
20145   /* Construct the API message */
20146   M (PG_CAPTURE, mp);
20147   mp->context = 0;
20148   mp->interface_id = ntohl (if_id);
20149   mp->is_enabled = enable;
20150   mp->count = ntohl (count);
20151   mp->pcap_name_length = ntohl (name_len);
20152   if (pcap_file_set != 0)
20153     {
20154       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20155     }
20156   vec_free (pcap_file);
20157
20158   S (mp);
20159   W (ret);
20160   return ret;
20161 }
20162
20163 int
20164 api_pg_enable_disable (vat_main_t * vam)
20165 {
20166   unformat_input_t *input = vam->input;
20167   vl_api_pg_enable_disable_t *mp;
20168
20169   u8 enable = 1;
20170   u8 stream_name_set = 0;
20171   u8 *stream_name = 0;
20172   int ret;
20173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20174     {
20175       if (unformat (input, "stream %s", &stream_name))
20176         stream_name_set = 1;
20177       else if (unformat (input, "disable"))
20178         enable = 0;
20179       else
20180         break;
20181     }
20182
20183   if (stream_name_set > 0)
20184     {
20185       if (vec_len (stream_name) > 255)
20186         {
20187           errmsg ("stream name too long");
20188           return -99;
20189         }
20190     }
20191
20192   u32 name_len = vec_len (stream_name);
20193   /* Construct the API message */
20194   M (PG_ENABLE_DISABLE, mp);
20195   mp->context = 0;
20196   mp->is_enabled = enable;
20197   if (stream_name_set != 0)
20198     {
20199       mp->stream_name_length = ntohl (name_len);
20200       clib_memcpy (mp->stream_name, stream_name, name_len);
20201     }
20202   vec_free (stream_name);
20203
20204   S (mp);
20205   W (ret);
20206   return ret;
20207 }
20208
20209 int
20210 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20211 {
20212   unformat_input_t *input = vam->input;
20213   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20214
20215   u16 *low_ports = 0;
20216   u16 *high_ports = 0;
20217   u16 this_low;
20218   u16 this_hi;
20219   vl_api_prefix_t prefix;
20220   u32 tmp, tmp2;
20221   u8 prefix_set = 0;
20222   u32 vrf_id = ~0;
20223   u8 is_add = 1;
20224   u8 is_ipv6 = 0;
20225   int ret;
20226
20227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20228     {
20229       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20230         prefix_set = 1;
20231       else if (unformat (input, "vrf %d", &vrf_id))
20232         ;
20233       else if (unformat (input, "del"))
20234         is_add = 0;
20235       else if (unformat (input, "port %d", &tmp))
20236         {
20237           if (tmp == 0 || tmp > 65535)
20238             {
20239               errmsg ("port %d out of range", tmp);
20240               return -99;
20241             }
20242           this_low = tmp;
20243           this_hi = this_low + 1;
20244           vec_add1 (low_ports, this_low);
20245           vec_add1 (high_ports, this_hi);
20246         }
20247       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20248         {
20249           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20250             {
20251               errmsg ("incorrect range parameters");
20252               return -99;
20253             }
20254           this_low = tmp;
20255           /* Note: in debug CLI +1 is added to high before
20256              passing to real fn that does "the work"
20257              (ip_source_and_port_range_check_add_del).
20258              This fn is a wrapper around the binary API fn a
20259              control plane will call, which expects this increment
20260              to have occurred. Hence letting the binary API control
20261              plane fn do the increment for consistency between VAT
20262              and other control planes.
20263            */
20264           this_hi = tmp2;
20265           vec_add1 (low_ports, this_low);
20266           vec_add1 (high_ports, this_hi);
20267         }
20268       else
20269         break;
20270     }
20271
20272   if (prefix_set == 0)
20273     {
20274       errmsg ("<address>/<mask> not specified");
20275       return -99;
20276     }
20277
20278   if (vrf_id == ~0)
20279     {
20280       errmsg ("VRF ID required, not specified");
20281       return -99;
20282     }
20283
20284   if (vrf_id == 0)
20285     {
20286       errmsg
20287         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20288       return -99;
20289     }
20290
20291   if (vec_len (low_ports) == 0)
20292     {
20293       errmsg ("At least one port or port range required");
20294       return -99;
20295     }
20296
20297   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20298
20299   mp->is_add = is_add;
20300
20301   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20302
20303   mp->number_of_ranges = vec_len (low_ports);
20304
20305   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20306   vec_free (low_ports);
20307
20308   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20309   vec_free (high_ports);
20310
20311   mp->vrf_id = ntohl (vrf_id);
20312
20313   S (mp);
20314   W (ret);
20315   return ret;
20316 }
20317
20318 int
20319 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20320 {
20321   unformat_input_t *input = vam->input;
20322   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20323   u32 sw_if_index = ~0;
20324   int vrf_set = 0;
20325   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20326   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20327   u8 is_add = 1;
20328   int ret;
20329
20330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20331     {
20332       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20333         ;
20334       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20335         ;
20336       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20337         vrf_set = 1;
20338       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20339         vrf_set = 1;
20340       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20341         vrf_set = 1;
20342       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20343         vrf_set = 1;
20344       else if (unformat (input, "del"))
20345         is_add = 0;
20346       else
20347         break;
20348     }
20349
20350   if (sw_if_index == ~0)
20351     {
20352       errmsg ("Interface required but not specified");
20353       return -99;
20354     }
20355
20356   if (vrf_set == 0)
20357     {
20358       errmsg ("VRF ID required but not specified");
20359       return -99;
20360     }
20361
20362   if (tcp_out_vrf_id == 0
20363       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20364     {
20365       errmsg
20366         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20367       return -99;
20368     }
20369
20370   /* Construct the API message */
20371   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20372
20373   mp->sw_if_index = ntohl (sw_if_index);
20374   mp->is_add = is_add;
20375   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20376   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20377   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20378   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20379
20380   /* send it... */
20381   S (mp);
20382
20383   /* Wait for a reply... */
20384   W (ret);
20385   return ret;
20386 }
20387
20388 static int
20389 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20390 {
20391   unformat_input_t *i = vam->input;
20392   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20393   u32 local_sa_id = 0;
20394   u32 remote_sa_id = 0;
20395   vl_api_ip4_address_t src_address;
20396   vl_api_ip4_address_t dst_address;
20397   u8 is_add = 1;
20398   int ret;
20399
20400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20401     {
20402       if (unformat (i, "local_sa %d", &local_sa_id))
20403         ;
20404       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20405         ;
20406       else
20407         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20408         ;
20409       else
20410         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20411         ;
20412       else if (unformat (i, "del"))
20413         is_add = 0;
20414       else
20415         {
20416           clib_warning ("parse error '%U'", format_unformat_error, i);
20417           return -99;
20418         }
20419     }
20420
20421   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20422
20423   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20424   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20425   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20426   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20427   mp->is_add = is_add;
20428
20429   S (mp);
20430   W (ret);
20431   return ret;
20432 }
20433
20434 static int
20435 api_set_punt (vat_main_t * vam)
20436 {
20437   unformat_input_t *i = vam->input;
20438   vl_api_set_punt_t *mp;
20439   u32 ipv = ~0;
20440   u32 protocol = ~0;
20441   u32 port = ~0;
20442   int is_add = 1;
20443   int ret;
20444
20445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20446     {
20447       if (unformat (i, "ip %d", &ipv))
20448         ;
20449       else if (unformat (i, "protocol %d", &protocol))
20450         ;
20451       else if (unformat (i, "port %d", &port))
20452         ;
20453       else if (unformat (i, "del"))
20454         is_add = 0;
20455       else
20456         {
20457           clib_warning ("parse error '%U'", format_unformat_error, i);
20458           return -99;
20459         }
20460     }
20461
20462   M (SET_PUNT, mp);
20463
20464   mp->is_add = (u8) is_add;
20465   mp->punt.ipv = (u8) ipv;
20466   mp->punt.l4_protocol = (u8) protocol;
20467   mp->punt.l4_port = htons ((u16) port);
20468
20469   S (mp);
20470   W (ret);
20471   return ret;
20472 }
20473
20474 static void vl_api_ipsec_gre_tunnel_details_t_handler
20475   (vl_api_ipsec_gre_tunnel_details_t * mp)
20476 {
20477   vat_main_t *vam = &vat_main;
20478
20479   print (vam->ofp, "%11d%15U%15U%14d%14d",
20480          ntohl (mp->tunnel.sw_if_index),
20481          format_vl_api_ip4_address, mp->tunnel.src,
20482          format_vl_api_ip4_address, mp->tunnel.dst,
20483          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20484 }
20485
20486 static void
20487 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20488                                 const char *name,
20489                                 const vl_api_ip4_address_t addr)
20490 {
20491   struct in_addr ip4;
20492
20493   clib_memcpy (&ip4, addr, sizeof (ip4));
20494   vat_json_object_add_ip4 (node, name, ip4);
20495 }
20496
20497 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20498   (vl_api_ipsec_gre_tunnel_details_t * mp)
20499 {
20500   vat_main_t *vam = &vat_main;
20501   vat_json_node_t *node = NULL;
20502   struct in_addr ip4;
20503
20504   if (VAT_JSON_ARRAY != vam->json_tree.type)
20505     {
20506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20507       vat_json_init_array (&vam->json_tree);
20508     }
20509   node = vat_json_array_add (&vam->json_tree);
20510
20511   vat_json_init_object (node);
20512   vat_json_object_add_uint (node, "sw_if_index",
20513                             ntohl (mp->tunnel.sw_if_index));
20514   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20515   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20516   vat_json_object_add_uint (node, "local_sa_id",
20517                             ntohl (mp->tunnel.local_sa_id));
20518   vat_json_object_add_uint (node, "remote_sa_id",
20519                             ntohl (mp->tunnel.remote_sa_id));
20520 }
20521
20522 static int
20523 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20524 {
20525   unformat_input_t *i = vam->input;
20526   vl_api_ipsec_gre_tunnel_dump_t *mp;
20527   vl_api_control_ping_t *mp_ping;
20528   u32 sw_if_index;
20529   u8 sw_if_index_set = 0;
20530   int ret;
20531
20532   /* Parse args required to build the message */
20533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20534     {
20535       if (unformat (i, "sw_if_index %d", &sw_if_index))
20536         sw_if_index_set = 1;
20537       else
20538         break;
20539     }
20540
20541   if (sw_if_index_set == 0)
20542     {
20543       sw_if_index = ~0;
20544     }
20545
20546   if (!vam->json_output)
20547     {
20548       print (vam->ofp, "%11s%15s%15s%14s%14s",
20549              "sw_if_index", "src_address", "dst_address",
20550              "local_sa_id", "remote_sa_id");
20551     }
20552
20553   /* Get list of gre-tunnel interfaces */
20554   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20555
20556   mp->sw_if_index = htonl (sw_if_index);
20557
20558   S (mp);
20559
20560   /* Use a control ping for synchronization */
20561   MPING (CONTROL_PING, mp_ping);
20562   S (mp_ping);
20563
20564   W (ret);
20565   return ret;
20566 }
20567
20568 static int
20569 api_delete_subif (vat_main_t * vam)
20570 {
20571   unformat_input_t *i = vam->input;
20572   vl_api_delete_subif_t *mp;
20573   u32 sw_if_index = ~0;
20574   int ret;
20575
20576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20577     {
20578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20579         ;
20580       if (unformat (i, "sw_if_index %d", &sw_if_index))
20581         ;
20582       else
20583         break;
20584     }
20585
20586   if (sw_if_index == ~0)
20587     {
20588       errmsg ("missing sw_if_index");
20589       return -99;
20590     }
20591
20592   /* Construct the API message */
20593   M (DELETE_SUBIF, mp);
20594   mp->sw_if_index = ntohl (sw_if_index);
20595
20596   S (mp);
20597   W (ret);
20598   return ret;
20599 }
20600
20601 #define foreach_pbb_vtr_op      \
20602 _("disable",  L2_VTR_DISABLED)  \
20603 _("pop",  L2_VTR_POP_2)         \
20604 _("push",  L2_VTR_PUSH_2)
20605
20606 static int
20607 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20608 {
20609   unformat_input_t *i = vam->input;
20610   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20611   u32 sw_if_index = ~0, vtr_op = ~0;
20612   u16 outer_tag = ~0;
20613   u8 dmac[6], smac[6];
20614   u8 dmac_set = 0, smac_set = 0;
20615   u16 vlanid = 0;
20616   u32 sid = ~0;
20617   u32 tmp;
20618   int ret;
20619
20620   /* Shut up coverity */
20621   clib_memset (dmac, 0, sizeof (dmac));
20622   clib_memset (smac, 0, sizeof (smac));
20623
20624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20625     {
20626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20627         ;
20628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20629         ;
20630       else if (unformat (i, "vtr_op %d", &vtr_op))
20631         ;
20632 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20633       foreach_pbb_vtr_op
20634 #undef _
20635         else if (unformat (i, "translate_pbb_stag"))
20636         {
20637           if (unformat (i, "%d", &tmp))
20638             {
20639               vtr_op = L2_VTR_TRANSLATE_2_1;
20640               outer_tag = tmp;
20641             }
20642           else
20643             {
20644               errmsg
20645                 ("translate_pbb_stag operation requires outer tag definition");
20646               return -99;
20647             }
20648         }
20649       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20650         dmac_set++;
20651       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20652         smac_set++;
20653       else if (unformat (i, "sid %d", &sid))
20654         ;
20655       else if (unformat (i, "vlanid %d", &tmp))
20656         vlanid = tmp;
20657       else
20658         {
20659           clib_warning ("parse error '%U'", format_unformat_error, i);
20660           return -99;
20661         }
20662     }
20663
20664   if ((sw_if_index == ~0) || (vtr_op == ~0))
20665     {
20666       errmsg ("missing sw_if_index or vtr operation");
20667       return -99;
20668     }
20669   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20670       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20671     {
20672       errmsg
20673         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20674       return -99;
20675     }
20676
20677   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20678   mp->sw_if_index = ntohl (sw_if_index);
20679   mp->vtr_op = ntohl (vtr_op);
20680   mp->outer_tag = ntohs (outer_tag);
20681   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20682   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20683   mp->b_vlanid = ntohs (vlanid);
20684   mp->i_sid = ntohl (sid);
20685
20686   S (mp);
20687   W (ret);
20688   return ret;
20689 }
20690
20691 static int
20692 api_flow_classify_set_interface (vat_main_t * vam)
20693 {
20694   unformat_input_t *i = vam->input;
20695   vl_api_flow_classify_set_interface_t *mp;
20696   u32 sw_if_index;
20697   int sw_if_index_set;
20698   u32 ip4_table_index = ~0;
20699   u32 ip6_table_index = ~0;
20700   u8 is_add = 1;
20701   int ret;
20702
20703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20704     {
20705       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20706         sw_if_index_set = 1;
20707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20708         sw_if_index_set = 1;
20709       else if (unformat (i, "del"))
20710         is_add = 0;
20711       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20712         ;
20713       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20714         ;
20715       else
20716         {
20717           clib_warning ("parse error '%U'", format_unformat_error, i);
20718           return -99;
20719         }
20720     }
20721
20722   if (sw_if_index_set == 0)
20723     {
20724       errmsg ("missing interface name or sw_if_index");
20725       return -99;
20726     }
20727
20728   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20729
20730   mp->sw_if_index = ntohl (sw_if_index);
20731   mp->ip4_table_index = ntohl (ip4_table_index);
20732   mp->ip6_table_index = ntohl (ip6_table_index);
20733   mp->is_add = is_add;
20734
20735   S (mp);
20736   W (ret);
20737   return ret;
20738 }
20739
20740 static int
20741 api_flow_classify_dump (vat_main_t * vam)
20742 {
20743   unformat_input_t *i = vam->input;
20744   vl_api_flow_classify_dump_t *mp;
20745   vl_api_control_ping_t *mp_ping;
20746   u8 type = FLOW_CLASSIFY_N_TABLES;
20747   int ret;
20748
20749   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20750     ;
20751   else
20752     {
20753       errmsg ("classify table type must be specified");
20754       return -99;
20755     }
20756
20757   if (!vam->json_output)
20758     {
20759       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20760     }
20761
20762   M (FLOW_CLASSIFY_DUMP, mp);
20763   mp->type = type;
20764   /* send it... */
20765   S (mp);
20766
20767   /* Use a control ping for synchronization */
20768   MPING (CONTROL_PING, mp_ping);
20769   S (mp_ping);
20770
20771   /* Wait for a reply... */
20772   W (ret);
20773   return ret;
20774 }
20775
20776 static int
20777 api_feature_enable_disable (vat_main_t * vam)
20778 {
20779   unformat_input_t *i = vam->input;
20780   vl_api_feature_enable_disable_t *mp;
20781   u8 *arc_name = 0;
20782   u8 *feature_name = 0;
20783   u32 sw_if_index = ~0;
20784   u8 enable = 1;
20785   int ret;
20786
20787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20788     {
20789       if (unformat (i, "arc_name %s", &arc_name))
20790         ;
20791       else if (unformat (i, "feature_name %s", &feature_name))
20792         ;
20793       else
20794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20795         ;
20796       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20797         ;
20798       else if (unformat (i, "disable"))
20799         enable = 0;
20800       else
20801         break;
20802     }
20803
20804   if (arc_name == 0)
20805     {
20806       errmsg ("missing arc name");
20807       return -99;
20808     }
20809   if (vec_len (arc_name) > 63)
20810     {
20811       errmsg ("arc name too long");
20812     }
20813
20814   if (feature_name == 0)
20815     {
20816       errmsg ("missing feature name");
20817       return -99;
20818     }
20819   if (vec_len (feature_name) > 63)
20820     {
20821       errmsg ("feature name too long");
20822     }
20823
20824   if (sw_if_index == ~0)
20825     {
20826       errmsg ("missing interface name or sw_if_index");
20827       return -99;
20828     }
20829
20830   /* Construct the API message */
20831   M (FEATURE_ENABLE_DISABLE, mp);
20832   mp->sw_if_index = ntohl (sw_if_index);
20833   mp->enable = enable;
20834   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20835   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20836   vec_free (arc_name);
20837   vec_free (feature_name);
20838
20839   S (mp);
20840   W (ret);
20841   return ret;
20842 }
20843
20844 static int
20845 api_sw_interface_tag_add_del (vat_main_t * vam)
20846 {
20847   unformat_input_t *i = vam->input;
20848   vl_api_sw_interface_tag_add_del_t *mp;
20849   u32 sw_if_index = ~0;
20850   u8 *tag = 0;
20851   u8 enable = 1;
20852   int ret;
20853
20854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20855     {
20856       if (unformat (i, "tag %s", &tag))
20857         ;
20858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20859         ;
20860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20861         ;
20862       else if (unformat (i, "del"))
20863         enable = 0;
20864       else
20865         break;
20866     }
20867
20868   if (sw_if_index == ~0)
20869     {
20870       errmsg ("missing interface name or sw_if_index");
20871       return -99;
20872     }
20873
20874   if (enable && (tag == 0))
20875     {
20876       errmsg ("no tag specified");
20877       return -99;
20878     }
20879
20880   /* Construct the API message */
20881   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20882   mp->sw_if_index = ntohl (sw_if_index);
20883   mp->is_add = enable;
20884   if (enable)
20885     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20886   vec_free (tag);
20887
20888   S (mp);
20889   W (ret);
20890   return ret;
20891 }
20892
20893 static void vl_api_l2_xconnect_details_t_handler
20894   (vl_api_l2_xconnect_details_t * mp)
20895 {
20896   vat_main_t *vam = &vat_main;
20897
20898   print (vam->ofp, "%15d%15d",
20899          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20900 }
20901
20902 static void vl_api_l2_xconnect_details_t_handler_json
20903   (vl_api_l2_xconnect_details_t * mp)
20904 {
20905   vat_main_t *vam = &vat_main;
20906   vat_json_node_t *node = NULL;
20907
20908   if (VAT_JSON_ARRAY != vam->json_tree.type)
20909     {
20910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20911       vat_json_init_array (&vam->json_tree);
20912     }
20913   node = vat_json_array_add (&vam->json_tree);
20914
20915   vat_json_init_object (node);
20916   vat_json_object_add_uint (node, "rx_sw_if_index",
20917                             ntohl (mp->rx_sw_if_index));
20918   vat_json_object_add_uint (node, "tx_sw_if_index",
20919                             ntohl (mp->tx_sw_if_index));
20920 }
20921
20922 static int
20923 api_l2_xconnect_dump (vat_main_t * vam)
20924 {
20925   vl_api_l2_xconnect_dump_t *mp;
20926   vl_api_control_ping_t *mp_ping;
20927   int ret;
20928
20929   if (!vam->json_output)
20930     {
20931       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20932     }
20933
20934   M (L2_XCONNECT_DUMP, mp);
20935
20936   S (mp);
20937
20938   /* Use a control ping for synchronization */
20939   MPING (CONTROL_PING, mp_ping);
20940   S (mp_ping);
20941
20942   W (ret);
20943   return ret;
20944 }
20945
20946 static int
20947 api_hw_interface_set_mtu (vat_main_t * vam)
20948 {
20949   unformat_input_t *i = vam->input;
20950   vl_api_hw_interface_set_mtu_t *mp;
20951   u32 sw_if_index = ~0;
20952   u32 mtu = 0;
20953   int ret;
20954
20955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20956     {
20957       if (unformat (i, "mtu %d", &mtu))
20958         ;
20959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20960         ;
20961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20962         ;
20963       else
20964         break;
20965     }
20966
20967   if (sw_if_index == ~0)
20968     {
20969       errmsg ("missing interface name or sw_if_index");
20970       return -99;
20971     }
20972
20973   if (mtu == 0)
20974     {
20975       errmsg ("no mtu specified");
20976       return -99;
20977     }
20978
20979   /* Construct the API message */
20980   M (HW_INTERFACE_SET_MTU, mp);
20981   mp->sw_if_index = ntohl (sw_if_index);
20982   mp->mtu = ntohs ((u16) mtu);
20983
20984   S (mp);
20985   W (ret);
20986   return ret;
20987 }
20988
20989 static int
20990 api_p2p_ethernet_add (vat_main_t * vam)
20991 {
20992   unformat_input_t *i = vam->input;
20993   vl_api_p2p_ethernet_add_t *mp;
20994   u32 parent_if_index = ~0;
20995   u32 sub_id = ~0;
20996   u8 remote_mac[6];
20997   u8 mac_set = 0;
20998   int ret;
20999
21000   clib_memset (remote_mac, 0, sizeof (remote_mac));
21001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21002     {
21003       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21004         ;
21005       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21006         ;
21007       else
21008         if (unformat
21009             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21010         mac_set++;
21011       else if (unformat (i, "sub_id %d", &sub_id))
21012         ;
21013       else
21014         {
21015           clib_warning ("parse error '%U'", format_unformat_error, i);
21016           return -99;
21017         }
21018     }
21019
21020   if (parent_if_index == ~0)
21021     {
21022       errmsg ("missing interface name or sw_if_index");
21023       return -99;
21024     }
21025   if (mac_set == 0)
21026     {
21027       errmsg ("missing remote mac address");
21028       return -99;
21029     }
21030   if (sub_id == ~0)
21031     {
21032       errmsg ("missing sub-interface id");
21033       return -99;
21034     }
21035
21036   M (P2P_ETHERNET_ADD, mp);
21037   mp->parent_if_index = ntohl (parent_if_index);
21038   mp->subif_id = ntohl (sub_id);
21039   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21040
21041   S (mp);
21042   W (ret);
21043   return ret;
21044 }
21045
21046 static int
21047 api_p2p_ethernet_del (vat_main_t * vam)
21048 {
21049   unformat_input_t *i = vam->input;
21050   vl_api_p2p_ethernet_del_t *mp;
21051   u32 parent_if_index = ~0;
21052   u8 remote_mac[6];
21053   u8 mac_set = 0;
21054   int ret;
21055
21056   clib_memset (remote_mac, 0, sizeof (remote_mac));
21057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21058     {
21059       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21060         ;
21061       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21062         ;
21063       else
21064         if (unformat
21065             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21066         mac_set++;
21067       else
21068         {
21069           clib_warning ("parse error '%U'", format_unformat_error, i);
21070           return -99;
21071         }
21072     }
21073
21074   if (parent_if_index == ~0)
21075     {
21076       errmsg ("missing interface name or sw_if_index");
21077       return -99;
21078     }
21079   if (mac_set == 0)
21080     {
21081       errmsg ("missing remote mac address");
21082       return -99;
21083     }
21084
21085   M (P2P_ETHERNET_DEL, mp);
21086   mp->parent_if_index = ntohl (parent_if_index);
21087   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21088
21089   S (mp);
21090   W (ret);
21091   return ret;
21092 }
21093
21094 static int
21095 api_lldp_config (vat_main_t * vam)
21096 {
21097   unformat_input_t *i = vam->input;
21098   vl_api_lldp_config_t *mp;
21099   int tx_hold = 0;
21100   int tx_interval = 0;
21101   u8 *sys_name = NULL;
21102   int ret;
21103
21104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21105     {
21106       if (unformat (i, "system-name %s", &sys_name))
21107         ;
21108       else if (unformat (i, "tx-hold %d", &tx_hold))
21109         ;
21110       else if (unformat (i, "tx-interval %d", &tx_interval))
21111         ;
21112       else
21113         {
21114           clib_warning ("parse error '%U'", format_unformat_error, i);
21115           return -99;
21116         }
21117     }
21118
21119   vec_add1 (sys_name, 0);
21120
21121   M (LLDP_CONFIG, mp);
21122   mp->tx_hold = htonl (tx_hold);
21123   mp->tx_interval = htonl (tx_interval);
21124   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21125   vec_free (sys_name);
21126
21127   S (mp);
21128   W (ret);
21129   return ret;
21130 }
21131
21132 static int
21133 api_sw_interface_set_lldp (vat_main_t * vam)
21134 {
21135   unformat_input_t *i = vam->input;
21136   vl_api_sw_interface_set_lldp_t *mp;
21137   u32 sw_if_index = ~0;
21138   u32 enable = 1;
21139   u8 *port_desc = NULL, *mgmt_oid = NULL;
21140   ip4_address_t ip4_addr;
21141   ip6_address_t ip6_addr;
21142   int ret;
21143
21144   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21145   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21146
21147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21148     {
21149       if (unformat (i, "disable"))
21150         enable = 0;
21151       else
21152         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21153         ;
21154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21155         ;
21156       else if (unformat (i, "port-desc %s", &port_desc))
21157         ;
21158       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21159         ;
21160       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21161         ;
21162       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21163         ;
21164       else
21165         break;
21166     }
21167
21168   if (sw_if_index == ~0)
21169     {
21170       errmsg ("missing interface name or sw_if_index");
21171       return -99;
21172     }
21173
21174   /* Construct the API message */
21175   vec_add1 (port_desc, 0);
21176   vec_add1 (mgmt_oid, 0);
21177   M (SW_INTERFACE_SET_LLDP, mp);
21178   mp->sw_if_index = ntohl (sw_if_index);
21179   mp->enable = enable;
21180   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21181   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21182   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21183   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21184   vec_free (port_desc);
21185   vec_free (mgmt_oid);
21186
21187   S (mp);
21188   W (ret);
21189   return ret;
21190 }
21191
21192 static int
21193 api_tcp_configure_src_addresses (vat_main_t * vam)
21194 {
21195   vl_api_tcp_configure_src_addresses_t *mp;
21196   unformat_input_t *i = vam->input;
21197   ip4_address_t v4first, v4last;
21198   ip6_address_t v6first, v6last;
21199   u8 range_set = 0;
21200   u32 vrf_id = 0;
21201   int ret;
21202
21203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21204     {
21205       if (unformat (i, "%U - %U",
21206                     unformat_ip4_address, &v4first,
21207                     unformat_ip4_address, &v4last))
21208         {
21209           if (range_set)
21210             {
21211               errmsg ("one range per message (range already set)");
21212               return -99;
21213             }
21214           range_set = 1;
21215         }
21216       else if (unformat (i, "%U - %U",
21217                          unformat_ip6_address, &v6first,
21218                          unformat_ip6_address, &v6last))
21219         {
21220           if (range_set)
21221             {
21222               errmsg ("one range per message (range already set)");
21223               return -99;
21224             }
21225           range_set = 2;
21226         }
21227       else if (unformat (i, "vrf %d", &vrf_id))
21228         ;
21229       else
21230         break;
21231     }
21232
21233   if (range_set == 0)
21234     {
21235       errmsg ("address range not set");
21236       return -99;
21237     }
21238
21239   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21240   mp->vrf_id = ntohl (vrf_id);
21241   /* ipv6? */
21242   if (range_set == 2)
21243     {
21244       mp->is_ipv6 = 1;
21245       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21246       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21247     }
21248   else
21249     {
21250       mp->is_ipv6 = 0;
21251       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21252       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21253     }
21254   S (mp);
21255   W (ret);
21256   return ret;
21257 }
21258
21259 static void vl_api_app_namespace_add_del_reply_t_handler
21260   (vl_api_app_namespace_add_del_reply_t * mp)
21261 {
21262   vat_main_t *vam = &vat_main;
21263   i32 retval = ntohl (mp->retval);
21264   if (vam->async_mode)
21265     {
21266       vam->async_errors += (retval < 0);
21267     }
21268   else
21269     {
21270       vam->retval = retval;
21271       if (retval == 0)
21272         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21273       vam->result_ready = 1;
21274     }
21275 }
21276
21277 static void vl_api_app_namespace_add_del_reply_t_handler_json
21278   (vl_api_app_namespace_add_del_reply_t * mp)
21279 {
21280   vat_main_t *vam = &vat_main;
21281   vat_json_node_t node;
21282
21283   vat_json_init_object (&node);
21284   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21285   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21286
21287   vat_json_print (vam->ofp, &node);
21288   vat_json_free (&node);
21289
21290   vam->retval = ntohl (mp->retval);
21291   vam->result_ready = 1;
21292 }
21293
21294 static int
21295 api_app_namespace_add_del (vat_main_t * vam)
21296 {
21297   vl_api_app_namespace_add_del_t *mp;
21298   unformat_input_t *i = vam->input;
21299   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21300   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21301   u64 secret;
21302   int ret;
21303
21304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21305     {
21306       if (unformat (i, "id %_%v%_", &ns_id))
21307         ;
21308       else if (unformat (i, "secret %lu", &secret))
21309         secret_set = 1;
21310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21311         sw_if_index_set = 1;
21312       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21313         ;
21314       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21315         ;
21316       else
21317         break;
21318     }
21319   if (!ns_id || !secret_set || !sw_if_index_set)
21320     {
21321       errmsg ("namespace id, secret and sw_if_index must be set");
21322       return -99;
21323     }
21324   if (vec_len (ns_id) > 64)
21325     {
21326       errmsg ("namespace id too long");
21327       return -99;
21328     }
21329   M (APP_NAMESPACE_ADD_DEL, mp);
21330
21331   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21332   mp->namespace_id_len = vec_len (ns_id);
21333   mp->secret = clib_host_to_net_u64 (secret);
21334   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21335   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21336   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21337   vec_free (ns_id);
21338   S (mp);
21339   W (ret);
21340   return ret;
21341 }
21342
21343 static int
21344 api_sock_init_shm (vat_main_t * vam)
21345 {
21346 #if VPP_API_TEST_BUILTIN == 0
21347   unformat_input_t *i = vam->input;
21348   vl_api_shm_elem_config_t *config = 0;
21349   u64 size = 64 << 20;
21350   int rv;
21351
21352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21353     {
21354       if (unformat (i, "size %U", unformat_memory_size, &size))
21355         ;
21356       else
21357         break;
21358     }
21359
21360   /*
21361    * Canned custom ring allocator config.
21362    * Should probably parse all of this
21363    */
21364   vec_validate (config, 6);
21365   config[0].type = VL_API_VLIB_RING;
21366   config[0].size = 256;
21367   config[0].count = 32;
21368
21369   config[1].type = VL_API_VLIB_RING;
21370   config[1].size = 1024;
21371   config[1].count = 16;
21372
21373   config[2].type = VL_API_VLIB_RING;
21374   config[2].size = 4096;
21375   config[2].count = 2;
21376
21377   config[3].type = VL_API_CLIENT_RING;
21378   config[3].size = 256;
21379   config[3].count = 32;
21380
21381   config[4].type = VL_API_CLIENT_RING;
21382   config[4].size = 1024;
21383   config[4].count = 16;
21384
21385   config[5].type = VL_API_CLIENT_RING;
21386   config[5].size = 4096;
21387   config[5].count = 2;
21388
21389   config[6].type = VL_API_QUEUE;
21390   config[6].count = 128;
21391   config[6].size = sizeof (uword);
21392
21393   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21394   if (!rv)
21395     vam->client_index_invalid = 1;
21396   return rv;
21397 #else
21398   return -99;
21399 #endif
21400 }
21401
21402 static int
21403 api_dns_enable_disable (vat_main_t * vam)
21404 {
21405   unformat_input_t *line_input = vam->input;
21406   vl_api_dns_enable_disable_t *mp;
21407   u8 enable_disable = 1;
21408   int ret;
21409
21410   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21411     {
21412       if (unformat (line_input, "disable"))
21413         enable_disable = 0;
21414       if (unformat (line_input, "enable"))
21415         enable_disable = 1;
21416       else
21417         break;
21418     }
21419
21420   /* Construct the API message */
21421   M (DNS_ENABLE_DISABLE, mp);
21422   mp->enable = enable_disable;
21423
21424   /* send it... */
21425   S (mp);
21426   /* Wait for the reply */
21427   W (ret);
21428   return ret;
21429 }
21430
21431 static int
21432 api_dns_resolve_name (vat_main_t * vam)
21433 {
21434   unformat_input_t *line_input = vam->input;
21435   vl_api_dns_resolve_name_t *mp;
21436   u8 *name = 0;
21437   int ret;
21438
21439   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21440     {
21441       if (unformat (line_input, "%s", &name))
21442         ;
21443       else
21444         break;
21445     }
21446
21447   if (vec_len (name) > 127)
21448     {
21449       errmsg ("name too long");
21450       return -99;
21451     }
21452
21453   /* Construct the API message */
21454   M (DNS_RESOLVE_NAME, mp);
21455   memcpy (mp->name, name, vec_len (name));
21456   vec_free (name);
21457
21458   /* send it... */
21459   S (mp);
21460   /* Wait for the reply */
21461   W (ret);
21462   return ret;
21463 }
21464
21465 static int
21466 api_dns_resolve_ip (vat_main_t * vam)
21467 {
21468   unformat_input_t *line_input = vam->input;
21469   vl_api_dns_resolve_ip_t *mp;
21470   int is_ip6 = -1;
21471   ip4_address_t addr4;
21472   ip6_address_t addr6;
21473   int ret;
21474
21475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21476     {
21477       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21478         is_ip6 = 1;
21479       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21480         is_ip6 = 0;
21481       else
21482         break;
21483     }
21484
21485   if (is_ip6 == -1)
21486     {
21487       errmsg ("missing address");
21488       return -99;
21489     }
21490
21491   /* Construct the API message */
21492   M (DNS_RESOLVE_IP, mp);
21493   mp->is_ip6 = is_ip6;
21494   if (is_ip6)
21495     memcpy (mp->address, &addr6, sizeof (addr6));
21496   else
21497     memcpy (mp->address, &addr4, sizeof (addr4));
21498
21499   /* send it... */
21500   S (mp);
21501   /* Wait for the reply */
21502   W (ret);
21503   return ret;
21504 }
21505
21506 static int
21507 api_dns_name_server_add_del (vat_main_t * vam)
21508 {
21509   unformat_input_t *i = vam->input;
21510   vl_api_dns_name_server_add_del_t *mp;
21511   u8 is_add = 1;
21512   ip6_address_t ip6_server;
21513   ip4_address_t ip4_server;
21514   int ip6_set = 0;
21515   int ip4_set = 0;
21516   int ret = 0;
21517
21518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21519     {
21520       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21521         ip6_set = 1;
21522       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21523         ip4_set = 1;
21524       else if (unformat (i, "del"))
21525         is_add = 0;
21526       else
21527         {
21528           clib_warning ("parse error '%U'", format_unformat_error, i);
21529           return -99;
21530         }
21531     }
21532
21533   if (ip4_set && ip6_set)
21534     {
21535       errmsg ("Only one server address allowed per message");
21536       return -99;
21537     }
21538   if ((ip4_set + ip6_set) == 0)
21539     {
21540       errmsg ("Server address required");
21541       return -99;
21542     }
21543
21544   /* Construct the API message */
21545   M (DNS_NAME_SERVER_ADD_DEL, mp);
21546
21547   if (ip6_set)
21548     {
21549       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21550       mp->is_ip6 = 1;
21551     }
21552   else
21553     {
21554       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21555       mp->is_ip6 = 0;
21556     }
21557
21558   mp->is_add = is_add;
21559
21560   /* send it... */
21561   S (mp);
21562
21563   /* Wait for a reply, return good/bad news  */
21564   W (ret);
21565   return ret;
21566 }
21567
21568 static void
21569 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21570 {
21571   vat_main_t *vam = &vat_main;
21572
21573   if (mp->is_ip4)
21574     {
21575       print (vam->ofp,
21576              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21577              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21578              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21579              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21580              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21581              clib_net_to_host_u32 (mp->action_index), mp->tag);
21582     }
21583   else
21584     {
21585       print (vam->ofp,
21586              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21587              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21588              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21589              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21590              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21591              clib_net_to_host_u32 (mp->action_index), mp->tag);
21592     }
21593 }
21594
21595 static void
21596 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21597                                              mp)
21598 {
21599   vat_main_t *vam = &vat_main;
21600   vat_json_node_t *node = NULL;
21601   struct in6_addr ip6;
21602   struct in_addr ip4;
21603
21604   if (VAT_JSON_ARRAY != vam->json_tree.type)
21605     {
21606       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21607       vat_json_init_array (&vam->json_tree);
21608     }
21609   node = vat_json_array_add (&vam->json_tree);
21610   vat_json_init_object (node);
21611
21612   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21613   vat_json_object_add_uint (node, "appns_index",
21614                             clib_net_to_host_u32 (mp->appns_index));
21615   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21616   vat_json_object_add_uint (node, "scope", mp->scope);
21617   vat_json_object_add_uint (node, "action_index",
21618                             clib_net_to_host_u32 (mp->action_index));
21619   vat_json_object_add_uint (node, "lcl_port",
21620                             clib_net_to_host_u16 (mp->lcl_port));
21621   vat_json_object_add_uint (node, "rmt_port",
21622                             clib_net_to_host_u16 (mp->rmt_port));
21623   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21624   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21625   vat_json_object_add_string_copy (node, "tag", mp->tag);
21626   if (mp->is_ip4)
21627     {
21628       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21629       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21630       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21631       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21632     }
21633   else
21634     {
21635       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21636       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21637       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21638       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21639     }
21640 }
21641
21642 static int
21643 api_session_rule_add_del (vat_main_t * vam)
21644 {
21645   vl_api_session_rule_add_del_t *mp;
21646   unformat_input_t *i = vam->input;
21647   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21648   u32 appns_index = 0, scope = 0;
21649   ip4_address_t lcl_ip4, rmt_ip4;
21650   ip6_address_t lcl_ip6, rmt_ip6;
21651   u8 is_ip4 = 1, conn_set = 0;
21652   u8 is_add = 1, *tag = 0;
21653   int ret;
21654
21655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21656     {
21657       if (unformat (i, "del"))
21658         is_add = 0;
21659       else if (unformat (i, "add"))
21660         ;
21661       else if (unformat (i, "proto tcp"))
21662         proto = 0;
21663       else if (unformat (i, "proto udp"))
21664         proto = 1;
21665       else if (unformat (i, "appns %d", &appns_index))
21666         ;
21667       else if (unformat (i, "scope %d", &scope))
21668         ;
21669       else if (unformat (i, "tag %_%v%_", &tag))
21670         ;
21671       else
21672         if (unformat
21673             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21674              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21675              &rmt_port))
21676         {
21677           is_ip4 = 1;
21678           conn_set = 1;
21679         }
21680       else
21681         if (unformat
21682             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21683              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21684              &rmt_port))
21685         {
21686           is_ip4 = 0;
21687           conn_set = 1;
21688         }
21689       else if (unformat (i, "action %d", &action))
21690         ;
21691       else
21692         break;
21693     }
21694   if (proto == ~0 || !conn_set || action == ~0)
21695     {
21696       errmsg ("transport proto, connection and action must be set");
21697       return -99;
21698     }
21699
21700   if (scope > 3)
21701     {
21702       errmsg ("scope should be 0-3");
21703       return -99;
21704     }
21705
21706   M (SESSION_RULE_ADD_DEL, mp);
21707
21708   mp->is_ip4 = is_ip4;
21709   mp->transport_proto = proto;
21710   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21711   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21712   mp->lcl_plen = lcl_plen;
21713   mp->rmt_plen = rmt_plen;
21714   mp->action_index = clib_host_to_net_u32 (action);
21715   mp->appns_index = clib_host_to_net_u32 (appns_index);
21716   mp->scope = scope;
21717   mp->is_add = is_add;
21718   if (is_ip4)
21719     {
21720       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21721       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21722     }
21723   else
21724     {
21725       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21726       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21727     }
21728   if (tag)
21729     {
21730       clib_memcpy (mp->tag, tag, vec_len (tag));
21731       vec_free (tag);
21732     }
21733
21734   S (mp);
21735   W (ret);
21736   return ret;
21737 }
21738
21739 static int
21740 api_session_rules_dump (vat_main_t * vam)
21741 {
21742   vl_api_session_rules_dump_t *mp;
21743   vl_api_control_ping_t *mp_ping;
21744   int ret;
21745
21746   if (!vam->json_output)
21747     {
21748       print (vam->ofp, "%=20s", "Session Rules");
21749     }
21750
21751   M (SESSION_RULES_DUMP, mp);
21752   /* send it... */
21753   S (mp);
21754
21755   /* Use a control ping for synchronization */
21756   MPING (CONTROL_PING, mp_ping);
21757   S (mp_ping);
21758
21759   /* Wait for a reply... */
21760   W (ret);
21761   return ret;
21762 }
21763
21764 static int
21765 api_ip_container_proxy_add_del (vat_main_t * vam)
21766 {
21767   vl_api_ip_container_proxy_add_del_t *mp;
21768   unformat_input_t *i = vam->input;
21769   u32 sw_if_index = ~0;
21770   vl_api_prefix_t pfx = { };
21771   u8 is_add = 1;
21772   int ret;
21773
21774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21775     {
21776       if (unformat (i, "del"))
21777         is_add = 0;
21778       else if (unformat (i, "add"))
21779         ;
21780       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21781         ;
21782       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21783         ;
21784       else
21785         break;
21786     }
21787   if (sw_if_index == ~0 || pfx.address_length == 0)
21788     {
21789       errmsg ("address and sw_if_index must be set");
21790       return -99;
21791     }
21792
21793   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21794
21795   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21796   mp->is_add = is_add;
21797   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21798
21799   S (mp);
21800   W (ret);
21801   return ret;
21802 }
21803
21804 static int
21805 api_qos_record_enable_disable (vat_main_t * vam)
21806 {
21807   unformat_input_t *i = vam->input;
21808   vl_api_qos_record_enable_disable_t *mp;
21809   u32 sw_if_index, qs = 0xff;
21810   u8 sw_if_index_set = 0;
21811   u8 enable = 1;
21812   int ret;
21813
21814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21815     {
21816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21817         sw_if_index_set = 1;
21818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21819         sw_if_index_set = 1;
21820       else if (unformat (i, "%U", unformat_qos_source, &qs))
21821         ;
21822       else if (unformat (i, "disable"))
21823         enable = 0;
21824       else
21825         {
21826           clib_warning ("parse error '%U'", format_unformat_error, i);
21827           return -99;
21828         }
21829     }
21830
21831   if (sw_if_index_set == 0)
21832     {
21833       errmsg ("missing interface name or sw_if_index");
21834       return -99;
21835     }
21836   if (qs == 0xff)
21837     {
21838       errmsg ("input location must be specified");
21839       return -99;
21840     }
21841
21842   M (QOS_RECORD_ENABLE_DISABLE, mp);
21843
21844   mp->sw_if_index = ntohl (sw_if_index);
21845   mp->input_source = qs;
21846   mp->enable = enable;
21847
21848   S (mp);
21849   W (ret);
21850   return ret;
21851 }
21852
21853
21854 static int
21855 q_or_quit (vat_main_t * vam)
21856 {
21857 #if VPP_API_TEST_BUILTIN == 0
21858   longjmp (vam->jump_buf, 1);
21859 #endif
21860   return 0;                     /* not so much */
21861 }
21862
21863 static int
21864 q (vat_main_t * vam)
21865 {
21866   return q_or_quit (vam);
21867 }
21868
21869 static int
21870 quit (vat_main_t * vam)
21871 {
21872   return q_or_quit (vam);
21873 }
21874
21875 static int
21876 comment (vat_main_t * vam)
21877 {
21878   return 0;
21879 }
21880
21881 static int
21882 statseg (vat_main_t * vam)
21883 {
21884   ssvm_private_t *ssvmp = &vam->stat_segment;
21885   ssvm_shared_header_t *shared_header = ssvmp->sh;
21886   vlib_counter_t **counters;
21887   u64 thread0_index1_packets;
21888   u64 thread0_index1_bytes;
21889   f64 vector_rate, input_rate;
21890   uword *p;
21891
21892   uword *counter_vector_by_name;
21893   if (vam->stat_segment_lockp == 0)
21894     {
21895       errmsg ("Stat segment not mapped...");
21896       return -99;
21897     }
21898
21899   /* look up "/if/rx for sw_if_index 1 as a test */
21900
21901   clib_spinlock_lock (vam->stat_segment_lockp);
21902
21903   counter_vector_by_name = (uword *) shared_header->opaque[1];
21904
21905   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21906   if (p == 0)
21907     {
21908       clib_spinlock_unlock (vam->stat_segment_lockp);
21909       errmsg ("/if/tx not found?");
21910       return -99;
21911     }
21912
21913   /* Fish per-thread vector of combined counters from shared memory */
21914   counters = (vlib_counter_t **) p[0];
21915
21916   if (vec_len (counters[0]) < 2)
21917     {
21918       clib_spinlock_unlock (vam->stat_segment_lockp);
21919       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21920       return -99;
21921     }
21922
21923   /* Read thread 0 sw_if_index 1 counter */
21924   thread0_index1_packets = counters[0][1].packets;
21925   thread0_index1_bytes = counters[0][1].bytes;
21926
21927   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21928   if (p == 0)
21929     {
21930       clib_spinlock_unlock (vam->stat_segment_lockp);
21931       errmsg ("vector_rate not found?");
21932       return -99;
21933     }
21934
21935   vector_rate = *(f64 *) (p[0]);
21936   p = hash_get_mem (counter_vector_by_name, "input_rate");
21937   if (p == 0)
21938     {
21939       clib_spinlock_unlock (vam->stat_segment_lockp);
21940       errmsg ("input_rate not found?");
21941       return -99;
21942     }
21943   input_rate = *(f64 *) (p[0]);
21944
21945   clib_spinlock_unlock (vam->stat_segment_lockp);
21946
21947   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21948          vector_rate, input_rate);
21949   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21950          thread0_index1_packets, thread0_index1_bytes);
21951
21952   return 0;
21953 }
21954
21955 static int
21956 cmd_cmp (void *a1, void *a2)
21957 {
21958   u8 **c1 = a1;
21959   u8 **c2 = a2;
21960
21961   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21962 }
21963
21964 static int
21965 help (vat_main_t * vam)
21966 {
21967   u8 **cmds = 0;
21968   u8 *name = 0;
21969   hash_pair_t *p;
21970   unformat_input_t *i = vam->input;
21971   int j;
21972
21973   if (unformat (i, "%s", &name))
21974     {
21975       uword *hs;
21976
21977       vec_add1 (name, 0);
21978
21979       hs = hash_get_mem (vam->help_by_name, name);
21980       if (hs)
21981         print (vam->ofp, "usage: %s %s", name, hs[0]);
21982       else
21983         print (vam->ofp, "No such msg / command '%s'", name);
21984       vec_free (name);
21985       return 0;
21986     }
21987
21988   print (vam->ofp, "Help is available for the following:");
21989
21990     /* *INDENT-OFF* */
21991     hash_foreach_pair (p, vam->function_by_name,
21992     ({
21993       vec_add1 (cmds, (u8 *)(p->key));
21994     }));
21995     /* *INDENT-ON* */
21996
21997   vec_sort_with_function (cmds, cmd_cmp);
21998
21999   for (j = 0; j < vec_len (cmds); j++)
22000     print (vam->ofp, "%s", cmds[j]);
22001
22002   vec_free (cmds);
22003   return 0;
22004 }
22005
22006 static int
22007 set (vat_main_t * vam)
22008 {
22009   u8 *name = 0, *value = 0;
22010   unformat_input_t *i = vam->input;
22011
22012   if (unformat (i, "%s", &name))
22013     {
22014       /* The input buffer is a vector, not a string. */
22015       value = vec_dup (i->buffer);
22016       vec_delete (value, i->index, 0);
22017       /* Almost certainly has a trailing newline */
22018       if (value[vec_len (value) - 1] == '\n')
22019         value[vec_len (value) - 1] = 0;
22020       /* Make sure it's a proper string, one way or the other */
22021       vec_add1 (value, 0);
22022       (void) clib_macro_set_value (&vam->macro_main,
22023                                    (char *) name, (char *) value);
22024     }
22025   else
22026     errmsg ("usage: set <name> <value>");
22027
22028   vec_free (name);
22029   vec_free (value);
22030   return 0;
22031 }
22032
22033 static int
22034 unset (vat_main_t * vam)
22035 {
22036   u8 *name = 0;
22037
22038   if (unformat (vam->input, "%s", &name))
22039     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22040       errmsg ("unset: %s wasn't set", name);
22041   vec_free (name);
22042   return 0;
22043 }
22044
22045 typedef struct
22046 {
22047   u8 *name;
22048   u8 *value;
22049 } macro_sort_t;
22050
22051
22052 static int
22053 macro_sort_cmp (void *a1, void *a2)
22054 {
22055   macro_sort_t *s1 = a1;
22056   macro_sort_t *s2 = a2;
22057
22058   return strcmp ((char *) (s1->name), (char *) (s2->name));
22059 }
22060
22061 static int
22062 dump_macro_table (vat_main_t * vam)
22063 {
22064   macro_sort_t *sort_me = 0, *sm;
22065   int i;
22066   hash_pair_t *p;
22067
22068     /* *INDENT-OFF* */
22069     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22070     ({
22071       vec_add2 (sort_me, sm, 1);
22072       sm->name = (u8 *)(p->key);
22073       sm->value = (u8 *) (p->value[0]);
22074     }));
22075     /* *INDENT-ON* */
22076
22077   vec_sort_with_function (sort_me, macro_sort_cmp);
22078
22079   if (vec_len (sort_me))
22080     print (vam->ofp, "%-15s%s", "Name", "Value");
22081   else
22082     print (vam->ofp, "The macro table is empty...");
22083
22084   for (i = 0; i < vec_len (sort_me); i++)
22085     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22086   return 0;
22087 }
22088
22089 static int
22090 dump_node_table (vat_main_t * vam)
22091 {
22092   int i, j;
22093   vlib_node_t *node, *next_node;
22094
22095   if (vec_len (vam->graph_nodes) == 0)
22096     {
22097       print (vam->ofp, "Node table empty, issue get_node_graph...");
22098       return 0;
22099     }
22100
22101   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22102     {
22103       node = vam->graph_nodes[0][i];
22104       print (vam->ofp, "[%d] %s", i, node->name);
22105       for (j = 0; j < vec_len (node->next_nodes); j++)
22106         {
22107           if (node->next_nodes[j] != ~0)
22108             {
22109               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22110               print (vam->ofp, "  [%d] %s", j, next_node->name);
22111             }
22112         }
22113     }
22114   return 0;
22115 }
22116
22117 static int
22118 value_sort_cmp (void *a1, void *a2)
22119 {
22120   name_sort_t *n1 = a1;
22121   name_sort_t *n2 = a2;
22122
22123   if (n1->value < n2->value)
22124     return -1;
22125   if (n1->value > n2->value)
22126     return 1;
22127   return 0;
22128 }
22129
22130
22131 static int
22132 dump_msg_api_table (vat_main_t * vam)
22133 {
22134   api_main_t *am = &api_main;
22135   name_sort_t *nses = 0, *ns;
22136   hash_pair_t *hp;
22137   int i;
22138
22139   /* *INDENT-OFF* */
22140   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22141   ({
22142     vec_add2 (nses, ns, 1);
22143     ns->name = (u8 *)(hp->key);
22144     ns->value = (u32) hp->value[0];
22145   }));
22146   /* *INDENT-ON* */
22147
22148   vec_sort_with_function (nses, value_sort_cmp);
22149
22150   for (i = 0; i < vec_len (nses); i++)
22151     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22152   vec_free (nses);
22153   return 0;
22154 }
22155
22156 static int
22157 get_msg_id (vat_main_t * vam)
22158 {
22159   u8 *name_and_crc;
22160   u32 message_index;
22161
22162   if (unformat (vam->input, "%s", &name_and_crc))
22163     {
22164       message_index = vl_msg_api_get_msg_index (name_and_crc);
22165       if (message_index == ~0)
22166         {
22167           print (vam->ofp, " '%s' not found", name_and_crc);
22168           return 0;
22169         }
22170       print (vam->ofp, " '%s' has message index %d",
22171              name_and_crc, message_index);
22172       return 0;
22173     }
22174   errmsg ("name_and_crc required...");
22175   return 0;
22176 }
22177
22178 static int
22179 search_node_table (vat_main_t * vam)
22180 {
22181   unformat_input_t *line_input = vam->input;
22182   u8 *node_to_find;
22183   int j;
22184   vlib_node_t *node, *next_node;
22185   uword *p;
22186
22187   if (vam->graph_node_index_by_name == 0)
22188     {
22189       print (vam->ofp, "Node table empty, issue get_node_graph...");
22190       return 0;
22191     }
22192
22193   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22194     {
22195       if (unformat (line_input, "%s", &node_to_find))
22196         {
22197           vec_add1 (node_to_find, 0);
22198           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22199           if (p == 0)
22200             {
22201               print (vam->ofp, "%s not found...", node_to_find);
22202               goto out;
22203             }
22204           node = vam->graph_nodes[0][p[0]];
22205           print (vam->ofp, "[%d] %s", p[0], node->name);
22206           for (j = 0; j < vec_len (node->next_nodes); j++)
22207             {
22208               if (node->next_nodes[j] != ~0)
22209                 {
22210                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22211                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22212                 }
22213             }
22214         }
22215
22216       else
22217         {
22218           clib_warning ("parse error '%U'", format_unformat_error,
22219                         line_input);
22220           return -99;
22221         }
22222
22223     out:
22224       vec_free (node_to_find);
22225
22226     }
22227
22228   return 0;
22229 }
22230
22231
22232 static int
22233 script (vat_main_t * vam)
22234 {
22235 #if (VPP_API_TEST_BUILTIN==0)
22236   u8 *s = 0;
22237   char *save_current_file;
22238   unformat_input_t save_input;
22239   jmp_buf save_jump_buf;
22240   u32 save_line_number;
22241
22242   FILE *new_fp, *save_ifp;
22243
22244   if (unformat (vam->input, "%s", &s))
22245     {
22246       new_fp = fopen ((char *) s, "r");
22247       if (new_fp == 0)
22248         {
22249           errmsg ("Couldn't open script file %s", s);
22250           vec_free (s);
22251           return -99;
22252         }
22253     }
22254   else
22255     {
22256       errmsg ("Missing script name");
22257       return -99;
22258     }
22259
22260   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22261   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22262   save_ifp = vam->ifp;
22263   save_line_number = vam->input_line_number;
22264   save_current_file = (char *) vam->current_file;
22265
22266   vam->input_line_number = 0;
22267   vam->ifp = new_fp;
22268   vam->current_file = s;
22269   do_one_file (vam);
22270
22271   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22272   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22273   vam->ifp = save_ifp;
22274   vam->input_line_number = save_line_number;
22275   vam->current_file = (u8 *) save_current_file;
22276   vec_free (s);
22277
22278   return 0;
22279 #else
22280   clib_warning ("use the exec command...");
22281   return -99;
22282 #endif
22283 }
22284
22285 static int
22286 echo (vat_main_t * vam)
22287 {
22288   print (vam->ofp, "%v", vam->input->buffer);
22289   return 0;
22290 }
22291
22292 /* List of API message constructors, CLI names map to api_xxx */
22293 #define foreach_vpe_api_msg                                             \
22294 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22295 _(sw_interface_dump,"")                                                 \
22296 _(sw_interface_set_flags,                                               \
22297   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22298 _(sw_interface_add_del_address,                                         \
22299   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22300 _(sw_interface_set_rx_mode,                                             \
22301   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22302 _(sw_interface_set_rx_placement,                                        \
22303   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22304 _(sw_interface_rx_placement_dump,                                       \
22305   "[<intfc> | sw_if_index <id>]")                                         \
22306 _(sw_interface_set_table,                                               \
22307   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22308 _(sw_interface_set_mpls_enable,                                         \
22309   "<intfc> | sw_if_index [disable | dis]")                              \
22310 _(sw_interface_set_vpath,                                               \
22311   "<intfc> | sw_if_index <id> enable | disable")                        \
22312 _(sw_interface_set_vxlan_bypass,                                        \
22313   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22314 _(sw_interface_set_geneve_bypass,                                       \
22315   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22316 _(sw_interface_set_l2_xconnect,                                         \
22317   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22318   "enable | disable")                                                   \
22319 _(sw_interface_set_l2_bridge,                                           \
22320   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22321   "[shg <split-horizon-group>] [bvi]\n"                                 \
22322   "enable | disable")                                                   \
22323 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22324 _(bridge_domain_add_del,                                                \
22325   "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") \
22326 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22327 _(l2fib_add_del,                                                        \
22328   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22329 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22330 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22331 _(l2_flags,                                                             \
22332   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22333 _(bridge_flags,                                                         \
22334   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22335 _(tap_create_v2,                                                        \
22336   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22337 _(tap_delete_v2,                                                        \
22338   "<vpp-if-name> | sw_if_index <id>")                                   \
22339 _(sw_interface_tap_v2_dump, "")                                         \
22340 _(virtio_pci_create,                                                    \
22341   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22342 _(virtio_pci_delete,                                                    \
22343   "<vpp-if-name> | sw_if_index <id>")                                   \
22344 _(sw_interface_virtio_pci_dump, "")                                     \
22345 _(bond_create,                                                          \
22346   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22347   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22348   "[id <if-id>]")                                                       \
22349 _(bond_delete,                                                          \
22350   "<vpp-if-name> | sw_if_index <id>")                                   \
22351 _(bond_enslave,                                                         \
22352   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22353 _(bond_detach_slave,                                                    \
22354   "sw_if_index <n>")                                                    \
22355 _(sw_interface_bond_dump, "")                                           \
22356 _(sw_interface_slave_dump,                                              \
22357   "<vpp-if-name> | sw_if_index <id>")                                   \
22358 _(ip_table_add_del,                                                     \
22359   "table <n> [ipv6] [add | del]\n")                                     \
22360 _(ip_add_del_route,                                                     \
22361   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22362   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22363   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22364   "[multipath] [count <n>] [del]")                                      \
22365 _(ip_mroute_add_del,                                                    \
22366   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22367   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22368 _(mpls_table_add_del,                                                   \
22369   "table <n> [add | del]\n")                                            \
22370 _(mpls_route_add_del,                                                   \
22371   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22372   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22373   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22374   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22375   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22376   "[count <n>] [del]")                                                  \
22377 _(mpls_ip_bind_unbind,                                                  \
22378   "<label> <addr/len>")                                                 \
22379 _(mpls_tunnel_add_del,                                                  \
22380   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22381   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22382   "[l2-only]  [out-label <n>]")                                         \
22383 _(sr_mpls_policy_add,                                                   \
22384   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22385 _(sr_mpls_policy_del,                                                   \
22386   "bsid <id>")                                                          \
22387 _(bier_table_add_del,                                                   \
22388   "<label> <sub-domain> <set> <bsl> [del]")                             \
22389 _(bier_route_add_del,                                                   \
22390   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22391   "[<intfc> | sw_if_index <id>]"                                        \
22392   "[weight <n>] [del] [multipath]")                                     \
22393 _(proxy_arp_add_del,                                                    \
22394   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22395 _(proxy_arp_intfc_enable_disable,                                       \
22396   "<intfc> | sw_if_index <id> enable | disable")                        \
22397 _(sw_interface_set_unnumbered,                                          \
22398   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22399 _(ip_neighbor_add_del,                                                  \
22400   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22401   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22402 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22403 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22404   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22405   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22406   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22407 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22408 _(reset_fib, "vrf <n> [ipv6]")                                          \
22409 _(dhcp_proxy_config,                                                    \
22410   "svr <v46-address> src <v46-address>\n"                               \
22411    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22412 _(dhcp_proxy_set_vss,                                                   \
22413   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22414 _(dhcp_proxy_dump, "ip6")                                               \
22415 _(dhcp_client_config,                                                   \
22416   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22417 _(set_ip_flow_hash,                                                     \
22418   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22419 _(sw_interface_ip6_enable_disable,                                      \
22420   "<intfc> | sw_if_index <id> enable | disable")                        \
22421 _(ip6nd_proxy_add_del,                                                  \
22422   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22423 _(ip6nd_proxy_dump, "")                                                 \
22424 _(sw_interface_ip6nd_ra_prefix,                                         \
22425   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22426   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22427   "[nolink] [isno]")                                                    \
22428 _(sw_interface_ip6nd_ra_config,                                         \
22429   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22430   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22431   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22432 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22433 _(l2_patch_add_del,                                                     \
22434   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22435   "enable | disable")                                                   \
22436 _(sr_localsid_add_del,                                                  \
22437   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22438   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22439 _(classify_add_del_table,                                               \
22440   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22441   " [del] [del-chain] mask <mask-value>\n"                              \
22442   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22443   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22444 _(classify_add_del_session,                                             \
22445   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22446   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22447   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22448   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22449 _(classify_set_interface_ip_table,                                      \
22450   "<intfc> | sw_if_index <nn> table <nn>")                              \
22451 _(classify_set_interface_l2_tables,                                     \
22452   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22453   "  [other-table <nn>]")                                               \
22454 _(get_node_index, "node <node-name")                                    \
22455 _(add_node_next, "node <node-name> next <next-node-name>")              \
22456 _(l2tpv3_create_tunnel,                                                 \
22457   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22458   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22459   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22460 _(l2tpv3_set_tunnel_cookies,                                            \
22461   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22462   "[new_remote_cookie <nn>]\n")                                         \
22463 _(l2tpv3_interface_enable_disable,                                      \
22464   "<intfc> | sw_if_index <nn> enable | disable")                        \
22465 _(l2tpv3_set_lookup_key,                                                \
22466   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22467 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22468 _(vxlan_offload_rx,                                                     \
22469   "hw { <interface name> | hw_if_index <nn>} "                          \
22470   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22471 _(vxlan_add_del_tunnel,                                                 \
22472   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22473   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22474   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22475 _(geneve_add_del_tunnel,                                                \
22476   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22477   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22478   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22479 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22480 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22481 _(gre_tunnel_add_del,                                                   \
22482   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22483   "[teb | erspan <session-id>] [del]")                                  \
22484 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22485 _(l2_fib_clear_table, "")                                               \
22486 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22487 _(l2_interface_vlan_tag_rewrite,                                        \
22488   "<intfc> | sw_if_index <nn> \n"                                       \
22489   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22490   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22491 _(create_vhost_user_if,                                                 \
22492         "socket <filename> [server] [renumber <dev_instance>] "         \
22493         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22494         "[mac <mac_address>]")                                          \
22495 _(modify_vhost_user_if,                                                 \
22496         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22497         "[server] [renumber <dev_instance>]")                           \
22498 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22499 _(sw_interface_vhost_user_dump, "")                                     \
22500 _(show_version, "")                                                     \
22501 _(show_threads, "")                                                     \
22502 _(vxlan_gpe_add_del_tunnel,                                             \
22503   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22504   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22505   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22506   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22507 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22508 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22509 _(interface_name_renumber,                                              \
22510   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22511 _(input_acl_set_interface,                                              \
22512   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22513   "  [l2-table <nn>] [del]")                                            \
22514 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22515 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22516   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22517 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22518 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22519 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22520 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22521 _(ip_dump, "ipv4 | ipv6")                                               \
22522 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22523 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22524   "  spid_id <n> ")                                                     \
22525 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22526   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22527   "  integ_alg <alg> integ_key <hex>")                                  \
22528 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22529   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22530   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22531   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22532 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22533 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22534   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22535   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22536   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22537   "  [instance <n>]")     \
22538 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22539 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22540   "  <alg> <hex>\n")                                                    \
22541 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22542 _(delete_loopback,"sw_if_index <nn>")                                   \
22543 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22544 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22545 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22546 _(want_interface_events,  "enable|disable")                             \
22547 _(get_first_msg_id, "client <name>")                                    \
22548 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22549 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22550   "fib-id <nn> [ip4][ip6][default]")                                    \
22551 _(get_node_graph, " ")                                                  \
22552 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22553 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22554 _(ioam_disable, "")                                                     \
22555 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22556                             " sw_if_index <sw_if_index> p <priority> "  \
22557                             "w <weight>] [del]")                        \
22558 _(one_add_del_locator, "locator-set <locator_name> "                    \
22559                         "iface <intf> | sw_if_index <sw_if_index> "     \
22560                         "p <priority> w <weight> [del]")                \
22561 _(one_add_del_local_eid,"vni <vni> eid "                                \
22562                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22563                          "locator-set <locator_name> [del]"             \
22564                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22565 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22566 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22567 _(one_enable_disable, "enable|disable")                                 \
22568 _(one_map_register_enable_disable, "enable|disable")                    \
22569 _(one_map_register_fallback_threshold, "<value>")                       \
22570 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22571 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22572                                "[seid <seid>] "                         \
22573                                "rloc <locator> p <prio> "               \
22574                                "w <weight> [rloc <loc> ... ] "          \
22575                                "action <action> [del-all]")             \
22576 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22577                           "<local-eid>")                                \
22578 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22579 _(one_use_petr, "ip-address> | disable")                                \
22580 _(one_map_request_mode, "src-dst|dst-only")                             \
22581 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22582 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22583 _(one_locator_set_dump, "[local | remote]")                             \
22584 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22585 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22586                        "[local] | [remote]")                            \
22587 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22588 _(one_ndp_bd_get, "")                                                   \
22589 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22590 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22591 _(one_l2_arp_bd_get, "")                                                \
22592 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22593 _(one_stats_enable_disable, "enable|disable")                           \
22594 _(show_one_stats_enable_disable, "")                                    \
22595 _(one_eid_table_vni_dump, "")                                           \
22596 _(one_eid_table_map_dump, "l2|l3")                                      \
22597 _(one_map_resolver_dump, "")                                            \
22598 _(one_map_server_dump, "")                                              \
22599 _(one_adjacencies_get, "vni <vni>")                                     \
22600 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22601 _(show_one_rloc_probe_state, "")                                        \
22602 _(show_one_map_register_state, "")                                      \
22603 _(show_one_status, "")                                                  \
22604 _(one_stats_dump, "")                                                   \
22605 _(one_stats_flush, "")                                                  \
22606 _(one_get_map_request_itr_rlocs, "")                                    \
22607 _(one_map_register_set_ttl, "<ttl>")                                    \
22608 _(one_set_transport_protocol, "udp|api")                                \
22609 _(one_get_transport_protocol, "")                                       \
22610 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22611 _(one_show_xtr_mode, "")                                                \
22612 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22613 _(one_show_pitr_mode, "")                                               \
22614 _(one_enable_disable_petr_mode, "enable|disable")                       \
22615 _(one_show_petr_mode, "")                                               \
22616 _(show_one_nsh_mapping, "")                                             \
22617 _(show_one_pitr, "")                                                    \
22618 _(show_one_use_petr, "")                                                \
22619 _(show_one_map_request_mode, "")                                        \
22620 _(show_one_map_register_ttl, "")                                        \
22621 _(show_one_map_register_fallback_threshold, "")                         \
22622 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22623                             " sw_if_index <sw_if_index> p <priority> "  \
22624                             "w <weight>] [del]")                        \
22625 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22626                         "iface <intf> | sw_if_index <sw_if_index> "     \
22627                         "p <priority> w <weight> [del]")                \
22628 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22629                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22630                          "locator-set <locator_name> [del]"             \
22631                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22632 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22633 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22634 _(lisp_enable_disable, "enable|disable")                                \
22635 _(lisp_map_register_enable_disable, "enable|disable")                   \
22636 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22637 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22638                                "[seid <seid>] "                         \
22639                                "rloc <locator> p <prio> "               \
22640                                "w <weight> [rloc <loc> ... ] "          \
22641                                "action <action> [del-all]")             \
22642 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22643                           "<local-eid>")                                \
22644 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22645 _(lisp_use_petr, "<ip-address> | disable")                              \
22646 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22647 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22648 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22649 _(lisp_locator_set_dump, "[local | remote]")                            \
22650 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22651 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22652                        "[local] | [remote]")                            \
22653 _(lisp_eid_table_vni_dump, "")                                          \
22654 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22655 _(lisp_map_resolver_dump, "")                                           \
22656 _(lisp_map_server_dump, "")                                             \
22657 _(lisp_adjacencies_get, "vni <vni>")                                    \
22658 _(gpe_fwd_entry_vnis_get, "")                                           \
22659 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22660 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22661                                 "[table <table-id>]")                   \
22662 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22663 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22664 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22665 _(gpe_get_encap_mode, "")                                               \
22666 _(lisp_gpe_add_del_iface, "up|down")                                    \
22667 _(lisp_gpe_enable_disable, "enable|disable")                            \
22668 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22669   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22670 _(show_lisp_rloc_probe_state, "")                                       \
22671 _(show_lisp_map_register_state, "")                                     \
22672 _(show_lisp_status, "")                                                 \
22673 _(lisp_get_map_request_itr_rlocs, "")                                   \
22674 _(show_lisp_pitr, "")                                                   \
22675 _(show_lisp_use_petr, "")                                               \
22676 _(show_lisp_map_request_mode, "")                                       \
22677 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22678 _(af_packet_delete, "name <host interface name>")                       \
22679 _(af_packet_dump, "")                                                   \
22680 _(policer_add_del, "name <policer name> <params> [del]")                \
22681 _(policer_dump, "[name <policer name>]")                                \
22682 _(policer_classify_set_interface,                                       \
22683   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22684   "  [l2-table <nn>] [del]")                                            \
22685 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22686 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22687     "[master|slave]")                                                   \
22688 _(netmap_delete, "name <interface name>")                               \
22689 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22690 _(mpls_fib_dump, "")                                                    \
22691 _(classify_table_ids, "")                                               \
22692 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22693 _(classify_table_info, "table_id <nn>")                                 \
22694 _(classify_session_dump, "table_id <nn>")                               \
22695 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22696     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22697     "[template_interval <nn>] [udp_checksum]")                          \
22698 _(ipfix_exporter_dump, "")                                              \
22699 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22700 _(ipfix_classify_stream_dump, "")                                       \
22701 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22702 _(ipfix_classify_table_dump, "")                                        \
22703 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22704 _(sw_interface_span_dump, "[l2]")                                           \
22705 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22706 _(pg_create_interface, "if_id <nn>")                                    \
22707 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22708 _(pg_enable_disable, "[stream <id>] disable")                           \
22709 _(ip_source_and_port_range_check_add_del,                               \
22710   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22711 _(ip_source_and_port_range_check_interface_add_del,                     \
22712   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22713   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22714 _(ipsec_gre_tunnel_add_del,                                             \
22715   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22716 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22717 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22718 _(l2_interface_pbb_tag_rewrite,                                         \
22719   "<intfc> | sw_if_index <nn> \n"                                       \
22720   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22721   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22722 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22723 _(flow_classify_set_interface,                                          \
22724   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22725 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22726 _(ip_fib_dump, "")                                                      \
22727 _(ip_mfib_dump, "")                                                     \
22728 _(ip6_fib_dump, "")                                                     \
22729 _(ip6_mfib_dump, "")                                                    \
22730 _(feature_enable_disable, "arc_name <arc_name> "                        \
22731   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22732 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22733 "[disable]")                                                            \
22734 _(l2_xconnect_dump, "")                                                 \
22735 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22736 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22737 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22738 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22739 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22740 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22741 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22742   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22743 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22744 _(sock_init_shm, "size <nnn>")                                          \
22745 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22746 _(dns_enable_disable, "[enable][disable]")                              \
22747 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22748 _(dns_resolve_name, "<hostname>")                                       \
22749 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22750 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22751 _(dns_resolve_name, "<hostname>")                                       \
22752 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22753   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22754 _(session_rules_dump, "")                                               \
22755 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22756 _(output_acl_set_interface,                                             \
22757   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22758   "  [l2-table <nn>] [del]")                                            \
22759 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22760
22761 /* List of command functions, CLI names map directly to functions */
22762 #define foreach_cli_function                                    \
22763 _(comment, "usage: comment <ignore-rest-of-line>")              \
22764 _(dump_interface_table, "usage: dump_interface_table")          \
22765 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22766 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22767 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22768 _(dump_macro_table, "usage: dump_macro_table ")                 \
22769 _(dump_node_table, "usage: dump_node_table")                    \
22770 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22771 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22772 _(echo, "usage: echo <message>")                                \
22773 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22774 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22775 _(help, "usage: help")                                          \
22776 _(q, "usage: quit")                                             \
22777 _(quit, "usage: quit")                                          \
22778 _(search_node_table, "usage: search_node_table <name>...")      \
22779 _(set, "usage: set <variable-name> <value>")                    \
22780 _(script, "usage: script <file-name>")                          \
22781 _(statseg, "usage: statseg");                                   \
22782 _(unset, "usage: unset <variable-name>")
22783
22784 #define _(N,n)                                  \
22785     static void vl_api_##n##_t_handler_uni      \
22786     (vl_api_##n##_t * mp)                       \
22787     {                                           \
22788         vat_main_t * vam = &vat_main;           \
22789         if (vam->json_output) {                 \
22790             vl_api_##n##_t_handler_json(mp);    \
22791         } else {                                \
22792             vl_api_##n##_t_handler(mp);         \
22793         }                                       \
22794     }
22795 foreach_vpe_api_reply_msg;
22796 #if VPP_API_TEST_BUILTIN == 0
22797 foreach_standalone_reply_msg;
22798 #endif
22799 #undef _
22800
22801 void
22802 vat_api_hookup (vat_main_t * vam)
22803 {
22804 #define _(N,n)                                                  \
22805     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22806                            vl_api_##n##_t_handler_uni,          \
22807                            vl_noop_handler,                     \
22808                            vl_api_##n##_t_endian,               \
22809                            vl_api_##n##_t_print,                \
22810                            sizeof(vl_api_##n##_t), 1);
22811   foreach_vpe_api_reply_msg;
22812 #if VPP_API_TEST_BUILTIN == 0
22813   foreach_standalone_reply_msg;
22814 #endif
22815 #undef _
22816
22817 #if (VPP_API_TEST_BUILTIN==0)
22818   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22819
22820   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22821
22822   vam->function_by_name = hash_create_string (0, sizeof (uword));
22823
22824   vam->help_by_name = hash_create_string (0, sizeof (uword));
22825 #endif
22826
22827   /* API messages we can send */
22828 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22829   foreach_vpe_api_msg;
22830 #undef _
22831
22832   /* Help strings */
22833 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22834   foreach_vpe_api_msg;
22835 #undef _
22836
22837   /* CLI functions */
22838 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22839   foreach_cli_function;
22840 #undef _
22841
22842   /* Help strings */
22843 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22844   foreach_cli_function;
22845 #undef _
22846 }
22847
22848 #if VPP_API_TEST_BUILTIN
22849 static clib_error_t *
22850 vat_api_hookup_shim (vlib_main_t * vm)
22851 {
22852   vat_api_hookup (&vat_main);
22853   return 0;
22854 }
22855
22856 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22857 #endif
22858
22859 /*
22860  * fd.io coding-style-patch-verification: ON
22861  *
22862  * Local Variables:
22863  * eval: (c-set-style "gnu")
22864  * End:
22865  */