GRE: API update
[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   mp->rx_ring_sz = htons (rx_ring_sz);
7736   mp->tx_ring_sz = htons (tx_ring_sz);
7737
7738   if (random_mac == 0)
7739     clib_memcpy (mp->mac_address, mac_address, 6);
7740
7741   /* send it... */
7742   S (mp);
7743
7744   /* Wait for a reply... */
7745   W (ret);
7746   return ret;
7747 }
7748
7749 static int
7750 api_virtio_pci_delete (vat_main_t * vam)
7751 {
7752   unformat_input_t *i = vam->input;
7753   vl_api_virtio_pci_delete_t *mp;
7754   u32 sw_if_index = ~0;
7755   u8 sw_if_index_set = 0;
7756   int ret;
7757
7758   /* Parse args required to build the message */
7759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7760     {
7761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7762         sw_if_index_set = 1;
7763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7764         sw_if_index_set = 1;
7765       else
7766         break;
7767     }
7768
7769   if (sw_if_index_set == 0)
7770     {
7771       errmsg ("missing vpp interface name. ");
7772       return -99;
7773     }
7774
7775   /* Construct the API message */
7776   M (VIRTIO_PCI_DELETE, mp);
7777
7778   mp->sw_if_index = htonl (sw_if_index);
7779
7780   /* send it... */
7781   S (mp);
7782
7783   /* Wait for a reply... */
7784   W (ret);
7785   return ret;
7786 }
7787
7788 static int
7789 api_bond_create (vat_main_t * vam)
7790 {
7791   unformat_input_t *i = vam->input;
7792   vl_api_bond_create_t *mp;
7793   u8 mac_address[6];
7794   u8 custom_mac = 0;
7795   int ret;
7796   u8 mode;
7797   u8 lb;
7798   u8 mode_is_set = 0;
7799   u32 id = ~0;
7800
7801   clib_memset (mac_address, 0, sizeof (mac_address));
7802   lb = BOND_LB_L2;
7803
7804   /* Parse args required to build the message */
7805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7806     {
7807       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7808         mode_is_set = 1;
7809       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7810                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7811         ;
7812       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7813                          mac_address))
7814         custom_mac = 1;
7815       else if (unformat (i, "id %u", &id))
7816         ;
7817       else
7818         break;
7819     }
7820
7821   if (mode_is_set == 0)
7822     {
7823       errmsg ("Missing bond mode. ");
7824       return -99;
7825     }
7826
7827   /* Construct the API message */
7828   M (BOND_CREATE, mp);
7829
7830   mp->use_custom_mac = custom_mac;
7831
7832   mp->mode = mode;
7833   mp->lb = lb;
7834   mp->id = htonl (id);
7835
7836   if (custom_mac)
7837     clib_memcpy (mp->mac_address, mac_address, 6);
7838
7839   /* send it... */
7840   S (mp);
7841
7842   /* Wait for a reply... */
7843   W (ret);
7844   return ret;
7845 }
7846
7847 static int
7848 api_bond_delete (vat_main_t * vam)
7849 {
7850   unformat_input_t *i = vam->input;
7851   vl_api_bond_delete_t *mp;
7852   u32 sw_if_index = ~0;
7853   u8 sw_if_index_set = 0;
7854   int ret;
7855
7856   /* Parse args required to build the message */
7857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7858     {
7859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7860         sw_if_index_set = 1;
7861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7862         sw_if_index_set = 1;
7863       else
7864         break;
7865     }
7866
7867   if (sw_if_index_set == 0)
7868     {
7869       errmsg ("missing vpp interface name. ");
7870       return -99;
7871     }
7872
7873   /* Construct the API message */
7874   M (BOND_DELETE, mp);
7875
7876   mp->sw_if_index = ntohl (sw_if_index);
7877
7878   /* send it... */
7879   S (mp);
7880
7881   /* Wait for a reply... */
7882   W (ret);
7883   return ret;
7884 }
7885
7886 static int
7887 api_bond_enslave (vat_main_t * vam)
7888 {
7889   unformat_input_t *i = vam->input;
7890   vl_api_bond_enslave_t *mp;
7891   u32 bond_sw_if_index;
7892   int ret;
7893   u8 is_passive;
7894   u8 is_long_timeout;
7895   u32 bond_sw_if_index_is_set = 0;
7896   u32 sw_if_index;
7897   u8 sw_if_index_is_set = 0;
7898
7899   /* Parse args required to build the message */
7900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7901     {
7902       if (unformat (i, "sw_if_index %d", &sw_if_index))
7903         sw_if_index_is_set = 1;
7904       else if (unformat (i, "bond %u", &bond_sw_if_index))
7905         bond_sw_if_index_is_set = 1;
7906       else if (unformat (i, "passive %d", &is_passive))
7907         ;
7908       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7909         ;
7910       else
7911         break;
7912     }
7913
7914   if (bond_sw_if_index_is_set == 0)
7915     {
7916       errmsg ("Missing bond sw_if_index. ");
7917       return -99;
7918     }
7919   if (sw_if_index_is_set == 0)
7920     {
7921       errmsg ("Missing slave sw_if_index. ");
7922       return -99;
7923     }
7924
7925   /* Construct the API message */
7926   M (BOND_ENSLAVE, mp);
7927
7928   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7929   mp->sw_if_index = ntohl (sw_if_index);
7930   mp->is_long_timeout = is_long_timeout;
7931   mp->is_passive = is_passive;
7932
7933   /* send it... */
7934   S (mp);
7935
7936   /* Wait for a reply... */
7937   W (ret);
7938   return ret;
7939 }
7940
7941 static int
7942 api_bond_detach_slave (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_bond_detach_slave_t *mp;
7946   u32 sw_if_index = ~0;
7947   u8 sw_if_index_set = 0;
7948   int ret;
7949
7950   /* Parse args required to build the message */
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7954         sw_if_index_set = 1;
7955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7956         sw_if_index_set = 1;
7957       else
7958         break;
7959     }
7960
7961   if (sw_if_index_set == 0)
7962     {
7963       errmsg ("missing vpp interface name. ");
7964       return -99;
7965     }
7966
7967   /* Construct the API message */
7968   M (BOND_DETACH_SLAVE, mp);
7969
7970   mp->sw_if_index = ntohl (sw_if_index);
7971
7972   /* send it... */
7973   S (mp);
7974
7975   /* Wait for a reply... */
7976   W (ret);
7977   return ret;
7978 }
7979
7980 static int
7981 api_ip_table_add_del (vat_main_t * vam)
7982 {
7983   unformat_input_t *i = vam->input;
7984   vl_api_ip_table_add_del_t *mp;
7985   u32 table_id = ~0;
7986   u8 is_ipv6 = 0;
7987   u8 is_add = 1;
7988   int ret = 0;
7989
7990   /* Parse args required to build the message */
7991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7992     {
7993       if (unformat (i, "ipv6"))
7994         is_ipv6 = 1;
7995       else if (unformat (i, "del"))
7996         is_add = 0;
7997       else if (unformat (i, "add"))
7998         is_add = 1;
7999       else if (unformat (i, "table %d", &table_id))
8000         ;
8001       else
8002         {
8003           clib_warning ("parse error '%U'", format_unformat_error, i);
8004           return -99;
8005         }
8006     }
8007
8008   if (~0 == table_id)
8009     {
8010       errmsg ("missing table-ID");
8011       return -99;
8012     }
8013
8014   /* Construct the API message */
8015   M (IP_TABLE_ADD_DEL, mp);
8016
8017   mp->table_id = ntohl (table_id);
8018   mp->is_ipv6 = is_ipv6;
8019   mp->is_add = is_add;
8020
8021   /* send it... */
8022   S (mp);
8023
8024   /* Wait for a reply... */
8025   W (ret);
8026
8027   return ret;
8028 }
8029
8030 static int
8031 api_ip_add_del_route (vat_main_t * vam)
8032 {
8033   unformat_input_t *i = vam->input;
8034   vl_api_ip_add_del_route_t *mp;
8035   u32 sw_if_index = ~0, vrf_id = 0;
8036   u8 is_ipv6 = 0;
8037   u8 is_local = 0, is_drop = 0;
8038   u8 is_unreach = 0, is_prohibit = 0;
8039   u8 is_add = 1;
8040   u32 next_hop_weight = 1;
8041   u8 is_multipath = 0;
8042   u8 address_set = 0;
8043   u8 address_length_set = 0;
8044   u32 next_hop_table_id = 0;
8045   u32 resolve_attempts = 0;
8046   u32 dst_address_length = 0;
8047   u8 next_hop_set = 0;
8048   ip4_address_t v4_dst_address, v4_next_hop_address;
8049   ip6_address_t v6_dst_address, v6_next_hop_address;
8050   int count = 1;
8051   int j;
8052   f64 before = 0;
8053   u32 random_add_del = 0;
8054   u32 *random_vector = 0;
8055   uword *random_hash;
8056   u32 random_seed = 0xdeaddabe;
8057   u32 classify_table_index = ~0;
8058   u8 is_classify = 0;
8059   u8 resolve_host = 0, resolve_attached = 0;
8060   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8061   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8062   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8063
8064   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8065   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8066   /* Parse args required to build the message */
8067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8070         ;
8071       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8072         ;
8073       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8074         {
8075           address_set = 1;
8076           is_ipv6 = 0;
8077         }
8078       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8079         {
8080           address_set = 1;
8081           is_ipv6 = 1;
8082         }
8083       else if (unformat (i, "/%d", &dst_address_length))
8084         {
8085           address_length_set = 1;
8086         }
8087
8088       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8089                                          &v4_next_hop_address))
8090         {
8091           next_hop_set = 1;
8092         }
8093       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8094                                          &v6_next_hop_address))
8095         {
8096           next_hop_set = 1;
8097         }
8098       else
8099         if (unformat
8100             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8101         {
8102           next_hop_set = 1;
8103         }
8104       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8105         {
8106           next_hop_set = 1;
8107         }
8108       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8109         ;
8110       else if (unformat (i, "weight %d", &next_hop_weight))
8111         ;
8112       else if (unformat (i, "drop"))
8113         {
8114           is_drop = 1;
8115         }
8116       else if (unformat (i, "null-send-unreach"))
8117         {
8118           is_unreach = 1;
8119         }
8120       else if (unformat (i, "null-send-prohibit"))
8121         {
8122           is_prohibit = 1;
8123         }
8124       else if (unformat (i, "local"))
8125         {
8126           is_local = 1;
8127         }
8128       else if (unformat (i, "classify %d", &classify_table_index))
8129         {
8130           is_classify = 1;
8131         }
8132       else if (unformat (i, "del"))
8133         is_add = 0;
8134       else if (unformat (i, "add"))
8135         is_add = 1;
8136       else if (unformat (i, "resolve-via-host"))
8137         resolve_host = 1;
8138       else if (unformat (i, "resolve-via-attached"))
8139         resolve_attached = 1;
8140       else if (unformat (i, "multipath"))
8141         is_multipath = 1;
8142       else if (unformat (i, "vrf %d", &vrf_id))
8143         ;
8144       else if (unformat (i, "count %d", &count))
8145         ;
8146       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8147         ;
8148       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8149         ;
8150       else if (unformat (i, "out-label %d", &next_hop_out_label))
8151         {
8152           vl_api_fib_mpls_label_t fib_label = {
8153             .label = ntohl (next_hop_out_label),
8154             .ttl = 64,
8155             .exp = 0,
8156           };
8157           vec_add1 (next_hop_out_label_stack, fib_label);
8158         }
8159       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8160         ;
8161       else if (unformat (i, "random"))
8162         random_add_del = 1;
8163       else if (unformat (i, "seed %d", &random_seed))
8164         ;
8165       else
8166         {
8167           clib_warning ("parse error '%U'", format_unformat_error, i);
8168           return -99;
8169         }
8170     }
8171
8172   if (!next_hop_set && !is_drop && !is_local &&
8173       !is_classify && !is_unreach && !is_prohibit &&
8174       MPLS_LABEL_INVALID == next_hop_via_label)
8175     {
8176       errmsg
8177         ("next hop / local / drop / unreach / prohibit / classify not set");
8178       return -99;
8179     }
8180
8181   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8182     {
8183       errmsg ("next hop and next-hop via label set");
8184       return -99;
8185     }
8186   if (address_set == 0)
8187     {
8188       errmsg ("missing addresses");
8189       return -99;
8190     }
8191
8192   if (address_length_set == 0)
8193     {
8194       errmsg ("missing address length");
8195       return -99;
8196     }
8197
8198   /* Generate a pile of unique, random routes */
8199   if (random_add_del)
8200     {
8201       u32 this_random_address;
8202       random_hash = hash_create (count, sizeof (uword));
8203
8204       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8205       for (j = 0; j <= count; j++)
8206         {
8207           do
8208             {
8209               this_random_address = random_u32 (&random_seed);
8210               this_random_address =
8211                 clib_host_to_net_u32 (this_random_address);
8212             }
8213           while (hash_get (random_hash, this_random_address));
8214           vec_add1 (random_vector, this_random_address);
8215           hash_set (random_hash, this_random_address, 1);
8216         }
8217       hash_free (random_hash);
8218       v4_dst_address.as_u32 = random_vector[0];
8219     }
8220
8221   if (count > 1)
8222     {
8223       /* Turn on async mode */
8224       vam->async_mode = 1;
8225       vam->async_errors = 0;
8226       before = vat_time_now (vam);
8227     }
8228
8229   for (j = 0; j < count; j++)
8230     {
8231       /* Construct the API message */
8232       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8233           vec_len (next_hop_out_label_stack));
8234
8235       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8236       mp->table_id = ntohl (vrf_id);
8237
8238       mp->is_add = is_add;
8239       mp->is_drop = is_drop;
8240       mp->is_unreach = is_unreach;
8241       mp->is_prohibit = is_prohibit;
8242       mp->is_ipv6 = is_ipv6;
8243       mp->is_local = is_local;
8244       mp->is_classify = is_classify;
8245       mp->is_multipath = is_multipath;
8246       mp->is_resolve_host = resolve_host;
8247       mp->is_resolve_attached = resolve_attached;
8248       mp->next_hop_weight = next_hop_weight;
8249       mp->next_hop_preference = 0;
8250       mp->dst_address_length = dst_address_length;
8251       mp->next_hop_table_id = ntohl (next_hop_table_id);
8252       mp->classify_table_index = ntohl (classify_table_index);
8253       mp->next_hop_via_label = ntohl (next_hop_via_label);
8254       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8255       if (0 != mp->next_hop_n_out_labels)
8256         {
8257           memcpy (mp->next_hop_out_label_stack,
8258                   next_hop_out_label_stack,
8259                   (vec_len (next_hop_out_label_stack) *
8260                    sizeof (vl_api_fib_mpls_label_t)));
8261           vec_free (next_hop_out_label_stack);
8262         }
8263
8264       if (is_ipv6)
8265         {
8266           clib_memcpy (mp->dst_address, &v6_dst_address,
8267                        sizeof (v6_dst_address));
8268           if (next_hop_set)
8269             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8270                          sizeof (v6_next_hop_address));
8271           increment_v6_address (&v6_dst_address);
8272         }
8273       else
8274         {
8275           clib_memcpy (mp->dst_address, &v4_dst_address,
8276                        sizeof (v4_dst_address));
8277           if (next_hop_set)
8278             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8279                          sizeof (v4_next_hop_address));
8280           if (random_add_del)
8281             v4_dst_address.as_u32 = random_vector[j + 1];
8282           else
8283             increment_v4_address (&v4_dst_address);
8284         }
8285       /* send it... */
8286       S (mp);
8287       /* If we receive SIGTERM, stop now... */
8288       if (vam->do_exit)
8289         break;
8290     }
8291
8292   /* When testing multiple add/del ops, use a control-ping to sync */
8293   if (count > 1)
8294     {
8295       vl_api_control_ping_t *mp_ping;
8296       f64 after;
8297       f64 timeout;
8298
8299       /* Shut off async mode */
8300       vam->async_mode = 0;
8301
8302       MPING (CONTROL_PING, mp_ping);
8303       S (mp_ping);
8304
8305       timeout = vat_time_now (vam) + 1.0;
8306       while (vat_time_now (vam) < timeout)
8307         if (vam->result_ready == 1)
8308           goto out;
8309       vam->retval = -99;
8310
8311     out:
8312       if (vam->retval == -99)
8313         errmsg ("timeout");
8314
8315       if (vam->async_errors > 0)
8316         {
8317           errmsg ("%d asynchronous errors", vam->async_errors);
8318           vam->retval = -98;
8319         }
8320       vam->async_errors = 0;
8321       after = vat_time_now (vam);
8322
8323       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8324       if (j > 0)
8325         count = j;
8326
8327       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8328              count, after - before, count / (after - before));
8329     }
8330   else
8331     {
8332       int ret;
8333
8334       /* Wait for a reply... */
8335       W (ret);
8336       return ret;
8337     }
8338
8339   /* Return the good/bad news */
8340   return (vam->retval);
8341 }
8342
8343 static int
8344 api_ip_mroute_add_del (vat_main_t * vam)
8345 {
8346   unformat_input_t *i = vam->input;
8347   vl_api_ip_mroute_add_del_t *mp;
8348   u32 sw_if_index = ~0, vrf_id = 0;
8349   u8 is_ipv6 = 0;
8350   u8 is_local = 0;
8351   u8 is_add = 1;
8352   u8 address_set = 0;
8353   u32 grp_address_length = 0;
8354   ip4_address_t v4_grp_address, v4_src_address;
8355   ip6_address_t v6_grp_address, v6_src_address;
8356   mfib_itf_flags_t iflags = 0;
8357   mfib_entry_flags_t eflags = 0;
8358   int ret;
8359
8360   /* Parse args required to build the message */
8361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8362     {
8363       if (unformat (i, "sw_if_index %d", &sw_if_index))
8364         ;
8365       else if (unformat (i, "%U %U",
8366                          unformat_ip4_address, &v4_src_address,
8367                          unformat_ip4_address, &v4_grp_address))
8368         {
8369           grp_address_length = 64;
8370           address_set = 1;
8371           is_ipv6 = 0;
8372         }
8373       else if (unformat (i, "%U %U",
8374                          unformat_ip6_address, &v6_src_address,
8375                          unformat_ip6_address, &v6_grp_address))
8376         {
8377           grp_address_length = 256;
8378           address_set = 1;
8379           is_ipv6 = 1;
8380         }
8381       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8382         {
8383           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8384           grp_address_length = 32;
8385           address_set = 1;
8386           is_ipv6 = 0;
8387         }
8388       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8389         {
8390           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8391           grp_address_length = 128;
8392           address_set = 1;
8393           is_ipv6 = 1;
8394         }
8395       else if (unformat (i, "/%d", &grp_address_length))
8396         ;
8397       else if (unformat (i, "local"))
8398         {
8399           is_local = 1;
8400         }
8401       else if (unformat (i, "del"))
8402         is_add = 0;
8403       else if (unformat (i, "add"))
8404         is_add = 1;
8405       else if (unformat (i, "vrf %d", &vrf_id))
8406         ;
8407       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8408         ;
8409       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8410         ;
8411       else
8412         {
8413           clib_warning ("parse error '%U'", format_unformat_error, i);
8414           return -99;
8415         }
8416     }
8417
8418   if (address_set == 0)
8419     {
8420       errmsg ("missing addresses\n");
8421       return -99;
8422     }
8423
8424   /* Construct the API message */
8425   M (IP_MROUTE_ADD_DEL, mp);
8426
8427   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8428   mp->table_id = ntohl (vrf_id);
8429
8430   mp->is_add = is_add;
8431   mp->is_ipv6 = is_ipv6;
8432   mp->is_local = is_local;
8433   mp->itf_flags = ntohl (iflags);
8434   mp->entry_flags = ntohl (eflags);
8435   mp->grp_address_length = grp_address_length;
8436   mp->grp_address_length = ntohs (mp->grp_address_length);
8437
8438   if (is_ipv6)
8439     {
8440       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8441       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8442     }
8443   else
8444     {
8445       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8446       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8447
8448     }
8449
8450   /* send it... */
8451   S (mp);
8452   /* Wait for a reply... */
8453   W (ret);
8454   return ret;
8455 }
8456
8457 static int
8458 api_mpls_table_add_del (vat_main_t * vam)
8459 {
8460   unformat_input_t *i = vam->input;
8461   vl_api_mpls_table_add_del_t *mp;
8462   u32 table_id = ~0;
8463   u8 is_add = 1;
8464   int ret = 0;
8465
8466   /* Parse args required to build the message */
8467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8468     {
8469       if (unformat (i, "table %d", &table_id))
8470         ;
8471       else if (unformat (i, "del"))
8472         is_add = 0;
8473       else if (unformat (i, "add"))
8474         is_add = 1;
8475       else
8476         {
8477           clib_warning ("parse error '%U'", format_unformat_error, i);
8478           return -99;
8479         }
8480     }
8481
8482   if (~0 == table_id)
8483     {
8484       errmsg ("missing table-ID");
8485       return -99;
8486     }
8487
8488   /* Construct the API message */
8489   M (MPLS_TABLE_ADD_DEL, mp);
8490
8491   mp->mt_table_id = ntohl (table_id);
8492   mp->mt_is_add = is_add;
8493
8494   /* send it... */
8495   S (mp);
8496
8497   /* Wait for a reply... */
8498   W (ret);
8499
8500   return ret;
8501 }
8502
8503 static int
8504 api_mpls_route_add_del (vat_main_t * vam)
8505 {
8506   unformat_input_t *i = vam->input;
8507   vl_api_mpls_route_add_del_t *mp;
8508   u32 sw_if_index = ~0, table_id = 0;
8509   u8 is_add = 1;
8510   u32 next_hop_weight = 1;
8511   u8 is_multipath = 0;
8512   u32 next_hop_table_id = 0;
8513   u8 next_hop_set = 0;
8514   ip4_address_t v4_next_hop_address = {
8515     .as_u32 = 0,
8516   };
8517   ip6_address_t v6_next_hop_address = { {0} };
8518   int count = 1;
8519   int j;
8520   f64 before = 0;
8521   u32 classify_table_index = ~0;
8522   u8 is_classify = 0;
8523   u8 resolve_host = 0, resolve_attached = 0;
8524   u8 is_interface_rx = 0;
8525   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8526   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8527   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8528   mpls_label_t local_label = MPLS_LABEL_INVALID;
8529   u8 is_eos = 0;
8530   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8531
8532   /* Parse args required to build the message */
8533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8534     {
8535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8536         ;
8537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8538         ;
8539       else if (unformat (i, "%d", &local_label))
8540         ;
8541       else if (unformat (i, "eos"))
8542         is_eos = 1;
8543       else if (unformat (i, "non-eos"))
8544         is_eos = 0;
8545       else if (unformat (i, "via %U", unformat_ip4_address,
8546                          &v4_next_hop_address))
8547         {
8548           next_hop_set = 1;
8549           next_hop_proto = DPO_PROTO_IP4;
8550         }
8551       else if (unformat (i, "via %U", unformat_ip6_address,
8552                          &v6_next_hop_address))
8553         {
8554           next_hop_set = 1;
8555           next_hop_proto = DPO_PROTO_IP6;
8556         }
8557       else if (unformat (i, "weight %d", &next_hop_weight))
8558         ;
8559       else if (unformat (i, "classify %d", &classify_table_index))
8560         {
8561           is_classify = 1;
8562         }
8563       else if (unformat (i, "del"))
8564         is_add = 0;
8565       else if (unformat (i, "add"))
8566         is_add = 1;
8567       else if (unformat (i, "resolve-via-host"))
8568         resolve_host = 1;
8569       else if (unformat (i, "resolve-via-attached"))
8570         resolve_attached = 1;
8571       else if (unformat (i, "multipath"))
8572         is_multipath = 1;
8573       else if (unformat (i, "count %d", &count))
8574         ;
8575       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8576         {
8577           next_hop_set = 1;
8578           next_hop_proto = DPO_PROTO_IP4;
8579         }
8580       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8581         {
8582           next_hop_set = 1;
8583           next_hop_proto = DPO_PROTO_IP6;
8584         }
8585       else
8586         if (unformat
8587             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8588              &sw_if_index))
8589         {
8590           next_hop_set = 1;
8591           next_hop_proto = DPO_PROTO_ETHERNET;
8592           is_interface_rx = 1;
8593         }
8594       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8595         {
8596           next_hop_set = 1;
8597           next_hop_proto = DPO_PROTO_ETHERNET;
8598           is_interface_rx = 1;
8599         }
8600       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8601         next_hop_set = 1;
8602       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8603         next_hop_set = 1;
8604       else if (unformat (i, "out-label %d", &next_hop_out_label))
8605         {
8606           vl_api_fib_mpls_label_t fib_label = {
8607             .label = ntohl (next_hop_out_label),
8608             .ttl = 64,
8609             .exp = 0,
8610           };
8611           vec_add1 (next_hop_out_label_stack, fib_label);
8612         }
8613       else
8614         {
8615           clib_warning ("parse error '%U'", format_unformat_error, i);
8616           return -99;
8617         }
8618     }
8619
8620   if (!next_hop_set && !is_classify)
8621     {
8622       errmsg ("next hop / classify not set");
8623       return -99;
8624     }
8625
8626   if (MPLS_LABEL_INVALID == local_label)
8627     {
8628       errmsg ("missing label");
8629       return -99;
8630     }
8631
8632   if (count > 1)
8633     {
8634       /* Turn on async mode */
8635       vam->async_mode = 1;
8636       vam->async_errors = 0;
8637       before = vat_time_now (vam);
8638     }
8639
8640   for (j = 0; j < count; j++)
8641     {
8642       /* Construct the API message */
8643       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8644           vec_len (next_hop_out_label_stack));
8645
8646       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8647       mp->mr_table_id = ntohl (table_id);
8648
8649       mp->mr_is_add = is_add;
8650       mp->mr_next_hop_proto = next_hop_proto;
8651       mp->mr_is_classify = is_classify;
8652       mp->mr_is_multipath = is_multipath;
8653       mp->mr_is_resolve_host = resolve_host;
8654       mp->mr_is_resolve_attached = resolve_attached;
8655       mp->mr_is_interface_rx = is_interface_rx;
8656       mp->mr_next_hop_weight = next_hop_weight;
8657       mp->mr_next_hop_preference = 0;
8658       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8659       mp->mr_classify_table_index = ntohl (classify_table_index);
8660       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8661       mp->mr_label = ntohl (local_label);
8662       mp->mr_eos = is_eos;
8663
8664       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8665       if (0 != mp->mr_next_hop_n_out_labels)
8666         {
8667           memcpy (mp->mr_next_hop_out_label_stack,
8668                   next_hop_out_label_stack,
8669                   vec_len (next_hop_out_label_stack) *
8670                   sizeof (vl_api_fib_mpls_label_t));
8671           vec_free (next_hop_out_label_stack);
8672         }
8673
8674       if (next_hop_set)
8675         {
8676           if (DPO_PROTO_IP4 == next_hop_proto)
8677             {
8678               clib_memcpy (mp->mr_next_hop,
8679                            &v4_next_hop_address,
8680                            sizeof (v4_next_hop_address));
8681             }
8682           else if (DPO_PROTO_IP6 == next_hop_proto)
8683
8684             {
8685               clib_memcpy (mp->mr_next_hop,
8686                            &v6_next_hop_address,
8687                            sizeof (v6_next_hop_address));
8688             }
8689         }
8690       local_label++;
8691
8692       /* send it... */
8693       S (mp);
8694       /* If we receive SIGTERM, stop now... */
8695       if (vam->do_exit)
8696         break;
8697     }
8698
8699   /* When testing multiple add/del ops, use a control-ping to sync */
8700   if (count > 1)
8701     {
8702       vl_api_control_ping_t *mp_ping;
8703       f64 after;
8704       f64 timeout;
8705
8706       /* Shut off async mode */
8707       vam->async_mode = 0;
8708
8709       MPING (CONTROL_PING, mp_ping);
8710       S (mp_ping);
8711
8712       timeout = vat_time_now (vam) + 1.0;
8713       while (vat_time_now (vam) < timeout)
8714         if (vam->result_ready == 1)
8715           goto out;
8716       vam->retval = -99;
8717
8718     out:
8719       if (vam->retval == -99)
8720         errmsg ("timeout");
8721
8722       if (vam->async_errors > 0)
8723         {
8724           errmsg ("%d asynchronous errors", vam->async_errors);
8725           vam->retval = -98;
8726         }
8727       vam->async_errors = 0;
8728       after = vat_time_now (vam);
8729
8730       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8731       if (j > 0)
8732         count = j;
8733
8734       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8735              count, after - before, count / (after - before));
8736     }
8737   else
8738     {
8739       int ret;
8740
8741       /* Wait for a reply... */
8742       W (ret);
8743       return ret;
8744     }
8745
8746   /* Return the good/bad news */
8747   return (vam->retval);
8748 }
8749
8750 static int
8751 api_mpls_ip_bind_unbind (vat_main_t * vam)
8752 {
8753   unformat_input_t *i = vam->input;
8754   vl_api_mpls_ip_bind_unbind_t *mp;
8755   u32 ip_table_id = 0;
8756   u8 is_bind = 1;
8757   u8 is_ip4 = 1;
8758   ip4_address_t v4_address;
8759   ip6_address_t v6_address;
8760   u32 address_length;
8761   u8 address_set = 0;
8762   mpls_label_t local_label = MPLS_LABEL_INVALID;
8763   int ret;
8764
8765   /* Parse args required to build the message */
8766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8767     {
8768       if (unformat (i, "%U/%d", unformat_ip4_address,
8769                     &v4_address, &address_length))
8770         {
8771           is_ip4 = 1;
8772           address_set = 1;
8773         }
8774       else if (unformat (i, "%U/%d", unformat_ip6_address,
8775                          &v6_address, &address_length))
8776         {
8777           is_ip4 = 0;
8778           address_set = 1;
8779         }
8780       else if (unformat (i, "%d", &local_label))
8781         ;
8782       else if (unformat (i, "table-id %d", &ip_table_id))
8783         ;
8784       else if (unformat (i, "unbind"))
8785         is_bind = 0;
8786       else if (unformat (i, "bind"))
8787         is_bind = 1;
8788       else
8789         {
8790           clib_warning ("parse error '%U'", format_unformat_error, i);
8791           return -99;
8792         }
8793     }
8794
8795   if (!address_set)
8796     {
8797       errmsg ("IP address not set");
8798       return -99;
8799     }
8800
8801   if (MPLS_LABEL_INVALID == local_label)
8802     {
8803       errmsg ("missing label");
8804       return -99;
8805     }
8806
8807   /* Construct the API message */
8808   M (MPLS_IP_BIND_UNBIND, mp);
8809
8810   mp->mb_is_bind = is_bind;
8811   mp->mb_is_ip4 = is_ip4;
8812   mp->mb_ip_table_id = ntohl (ip_table_id);
8813   mp->mb_mpls_table_id = 0;
8814   mp->mb_label = ntohl (local_label);
8815   mp->mb_address_length = address_length;
8816
8817   if (is_ip4)
8818     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8819   else
8820     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8821
8822   /* send it... */
8823   S (mp);
8824
8825   /* Wait for a reply... */
8826   W (ret);
8827   return ret;
8828 }
8829
8830 static int
8831 api_sr_mpls_policy_add (vat_main_t * vam)
8832 {
8833   unformat_input_t *i = vam->input;
8834   vl_api_sr_mpls_policy_add_t *mp;
8835   u32 bsid = 0;
8836   u32 weight = 1;
8837   u8 type = 0;
8838   u8 n_segments = 0;
8839   u32 sid;
8840   u32 *segments = NULL;
8841   int ret;
8842
8843   /* Parse args required to build the message */
8844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8845     {
8846       if (unformat (i, "bsid %d", &bsid))
8847         ;
8848       else if (unformat (i, "weight %d", &weight))
8849         ;
8850       else if (unformat (i, "spray"))
8851         type = 1;
8852       else if (unformat (i, "next %d", &sid))
8853         {
8854           n_segments += 1;
8855           vec_add1 (segments, htonl (sid));
8856         }
8857       else
8858         {
8859           clib_warning ("parse error '%U'", format_unformat_error, i);
8860           return -99;
8861         }
8862     }
8863
8864   if (bsid == 0)
8865     {
8866       errmsg ("bsid not set");
8867       return -99;
8868     }
8869
8870   if (n_segments == 0)
8871     {
8872       errmsg ("no sid in segment stack");
8873       return -99;
8874     }
8875
8876   /* Construct the API message */
8877   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8878
8879   mp->bsid = htonl (bsid);
8880   mp->weight = htonl (weight);
8881   mp->type = type;
8882   mp->n_segments = n_segments;
8883   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8884   vec_free (segments);
8885
8886   /* send it... */
8887   S (mp);
8888
8889   /* Wait for a reply... */
8890   W (ret);
8891   return ret;
8892 }
8893
8894 static int
8895 api_sr_mpls_policy_del (vat_main_t * vam)
8896 {
8897   unformat_input_t *i = vam->input;
8898   vl_api_sr_mpls_policy_del_t *mp;
8899   u32 bsid = 0;
8900   int ret;
8901
8902   /* Parse args required to build the message */
8903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8904     {
8905       if (unformat (i, "bsid %d", &bsid))
8906         ;
8907       else
8908         {
8909           clib_warning ("parse error '%U'", format_unformat_error, i);
8910           return -99;
8911         }
8912     }
8913
8914   if (bsid == 0)
8915     {
8916       errmsg ("bsid not set");
8917       return -99;
8918     }
8919
8920   /* Construct the API message */
8921   M (SR_MPLS_POLICY_DEL, mp);
8922
8923   mp->bsid = htonl (bsid);
8924
8925   /* send it... */
8926   S (mp);
8927
8928   /* Wait for a reply... */
8929   W (ret);
8930   return ret;
8931 }
8932
8933 static int
8934 api_bier_table_add_del (vat_main_t * vam)
8935 {
8936   unformat_input_t *i = vam->input;
8937   vl_api_bier_table_add_del_t *mp;
8938   u8 is_add = 1;
8939   u32 set = 0, sub_domain = 0, hdr_len = 3;
8940   mpls_label_t local_label = MPLS_LABEL_INVALID;
8941   int ret;
8942
8943   /* Parse args required to build the message */
8944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8945     {
8946       if (unformat (i, "sub-domain %d", &sub_domain))
8947         ;
8948       else if (unformat (i, "set %d", &set))
8949         ;
8950       else if (unformat (i, "label %d", &local_label))
8951         ;
8952       else if (unformat (i, "hdr-len %d", &hdr_len))
8953         ;
8954       else if (unformat (i, "add"))
8955         is_add = 1;
8956       else if (unformat (i, "del"))
8957         is_add = 0;
8958       else
8959         {
8960           clib_warning ("parse error '%U'", format_unformat_error, i);
8961           return -99;
8962         }
8963     }
8964
8965   if (MPLS_LABEL_INVALID == local_label)
8966     {
8967       errmsg ("missing label\n");
8968       return -99;
8969     }
8970
8971   /* Construct the API message */
8972   M (BIER_TABLE_ADD_DEL, mp);
8973
8974   mp->bt_is_add = is_add;
8975   mp->bt_label = ntohl (local_label);
8976   mp->bt_tbl_id.bt_set = set;
8977   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8978   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8979
8980   /* send it... */
8981   S (mp);
8982
8983   /* Wait for a reply... */
8984   W (ret);
8985
8986   return (ret);
8987 }
8988
8989 static int
8990 api_bier_route_add_del (vat_main_t * vam)
8991 {
8992   unformat_input_t *i = vam->input;
8993   vl_api_bier_route_add_del_t *mp;
8994   u8 is_add = 1;
8995   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8996   ip4_address_t v4_next_hop_address;
8997   ip6_address_t v6_next_hop_address;
8998   u8 next_hop_set = 0;
8999   u8 next_hop_proto_is_ip4 = 1;
9000   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9001   int ret;
9002
9003   /* Parse args required to build the message */
9004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9005     {
9006       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9007         {
9008           next_hop_proto_is_ip4 = 1;
9009           next_hop_set = 1;
9010         }
9011       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9012         {
9013           next_hop_proto_is_ip4 = 0;
9014           next_hop_set = 1;
9015         }
9016       if (unformat (i, "sub-domain %d", &sub_domain))
9017         ;
9018       else if (unformat (i, "set %d", &set))
9019         ;
9020       else if (unformat (i, "hdr-len %d", &hdr_len))
9021         ;
9022       else if (unformat (i, "bp %d", &bp))
9023         ;
9024       else if (unformat (i, "add"))
9025         is_add = 1;
9026       else if (unformat (i, "del"))
9027         is_add = 0;
9028       else if (unformat (i, "out-label %d", &next_hop_out_label))
9029         ;
9030       else
9031         {
9032           clib_warning ("parse error '%U'", format_unformat_error, i);
9033           return -99;
9034         }
9035     }
9036
9037   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9038     {
9039       errmsg ("next hop / label set\n");
9040       return -99;
9041     }
9042   if (0 == bp)
9043     {
9044       errmsg ("bit=position not set\n");
9045       return -99;
9046     }
9047
9048   /* Construct the API message */
9049   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9050
9051   mp->br_is_add = is_add;
9052   mp->br_tbl_id.bt_set = set;
9053   mp->br_tbl_id.bt_sub_domain = sub_domain;
9054   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9055   mp->br_bp = ntohs (bp);
9056   mp->br_n_paths = 1;
9057   mp->br_paths[0].n_labels = 1;
9058   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9059   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9060
9061   if (next_hop_proto_is_ip4)
9062     {
9063       clib_memcpy (mp->br_paths[0].next_hop,
9064                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9065     }
9066   else
9067     {
9068       clib_memcpy (mp->br_paths[0].next_hop,
9069                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9070     }
9071
9072   /* send it... */
9073   S (mp);
9074
9075   /* Wait for a reply... */
9076   W (ret);
9077
9078   return (ret);
9079 }
9080
9081 static int
9082 api_proxy_arp_add_del (vat_main_t * vam)
9083 {
9084   unformat_input_t *i = vam->input;
9085   vl_api_proxy_arp_add_del_t *mp;
9086   u32 vrf_id = 0;
9087   u8 is_add = 1;
9088   vl_api_ip4_address_t lo, hi;
9089   u8 range_set = 0;
9090   int ret;
9091
9092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9093     {
9094       if (unformat (i, "vrf %d", &vrf_id))
9095         ;
9096       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9097                          unformat_vl_api_ip4_address, &hi))
9098         range_set = 1;
9099       else if (unformat (i, "del"))
9100         is_add = 0;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   if (range_set == 0)
9109     {
9110       errmsg ("address range not set");
9111       return -99;
9112     }
9113
9114   M (PROXY_ARP_ADD_DEL, mp);
9115
9116   mp->proxy.table_id = ntohl (vrf_id);
9117   mp->is_add = is_add;
9118   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9119   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9120
9121   S (mp);
9122   W (ret);
9123   return ret;
9124 }
9125
9126 static int
9127 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9128 {
9129   unformat_input_t *i = vam->input;
9130   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9131   u32 sw_if_index;
9132   u8 enable = 1;
9133   u8 sw_if_index_set = 0;
9134   int ret;
9135
9136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9137     {
9138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9139         sw_if_index_set = 1;
9140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9141         sw_if_index_set = 1;
9142       else if (unformat (i, "enable"))
9143         enable = 1;
9144       else if (unformat (i, "disable"))
9145         enable = 0;
9146       else
9147         {
9148           clib_warning ("parse error '%U'", format_unformat_error, i);
9149           return -99;
9150         }
9151     }
9152
9153   if (sw_if_index_set == 0)
9154     {
9155       errmsg ("missing interface name or sw_if_index");
9156       return -99;
9157     }
9158
9159   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9160
9161   mp->sw_if_index = ntohl (sw_if_index);
9162   mp->enable_disable = enable;
9163
9164   S (mp);
9165   W (ret);
9166   return ret;
9167 }
9168
9169 static int
9170 api_mpls_tunnel_add_del (vat_main_t * vam)
9171 {
9172   unformat_input_t *i = vam->input;
9173   vl_api_mpls_tunnel_add_del_t *mp;
9174
9175   u8 is_add = 1;
9176   u8 l2_only = 0;
9177   u32 sw_if_index = ~0;
9178   u32 next_hop_sw_if_index = ~0;
9179   u32 next_hop_proto_is_ip4 = 1;
9180
9181   u32 next_hop_table_id = 0;
9182   ip4_address_t v4_next_hop_address = {
9183     .as_u32 = 0,
9184   };
9185   ip6_address_t v6_next_hop_address = { {0} };
9186   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9187   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9188   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9189   int ret;
9190
9191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9192     {
9193       if (unformat (i, "add"))
9194         is_add = 1;
9195       else
9196         if (unformat
9197             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9198         is_add = 0;
9199       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9200         is_add = 0;
9201       else if (unformat (i, "via %U",
9202                          unformat_ip4_address, &v4_next_hop_address))
9203         {
9204           next_hop_proto_is_ip4 = 1;
9205         }
9206       else if (unformat (i, "via %U",
9207                          unformat_ip6_address, &v6_next_hop_address))
9208         {
9209           next_hop_proto_is_ip4 = 0;
9210         }
9211       else if (unformat (i, "via-label %d", &next_hop_via_label))
9212         ;
9213       else
9214         if (unformat
9215             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9216         ;
9217       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9218         ;
9219       else if (unformat (i, "l2-only"))
9220         l2_only = 1;
9221       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9222         ;
9223       else if (unformat (i, "out-label %d", &next_hop_out_label))
9224         {
9225           vl_api_fib_mpls_label_t fib_label = {
9226             .label = ntohl (next_hop_out_label),
9227             .ttl = 64,
9228             .exp = 0,
9229           };
9230           vec_add1 (next_hop_out_label_stack, fib_label);
9231         }
9232       else
9233         {
9234           clib_warning ("parse error '%U'", format_unformat_error, i);
9235           return -99;
9236         }
9237     }
9238
9239   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9240       vec_len (next_hop_out_label_stack));
9241
9242   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9243   mp->mt_sw_if_index = ntohl (sw_if_index);
9244   mp->mt_is_add = is_add;
9245   mp->mt_l2_only = l2_only;
9246   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9247   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9248   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9249   mp->mt_next_hop_weight = 1;
9250   mp->mt_next_hop_preference = 0;
9251
9252   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9253
9254   if (0 != mp->mt_next_hop_n_out_labels)
9255     {
9256       clib_memcpy (mp->mt_next_hop_out_label_stack,
9257                    next_hop_out_label_stack,
9258                    (vec_len (next_hop_out_label_stack) *
9259                     sizeof (vl_api_fib_mpls_label_t)));
9260       vec_free (next_hop_out_label_stack);
9261     }
9262
9263   if (next_hop_proto_is_ip4)
9264     {
9265       clib_memcpy (mp->mt_next_hop,
9266                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9267     }
9268   else
9269     {
9270       clib_memcpy (mp->mt_next_hop,
9271                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9272     }
9273
9274   S (mp);
9275   W (ret);
9276   return ret;
9277 }
9278
9279 static int
9280 api_sw_interface_set_unnumbered (vat_main_t * vam)
9281 {
9282   unformat_input_t *i = vam->input;
9283   vl_api_sw_interface_set_unnumbered_t *mp;
9284   u32 sw_if_index;
9285   u32 unnum_sw_index = ~0;
9286   u8 is_add = 1;
9287   u8 sw_if_index_set = 0;
9288   int ret;
9289
9290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9291     {
9292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9293         sw_if_index_set = 1;
9294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9295         sw_if_index_set = 1;
9296       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9297         ;
9298       else if (unformat (i, "del"))
9299         is_add = 0;
9300       else
9301         {
9302           clib_warning ("parse error '%U'", format_unformat_error, i);
9303           return -99;
9304         }
9305     }
9306
9307   if (sw_if_index_set == 0)
9308     {
9309       errmsg ("missing interface name or sw_if_index");
9310       return -99;
9311     }
9312
9313   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9314
9315   mp->sw_if_index = ntohl (sw_if_index);
9316   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9317   mp->is_add = is_add;
9318
9319   S (mp);
9320   W (ret);
9321   return ret;
9322 }
9323
9324 static int
9325 api_ip_neighbor_add_del (vat_main_t * vam)
9326 {
9327   vl_api_mac_address_t mac_address;
9328   unformat_input_t *i = vam->input;
9329   vl_api_ip_neighbor_add_del_t *mp;
9330   vl_api_address_t ip_address;
9331   u32 sw_if_index;
9332   u8 sw_if_index_set = 0;
9333   u8 is_add = 1;
9334   u8 mac_set = 0;
9335   u8 address_set = 0;
9336   int ret;
9337   ip_neighbor_flags_t flags;
9338
9339   flags = IP_NEIGHBOR_FLAG_NONE;
9340   clib_memset (&ip_address, 0, sizeof (ip_address));
9341   clib_memset (&mac_address, 0, sizeof (mac_address));
9342   /* Parse args required to build the message */
9343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9344     {
9345       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9346         {
9347           mac_set = 1;
9348         }
9349       else if (unformat (i, "del"))
9350         is_add = 0;
9351       else
9352         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9353         sw_if_index_set = 1;
9354       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9355         sw_if_index_set = 1;
9356       else if (unformat (i, "static"))
9357         flags |= IP_NEIGHBOR_FLAG_STATIC;
9358       else if (unformat (i, "no-fib-entry"))
9359         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9360       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9361         address_set = 1;
9362       else
9363         {
9364           clib_warning ("parse error '%U'", format_unformat_error, i);
9365           return -99;
9366         }
9367     }
9368
9369   if (sw_if_index_set == 0)
9370     {
9371       errmsg ("missing interface name or sw_if_index");
9372       return -99;
9373     }
9374   if (!address_set)
9375     {
9376       errmsg ("no address set");
9377       return -99;
9378     }
9379
9380   /* Construct the API message */
9381   M (IP_NEIGHBOR_ADD_DEL, mp);
9382
9383   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9384   mp->is_add = is_add;
9385   mp->neighbor.flags = htonl (flags);
9386   if (mac_set)
9387     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9388                  sizeof (mac_address));
9389   if (address_set)
9390     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9391
9392   /* send it... */
9393   S (mp);
9394
9395   /* Wait for a reply, return good/bad news  */
9396   W (ret);
9397   return ret;
9398 }
9399
9400 static int
9401 api_create_vlan_subif (vat_main_t * vam)
9402 {
9403   unformat_input_t *i = vam->input;
9404   vl_api_create_vlan_subif_t *mp;
9405   u32 sw_if_index;
9406   u8 sw_if_index_set = 0;
9407   u32 vlan_id;
9408   u8 vlan_id_set = 0;
9409   int ret;
9410
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "sw_if_index %d", &sw_if_index))
9414         sw_if_index_set = 1;
9415       else
9416         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9417         sw_if_index_set = 1;
9418       else if (unformat (i, "vlan %d", &vlan_id))
9419         vlan_id_set = 1;
9420       else
9421         {
9422           clib_warning ("parse error '%U'", format_unformat_error, i);
9423           return -99;
9424         }
9425     }
9426
9427   if (sw_if_index_set == 0)
9428     {
9429       errmsg ("missing interface name or sw_if_index");
9430       return -99;
9431     }
9432
9433   if (vlan_id_set == 0)
9434     {
9435       errmsg ("missing vlan_id");
9436       return -99;
9437     }
9438   M (CREATE_VLAN_SUBIF, mp);
9439
9440   mp->sw_if_index = ntohl (sw_if_index);
9441   mp->vlan_id = ntohl (vlan_id);
9442
9443   S (mp);
9444   W (ret);
9445   return ret;
9446 }
9447
9448 #define foreach_create_subif_bit                \
9449 _(no_tags)                                      \
9450 _(one_tag)                                      \
9451 _(two_tags)                                     \
9452 _(dot1ad)                                       \
9453 _(exact_match)                                  \
9454 _(default_sub)                                  \
9455 _(outer_vlan_id_any)                            \
9456 _(inner_vlan_id_any)
9457
9458 static int
9459 api_create_subif (vat_main_t * vam)
9460 {
9461   unformat_input_t *i = vam->input;
9462   vl_api_create_subif_t *mp;
9463   u32 sw_if_index;
9464   u8 sw_if_index_set = 0;
9465   u32 sub_id;
9466   u8 sub_id_set = 0;
9467   u32 no_tags = 0;
9468   u32 one_tag = 0;
9469   u32 two_tags = 0;
9470   u32 dot1ad = 0;
9471   u32 exact_match = 0;
9472   u32 default_sub = 0;
9473   u32 outer_vlan_id_any = 0;
9474   u32 inner_vlan_id_any = 0;
9475   u32 tmp;
9476   u16 outer_vlan_id = 0;
9477   u16 inner_vlan_id = 0;
9478   int ret;
9479
9480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9481     {
9482       if (unformat (i, "sw_if_index %d", &sw_if_index))
9483         sw_if_index_set = 1;
9484       else
9485         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9486         sw_if_index_set = 1;
9487       else if (unformat (i, "sub_id %d", &sub_id))
9488         sub_id_set = 1;
9489       else if (unformat (i, "outer_vlan_id %d", &tmp))
9490         outer_vlan_id = tmp;
9491       else if (unformat (i, "inner_vlan_id %d", &tmp))
9492         inner_vlan_id = tmp;
9493
9494 #define _(a) else if (unformat (i, #a)) a = 1 ;
9495       foreach_create_subif_bit
9496 #undef _
9497         else
9498         {
9499           clib_warning ("parse error '%U'", format_unformat_error, i);
9500           return -99;
9501         }
9502     }
9503
9504   if (sw_if_index_set == 0)
9505     {
9506       errmsg ("missing interface name or sw_if_index");
9507       return -99;
9508     }
9509
9510   if (sub_id_set == 0)
9511     {
9512       errmsg ("missing sub_id");
9513       return -99;
9514     }
9515   M (CREATE_SUBIF, mp);
9516
9517   mp->sw_if_index = ntohl (sw_if_index);
9518   mp->sub_id = ntohl (sub_id);
9519
9520 #define _(a) mp->a = a;
9521   foreach_create_subif_bit;
9522 #undef _
9523
9524   mp->outer_vlan_id = ntohs (outer_vlan_id);
9525   mp->inner_vlan_id = ntohs (inner_vlan_id);
9526
9527   S (mp);
9528   W (ret);
9529   return ret;
9530 }
9531
9532 static int
9533 api_oam_add_del (vat_main_t * vam)
9534 {
9535   unformat_input_t *i = vam->input;
9536   vl_api_oam_add_del_t *mp;
9537   u32 vrf_id = 0;
9538   u8 is_add = 1;
9539   ip4_address_t src, dst;
9540   u8 src_set = 0;
9541   u8 dst_set = 0;
9542   int ret;
9543
9544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9545     {
9546       if (unformat (i, "vrf %d", &vrf_id))
9547         ;
9548       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9549         src_set = 1;
9550       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9551         dst_set = 1;
9552       else if (unformat (i, "del"))
9553         is_add = 0;
9554       else
9555         {
9556           clib_warning ("parse error '%U'", format_unformat_error, i);
9557           return -99;
9558         }
9559     }
9560
9561   if (src_set == 0)
9562     {
9563       errmsg ("missing src addr");
9564       return -99;
9565     }
9566
9567   if (dst_set == 0)
9568     {
9569       errmsg ("missing dst addr");
9570       return -99;
9571     }
9572
9573   M (OAM_ADD_DEL, mp);
9574
9575   mp->vrf_id = ntohl (vrf_id);
9576   mp->is_add = is_add;
9577   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9578   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9579
9580   S (mp);
9581   W (ret);
9582   return ret;
9583 }
9584
9585 static int
9586 api_reset_fib (vat_main_t * vam)
9587 {
9588   unformat_input_t *i = vam->input;
9589   vl_api_reset_fib_t *mp;
9590   u32 vrf_id = 0;
9591   u8 is_ipv6 = 0;
9592   u8 vrf_id_set = 0;
9593
9594   int ret;
9595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9596     {
9597       if (unformat (i, "vrf %d", &vrf_id))
9598         vrf_id_set = 1;
9599       else if (unformat (i, "ipv6"))
9600         is_ipv6 = 1;
9601       else
9602         {
9603           clib_warning ("parse error '%U'", format_unformat_error, i);
9604           return -99;
9605         }
9606     }
9607
9608   if (vrf_id_set == 0)
9609     {
9610       errmsg ("missing vrf id");
9611       return -99;
9612     }
9613
9614   M (RESET_FIB, mp);
9615
9616   mp->vrf_id = ntohl (vrf_id);
9617   mp->is_ipv6 = is_ipv6;
9618
9619   S (mp);
9620   W (ret);
9621   return ret;
9622 }
9623
9624 static int
9625 api_dhcp_proxy_config (vat_main_t * vam)
9626 {
9627   unformat_input_t *i = vam->input;
9628   vl_api_dhcp_proxy_config_t *mp;
9629   u32 rx_vrf_id = 0;
9630   u32 server_vrf_id = 0;
9631   u8 is_add = 1;
9632   u8 v4_address_set = 0;
9633   u8 v6_address_set = 0;
9634   ip4_address_t v4address;
9635   ip6_address_t v6address;
9636   u8 v4_src_address_set = 0;
9637   u8 v6_src_address_set = 0;
9638   ip4_address_t v4srcaddress;
9639   ip6_address_t v6srcaddress;
9640   int ret;
9641
9642   /* Parse args required to build the message */
9643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9644     {
9645       if (unformat (i, "del"))
9646         is_add = 0;
9647       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9648         ;
9649       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9650         ;
9651       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9652         v4_address_set = 1;
9653       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9654         v6_address_set = 1;
9655       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9656         v4_src_address_set = 1;
9657       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9658         v6_src_address_set = 1;
9659       else
9660         break;
9661     }
9662
9663   if (v4_address_set && v6_address_set)
9664     {
9665       errmsg ("both v4 and v6 server addresses set");
9666       return -99;
9667     }
9668   if (!v4_address_set && !v6_address_set)
9669     {
9670       errmsg ("no server addresses set");
9671       return -99;
9672     }
9673
9674   if (v4_src_address_set && v6_src_address_set)
9675     {
9676       errmsg ("both v4 and v6  src addresses set");
9677       return -99;
9678     }
9679   if (!v4_src_address_set && !v6_src_address_set)
9680     {
9681       errmsg ("no src addresses set");
9682       return -99;
9683     }
9684
9685   if (!(v4_src_address_set && v4_address_set) &&
9686       !(v6_src_address_set && v6_address_set))
9687     {
9688       errmsg ("no matching server and src addresses set");
9689       return -99;
9690     }
9691
9692   /* Construct the API message */
9693   M (DHCP_PROXY_CONFIG, mp);
9694
9695   mp->is_add = is_add;
9696   mp->rx_vrf_id = ntohl (rx_vrf_id);
9697   mp->server_vrf_id = ntohl (server_vrf_id);
9698   if (v6_address_set)
9699     {
9700       mp->is_ipv6 = 1;
9701       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9702       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9703     }
9704   else
9705     {
9706       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9707       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9708     }
9709
9710   /* send it... */
9711   S (mp);
9712
9713   /* Wait for a reply, return good/bad news  */
9714   W (ret);
9715   return ret;
9716 }
9717
9718 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9719 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9720
9721 static void
9722 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9723 {
9724   vat_main_t *vam = &vat_main;
9725   u32 i, count = mp->count;
9726   vl_api_dhcp_server_t *s;
9727
9728   if (mp->is_ipv6)
9729     print (vam->ofp,
9730            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9731            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9732            ntohl (mp->rx_vrf_id),
9733            format_ip6_address, mp->dhcp_src_address,
9734            mp->vss_type, mp->vss_vpn_ascii_id,
9735            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9736   else
9737     print (vam->ofp,
9738            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9739            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9740            ntohl (mp->rx_vrf_id),
9741            format_ip4_address, mp->dhcp_src_address,
9742            mp->vss_type, mp->vss_vpn_ascii_id,
9743            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9744
9745   for (i = 0; i < count; i++)
9746     {
9747       s = &mp->servers[i];
9748
9749       if (mp->is_ipv6)
9750         print (vam->ofp,
9751                " Server Table-ID %d, Server Address %U",
9752                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9753       else
9754         print (vam->ofp,
9755                " Server Table-ID %d, Server Address %U",
9756                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9757     }
9758 }
9759
9760 static void vl_api_dhcp_proxy_details_t_handler_json
9761   (vl_api_dhcp_proxy_details_t * mp)
9762 {
9763   vat_main_t *vam = &vat_main;
9764   vat_json_node_t *node = NULL;
9765   u32 i, count = mp->count;
9766   struct in_addr ip4;
9767   struct in6_addr ip6;
9768   vl_api_dhcp_server_t *s;
9769
9770   if (VAT_JSON_ARRAY != vam->json_tree.type)
9771     {
9772       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9773       vat_json_init_array (&vam->json_tree);
9774     }
9775   node = vat_json_array_add (&vam->json_tree);
9776
9777   vat_json_init_object (node);
9778   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9779   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9780                              sizeof (mp->vss_type));
9781   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9782                                    mp->vss_vpn_ascii_id);
9783   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9784   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9785
9786   if (mp->is_ipv6)
9787     {
9788       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9789       vat_json_object_add_ip6 (node, "src_address", ip6);
9790     }
9791   else
9792     {
9793       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9794       vat_json_object_add_ip4 (node, "src_address", ip4);
9795     }
9796
9797   for (i = 0; i < count; i++)
9798     {
9799       s = &mp->servers[i];
9800
9801       vat_json_object_add_uint (node, "server-table-id",
9802                                 ntohl (s->server_vrf_id));
9803
9804       if (mp->is_ipv6)
9805         {
9806           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9807           vat_json_object_add_ip4 (node, "src_address", ip4);
9808         }
9809       else
9810         {
9811           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9812           vat_json_object_add_ip6 (node, "server_address", ip6);
9813         }
9814     }
9815 }
9816
9817 static int
9818 api_dhcp_proxy_dump (vat_main_t * vam)
9819 {
9820   unformat_input_t *i = vam->input;
9821   vl_api_control_ping_t *mp_ping;
9822   vl_api_dhcp_proxy_dump_t *mp;
9823   u8 is_ipv6 = 0;
9824   int ret;
9825
9826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9827     {
9828       if (unformat (i, "ipv6"))
9829         is_ipv6 = 1;
9830       else
9831         {
9832           clib_warning ("parse error '%U'", format_unformat_error, i);
9833           return -99;
9834         }
9835     }
9836
9837   M (DHCP_PROXY_DUMP, mp);
9838
9839   mp->is_ip6 = is_ipv6;
9840   S (mp);
9841
9842   /* Use a control ping for synchronization */
9843   MPING (CONTROL_PING, mp_ping);
9844   S (mp_ping);
9845
9846   W (ret);
9847   return ret;
9848 }
9849
9850 static int
9851 api_dhcp_proxy_set_vss (vat_main_t * vam)
9852 {
9853   unformat_input_t *i = vam->input;
9854   vl_api_dhcp_proxy_set_vss_t *mp;
9855   u8 is_ipv6 = 0;
9856   u8 is_add = 1;
9857   u32 tbl_id = ~0;
9858   u8 vss_type = VSS_TYPE_DEFAULT;
9859   u8 *vpn_ascii_id = 0;
9860   u32 oui = 0;
9861   u32 fib_id = 0;
9862   int ret;
9863
9864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9865     {
9866       if (unformat (i, "tbl_id %d", &tbl_id))
9867         ;
9868       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9869         vss_type = VSS_TYPE_ASCII;
9870       else if (unformat (i, "fib_id %d", &fib_id))
9871         vss_type = VSS_TYPE_VPN_ID;
9872       else if (unformat (i, "oui %d", &oui))
9873         vss_type = VSS_TYPE_VPN_ID;
9874       else if (unformat (i, "ipv6"))
9875         is_ipv6 = 1;
9876       else if (unformat (i, "del"))
9877         is_add = 0;
9878       else
9879         break;
9880     }
9881
9882   if (tbl_id == ~0)
9883     {
9884       errmsg ("missing tbl_id ");
9885       vec_free (vpn_ascii_id);
9886       return -99;
9887     }
9888
9889   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9890     {
9891       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9892       vec_free (vpn_ascii_id);
9893       return -99;
9894     }
9895
9896   M (DHCP_PROXY_SET_VSS, mp);
9897   mp->tbl_id = ntohl (tbl_id);
9898   mp->vss_type = vss_type;
9899   if (vpn_ascii_id)
9900     {
9901       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9902       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9903     }
9904   mp->vpn_index = ntohl (fib_id);
9905   mp->oui = ntohl (oui);
9906   mp->is_ipv6 = is_ipv6;
9907   mp->is_add = is_add;
9908
9909   S (mp);
9910   W (ret);
9911
9912   vec_free (vpn_ascii_id);
9913   return ret;
9914 }
9915
9916 static int
9917 api_dhcp_client_config (vat_main_t * vam)
9918 {
9919   unformat_input_t *i = vam->input;
9920   vl_api_dhcp_client_config_t *mp;
9921   u32 sw_if_index;
9922   u8 sw_if_index_set = 0;
9923   u8 is_add = 1;
9924   u8 *hostname = 0;
9925   u8 disable_event = 0;
9926   int ret;
9927
9928   /* Parse args required to build the message */
9929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9930     {
9931       if (unformat (i, "del"))
9932         is_add = 0;
9933       else
9934         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9935         sw_if_index_set = 1;
9936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9937         sw_if_index_set = 1;
9938       else if (unformat (i, "hostname %s", &hostname))
9939         ;
9940       else if (unformat (i, "disable_event"))
9941         disable_event = 1;
9942       else
9943         break;
9944     }
9945
9946   if (sw_if_index_set == 0)
9947     {
9948       errmsg ("missing interface name or sw_if_index");
9949       return -99;
9950     }
9951
9952   if (vec_len (hostname) > 63)
9953     {
9954       errmsg ("hostname too long");
9955     }
9956   vec_add1 (hostname, 0);
9957
9958   /* Construct the API message */
9959   M (DHCP_CLIENT_CONFIG, mp);
9960
9961   mp->is_add = is_add;
9962   mp->client.sw_if_index = htonl (sw_if_index);
9963   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9964   vec_free (hostname);
9965   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9966   mp->client.pid = htonl (getpid ());
9967
9968   /* send it... */
9969   S (mp);
9970
9971   /* Wait for a reply, return good/bad news  */
9972   W (ret);
9973   return ret;
9974 }
9975
9976 static int
9977 api_set_ip_flow_hash (vat_main_t * vam)
9978 {
9979   unformat_input_t *i = vam->input;
9980   vl_api_set_ip_flow_hash_t *mp;
9981   u32 vrf_id = 0;
9982   u8 is_ipv6 = 0;
9983   u8 vrf_id_set = 0;
9984   u8 src = 0;
9985   u8 dst = 0;
9986   u8 sport = 0;
9987   u8 dport = 0;
9988   u8 proto = 0;
9989   u8 reverse = 0;
9990   int ret;
9991
9992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9993     {
9994       if (unformat (i, "vrf %d", &vrf_id))
9995         vrf_id_set = 1;
9996       else if (unformat (i, "ipv6"))
9997         is_ipv6 = 1;
9998       else if (unformat (i, "src"))
9999         src = 1;
10000       else if (unformat (i, "dst"))
10001         dst = 1;
10002       else if (unformat (i, "sport"))
10003         sport = 1;
10004       else if (unformat (i, "dport"))
10005         dport = 1;
10006       else if (unformat (i, "proto"))
10007         proto = 1;
10008       else if (unformat (i, "reverse"))
10009         reverse = 1;
10010
10011       else
10012         {
10013           clib_warning ("parse error '%U'", format_unformat_error, i);
10014           return -99;
10015         }
10016     }
10017
10018   if (vrf_id_set == 0)
10019     {
10020       errmsg ("missing vrf id");
10021       return -99;
10022     }
10023
10024   M (SET_IP_FLOW_HASH, mp);
10025   mp->src = src;
10026   mp->dst = dst;
10027   mp->sport = sport;
10028   mp->dport = dport;
10029   mp->proto = proto;
10030   mp->reverse = reverse;
10031   mp->vrf_id = ntohl (vrf_id);
10032   mp->is_ipv6 = is_ipv6;
10033
10034   S (mp);
10035   W (ret);
10036   return ret;
10037 }
10038
10039 static int
10040 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10041 {
10042   unformat_input_t *i = vam->input;
10043   vl_api_sw_interface_ip6_enable_disable_t *mp;
10044   u32 sw_if_index;
10045   u8 sw_if_index_set = 0;
10046   u8 enable = 0;
10047   int ret;
10048
10049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10050     {
10051       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10052         sw_if_index_set = 1;
10053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10054         sw_if_index_set = 1;
10055       else if (unformat (i, "enable"))
10056         enable = 1;
10057       else if (unformat (i, "disable"))
10058         enable = 0;
10059       else
10060         {
10061           clib_warning ("parse error '%U'", format_unformat_error, i);
10062           return -99;
10063         }
10064     }
10065
10066   if (sw_if_index_set == 0)
10067     {
10068       errmsg ("missing interface name or sw_if_index");
10069       return -99;
10070     }
10071
10072   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10073
10074   mp->sw_if_index = ntohl (sw_if_index);
10075   mp->enable = enable;
10076
10077   S (mp);
10078   W (ret);
10079   return ret;
10080 }
10081
10082 static int
10083 api_ip6nd_proxy_add_del (vat_main_t * vam)
10084 {
10085   unformat_input_t *i = vam->input;
10086   vl_api_ip6nd_proxy_add_del_t *mp;
10087   u32 sw_if_index = ~0;
10088   u8 v6_address_set = 0;
10089   vl_api_ip6_address_t v6address;
10090   u8 is_del = 0;
10091   int ret;
10092
10093   /* Parse args required to build the message */
10094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10095     {
10096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10097         ;
10098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10099         ;
10100       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10101         v6_address_set = 1;
10102       if (unformat (i, "del"))
10103         is_del = 1;
10104       else
10105         {
10106           clib_warning ("parse error '%U'", format_unformat_error, i);
10107           return -99;
10108         }
10109     }
10110
10111   if (sw_if_index == ~0)
10112     {
10113       errmsg ("missing interface name or sw_if_index");
10114       return -99;
10115     }
10116   if (!v6_address_set)
10117     {
10118       errmsg ("no address set");
10119       return -99;
10120     }
10121
10122   /* Construct the API message */
10123   M (IP6ND_PROXY_ADD_DEL, mp);
10124
10125   mp->is_del = is_del;
10126   mp->sw_if_index = ntohl (sw_if_index);
10127   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10128
10129   /* send it... */
10130   S (mp);
10131
10132   /* Wait for a reply, return good/bad news  */
10133   W (ret);
10134   return ret;
10135 }
10136
10137 static int
10138 api_ip6nd_proxy_dump (vat_main_t * vam)
10139 {
10140   vl_api_ip6nd_proxy_dump_t *mp;
10141   vl_api_control_ping_t *mp_ping;
10142   int ret;
10143
10144   M (IP6ND_PROXY_DUMP, mp);
10145
10146   S (mp);
10147
10148   /* Use a control ping for synchronization */
10149   MPING (CONTROL_PING, mp_ping);
10150   S (mp_ping);
10151
10152   W (ret);
10153   return ret;
10154 }
10155
10156 static void vl_api_ip6nd_proxy_details_t_handler
10157   (vl_api_ip6nd_proxy_details_t * mp)
10158 {
10159   vat_main_t *vam = &vat_main;
10160
10161   print (vam->ofp, "host %U sw_if_index %d",
10162          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10163 }
10164
10165 static void vl_api_ip6nd_proxy_details_t_handler_json
10166   (vl_api_ip6nd_proxy_details_t * mp)
10167 {
10168   vat_main_t *vam = &vat_main;
10169   struct in6_addr ip6;
10170   vat_json_node_t *node = NULL;
10171
10172   if (VAT_JSON_ARRAY != vam->json_tree.type)
10173     {
10174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10175       vat_json_init_array (&vam->json_tree);
10176     }
10177   node = vat_json_array_add (&vam->json_tree);
10178
10179   vat_json_init_object (node);
10180   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10181
10182   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10183   vat_json_object_add_ip6 (node, "host", ip6);
10184 }
10185
10186 static int
10187 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10188 {
10189   unformat_input_t *i = vam->input;
10190   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10191   u32 sw_if_index;
10192   u8 sw_if_index_set = 0;
10193   u32 address_length = 0;
10194   u8 v6_address_set = 0;
10195   vl_api_prefix_t pfx;
10196   u8 use_default = 0;
10197   u8 no_advertise = 0;
10198   u8 off_link = 0;
10199   u8 no_autoconfig = 0;
10200   u8 no_onlink = 0;
10201   u8 is_no = 0;
10202   u32 val_lifetime = 0;
10203   u32 pref_lifetime = 0;
10204   int ret;
10205
10206   /* Parse args required to build the message */
10207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10210         sw_if_index_set = 1;
10211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10212         sw_if_index_set = 1;
10213       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10214         v6_address_set = 1;
10215       else if (unformat (i, "val_life %d", &val_lifetime))
10216         ;
10217       else if (unformat (i, "pref_life %d", &pref_lifetime))
10218         ;
10219       else if (unformat (i, "def"))
10220         use_default = 1;
10221       else if (unformat (i, "noadv"))
10222         no_advertise = 1;
10223       else if (unformat (i, "offl"))
10224         off_link = 1;
10225       else if (unformat (i, "noauto"))
10226         no_autoconfig = 1;
10227       else if (unformat (i, "nolink"))
10228         no_onlink = 1;
10229       else if (unformat (i, "isno"))
10230         is_no = 1;
10231       else
10232         {
10233           clib_warning ("parse error '%U'", format_unformat_error, i);
10234           return -99;
10235         }
10236     }
10237
10238   if (sw_if_index_set == 0)
10239     {
10240       errmsg ("missing interface name or sw_if_index");
10241       return -99;
10242     }
10243   if (!v6_address_set)
10244     {
10245       errmsg ("no address set");
10246       return -99;
10247     }
10248
10249   /* Construct the API message */
10250   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10251
10252   mp->sw_if_index = ntohl (sw_if_index);
10253   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10254   mp->use_default = use_default;
10255   mp->no_advertise = no_advertise;
10256   mp->off_link = off_link;
10257   mp->no_autoconfig = no_autoconfig;
10258   mp->no_onlink = no_onlink;
10259   mp->is_no = is_no;
10260   mp->val_lifetime = ntohl (val_lifetime);
10261   mp->pref_lifetime = ntohl (pref_lifetime);
10262
10263   /* send it... */
10264   S (mp);
10265
10266   /* Wait for a reply, return good/bad news  */
10267   W (ret);
10268   return ret;
10269 }
10270
10271 static int
10272 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10273 {
10274   unformat_input_t *i = vam->input;
10275   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10276   u32 sw_if_index;
10277   u8 sw_if_index_set = 0;
10278   u8 suppress = 0;
10279   u8 managed = 0;
10280   u8 other = 0;
10281   u8 ll_option = 0;
10282   u8 send_unicast = 0;
10283   u8 cease = 0;
10284   u8 is_no = 0;
10285   u8 default_router = 0;
10286   u32 max_interval = 0;
10287   u32 min_interval = 0;
10288   u32 lifetime = 0;
10289   u32 initial_count = 0;
10290   u32 initial_interval = 0;
10291   int ret;
10292
10293
10294   /* Parse args required to build the message */
10295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10296     {
10297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10298         sw_if_index_set = 1;
10299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10300         sw_if_index_set = 1;
10301       else if (unformat (i, "maxint %d", &max_interval))
10302         ;
10303       else if (unformat (i, "minint %d", &min_interval))
10304         ;
10305       else if (unformat (i, "life %d", &lifetime))
10306         ;
10307       else if (unformat (i, "count %d", &initial_count))
10308         ;
10309       else if (unformat (i, "interval %d", &initial_interval))
10310         ;
10311       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10312         suppress = 1;
10313       else if (unformat (i, "managed"))
10314         managed = 1;
10315       else if (unformat (i, "other"))
10316         other = 1;
10317       else if (unformat (i, "ll"))
10318         ll_option = 1;
10319       else if (unformat (i, "send"))
10320         send_unicast = 1;
10321       else if (unformat (i, "cease"))
10322         cease = 1;
10323       else if (unformat (i, "isno"))
10324         is_no = 1;
10325       else if (unformat (i, "def"))
10326         default_router = 1;
10327       else
10328         {
10329           clib_warning ("parse error '%U'", format_unformat_error, i);
10330           return -99;
10331         }
10332     }
10333
10334   if (sw_if_index_set == 0)
10335     {
10336       errmsg ("missing interface name or sw_if_index");
10337       return -99;
10338     }
10339
10340   /* Construct the API message */
10341   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10342
10343   mp->sw_if_index = ntohl (sw_if_index);
10344   mp->max_interval = ntohl (max_interval);
10345   mp->min_interval = ntohl (min_interval);
10346   mp->lifetime = ntohl (lifetime);
10347   mp->initial_count = ntohl (initial_count);
10348   mp->initial_interval = ntohl (initial_interval);
10349   mp->suppress = suppress;
10350   mp->managed = managed;
10351   mp->other = other;
10352   mp->ll_option = ll_option;
10353   mp->send_unicast = send_unicast;
10354   mp->cease = cease;
10355   mp->is_no = is_no;
10356   mp->default_router = default_router;
10357
10358   /* send it... */
10359   S (mp);
10360
10361   /* Wait for a reply, return good/bad news  */
10362   W (ret);
10363   return ret;
10364 }
10365
10366 static int
10367 api_set_arp_neighbor_limit (vat_main_t * vam)
10368 {
10369   unformat_input_t *i = vam->input;
10370   vl_api_set_arp_neighbor_limit_t *mp;
10371   u32 arp_nbr_limit;
10372   u8 limit_set = 0;
10373   u8 is_ipv6 = 0;
10374   int ret;
10375
10376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10377     {
10378       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10379         limit_set = 1;
10380       else if (unformat (i, "ipv6"))
10381         is_ipv6 = 1;
10382       else
10383         {
10384           clib_warning ("parse error '%U'", format_unformat_error, i);
10385           return -99;
10386         }
10387     }
10388
10389   if (limit_set == 0)
10390     {
10391       errmsg ("missing limit value");
10392       return -99;
10393     }
10394
10395   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10396
10397   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10398   mp->is_ipv6 = is_ipv6;
10399
10400   S (mp);
10401   W (ret);
10402   return ret;
10403 }
10404
10405 static int
10406 api_l2_patch_add_del (vat_main_t * vam)
10407 {
10408   unformat_input_t *i = vam->input;
10409   vl_api_l2_patch_add_del_t *mp;
10410   u32 rx_sw_if_index;
10411   u8 rx_sw_if_index_set = 0;
10412   u32 tx_sw_if_index;
10413   u8 tx_sw_if_index_set = 0;
10414   u8 is_add = 1;
10415   int ret;
10416
10417   /* Parse args required to build the message */
10418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10419     {
10420       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10421         rx_sw_if_index_set = 1;
10422       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10423         tx_sw_if_index_set = 1;
10424       else if (unformat (i, "rx"))
10425         {
10426           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10427             {
10428               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10429                             &rx_sw_if_index))
10430                 rx_sw_if_index_set = 1;
10431             }
10432           else
10433             break;
10434         }
10435       else if (unformat (i, "tx"))
10436         {
10437           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10438             {
10439               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10440                             &tx_sw_if_index))
10441                 tx_sw_if_index_set = 1;
10442             }
10443           else
10444             break;
10445         }
10446       else if (unformat (i, "del"))
10447         is_add = 0;
10448       else
10449         break;
10450     }
10451
10452   if (rx_sw_if_index_set == 0)
10453     {
10454       errmsg ("missing rx interface name or rx_sw_if_index");
10455       return -99;
10456     }
10457
10458   if (tx_sw_if_index_set == 0)
10459     {
10460       errmsg ("missing tx interface name or tx_sw_if_index");
10461       return -99;
10462     }
10463
10464   M (L2_PATCH_ADD_DEL, mp);
10465
10466   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10467   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10468   mp->is_add = is_add;
10469
10470   S (mp);
10471   W (ret);
10472   return ret;
10473 }
10474
10475 u8 is_del;
10476 u8 localsid_addr[16];
10477 u8 end_psp;
10478 u8 behavior;
10479 u32 sw_if_index;
10480 u32 vlan_index;
10481 u32 fib_table;
10482 u8 nh_addr[16];
10483
10484 static int
10485 api_sr_localsid_add_del (vat_main_t * vam)
10486 {
10487   unformat_input_t *i = vam->input;
10488   vl_api_sr_localsid_add_del_t *mp;
10489
10490   u8 is_del;
10491   ip6_address_t localsid;
10492   u8 end_psp = 0;
10493   u8 behavior = ~0;
10494   u32 sw_if_index;
10495   u32 fib_table = ~(u32) 0;
10496   ip6_address_t nh_addr6;
10497   ip4_address_t nh_addr4;
10498   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10499   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10500
10501   bool nexthop_set = 0;
10502
10503   int ret;
10504
10505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10506     {
10507       if (unformat (i, "del"))
10508         is_del = 1;
10509       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10510       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10511         nexthop_set = 1;
10512       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10513         nexthop_set = 1;
10514       else if (unformat (i, "behavior %u", &behavior));
10515       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10516       else if (unformat (i, "fib-table %u", &fib_table));
10517       else if (unformat (i, "end.psp %u", &behavior));
10518       else
10519         break;
10520     }
10521
10522   M (SR_LOCALSID_ADD_DEL, mp);
10523
10524   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10525   if (nexthop_set)
10526     {
10527       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10528       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10529     }
10530   mp->behavior = behavior;
10531   mp->sw_if_index = ntohl (sw_if_index);
10532   mp->fib_table = ntohl (fib_table);
10533   mp->end_psp = end_psp;
10534   mp->is_del = is_del;
10535
10536   S (mp);
10537   W (ret);
10538   return ret;
10539 }
10540
10541 static int
10542 api_ioam_enable (vat_main_t * vam)
10543 {
10544   unformat_input_t *input = vam->input;
10545   vl_api_ioam_enable_t *mp;
10546   u32 id = 0;
10547   int has_trace_option = 0;
10548   int has_pot_option = 0;
10549   int has_seqno_option = 0;
10550   int has_analyse_option = 0;
10551   int ret;
10552
10553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10554     {
10555       if (unformat (input, "trace"))
10556         has_trace_option = 1;
10557       else if (unformat (input, "pot"))
10558         has_pot_option = 1;
10559       else if (unformat (input, "seqno"))
10560         has_seqno_option = 1;
10561       else if (unformat (input, "analyse"))
10562         has_analyse_option = 1;
10563       else
10564         break;
10565     }
10566   M (IOAM_ENABLE, mp);
10567   mp->id = htons (id);
10568   mp->seqno = has_seqno_option;
10569   mp->analyse = has_analyse_option;
10570   mp->pot_enable = has_pot_option;
10571   mp->trace_enable = has_trace_option;
10572
10573   S (mp);
10574   W (ret);
10575   return ret;
10576 }
10577
10578
10579 static int
10580 api_ioam_disable (vat_main_t * vam)
10581 {
10582   vl_api_ioam_disable_t *mp;
10583   int ret;
10584
10585   M (IOAM_DISABLE, mp);
10586   S (mp);
10587   W (ret);
10588   return ret;
10589 }
10590
10591 #define foreach_tcp_proto_field                 \
10592 _(src_port)                                     \
10593 _(dst_port)
10594
10595 #define foreach_udp_proto_field                 \
10596 _(src_port)                                     \
10597 _(dst_port)
10598
10599 #define foreach_ip4_proto_field                 \
10600 _(src_address)                                  \
10601 _(dst_address)                                  \
10602 _(tos)                                          \
10603 _(length)                                       \
10604 _(fragment_id)                                  \
10605 _(ttl)                                          \
10606 _(protocol)                                     \
10607 _(checksum)
10608
10609 typedef struct
10610 {
10611   u16 src_port, dst_port;
10612 } tcpudp_header_t;
10613
10614 #if VPP_API_TEST_BUILTIN == 0
10615 uword
10616 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10617 {
10618   u8 **maskp = va_arg (*args, u8 **);
10619   u8 *mask = 0;
10620   u8 found_something = 0;
10621   tcp_header_t *tcp;
10622
10623 #define _(a) u8 a=0;
10624   foreach_tcp_proto_field;
10625 #undef _
10626
10627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10628     {
10629       if (0);
10630 #define _(a) else if (unformat (input, #a)) a=1;
10631       foreach_tcp_proto_field
10632 #undef _
10633         else
10634         break;
10635     }
10636
10637 #define _(a) found_something += a;
10638   foreach_tcp_proto_field;
10639 #undef _
10640
10641   if (found_something == 0)
10642     return 0;
10643
10644   vec_validate (mask, sizeof (*tcp) - 1);
10645
10646   tcp = (tcp_header_t *) mask;
10647
10648 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10649   foreach_tcp_proto_field;
10650 #undef _
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 uword
10657 unformat_udp_mask (unformat_input_t * input, va_list * args)
10658 {
10659   u8 **maskp = va_arg (*args, u8 **);
10660   u8 *mask = 0;
10661   u8 found_something = 0;
10662   udp_header_t *udp;
10663
10664 #define _(a) u8 a=0;
10665   foreach_udp_proto_field;
10666 #undef _
10667
10668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10669     {
10670       if (0);
10671 #define _(a) else if (unformat (input, #a)) a=1;
10672       foreach_udp_proto_field
10673 #undef _
10674         else
10675         break;
10676     }
10677
10678 #define _(a) found_something += a;
10679   foreach_udp_proto_field;
10680 #undef _
10681
10682   if (found_something == 0)
10683     return 0;
10684
10685   vec_validate (mask, sizeof (*udp) - 1);
10686
10687   udp = (udp_header_t *) mask;
10688
10689 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10690   foreach_udp_proto_field;
10691 #undef _
10692
10693   *maskp = mask;
10694   return 1;
10695 }
10696
10697 uword
10698 unformat_l4_mask (unformat_input_t * input, va_list * args)
10699 {
10700   u8 **maskp = va_arg (*args, u8 **);
10701   u16 src_port = 0, dst_port = 0;
10702   tcpudp_header_t *tcpudp;
10703
10704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10707         return 1;
10708       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10709         return 1;
10710       else if (unformat (input, "src_port"))
10711         src_port = 0xFFFF;
10712       else if (unformat (input, "dst_port"))
10713         dst_port = 0xFFFF;
10714       else
10715         return 0;
10716     }
10717
10718   if (!src_port && !dst_port)
10719     return 0;
10720
10721   u8 *mask = 0;
10722   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10723
10724   tcpudp = (tcpudp_header_t *) mask;
10725   tcpudp->src_port = src_port;
10726   tcpudp->dst_port = dst_port;
10727
10728   *maskp = mask;
10729
10730   return 1;
10731 }
10732
10733 uword
10734 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10735 {
10736   u8 **maskp = va_arg (*args, u8 **);
10737   u8 *mask = 0;
10738   u8 found_something = 0;
10739   ip4_header_t *ip;
10740
10741 #define _(a) u8 a=0;
10742   foreach_ip4_proto_field;
10743 #undef _
10744   u8 version = 0;
10745   u8 hdr_length = 0;
10746
10747
10748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10749     {
10750       if (unformat (input, "version"))
10751         version = 1;
10752       else if (unformat (input, "hdr_length"))
10753         hdr_length = 1;
10754       else if (unformat (input, "src"))
10755         src_address = 1;
10756       else if (unformat (input, "dst"))
10757         dst_address = 1;
10758       else if (unformat (input, "proto"))
10759         protocol = 1;
10760
10761 #define _(a) else if (unformat (input, #a)) a=1;
10762       foreach_ip4_proto_field
10763 #undef _
10764         else
10765         break;
10766     }
10767
10768 #define _(a) found_something += a;
10769   foreach_ip4_proto_field;
10770 #undef _
10771
10772   if (found_something == 0)
10773     return 0;
10774
10775   vec_validate (mask, sizeof (*ip) - 1);
10776
10777   ip = (ip4_header_t *) mask;
10778
10779 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10780   foreach_ip4_proto_field;
10781 #undef _
10782
10783   ip->ip_version_and_header_length = 0;
10784
10785   if (version)
10786     ip->ip_version_and_header_length |= 0xF0;
10787
10788   if (hdr_length)
10789     ip->ip_version_and_header_length |= 0x0F;
10790
10791   *maskp = mask;
10792   return 1;
10793 }
10794
10795 #define foreach_ip6_proto_field                 \
10796 _(src_address)                                  \
10797 _(dst_address)                                  \
10798 _(payload_length)                               \
10799 _(hop_limit)                                    \
10800 _(protocol)
10801
10802 uword
10803 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10804 {
10805   u8 **maskp = va_arg (*args, u8 **);
10806   u8 *mask = 0;
10807   u8 found_something = 0;
10808   ip6_header_t *ip;
10809   u32 ip_version_traffic_class_and_flow_label;
10810
10811 #define _(a) u8 a=0;
10812   foreach_ip6_proto_field;
10813 #undef _
10814   u8 version = 0;
10815   u8 traffic_class = 0;
10816   u8 flow_label = 0;
10817
10818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10819     {
10820       if (unformat (input, "version"))
10821         version = 1;
10822       else if (unformat (input, "traffic-class"))
10823         traffic_class = 1;
10824       else if (unformat (input, "flow-label"))
10825         flow_label = 1;
10826       else if (unformat (input, "src"))
10827         src_address = 1;
10828       else if (unformat (input, "dst"))
10829         dst_address = 1;
10830       else if (unformat (input, "proto"))
10831         protocol = 1;
10832
10833 #define _(a) else if (unformat (input, #a)) a=1;
10834       foreach_ip6_proto_field
10835 #undef _
10836         else
10837         break;
10838     }
10839
10840 #define _(a) found_something += a;
10841   foreach_ip6_proto_field;
10842 #undef _
10843
10844   if (found_something == 0)
10845     return 0;
10846
10847   vec_validate (mask, sizeof (*ip) - 1);
10848
10849   ip = (ip6_header_t *) mask;
10850
10851 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10852   foreach_ip6_proto_field;
10853 #undef _
10854
10855   ip_version_traffic_class_and_flow_label = 0;
10856
10857   if (version)
10858     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10859
10860   if (traffic_class)
10861     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10862
10863   if (flow_label)
10864     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10865
10866   ip->ip_version_traffic_class_and_flow_label =
10867     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10868
10869   *maskp = mask;
10870   return 1;
10871 }
10872
10873 uword
10874 unformat_l3_mask (unformat_input_t * input, va_list * args)
10875 {
10876   u8 **maskp = va_arg (*args, u8 **);
10877
10878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10879     {
10880       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10881         return 1;
10882       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10883         return 1;
10884       else
10885         break;
10886     }
10887   return 0;
10888 }
10889
10890 uword
10891 unformat_l2_mask (unformat_input_t * input, va_list * args)
10892 {
10893   u8 **maskp = va_arg (*args, u8 **);
10894   u8 *mask = 0;
10895   u8 src = 0;
10896   u8 dst = 0;
10897   u8 proto = 0;
10898   u8 tag1 = 0;
10899   u8 tag2 = 0;
10900   u8 ignore_tag1 = 0;
10901   u8 ignore_tag2 = 0;
10902   u8 cos1 = 0;
10903   u8 cos2 = 0;
10904   u8 dot1q = 0;
10905   u8 dot1ad = 0;
10906   int len = 14;
10907
10908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10909     {
10910       if (unformat (input, "src"))
10911         src = 1;
10912       else if (unformat (input, "dst"))
10913         dst = 1;
10914       else if (unformat (input, "proto"))
10915         proto = 1;
10916       else if (unformat (input, "tag1"))
10917         tag1 = 1;
10918       else if (unformat (input, "tag2"))
10919         tag2 = 1;
10920       else if (unformat (input, "ignore-tag1"))
10921         ignore_tag1 = 1;
10922       else if (unformat (input, "ignore-tag2"))
10923         ignore_tag2 = 1;
10924       else if (unformat (input, "cos1"))
10925         cos1 = 1;
10926       else if (unformat (input, "cos2"))
10927         cos2 = 1;
10928       else if (unformat (input, "dot1q"))
10929         dot1q = 1;
10930       else if (unformat (input, "dot1ad"))
10931         dot1ad = 1;
10932       else
10933         break;
10934     }
10935   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10936        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10937     return 0;
10938
10939   if (tag1 || ignore_tag1 || cos1 || dot1q)
10940     len = 18;
10941   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10942     len = 22;
10943
10944   vec_validate (mask, len - 1);
10945
10946   if (dst)
10947     clib_memset (mask, 0xff, 6);
10948
10949   if (src)
10950     clib_memset (mask + 6, 0xff, 6);
10951
10952   if (tag2 || dot1ad)
10953     {
10954       /* inner vlan tag */
10955       if (tag2)
10956         {
10957           mask[19] = 0xff;
10958           mask[18] = 0x0f;
10959         }
10960       if (cos2)
10961         mask[18] |= 0xe0;
10962       if (proto)
10963         mask[21] = mask[20] = 0xff;
10964       if (tag1)
10965         {
10966           mask[15] = 0xff;
10967           mask[14] = 0x0f;
10968         }
10969       if (cos1)
10970         mask[14] |= 0xe0;
10971       *maskp = mask;
10972       return 1;
10973     }
10974   if (tag1 | dot1q)
10975     {
10976       if (tag1)
10977         {
10978           mask[15] = 0xff;
10979           mask[14] = 0x0f;
10980         }
10981       if (cos1)
10982         mask[14] |= 0xe0;
10983       if (proto)
10984         mask[16] = mask[17] = 0xff;
10985
10986       *maskp = mask;
10987       return 1;
10988     }
10989   if (cos2)
10990     mask[18] |= 0xe0;
10991   if (cos1)
10992     mask[14] |= 0xe0;
10993   if (proto)
10994     mask[12] = mask[13] = 0xff;
10995
10996   *maskp = mask;
10997   return 1;
10998 }
10999
11000 uword
11001 unformat_classify_mask (unformat_input_t * input, va_list * args)
11002 {
11003   u8 **maskp = va_arg (*args, u8 **);
11004   u32 *skipp = va_arg (*args, u32 *);
11005   u32 *matchp = va_arg (*args, u32 *);
11006   u32 match;
11007   u8 *mask = 0;
11008   u8 *l2 = 0;
11009   u8 *l3 = 0;
11010   u8 *l4 = 0;
11011   int i;
11012
11013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11014     {
11015       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11016         ;
11017       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11018         ;
11019       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11020         ;
11021       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11022         ;
11023       else
11024         break;
11025     }
11026
11027   if (l4 && !l3)
11028     {
11029       vec_free (mask);
11030       vec_free (l2);
11031       vec_free (l4);
11032       return 0;
11033     }
11034
11035   if (mask || l2 || l3 || l4)
11036     {
11037       if (l2 || l3 || l4)
11038         {
11039           /* "With a free Ethernet header in every package" */
11040           if (l2 == 0)
11041             vec_validate (l2, 13);
11042           mask = l2;
11043           if (vec_len (l3))
11044             {
11045               vec_append (mask, l3);
11046               vec_free (l3);
11047             }
11048           if (vec_len (l4))
11049             {
11050               vec_append (mask, l4);
11051               vec_free (l4);
11052             }
11053         }
11054
11055       /* Scan forward looking for the first significant mask octet */
11056       for (i = 0; i < vec_len (mask); i++)
11057         if (mask[i])
11058           break;
11059
11060       /* compute (skip, match) params */
11061       *skipp = i / sizeof (u32x4);
11062       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11063
11064       /* Pad mask to an even multiple of the vector size */
11065       while (vec_len (mask) % sizeof (u32x4))
11066         vec_add1 (mask, 0);
11067
11068       match = vec_len (mask) / sizeof (u32x4);
11069
11070       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11071         {
11072           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11073           if (*tmp || *(tmp + 1))
11074             break;
11075           match--;
11076         }
11077       if (match == 0)
11078         clib_warning ("BUG: match 0");
11079
11080       _vec_len (mask) = match * sizeof (u32x4);
11081
11082       *matchp = match;
11083       *maskp = mask;
11084
11085       return 1;
11086     }
11087
11088   return 0;
11089 }
11090 #endif /* VPP_API_TEST_BUILTIN */
11091
11092 #define foreach_l2_next                         \
11093 _(drop, DROP)                                   \
11094 _(ethernet, ETHERNET_INPUT)                     \
11095 _(ip4, IP4_INPUT)                               \
11096 _(ip6, IP6_INPUT)
11097
11098 uword
11099 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11100 {
11101   u32 *miss_next_indexp = va_arg (*args, u32 *);
11102   u32 next_index = 0;
11103   u32 tmp;
11104
11105 #define _(n,N) \
11106   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11107   foreach_l2_next;
11108 #undef _
11109
11110   if (unformat (input, "%d", &tmp))
11111     {
11112       next_index = tmp;
11113       goto out;
11114     }
11115
11116   return 0;
11117
11118 out:
11119   *miss_next_indexp = next_index;
11120   return 1;
11121 }
11122
11123 #define foreach_ip_next                         \
11124 _(drop, DROP)                                   \
11125 _(local, LOCAL)                                 \
11126 _(rewrite, REWRITE)
11127
11128 uword
11129 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11130 {
11131   u32 *miss_next_indexp = va_arg (*args, u32 *);
11132   u32 next_index = 0;
11133   u32 tmp;
11134
11135 #define _(n,N) \
11136   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11137   foreach_ip_next;
11138 #undef _
11139
11140   if (unformat (input, "%d", &tmp))
11141     {
11142       next_index = tmp;
11143       goto out;
11144     }
11145
11146   return 0;
11147
11148 out:
11149   *miss_next_indexp = next_index;
11150   return 1;
11151 }
11152
11153 #define foreach_acl_next                        \
11154 _(deny, DENY)
11155
11156 uword
11157 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11158 {
11159   u32 *miss_next_indexp = va_arg (*args, u32 *);
11160   u32 next_index = 0;
11161   u32 tmp;
11162
11163 #define _(n,N) \
11164   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11165   foreach_acl_next;
11166 #undef _
11167
11168   if (unformat (input, "permit"))
11169     {
11170       next_index = ~0;
11171       goto out;
11172     }
11173   else if (unformat (input, "%d", &tmp))
11174     {
11175       next_index = tmp;
11176       goto out;
11177     }
11178
11179   return 0;
11180
11181 out:
11182   *miss_next_indexp = next_index;
11183   return 1;
11184 }
11185
11186 uword
11187 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11188 {
11189   u32 *r = va_arg (*args, u32 *);
11190
11191   if (unformat (input, "conform-color"))
11192     *r = POLICE_CONFORM;
11193   else if (unformat (input, "exceed-color"))
11194     *r = POLICE_EXCEED;
11195   else
11196     return 0;
11197
11198   return 1;
11199 }
11200
11201 static int
11202 api_classify_add_del_table (vat_main_t * vam)
11203 {
11204   unformat_input_t *i = vam->input;
11205   vl_api_classify_add_del_table_t *mp;
11206
11207   u32 nbuckets = 2;
11208   u32 skip = ~0;
11209   u32 match = ~0;
11210   int is_add = 1;
11211   int del_chain = 0;
11212   u32 table_index = ~0;
11213   u32 next_table_index = ~0;
11214   u32 miss_next_index = ~0;
11215   u32 memory_size = 32 << 20;
11216   u8 *mask = 0;
11217   u32 current_data_flag = 0;
11218   int current_data_offset = 0;
11219   int ret;
11220
11221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11222     {
11223       if (unformat (i, "del"))
11224         is_add = 0;
11225       else if (unformat (i, "del-chain"))
11226         {
11227           is_add = 0;
11228           del_chain = 1;
11229         }
11230       else if (unformat (i, "buckets %d", &nbuckets))
11231         ;
11232       else if (unformat (i, "memory_size %d", &memory_size))
11233         ;
11234       else if (unformat (i, "skip %d", &skip))
11235         ;
11236       else if (unformat (i, "match %d", &match))
11237         ;
11238       else if (unformat (i, "table %d", &table_index))
11239         ;
11240       else if (unformat (i, "mask %U", unformat_classify_mask,
11241                          &mask, &skip, &match))
11242         ;
11243       else if (unformat (i, "next-table %d", &next_table_index))
11244         ;
11245       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11246                          &miss_next_index))
11247         ;
11248       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11249                          &miss_next_index))
11250         ;
11251       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11252                          &miss_next_index))
11253         ;
11254       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11255         ;
11256       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11257         ;
11258       else
11259         break;
11260     }
11261
11262   if (is_add && mask == 0)
11263     {
11264       errmsg ("Mask required");
11265       return -99;
11266     }
11267
11268   if (is_add && skip == ~0)
11269     {
11270       errmsg ("skip count required");
11271       return -99;
11272     }
11273
11274   if (is_add && match == ~0)
11275     {
11276       errmsg ("match count required");
11277       return -99;
11278     }
11279
11280   if (!is_add && table_index == ~0)
11281     {
11282       errmsg ("table index required for delete");
11283       return -99;
11284     }
11285
11286   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11287
11288   mp->is_add = is_add;
11289   mp->del_chain = del_chain;
11290   mp->table_index = ntohl (table_index);
11291   mp->nbuckets = ntohl (nbuckets);
11292   mp->memory_size = ntohl (memory_size);
11293   mp->skip_n_vectors = ntohl (skip);
11294   mp->match_n_vectors = ntohl (match);
11295   mp->next_table_index = ntohl (next_table_index);
11296   mp->miss_next_index = ntohl (miss_next_index);
11297   mp->current_data_flag = ntohl (current_data_flag);
11298   mp->current_data_offset = ntohl (current_data_offset);
11299   mp->mask_len = ntohl (vec_len (mask));
11300   clib_memcpy (mp->mask, mask, vec_len (mask));
11301
11302   vec_free (mask);
11303
11304   S (mp);
11305   W (ret);
11306   return ret;
11307 }
11308
11309 #if VPP_API_TEST_BUILTIN == 0
11310 uword
11311 unformat_l4_match (unformat_input_t * input, va_list * args)
11312 {
11313   u8 **matchp = va_arg (*args, u8 **);
11314
11315   u8 *proto_header = 0;
11316   int src_port = 0;
11317   int dst_port = 0;
11318
11319   tcpudp_header_t h;
11320
11321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11322     {
11323       if (unformat (input, "src_port %d", &src_port))
11324         ;
11325       else if (unformat (input, "dst_port %d", &dst_port))
11326         ;
11327       else
11328         return 0;
11329     }
11330
11331   h.src_port = clib_host_to_net_u16 (src_port);
11332   h.dst_port = clib_host_to_net_u16 (dst_port);
11333   vec_validate (proto_header, sizeof (h) - 1);
11334   memcpy (proto_header, &h, sizeof (h));
11335
11336   *matchp = proto_header;
11337
11338   return 1;
11339 }
11340
11341 uword
11342 unformat_ip4_match (unformat_input_t * input, va_list * args)
11343 {
11344   u8 **matchp = va_arg (*args, u8 **);
11345   u8 *match = 0;
11346   ip4_header_t *ip;
11347   int version = 0;
11348   u32 version_val;
11349   int hdr_length = 0;
11350   u32 hdr_length_val;
11351   int src = 0, dst = 0;
11352   ip4_address_t src_val, dst_val;
11353   int proto = 0;
11354   u32 proto_val;
11355   int tos = 0;
11356   u32 tos_val;
11357   int length = 0;
11358   u32 length_val;
11359   int fragment_id = 0;
11360   u32 fragment_id_val;
11361   int ttl = 0;
11362   int ttl_val;
11363   int checksum = 0;
11364   u32 checksum_val;
11365
11366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11367     {
11368       if (unformat (input, "version %d", &version_val))
11369         version = 1;
11370       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11371         hdr_length = 1;
11372       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11373         src = 1;
11374       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11375         dst = 1;
11376       else if (unformat (input, "proto %d", &proto_val))
11377         proto = 1;
11378       else if (unformat (input, "tos %d", &tos_val))
11379         tos = 1;
11380       else if (unformat (input, "length %d", &length_val))
11381         length = 1;
11382       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11383         fragment_id = 1;
11384       else if (unformat (input, "ttl %d", &ttl_val))
11385         ttl = 1;
11386       else if (unformat (input, "checksum %d", &checksum_val))
11387         checksum = 1;
11388       else
11389         break;
11390     }
11391
11392   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11393       + ttl + checksum == 0)
11394     return 0;
11395
11396   /*
11397    * Aligned because we use the real comparison functions
11398    */
11399   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11400
11401   ip = (ip4_header_t *) match;
11402
11403   /* These are realistically matched in practice */
11404   if (src)
11405     ip->src_address.as_u32 = src_val.as_u32;
11406
11407   if (dst)
11408     ip->dst_address.as_u32 = dst_val.as_u32;
11409
11410   if (proto)
11411     ip->protocol = proto_val;
11412
11413
11414   /* These are not, but they're included for completeness */
11415   if (version)
11416     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11417
11418   if (hdr_length)
11419     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11420
11421   if (tos)
11422     ip->tos = tos_val;
11423
11424   if (length)
11425     ip->length = clib_host_to_net_u16 (length_val);
11426
11427   if (ttl)
11428     ip->ttl = ttl_val;
11429
11430   if (checksum)
11431     ip->checksum = clib_host_to_net_u16 (checksum_val);
11432
11433   *matchp = match;
11434   return 1;
11435 }
11436
11437 uword
11438 unformat_ip6_match (unformat_input_t * input, va_list * args)
11439 {
11440   u8 **matchp = va_arg (*args, u8 **);
11441   u8 *match = 0;
11442   ip6_header_t *ip;
11443   int version = 0;
11444   u32 version_val;
11445   u8 traffic_class = 0;
11446   u32 traffic_class_val = 0;
11447   u8 flow_label = 0;
11448   u8 flow_label_val;
11449   int src = 0, dst = 0;
11450   ip6_address_t src_val, dst_val;
11451   int proto = 0;
11452   u32 proto_val;
11453   int payload_length = 0;
11454   u32 payload_length_val;
11455   int hop_limit = 0;
11456   int hop_limit_val;
11457   u32 ip_version_traffic_class_and_flow_label;
11458
11459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11460     {
11461       if (unformat (input, "version %d", &version_val))
11462         version = 1;
11463       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11464         traffic_class = 1;
11465       else if (unformat (input, "flow_label %d", &flow_label_val))
11466         flow_label = 1;
11467       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11468         src = 1;
11469       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11470         dst = 1;
11471       else if (unformat (input, "proto %d", &proto_val))
11472         proto = 1;
11473       else if (unformat (input, "payload_length %d", &payload_length_val))
11474         payload_length = 1;
11475       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11476         hop_limit = 1;
11477       else
11478         break;
11479     }
11480
11481   if (version + traffic_class + flow_label + src + dst + proto +
11482       payload_length + hop_limit == 0)
11483     return 0;
11484
11485   /*
11486    * Aligned because we use the real comparison functions
11487    */
11488   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11489
11490   ip = (ip6_header_t *) match;
11491
11492   if (src)
11493     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11494
11495   if (dst)
11496     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11497
11498   if (proto)
11499     ip->protocol = proto_val;
11500
11501   ip_version_traffic_class_and_flow_label = 0;
11502
11503   if (version)
11504     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11505
11506   if (traffic_class)
11507     ip_version_traffic_class_and_flow_label |=
11508       (traffic_class_val & 0xFF) << 20;
11509
11510   if (flow_label)
11511     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11512
11513   ip->ip_version_traffic_class_and_flow_label =
11514     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11515
11516   if (payload_length)
11517     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11518
11519   if (hop_limit)
11520     ip->hop_limit = hop_limit_val;
11521
11522   *matchp = match;
11523   return 1;
11524 }
11525
11526 uword
11527 unformat_l3_match (unformat_input_t * input, va_list * args)
11528 {
11529   u8 **matchp = va_arg (*args, u8 **);
11530
11531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11534         return 1;
11535       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11536         return 1;
11537       else
11538         break;
11539     }
11540   return 0;
11541 }
11542
11543 uword
11544 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11545 {
11546   u8 *tagp = va_arg (*args, u8 *);
11547   u32 tag;
11548
11549   if (unformat (input, "%d", &tag))
11550     {
11551       tagp[0] = (tag >> 8) & 0x0F;
11552       tagp[1] = tag & 0xFF;
11553       return 1;
11554     }
11555
11556   return 0;
11557 }
11558
11559 uword
11560 unformat_l2_match (unformat_input_t * input, va_list * args)
11561 {
11562   u8 **matchp = va_arg (*args, u8 **);
11563   u8 *match = 0;
11564   u8 src = 0;
11565   u8 src_val[6];
11566   u8 dst = 0;
11567   u8 dst_val[6];
11568   u8 proto = 0;
11569   u16 proto_val;
11570   u8 tag1 = 0;
11571   u8 tag1_val[2];
11572   u8 tag2 = 0;
11573   u8 tag2_val[2];
11574   int len = 14;
11575   u8 ignore_tag1 = 0;
11576   u8 ignore_tag2 = 0;
11577   u8 cos1 = 0;
11578   u8 cos2 = 0;
11579   u32 cos1_val = 0;
11580   u32 cos2_val = 0;
11581
11582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11583     {
11584       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11585         src = 1;
11586       else
11587         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11588         dst = 1;
11589       else if (unformat (input, "proto %U",
11590                          unformat_ethernet_type_host_byte_order, &proto_val))
11591         proto = 1;
11592       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11593         tag1 = 1;
11594       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11595         tag2 = 1;
11596       else if (unformat (input, "ignore-tag1"))
11597         ignore_tag1 = 1;
11598       else if (unformat (input, "ignore-tag2"))
11599         ignore_tag2 = 1;
11600       else if (unformat (input, "cos1 %d", &cos1_val))
11601         cos1 = 1;
11602       else if (unformat (input, "cos2 %d", &cos2_val))
11603         cos2 = 1;
11604       else
11605         break;
11606     }
11607   if ((src + dst + proto + tag1 + tag2 +
11608        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11609     return 0;
11610
11611   if (tag1 || ignore_tag1 || cos1)
11612     len = 18;
11613   if (tag2 || ignore_tag2 || cos2)
11614     len = 22;
11615
11616   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11617
11618   if (dst)
11619     clib_memcpy (match, dst_val, 6);
11620
11621   if (src)
11622     clib_memcpy (match + 6, src_val, 6);
11623
11624   if (tag2)
11625     {
11626       /* inner vlan tag */
11627       match[19] = tag2_val[1];
11628       match[18] = tag2_val[0];
11629       if (cos2)
11630         match[18] |= (cos2_val & 0x7) << 5;
11631       if (proto)
11632         {
11633           match[21] = proto_val & 0xff;
11634           match[20] = proto_val >> 8;
11635         }
11636       if (tag1)
11637         {
11638           match[15] = tag1_val[1];
11639           match[14] = tag1_val[0];
11640         }
11641       if (cos1)
11642         match[14] |= (cos1_val & 0x7) << 5;
11643       *matchp = match;
11644       return 1;
11645     }
11646   if (tag1)
11647     {
11648       match[15] = tag1_val[1];
11649       match[14] = tag1_val[0];
11650       if (proto)
11651         {
11652           match[17] = proto_val & 0xff;
11653           match[16] = proto_val >> 8;
11654         }
11655       if (cos1)
11656         match[14] |= (cos1_val & 0x7) << 5;
11657
11658       *matchp = match;
11659       return 1;
11660     }
11661   if (cos2)
11662     match[18] |= (cos2_val & 0x7) << 5;
11663   if (cos1)
11664     match[14] |= (cos1_val & 0x7) << 5;
11665   if (proto)
11666     {
11667       match[13] = proto_val & 0xff;
11668       match[12] = proto_val >> 8;
11669     }
11670
11671   *matchp = match;
11672   return 1;
11673 }
11674
11675 uword
11676 unformat_qos_source (unformat_input_t * input, va_list * args)
11677 {
11678   int *qs = va_arg (*args, int *);
11679
11680   if (unformat (input, "ip"))
11681     *qs = QOS_SOURCE_IP;
11682   else if (unformat (input, "mpls"))
11683     *qs = QOS_SOURCE_MPLS;
11684   else if (unformat (input, "ext"))
11685     *qs = QOS_SOURCE_EXT;
11686   else if (unformat (input, "vlan"))
11687     *qs = QOS_SOURCE_VLAN;
11688   else
11689     return 0;
11690
11691   return 1;
11692 }
11693 #endif
11694
11695 uword
11696 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11697 {
11698   u8 **matchp = va_arg (*args, u8 **);
11699   u32 skip_n_vectors = va_arg (*args, u32);
11700   u32 match_n_vectors = va_arg (*args, u32);
11701
11702   u8 *match = 0;
11703   u8 *l2 = 0;
11704   u8 *l3 = 0;
11705   u8 *l4 = 0;
11706
11707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11708     {
11709       if (unformat (input, "hex %U", unformat_hex_string, &match))
11710         ;
11711       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11712         ;
11713       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11714         ;
11715       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11716         ;
11717       else
11718         break;
11719     }
11720
11721   if (l4 && !l3)
11722     {
11723       vec_free (match);
11724       vec_free (l2);
11725       vec_free (l4);
11726       return 0;
11727     }
11728
11729   if (match || l2 || l3 || l4)
11730     {
11731       if (l2 || l3 || l4)
11732         {
11733           /* "Win a free Ethernet header in every packet" */
11734           if (l2 == 0)
11735             vec_validate_aligned (l2, 13, sizeof (u32x4));
11736           match = l2;
11737           if (vec_len (l3))
11738             {
11739               vec_append_aligned (match, l3, sizeof (u32x4));
11740               vec_free (l3);
11741             }
11742           if (vec_len (l4))
11743             {
11744               vec_append_aligned (match, l4, sizeof (u32x4));
11745               vec_free (l4);
11746             }
11747         }
11748
11749       /* Make sure the vector is big enough even if key is all 0's */
11750       vec_validate_aligned
11751         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11752          sizeof (u32x4));
11753
11754       /* Set size, include skipped vectors */
11755       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11756
11757       *matchp = match;
11758
11759       return 1;
11760     }
11761
11762   return 0;
11763 }
11764
11765 static int
11766 api_classify_add_del_session (vat_main_t * vam)
11767 {
11768   unformat_input_t *i = vam->input;
11769   vl_api_classify_add_del_session_t *mp;
11770   int is_add = 1;
11771   u32 table_index = ~0;
11772   u32 hit_next_index = ~0;
11773   u32 opaque_index = ~0;
11774   u8 *match = 0;
11775   i32 advance = 0;
11776   u32 skip_n_vectors = 0;
11777   u32 match_n_vectors = 0;
11778   u32 action = 0;
11779   u32 metadata = 0;
11780   int ret;
11781
11782   /*
11783    * Warning: you have to supply skip_n and match_n
11784    * because the API client cant simply look at the classify
11785    * table object.
11786    */
11787
11788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11789     {
11790       if (unformat (i, "del"))
11791         is_add = 0;
11792       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11793                          &hit_next_index))
11794         ;
11795       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11796                          &hit_next_index))
11797         ;
11798       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11799                          &hit_next_index))
11800         ;
11801       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11802         ;
11803       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11804         ;
11805       else if (unformat (i, "opaque-index %d", &opaque_index))
11806         ;
11807       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11808         ;
11809       else if (unformat (i, "match_n %d", &match_n_vectors))
11810         ;
11811       else if (unformat (i, "match %U", api_unformat_classify_match,
11812                          &match, skip_n_vectors, match_n_vectors))
11813         ;
11814       else if (unformat (i, "advance %d", &advance))
11815         ;
11816       else if (unformat (i, "table-index %d", &table_index))
11817         ;
11818       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11819         action = 1;
11820       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11821         action = 2;
11822       else if (unformat (i, "action %d", &action))
11823         ;
11824       else if (unformat (i, "metadata %d", &metadata))
11825         ;
11826       else
11827         break;
11828     }
11829
11830   if (table_index == ~0)
11831     {
11832       errmsg ("Table index required");
11833       return -99;
11834     }
11835
11836   if (is_add && match == 0)
11837     {
11838       errmsg ("Match value required");
11839       return -99;
11840     }
11841
11842   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11843
11844   mp->is_add = is_add;
11845   mp->table_index = ntohl (table_index);
11846   mp->hit_next_index = ntohl (hit_next_index);
11847   mp->opaque_index = ntohl (opaque_index);
11848   mp->advance = ntohl (advance);
11849   mp->action = action;
11850   mp->metadata = ntohl (metadata);
11851   mp->match_len = ntohl (vec_len (match));
11852   clib_memcpy (mp->match, match, vec_len (match));
11853   vec_free (match);
11854
11855   S (mp);
11856   W (ret);
11857   return ret;
11858 }
11859
11860 static int
11861 api_classify_set_interface_ip_table (vat_main_t * vam)
11862 {
11863   unformat_input_t *i = vam->input;
11864   vl_api_classify_set_interface_ip_table_t *mp;
11865   u32 sw_if_index;
11866   int sw_if_index_set;
11867   u32 table_index = ~0;
11868   u8 is_ipv6 = 0;
11869   int ret;
11870
11871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11872     {
11873       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11874         sw_if_index_set = 1;
11875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11876         sw_if_index_set = 1;
11877       else if (unformat (i, "table %d", &table_index))
11878         ;
11879       else
11880         {
11881           clib_warning ("parse error '%U'", format_unformat_error, i);
11882           return -99;
11883         }
11884     }
11885
11886   if (sw_if_index_set == 0)
11887     {
11888       errmsg ("missing interface name or sw_if_index");
11889       return -99;
11890     }
11891
11892
11893   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11894
11895   mp->sw_if_index = ntohl (sw_if_index);
11896   mp->table_index = ntohl (table_index);
11897   mp->is_ipv6 = is_ipv6;
11898
11899   S (mp);
11900   W (ret);
11901   return ret;
11902 }
11903
11904 static int
11905 api_classify_set_interface_l2_tables (vat_main_t * vam)
11906 {
11907   unformat_input_t *i = vam->input;
11908   vl_api_classify_set_interface_l2_tables_t *mp;
11909   u32 sw_if_index;
11910   int sw_if_index_set;
11911   u32 ip4_table_index = ~0;
11912   u32 ip6_table_index = ~0;
11913   u32 other_table_index = ~0;
11914   u32 is_input = 1;
11915   int ret;
11916
11917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11920         sw_if_index_set = 1;
11921       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11922         sw_if_index_set = 1;
11923       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11924         ;
11925       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11926         ;
11927       else if (unformat (i, "other-table %d", &other_table_index))
11928         ;
11929       else if (unformat (i, "is-input %d", &is_input))
11930         ;
11931       else
11932         {
11933           clib_warning ("parse error '%U'", format_unformat_error, i);
11934           return -99;
11935         }
11936     }
11937
11938   if (sw_if_index_set == 0)
11939     {
11940       errmsg ("missing interface name or sw_if_index");
11941       return -99;
11942     }
11943
11944
11945   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11946
11947   mp->sw_if_index = ntohl (sw_if_index);
11948   mp->ip4_table_index = ntohl (ip4_table_index);
11949   mp->ip6_table_index = ntohl (ip6_table_index);
11950   mp->other_table_index = ntohl (other_table_index);
11951   mp->is_input = (u8) is_input;
11952
11953   S (mp);
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_set_ipfix_exporter (vat_main_t * vam)
11960 {
11961   unformat_input_t *i = vam->input;
11962   vl_api_set_ipfix_exporter_t *mp;
11963   ip4_address_t collector_address;
11964   u8 collector_address_set = 0;
11965   u32 collector_port = ~0;
11966   ip4_address_t src_address;
11967   u8 src_address_set = 0;
11968   u32 vrf_id = ~0;
11969   u32 path_mtu = ~0;
11970   u32 template_interval = ~0;
11971   u8 udp_checksum = 0;
11972   int ret;
11973
11974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11975     {
11976       if (unformat (i, "collector_address %U", unformat_ip4_address,
11977                     &collector_address))
11978         collector_address_set = 1;
11979       else if (unformat (i, "collector_port %d", &collector_port))
11980         ;
11981       else if (unformat (i, "src_address %U", unformat_ip4_address,
11982                          &src_address))
11983         src_address_set = 1;
11984       else if (unformat (i, "vrf_id %d", &vrf_id))
11985         ;
11986       else if (unformat (i, "path_mtu %d", &path_mtu))
11987         ;
11988       else if (unformat (i, "template_interval %d", &template_interval))
11989         ;
11990       else if (unformat (i, "udp_checksum"))
11991         udp_checksum = 1;
11992       else
11993         break;
11994     }
11995
11996   if (collector_address_set == 0)
11997     {
11998       errmsg ("collector_address required");
11999       return -99;
12000     }
12001
12002   if (src_address_set == 0)
12003     {
12004       errmsg ("src_address required");
12005       return -99;
12006     }
12007
12008   M (SET_IPFIX_EXPORTER, mp);
12009
12010   memcpy (mp->collector_address, collector_address.data,
12011           sizeof (collector_address.data));
12012   mp->collector_port = htons ((u16) collector_port);
12013   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12014   mp->vrf_id = htonl (vrf_id);
12015   mp->path_mtu = htonl (path_mtu);
12016   mp->template_interval = htonl (template_interval);
12017   mp->udp_checksum = udp_checksum;
12018
12019   S (mp);
12020   W (ret);
12021   return ret;
12022 }
12023
12024 static int
12025 api_set_ipfix_classify_stream (vat_main_t * vam)
12026 {
12027   unformat_input_t *i = vam->input;
12028   vl_api_set_ipfix_classify_stream_t *mp;
12029   u32 domain_id = 0;
12030   u32 src_port = UDP_DST_PORT_ipfix;
12031   int ret;
12032
12033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12034     {
12035       if (unformat (i, "domain %d", &domain_id))
12036         ;
12037       else if (unformat (i, "src_port %d", &src_port))
12038         ;
12039       else
12040         {
12041           errmsg ("unknown input `%U'", format_unformat_error, i);
12042           return -99;
12043         }
12044     }
12045
12046   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12047
12048   mp->domain_id = htonl (domain_id);
12049   mp->src_port = htons ((u16) src_port);
12050
12051   S (mp);
12052   W (ret);
12053   return ret;
12054 }
12055
12056 static int
12057 api_ipfix_classify_table_add_del (vat_main_t * vam)
12058 {
12059   unformat_input_t *i = vam->input;
12060   vl_api_ipfix_classify_table_add_del_t *mp;
12061   int is_add = -1;
12062   u32 classify_table_index = ~0;
12063   u8 ip_version = 0;
12064   u8 transport_protocol = 255;
12065   int ret;
12066
12067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12068     {
12069       if (unformat (i, "add"))
12070         is_add = 1;
12071       else if (unformat (i, "del"))
12072         is_add = 0;
12073       else if (unformat (i, "table %d", &classify_table_index))
12074         ;
12075       else if (unformat (i, "ip4"))
12076         ip_version = 4;
12077       else if (unformat (i, "ip6"))
12078         ip_version = 6;
12079       else if (unformat (i, "tcp"))
12080         transport_protocol = 6;
12081       else if (unformat (i, "udp"))
12082         transport_protocol = 17;
12083       else
12084         {
12085           errmsg ("unknown input `%U'", format_unformat_error, i);
12086           return -99;
12087         }
12088     }
12089
12090   if (is_add == -1)
12091     {
12092       errmsg ("expecting: add|del");
12093       return -99;
12094     }
12095   if (classify_table_index == ~0)
12096     {
12097       errmsg ("classifier table not specified");
12098       return -99;
12099     }
12100   if (ip_version == 0)
12101     {
12102       errmsg ("IP version not specified");
12103       return -99;
12104     }
12105
12106   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12107
12108   mp->is_add = is_add;
12109   mp->table_id = htonl (classify_table_index);
12110   mp->ip_version = ip_version;
12111   mp->transport_protocol = transport_protocol;
12112
12113   S (mp);
12114   W (ret);
12115   return ret;
12116 }
12117
12118 static int
12119 api_get_node_index (vat_main_t * vam)
12120 {
12121   unformat_input_t *i = vam->input;
12122   vl_api_get_node_index_t *mp;
12123   u8 *name = 0;
12124   int ret;
12125
12126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12127     {
12128       if (unformat (i, "node %s", &name))
12129         ;
12130       else
12131         break;
12132     }
12133   if (name == 0)
12134     {
12135       errmsg ("node name required");
12136       return -99;
12137     }
12138   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12139     {
12140       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12141       return -99;
12142     }
12143
12144   M (GET_NODE_INDEX, mp);
12145   clib_memcpy (mp->node_name, name, vec_len (name));
12146   vec_free (name);
12147
12148   S (mp);
12149   W (ret);
12150   return ret;
12151 }
12152
12153 static int
12154 api_get_next_index (vat_main_t * vam)
12155 {
12156   unformat_input_t *i = vam->input;
12157   vl_api_get_next_index_t *mp;
12158   u8 *node_name = 0, *next_node_name = 0;
12159   int ret;
12160
12161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12162     {
12163       if (unformat (i, "node-name %s", &node_name))
12164         ;
12165       else if (unformat (i, "next-node-name %s", &next_node_name))
12166         break;
12167     }
12168
12169   if (node_name == 0)
12170     {
12171       errmsg ("node name required");
12172       return -99;
12173     }
12174   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12175     {
12176       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12177       return -99;
12178     }
12179
12180   if (next_node_name == 0)
12181     {
12182       errmsg ("next node name required");
12183       return -99;
12184     }
12185   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12186     {
12187       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12188       return -99;
12189     }
12190
12191   M (GET_NEXT_INDEX, mp);
12192   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12193   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12194   vec_free (node_name);
12195   vec_free (next_node_name);
12196
12197   S (mp);
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static int
12203 api_add_node_next (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   vl_api_add_node_next_t *mp;
12207   u8 *name = 0;
12208   u8 *next = 0;
12209   int ret;
12210
12211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12212     {
12213       if (unformat (i, "node %s", &name))
12214         ;
12215       else if (unformat (i, "next %s", &next))
12216         ;
12217       else
12218         break;
12219     }
12220   if (name == 0)
12221     {
12222       errmsg ("node name required");
12223       return -99;
12224     }
12225   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12226     {
12227       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12228       return -99;
12229     }
12230   if (next == 0)
12231     {
12232       errmsg ("next node required");
12233       return -99;
12234     }
12235   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12236     {
12237       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12238       return -99;
12239     }
12240
12241   M (ADD_NODE_NEXT, mp);
12242   clib_memcpy (mp->node_name, name, vec_len (name));
12243   clib_memcpy (mp->next_name, next, vec_len (next));
12244   vec_free (name);
12245   vec_free (next);
12246
12247   S (mp);
12248   W (ret);
12249   return ret;
12250 }
12251
12252 static int
12253 api_l2tpv3_create_tunnel (vat_main_t * vam)
12254 {
12255   unformat_input_t *i = vam->input;
12256   ip6_address_t client_address, our_address;
12257   int client_address_set = 0;
12258   int our_address_set = 0;
12259   u32 local_session_id = 0;
12260   u32 remote_session_id = 0;
12261   u64 local_cookie = 0;
12262   u64 remote_cookie = 0;
12263   u8 l2_sublayer_present = 0;
12264   vl_api_l2tpv3_create_tunnel_t *mp;
12265   int ret;
12266
12267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12268     {
12269       if (unformat (i, "client_address %U", unformat_ip6_address,
12270                     &client_address))
12271         client_address_set = 1;
12272       else if (unformat (i, "our_address %U", unformat_ip6_address,
12273                          &our_address))
12274         our_address_set = 1;
12275       else if (unformat (i, "local_session_id %d", &local_session_id))
12276         ;
12277       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12278         ;
12279       else if (unformat (i, "local_cookie %lld", &local_cookie))
12280         ;
12281       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12282         ;
12283       else if (unformat (i, "l2-sublayer-present"))
12284         l2_sublayer_present = 1;
12285       else
12286         break;
12287     }
12288
12289   if (client_address_set == 0)
12290     {
12291       errmsg ("client_address required");
12292       return -99;
12293     }
12294
12295   if (our_address_set == 0)
12296     {
12297       errmsg ("our_address required");
12298       return -99;
12299     }
12300
12301   M (L2TPV3_CREATE_TUNNEL, mp);
12302
12303   clib_memcpy (mp->client_address, client_address.as_u8,
12304                sizeof (mp->client_address));
12305
12306   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12307
12308   mp->local_session_id = ntohl (local_session_id);
12309   mp->remote_session_id = ntohl (remote_session_id);
12310   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12311   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12312   mp->l2_sublayer_present = l2_sublayer_present;
12313   mp->is_ipv6 = 1;
12314
12315   S (mp);
12316   W (ret);
12317   return ret;
12318 }
12319
12320 static int
12321 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12322 {
12323   unformat_input_t *i = vam->input;
12324   u32 sw_if_index;
12325   u8 sw_if_index_set = 0;
12326   u64 new_local_cookie = 0;
12327   u64 new_remote_cookie = 0;
12328   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12329   int ret;
12330
12331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12332     {
12333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12334         sw_if_index_set = 1;
12335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12336         sw_if_index_set = 1;
12337       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12338         ;
12339       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12340         ;
12341       else
12342         break;
12343     }
12344
12345   if (sw_if_index_set == 0)
12346     {
12347       errmsg ("missing interface name or sw_if_index");
12348       return -99;
12349     }
12350
12351   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12352
12353   mp->sw_if_index = ntohl (sw_if_index);
12354   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12355   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12356
12357   S (mp);
12358   W (ret);
12359   return ret;
12360 }
12361
12362 static int
12363 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12364 {
12365   unformat_input_t *i = vam->input;
12366   vl_api_l2tpv3_interface_enable_disable_t *mp;
12367   u32 sw_if_index;
12368   u8 sw_if_index_set = 0;
12369   u8 enable_disable = 1;
12370   int ret;
12371
12372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12373     {
12374       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12375         sw_if_index_set = 1;
12376       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12377         sw_if_index_set = 1;
12378       else if (unformat (i, "enable"))
12379         enable_disable = 1;
12380       else if (unformat (i, "disable"))
12381         enable_disable = 0;
12382       else
12383         break;
12384     }
12385
12386   if (sw_if_index_set == 0)
12387     {
12388       errmsg ("missing interface name or sw_if_index");
12389       return -99;
12390     }
12391
12392   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12393
12394   mp->sw_if_index = ntohl (sw_if_index);
12395   mp->enable_disable = enable_disable;
12396
12397   S (mp);
12398   W (ret);
12399   return ret;
12400 }
12401
12402 static int
12403 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12404 {
12405   unformat_input_t *i = vam->input;
12406   vl_api_l2tpv3_set_lookup_key_t *mp;
12407   u8 key = ~0;
12408   int ret;
12409
12410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12411     {
12412       if (unformat (i, "lookup_v6_src"))
12413         key = L2T_LOOKUP_SRC_ADDRESS;
12414       else if (unformat (i, "lookup_v6_dst"))
12415         key = L2T_LOOKUP_DST_ADDRESS;
12416       else if (unformat (i, "lookup_session_id"))
12417         key = L2T_LOOKUP_SESSION_ID;
12418       else
12419         break;
12420     }
12421
12422   if (key == (u8) ~ 0)
12423     {
12424       errmsg ("l2tp session lookup key unset");
12425       return -99;
12426     }
12427
12428   M (L2TPV3_SET_LOOKUP_KEY, mp);
12429
12430   mp->key = key;
12431
12432   S (mp);
12433   W (ret);
12434   return ret;
12435 }
12436
12437 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12438   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12439 {
12440   vat_main_t *vam = &vat_main;
12441
12442   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12443          format_ip6_address, mp->our_address,
12444          format_ip6_address, mp->client_address,
12445          clib_net_to_host_u32 (mp->sw_if_index));
12446
12447   print (vam->ofp,
12448          "   local cookies %016llx %016llx remote cookie %016llx",
12449          clib_net_to_host_u64 (mp->local_cookie[0]),
12450          clib_net_to_host_u64 (mp->local_cookie[1]),
12451          clib_net_to_host_u64 (mp->remote_cookie));
12452
12453   print (vam->ofp, "   local session-id %d remote session-id %d",
12454          clib_net_to_host_u32 (mp->local_session_id),
12455          clib_net_to_host_u32 (mp->remote_session_id));
12456
12457   print (vam->ofp, "   l2 specific sublayer %s\n",
12458          mp->l2_sublayer_present ? "preset" : "absent");
12459
12460 }
12461
12462 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12463   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12464 {
12465   vat_main_t *vam = &vat_main;
12466   vat_json_node_t *node = NULL;
12467   struct in6_addr addr;
12468
12469   if (VAT_JSON_ARRAY != vam->json_tree.type)
12470     {
12471       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12472       vat_json_init_array (&vam->json_tree);
12473     }
12474   node = vat_json_array_add (&vam->json_tree);
12475
12476   vat_json_init_object (node);
12477
12478   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12479   vat_json_object_add_ip6 (node, "our_address", addr);
12480   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12481   vat_json_object_add_ip6 (node, "client_address", addr);
12482
12483   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12484   vat_json_init_array (lc);
12485   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12486   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12487   vat_json_object_add_uint (node, "remote_cookie",
12488                             clib_net_to_host_u64 (mp->remote_cookie));
12489
12490   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12491   vat_json_object_add_uint (node, "local_session_id",
12492                             clib_net_to_host_u32 (mp->local_session_id));
12493   vat_json_object_add_uint (node, "remote_session_id",
12494                             clib_net_to_host_u32 (mp->remote_session_id));
12495   vat_json_object_add_string_copy (node, "l2_sublayer",
12496                                    mp->l2_sublayer_present ? (u8 *) "present"
12497                                    : (u8 *) "absent");
12498 }
12499
12500 static int
12501 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12502 {
12503   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12504   vl_api_control_ping_t *mp_ping;
12505   int ret;
12506
12507   /* Get list of l2tpv3-tunnel interfaces */
12508   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12509   S (mp);
12510
12511   /* Use a control ping for synchronization */
12512   MPING (CONTROL_PING, mp_ping);
12513   S (mp_ping);
12514
12515   W (ret);
12516   return ret;
12517 }
12518
12519
12520 static void vl_api_sw_interface_tap_v2_details_t_handler
12521   (vl_api_sw_interface_tap_v2_details_t * mp)
12522 {
12523   vat_main_t *vam = &vat_main;
12524
12525   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12526                     mp->host_ip4_prefix_len);
12527   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12528                     mp->host_ip6_prefix_len);
12529
12530   print (vam->ofp,
12531          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12532          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12533          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12534          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12535          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12536
12537   vec_free (ip4);
12538   vec_free (ip6);
12539 }
12540
12541 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12542   (vl_api_sw_interface_tap_v2_details_t * mp)
12543 {
12544   vat_main_t *vam = &vat_main;
12545   vat_json_node_t *node = NULL;
12546
12547   if (VAT_JSON_ARRAY != vam->json_tree.type)
12548     {
12549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12550       vat_json_init_array (&vam->json_tree);
12551     }
12552   node = vat_json_array_add (&vam->json_tree);
12553
12554   vat_json_init_object (node);
12555   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12556   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12557   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12558   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12559   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12560   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12561   vat_json_object_add_string_copy (node, "host_mac_addr",
12562                                    format (0, "%U", format_ethernet_address,
12563                                            &mp->host_mac_addr));
12564   vat_json_object_add_string_copy (node, "host_namespace",
12565                                    mp->host_namespace);
12566   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12567   vat_json_object_add_string_copy (node, "host_ip4_addr",
12568                                    format (0, "%U/%d", format_ip4_address,
12569                                            mp->host_ip4_addr,
12570                                            mp->host_ip4_prefix_len));
12571   vat_json_object_add_string_copy (node, "host_ip6_addr",
12572                                    format (0, "%U/%d", format_ip6_address,
12573                                            mp->host_ip6_addr,
12574                                            mp->host_ip6_prefix_len));
12575
12576 }
12577
12578 static int
12579 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12580 {
12581   vl_api_sw_interface_tap_v2_dump_t *mp;
12582   vl_api_control_ping_t *mp_ping;
12583   int ret;
12584
12585   print (vam->ofp,
12586          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12587          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12588          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12589          "host_ip6_addr");
12590
12591   /* Get list of tap interfaces */
12592   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12593   S (mp);
12594
12595   /* Use a control ping for synchronization */
12596   MPING (CONTROL_PING, mp_ping);
12597   S (mp_ping);
12598
12599   W (ret);
12600   return ret;
12601 }
12602
12603 static void vl_api_sw_interface_virtio_pci_details_t_handler
12604   (vl_api_sw_interface_virtio_pci_details_t * mp)
12605 {
12606   vat_main_t *vam = &vat_main;
12607
12608   typedef union
12609   {
12610     struct
12611     {
12612       u16 domain;
12613       u8 bus;
12614       u8 slot:5;
12615       u8 function:3;
12616     };
12617     u32 as_u32;
12618   } pci_addr_t;
12619   pci_addr_t addr;
12620   addr.as_u32 = ntohl (mp->pci_addr);
12621   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12622                          addr.slot, addr.function);
12623
12624   print (vam->ofp,
12625          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12626          pci_addr, ntohl (mp->sw_if_index),
12627          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12628          format_ethernet_address, mp->mac_addr,
12629          clib_net_to_host_u64 (mp->features));
12630   vec_free (pci_addr);
12631 }
12632
12633 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12634   (vl_api_sw_interface_virtio_pci_details_t * mp)
12635 {
12636   vat_main_t *vam = &vat_main;
12637   vat_json_node_t *node = NULL;
12638
12639   if (VAT_JSON_ARRAY != vam->json_tree.type)
12640     {
12641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12642       vat_json_init_array (&vam->json_tree);
12643     }
12644   node = vat_json_array_add (&vam->json_tree);
12645
12646   vat_json_init_object (node);
12647   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12648   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12649   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12650   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12651   vat_json_object_add_uint (node, "features",
12652                             clib_net_to_host_u64 (mp->features));
12653   vat_json_object_add_string_copy (node, "mac_addr",
12654                                    format (0, "%U", format_ethernet_address,
12655                                            &mp->mac_addr));
12656 }
12657
12658 static int
12659 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12660 {
12661   vl_api_sw_interface_virtio_pci_dump_t *mp;
12662   vl_api_control_ping_t *mp_ping;
12663   int ret;
12664
12665   print (vam->ofp,
12666          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12667          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12668          "mac_addr", "features");
12669
12670   /* Get list of tap interfaces */
12671   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12672   S (mp);
12673
12674   /* Use a control ping for synchronization */
12675   MPING (CONTROL_PING, mp_ping);
12676   S (mp_ping);
12677
12678   W (ret);
12679   return ret;
12680 }
12681
12682 static int
12683 api_vxlan_offload_rx (vat_main_t * vam)
12684 {
12685   unformat_input_t *line_input = vam->input;
12686   vl_api_vxlan_offload_rx_t *mp;
12687   u32 hw_if_index = ~0, rx_if_index = ~0;
12688   u8 is_add = 1;
12689   int ret;
12690
12691   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12692     {
12693       if (unformat (line_input, "del"))
12694         is_add = 0;
12695       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12696                          &hw_if_index))
12697         ;
12698       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12699         ;
12700       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12701                          &rx_if_index))
12702         ;
12703       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12704         ;
12705       else
12706         {
12707           errmsg ("parse error '%U'", format_unformat_error, line_input);
12708           return -99;
12709         }
12710     }
12711
12712   if (hw_if_index == ~0)
12713     {
12714       errmsg ("no hw interface");
12715       return -99;
12716     }
12717
12718   if (rx_if_index == ~0)
12719     {
12720       errmsg ("no rx tunnel");
12721       return -99;
12722     }
12723
12724   M (VXLAN_OFFLOAD_RX, mp);
12725
12726   mp->hw_if_index = ntohl (hw_if_index);
12727   mp->sw_if_index = ntohl (rx_if_index);
12728   mp->enable = is_add;
12729
12730   S (mp);
12731   W (ret);
12732   return ret;
12733 }
12734
12735 static uword unformat_vxlan_decap_next
12736   (unformat_input_t * input, va_list * args)
12737 {
12738   u32 *result = va_arg (*args, u32 *);
12739   u32 tmp;
12740
12741   if (unformat (input, "l2"))
12742     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12743   else if (unformat (input, "%d", &tmp))
12744     *result = tmp;
12745   else
12746     return 0;
12747   return 1;
12748 }
12749
12750 static int
12751 api_vxlan_add_del_tunnel (vat_main_t * vam)
12752 {
12753   unformat_input_t *line_input = vam->input;
12754   vl_api_vxlan_add_del_tunnel_t *mp;
12755   ip46_address_t src, dst;
12756   u8 is_add = 1;
12757   u8 ipv4_set = 0, ipv6_set = 0;
12758   u8 src_set = 0;
12759   u8 dst_set = 0;
12760   u8 grp_set = 0;
12761   u32 instance = ~0;
12762   u32 mcast_sw_if_index = ~0;
12763   u32 encap_vrf_id = 0;
12764   u32 decap_next_index = ~0;
12765   u32 vni = 0;
12766   int ret;
12767
12768   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12769   clib_memset (&src, 0, sizeof src);
12770   clib_memset (&dst, 0, sizeof dst);
12771
12772   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12773     {
12774       if (unformat (line_input, "del"))
12775         is_add = 0;
12776       else if (unformat (line_input, "instance %d", &instance))
12777         ;
12778       else
12779         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12780         {
12781           ipv4_set = 1;
12782           src_set = 1;
12783         }
12784       else
12785         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12786         {
12787           ipv4_set = 1;
12788           dst_set = 1;
12789         }
12790       else
12791         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12792         {
12793           ipv6_set = 1;
12794           src_set = 1;
12795         }
12796       else
12797         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12798         {
12799           ipv6_set = 1;
12800           dst_set = 1;
12801         }
12802       else if (unformat (line_input, "group %U %U",
12803                          unformat_ip4_address, &dst.ip4,
12804                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12805         {
12806           grp_set = dst_set = 1;
12807           ipv4_set = 1;
12808         }
12809       else if (unformat (line_input, "group %U",
12810                          unformat_ip4_address, &dst.ip4))
12811         {
12812           grp_set = dst_set = 1;
12813           ipv4_set = 1;
12814         }
12815       else if (unformat (line_input, "group %U %U",
12816                          unformat_ip6_address, &dst.ip6,
12817                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12818         {
12819           grp_set = dst_set = 1;
12820           ipv6_set = 1;
12821         }
12822       else if (unformat (line_input, "group %U",
12823                          unformat_ip6_address, &dst.ip6))
12824         {
12825           grp_set = dst_set = 1;
12826           ipv6_set = 1;
12827         }
12828       else
12829         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12830         ;
12831       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12832         ;
12833       else if (unformat (line_input, "decap-next %U",
12834                          unformat_vxlan_decap_next, &decap_next_index))
12835         ;
12836       else if (unformat (line_input, "vni %d", &vni))
12837         ;
12838       else
12839         {
12840           errmsg ("parse error '%U'", format_unformat_error, line_input);
12841           return -99;
12842         }
12843     }
12844
12845   if (src_set == 0)
12846     {
12847       errmsg ("tunnel src address not specified");
12848       return -99;
12849     }
12850   if (dst_set == 0)
12851     {
12852       errmsg ("tunnel dst address not specified");
12853       return -99;
12854     }
12855
12856   if (grp_set && !ip46_address_is_multicast (&dst))
12857     {
12858       errmsg ("tunnel group address not multicast");
12859       return -99;
12860     }
12861   if (grp_set && mcast_sw_if_index == ~0)
12862     {
12863       errmsg ("tunnel nonexistent multicast device");
12864       return -99;
12865     }
12866   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12867     {
12868       errmsg ("tunnel dst address must be unicast");
12869       return -99;
12870     }
12871
12872
12873   if (ipv4_set && ipv6_set)
12874     {
12875       errmsg ("both IPv4 and IPv6 addresses specified");
12876       return -99;
12877     }
12878
12879   if ((vni == 0) || (vni >> 24))
12880     {
12881       errmsg ("vni not specified or out of range");
12882       return -99;
12883     }
12884
12885   M (VXLAN_ADD_DEL_TUNNEL, mp);
12886
12887   if (ipv6_set)
12888     {
12889       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12890       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12891     }
12892   else
12893     {
12894       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12895       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12896     }
12897
12898   mp->instance = htonl (instance);
12899   mp->encap_vrf_id = ntohl (encap_vrf_id);
12900   mp->decap_next_index = ntohl (decap_next_index);
12901   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12902   mp->vni = ntohl (vni);
12903   mp->is_add = is_add;
12904   mp->is_ipv6 = ipv6_set;
12905
12906   S (mp);
12907   W (ret);
12908   return ret;
12909 }
12910
12911 static void vl_api_vxlan_tunnel_details_t_handler
12912   (vl_api_vxlan_tunnel_details_t * mp)
12913 {
12914   vat_main_t *vam = &vat_main;
12915   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12916   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12917
12918   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12919          ntohl (mp->sw_if_index),
12920          ntohl (mp->instance),
12921          format_ip46_address, &src, IP46_TYPE_ANY,
12922          format_ip46_address, &dst, IP46_TYPE_ANY,
12923          ntohl (mp->encap_vrf_id),
12924          ntohl (mp->decap_next_index), ntohl (mp->vni),
12925          ntohl (mp->mcast_sw_if_index));
12926 }
12927
12928 static void vl_api_vxlan_tunnel_details_t_handler_json
12929   (vl_api_vxlan_tunnel_details_t * mp)
12930 {
12931   vat_main_t *vam = &vat_main;
12932   vat_json_node_t *node = NULL;
12933
12934   if (VAT_JSON_ARRAY != vam->json_tree.type)
12935     {
12936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12937       vat_json_init_array (&vam->json_tree);
12938     }
12939   node = vat_json_array_add (&vam->json_tree);
12940
12941   vat_json_init_object (node);
12942   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12943
12944   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12945
12946   if (mp->is_ipv6)
12947     {
12948       struct in6_addr ip6;
12949
12950       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12951       vat_json_object_add_ip6 (node, "src_address", ip6);
12952       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12953       vat_json_object_add_ip6 (node, "dst_address", ip6);
12954     }
12955   else
12956     {
12957       struct in_addr ip4;
12958
12959       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12960       vat_json_object_add_ip4 (node, "src_address", ip4);
12961       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12962       vat_json_object_add_ip4 (node, "dst_address", ip4);
12963     }
12964   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12965   vat_json_object_add_uint (node, "decap_next_index",
12966                             ntohl (mp->decap_next_index));
12967   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12968   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12969   vat_json_object_add_uint (node, "mcast_sw_if_index",
12970                             ntohl (mp->mcast_sw_if_index));
12971 }
12972
12973 static int
12974 api_vxlan_tunnel_dump (vat_main_t * vam)
12975 {
12976   unformat_input_t *i = vam->input;
12977   vl_api_vxlan_tunnel_dump_t *mp;
12978   vl_api_control_ping_t *mp_ping;
12979   u32 sw_if_index;
12980   u8 sw_if_index_set = 0;
12981   int ret;
12982
12983   /* Parse args required to build the message */
12984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12985     {
12986       if (unformat (i, "sw_if_index %d", &sw_if_index))
12987         sw_if_index_set = 1;
12988       else
12989         break;
12990     }
12991
12992   if (sw_if_index_set == 0)
12993     {
12994       sw_if_index = ~0;
12995     }
12996
12997   if (!vam->json_output)
12998     {
12999       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13000              "sw_if_index", "instance", "src_address", "dst_address",
13001              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13002     }
13003
13004   /* Get list of vxlan-tunnel interfaces */
13005   M (VXLAN_TUNNEL_DUMP, mp);
13006
13007   mp->sw_if_index = htonl (sw_if_index);
13008
13009   S (mp);
13010
13011   /* Use a control ping for synchronization */
13012   MPING (CONTROL_PING, mp_ping);
13013   S (mp_ping);
13014
13015   W (ret);
13016   return ret;
13017 }
13018
13019 static uword unformat_geneve_decap_next
13020   (unformat_input_t * input, va_list * args)
13021 {
13022   u32 *result = va_arg (*args, u32 *);
13023   u32 tmp;
13024
13025   if (unformat (input, "l2"))
13026     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13027   else if (unformat (input, "%d", &tmp))
13028     *result = tmp;
13029   else
13030     return 0;
13031   return 1;
13032 }
13033
13034 static int
13035 api_geneve_add_del_tunnel (vat_main_t * vam)
13036 {
13037   unformat_input_t *line_input = vam->input;
13038   vl_api_geneve_add_del_tunnel_t *mp;
13039   ip46_address_t src, dst;
13040   u8 is_add = 1;
13041   u8 ipv4_set = 0, ipv6_set = 0;
13042   u8 src_set = 0;
13043   u8 dst_set = 0;
13044   u8 grp_set = 0;
13045   u32 mcast_sw_if_index = ~0;
13046   u32 encap_vrf_id = 0;
13047   u32 decap_next_index = ~0;
13048   u32 vni = 0;
13049   int ret;
13050
13051   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13052   clib_memset (&src, 0, sizeof src);
13053   clib_memset (&dst, 0, sizeof dst);
13054
13055   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13056     {
13057       if (unformat (line_input, "del"))
13058         is_add = 0;
13059       else
13060         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13061         {
13062           ipv4_set = 1;
13063           src_set = 1;
13064         }
13065       else
13066         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13067         {
13068           ipv4_set = 1;
13069           dst_set = 1;
13070         }
13071       else
13072         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13073         {
13074           ipv6_set = 1;
13075           src_set = 1;
13076         }
13077       else
13078         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13079         {
13080           ipv6_set = 1;
13081           dst_set = 1;
13082         }
13083       else if (unformat (line_input, "group %U %U",
13084                          unformat_ip4_address, &dst.ip4,
13085                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13086         {
13087           grp_set = dst_set = 1;
13088           ipv4_set = 1;
13089         }
13090       else if (unformat (line_input, "group %U",
13091                          unformat_ip4_address, &dst.ip4))
13092         {
13093           grp_set = dst_set = 1;
13094           ipv4_set = 1;
13095         }
13096       else if (unformat (line_input, "group %U %U",
13097                          unformat_ip6_address, &dst.ip6,
13098                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13099         {
13100           grp_set = dst_set = 1;
13101           ipv6_set = 1;
13102         }
13103       else if (unformat (line_input, "group %U",
13104                          unformat_ip6_address, &dst.ip6))
13105         {
13106           grp_set = dst_set = 1;
13107           ipv6_set = 1;
13108         }
13109       else
13110         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13111         ;
13112       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13113         ;
13114       else if (unformat (line_input, "decap-next %U",
13115                          unformat_geneve_decap_next, &decap_next_index))
13116         ;
13117       else if (unformat (line_input, "vni %d", &vni))
13118         ;
13119       else
13120         {
13121           errmsg ("parse error '%U'", format_unformat_error, line_input);
13122           return -99;
13123         }
13124     }
13125
13126   if (src_set == 0)
13127     {
13128       errmsg ("tunnel src address not specified");
13129       return -99;
13130     }
13131   if (dst_set == 0)
13132     {
13133       errmsg ("tunnel dst address not specified");
13134       return -99;
13135     }
13136
13137   if (grp_set && !ip46_address_is_multicast (&dst))
13138     {
13139       errmsg ("tunnel group address not multicast");
13140       return -99;
13141     }
13142   if (grp_set && mcast_sw_if_index == ~0)
13143     {
13144       errmsg ("tunnel nonexistent multicast device");
13145       return -99;
13146     }
13147   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13148     {
13149       errmsg ("tunnel dst address must be unicast");
13150       return -99;
13151     }
13152
13153
13154   if (ipv4_set && ipv6_set)
13155     {
13156       errmsg ("both IPv4 and IPv6 addresses specified");
13157       return -99;
13158     }
13159
13160   if ((vni == 0) || (vni >> 24))
13161     {
13162       errmsg ("vni not specified or out of range");
13163       return -99;
13164     }
13165
13166   M (GENEVE_ADD_DEL_TUNNEL, mp);
13167
13168   if (ipv6_set)
13169     {
13170       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13171       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13172     }
13173   else
13174     {
13175       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13176       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13177     }
13178   mp->encap_vrf_id = ntohl (encap_vrf_id);
13179   mp->decap_next_index = ntohl (decap_next_index);
13180   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13181   mp->vni = ntohl (vni);
13182   mp->is_add = is_add;
13183   mp->is_ipv6 = ipv6_set;
13184
13185   S (mp);
13186   W (ret);
13187   return ret;
13188 }
13189
13190 static void vl_api_geneve_tunnel_details_t_handler
13191   (vl_api_geneve_tunnel_details_t * mp)
13192 {
13193   vat_main_t *vam = &vat_main;
13194   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13195   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13196
13197   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13198          ntohl (mp->sw_if_index),
13199          format_ip46_address, &src, IP46_TYPE_ANY,
13200          format_ip46_address, &dst, IP46_TYPE_ANY,
13201          ntohl (mp->encap_vrf_id),
13202          ntohl (mp->decap_next_index), ntohl (mp->vni),
13203          ntohl (mp->mcast_sw_if_index));
13204 }
13205
13206 static void vl_api_geneve_tunnel_details_t_handler_json
13207   (vl_api_geneve_tunnel_details_t * mp)
13208 {
13209   vat_main_t *vam = &vat_main;
13210   vat_json_node_t *node = NULL;
13211
13212   if (VAT_JSON_ARRAY != vam->json_tree.type)
13213     {
13214       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13215       vat_json_init_array (&vam->json_tree);
13216     }
13217   node = vat_json_array_add (&vam->json_tree);
13218
13219   vat_json_init_object (node);
13220   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13221   if (mp->is_ipv6)
13222     {
13223       struct in6_addr ip6;
13224
13225       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13226       vat_json_object_add_ip6 (node, "src_address", ip6);
13227       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13228       vat_json_object_add_ip6 (node, "dst_address", ip6);
13229     }
13230   else
13231     {
13232       struct in_addr ip4;
13233
13234       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13235       vat_json_object_add_ip4 (node, "src_address", ip4);
13236       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13237       vat_json_object_add_ip4 (node, "dst_address", ip4);
13238     }
13239   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13240   vat_json_object_add_uint (node, "decap_next_index",
13241                             ntohl (mp->decap_next_index));
13242   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13243   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13244   vat_json_object_add_uint (node, "mcast_sw_if_index",
13245                             ntohl (mp->mcast_sw_if_index));
13246 }
13247
13248 static int
13249 api_geneve_tunnel_dump (vat_main_t * vam)
13250 {
13251   unformat_input_t *i = vam->input;
13252   vl_api_geneve_tunnel_dump_t *mp;
13253   vl_api_control_ping_t *mp_ping;
13254   u32 sw_if_index;
13255   u8 sw_if_index_set = 0;
13256   int ret;
13257
13258   /* Parse args required to build the message */
13259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13260     {
13261       if (unformat (i, "sw_if_index %d", &sw_if_index))
13262         sw_if_index_set = 1;
13263       else
13264         break;
13265     }
13266
13267   if (sw_if_index_set == 0)
13268     {
13269       sw_if_index = ~0;
13270     }
13271
13272   if (!vam->json_output)
13273     {
13274       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13275              "sw_if_index", "local_address", "remote_address",
13276              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13277     }
13278
13279   /* Get list of geneve-tunnel interfaces */
13280   M (GENEVE_TUNNEL_DUMP, mp);
13281
13282   mp->sw_if_index = htonl (sw_if_index);
13283
13284   S (mp);
13285
13286   /* Use a control ping for synchronization */
13287   M (CONTROL_PING, mp_ping);
13288   S (mp_ping);
13289
13290   W (ret);
13291   return ret;
13292 }
13293
13294 static int
13295 api_gre_tunnel_add_del (vat_main_t * vam)
13296 {
13297   unformat_input_t *line_input = vam->input;
13298   vl_api_address_t src = { }, dst =
13299   {
13300   };
13301   vl_api_gre_tunnel_add_del_t *mp;
13302   vl_api_gre_tunnel_type_t t_type;
13303   u8 is_add = 1;
13304   u8 ipv4_set = 0;
13305   u8 ipv6_set = 0;
13306   u8 src_set = 0;
13307   u8 dst_set = 0;
13308   u32 outer_fib_id = 0;
13309   u32 session_id = 0;
13310   u32 instance = ~0;
13311   int ret;
13312
13313   t_type = GRE_API_TUNNEL_TYPE_L3;
13314
13315   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13316     {
13317       if (unformat (line_input, "del"))
13318         is_add = 0;
13319       else if (unformat (line_input, "instance %d", &instance))
13320         ;
13321       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13322         {
13323           src_set = 1;
13324         }
13325       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13326         {
13327           dst_set = 1;
13328         }
13329       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13330         ;
13331       else if (unformat (line_input, "teb"))
13332         t_type = GRE_API_TUNNEL_TYPE_TEB;
13333       else if (unformat (line_input, "erspan %d", &session_id))
13334         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13335       else
13336         {
13337           errmsg ("parse error '%U'", format_unformat_error, line_input);
13338           return -99;
13339         }
13340     }
13341
13342   if (src_set == 0)
13343     {
13344       errmsg ("tunnel src address not specified");
13345       return -99;
13346     }
13347   if (dst_set == 0)
13348     {
13349       errmsg ("tunnel dst address not specified");
13350       return -99;
13351     }
13352
13353   M (GRE_TUNNEL_ADD_DEL, mp);
13354
13355   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13356   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13357
13358   mp->tunnel.instance = htonl (instance);
13359   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13360   mp->is_add = is_add;
13361   mp->tunnel.session_id = htons ((u16) session_id);
13362   mp->tunnel.type = htonl (t_type);
13363
13364   S (mp);
13365   W (ret);
13366   return ret;
13367 }
13368
13369 static void vl_api_gre_tunnel_details_t_handler
13370   (vl_api_gre_tunnel_details_t * mp)
13371 {
13372   vat_main_t *vam = &vat_main;
13373
13374   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13375          ntohl (mp->tunnel.sw_if_index),
13376          ntohl (mp->tunnel.instance),
13377          format_vl_api_address, &mp->tunnel.src,
13378          format_vl_api_address, &mp->tunnel.dst,
13379          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13380          ntohl (mp->tunnel.session_id));
13381 }
13382
13383 static void
13384 vat_json_object_add_address (vat_json_node_t * node,
13385                              const char *str, const vl_api_address_t * addr)
13386 {
13387   if (ADDRESS_IP6 == addr->af)
13388     {
13389       struct in6_addr ip6;
13390
13391       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13392       vat_json_object_add_ip6 (node, str, ip6);
13393     }
13394   else
13395     {
13396       struct in_addr ip4;
13397
13398       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13399       vat_json_object_add_ip4 (node, str, ip4);
13400     }
13401 }
13402
13403 static void vl_api_gre_tunnel_details_t_handler_json
13404   (vl_api_gre_tunnel_details_t * mp)
13405 {
13406   vat_main_t *vam = &vat_main;
13407   vat_json_node_t *node = NULL;
13408   struct in_addr ip4;
13409   struct in6_addr ip6;
13410
13411   if (VAT_JSON_ARRAY != vam->json_tree.type)
13412     {
13413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13414       vat_json_init_array (&vam->json_tree);
13415     }
13416   node = vat_json_array_add (&vam->json_tree);
13417
13418   vat_json_init_object (node);
13419   vat_json_object_add_uint (node, "sw_if_index",
13420                             ntohl (mp->tunnel.sw_if_index));
13421   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13422
13423   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13424   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13425   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13426   vat_json_object_add_uint (node, "outer_fib_id",
13427                             ntohl (mp->tunnel.outer_fib_id));
13428   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13429 }
13430
13431 static int
13432 api_gre_tunnel_dump (vat_main_t * vam)
13433 {
13434   unformat_input_t *i = vam->input;
13435   vl_api_gre_tunnel_dump_t *mp;
13436   vl_api_control_ping_t *mp_ping;
13437   u32 sw_if_index;
13438   u8 sw_if_index_set = 0;
13439   int ret;
13440
13441   /* Parse args required to build the message */
13442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13443     {
13444       if (unformat (i, "sw_if_index %d", &sw_if_index))
13445         sw_if_index_set = 1;
13446       else
13447         break;
13448     }
13449
13450   if (sw_if_index_set == 0)
13451     {
13452       sw_if_index = ~0;
13453     }
13454
13455   if (!vam->json_output)
13456     {
13457       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13458              "sw_if_index", "instance", "src_address", "dst_address",
13459              "tunnel_type", "outer_fib_id", "session_id");
13460     }
13461
13462   /* Get list of gre-tunnel interfaces */
13463   M (GRE_TUNNEL_DUMP, mp);
13464
13465   mp->sw_if_index = htonl (sw_if_index);
13466
13467   S (mp);
13468
13469   /* Use a control ping for synchronization */
13470   MPING (CONTROL_PING, mp_ping);
13471   S (mp_ping);
13472
13473   W (ret);
13474   return ret;
13475 }
13476
13477 static int
13478 api_l2_fib_clear_table (vat_main_t * vam)
13479 {
13480 //  unformat_input_t * i = vam->input;
13481   vl_api_l2_fib_clear_table_t *mp;
13482   int ret;
13483
13484   M (L2_FIB_CLEAR_TABLE, mp);
13485
13486   S (mp);
13487   W (ret);
13488   return ret;
13489 }
13490
13491 static int
13492 api_l2_interface_efp_filter (vat_main_t * vam)
13493 {
13494   unformat_input_t *i = vam->input;
13495   vl_api_l2_interface_efp_filter_t *mp;
13496   u32 sw_if_index;
13497   u8 enable = 1;
13498   u8 sw_if_index_set = 0;
13499   int ret;
13500
13501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13502     {
13503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13504         sw_if_index_set = 1;
13505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13506         sw_if_index_set = 1;
13507       else if (unformat (i, "enable"))
13508         enable = 1;
13509       else if (unformat (i, "disable"))
13510         enable = 0;
13511       else
13512         {
13513           clib_warning ("parse error '%U'", format_unformat_error, i);
13514           return -99;
13515         }
13516     }
13517
13518   if (sw_if_index_set == 0)
13519     {
13520       errmsg ("missing sw_if_index");
13521       return -99;
13522     }
13523
13524   M (L2_INTERFACE_EFP_FILTER, mp);
13525
13526   mp->sw_if_index = ntohl (sw_if_index);
13527   mp->enable_disable = enable;
13528
13529   S (mp);
13530   W (ret);
13531   return ret;
13532 }
13533
13534 #define foreach_vtr_op                          \
13535 _("disable",  L2_VTR_DISABLED)                  \
13536 _("push-1",  L2_VTR_PUSH_1)                     \
13537 _("push-2",  L2_VTR_PUSH_2)                     \
13538 _("pop-1",  L2_VTR_POP_1)                       \
13539 _("pop-2",  L2_VTR_POP_2)                       \
13540 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13541 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13542 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13543 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13544
13545 static int
13546 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13547 {
13548   unformat_input_t *i = vam->input;
13549   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13550   u32 sw_if_index;
13551   u8 sw_if_index_set = 0;
13552   u8 vtr_op_set = 0;
13553   u32 vtr_op = 0;
13554   u32 push_dot1q = 1;
13555   u32 tag1 = ~0;
13556   u32 tag2 = ~0;
13557   int ret;
13558
13559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560     {
13561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13562         sw_if_index_set = 1;
13563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13564         sw_if_index_set = 1;
13565       else if (unformat (i, "vtr_op %d", &vtr_op))
13566         vtr_op_set = 1;
13567 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13568       foreach_vtr_op
13569 #undef _
13570         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13571         ;
13572       else if (unformat (i, "tag1 %d", &tag1))
13573         ;
13574       else if (unformat (i, "tag2 %d", &tag2))
13575         ;
13576       else
13577         {
13578           clib_warning ("parse error '%U'", format_unformat_error, i);
13579           return -99;
13580         }
13581     }
13582
13583   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13584     {
13585       errmsg ("missing vtr operation or sw_if_index");
13586       return -99;
13587     }
13588
13589   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13590   mp->sw_if_index = ntohl (sw_if_index);
13591   mp->vtr_op = ntohl (vtr_op);
13592   mp->push_dot1q = ntohl (push_dot1q);
13593   mp->tag1 = ntohl (tag1);
13594   mp->tag2 = ntohl (tag2);
13595
13596   S (mp);
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static int
13602 api_create_vhost_user_if (vat_main_t * vam)
13603 {
13604   unformat_input_t *i = vam->input;
13605   vl_api_create_vhost_user_if_t *mp;
13606   u8 *file_name;
13607   u8 is_server = 0;
13608   u8 file_name_set = 0;
13609   u32 custom_dev_instance = ~0;
13610   u8 hwaddr[6];
13611   u8 use_custom_mac = 0;
13612   u8 disable_mrg_rxbuf = 0;
13613   u8 disable_indirect_desc = 0;
13614   u8 *tag = 0;
13615   int ret;
13616
13617   /* Shut up coverity */
13618   clib_memset (hwaddr, 0, sizeof (hwaddr));
13619
13620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13621     {
13622       if (unformat (i, "socket %s", &file_name))
13623         {
13624           file_name_set = 1;
13625         }
13626       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13627         ;
13628       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13629         use_custom_mac = 1;
13630       else if (unformat (i, "server"))
13631         is_server = 1;
13632       else if (unformat (i, "disable_mrg_rxbuf"))
13633         disable_mrg_rxbuf = 1;
13634       else if (unformat (i, "disable_indirect_desc"))
13635         disable_indirect_desc = 1;
13636       else if (unformat (i, "tag %s", &tag))
13637         ;
13638       else
13639         break;
13640     }
13641
13642   if (file_name_set == 0)
13643     {
13644       errmsg ("missing socket file name");
13645       return -99;
13646     }
13647
13648   if (vec_len (file_name) > 255)
13649     {
13650       errmsg ("socket file name too long");
13651       return -99;
13652     }
13653   vec_add1 (file_name, 0);
13654
13655   M (CREATE_VHOST_USER_IF, mp);
13656
13657   mp->is_server = is_server;
13658   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13659   mp->disable_indirect_desc = disable_indirect_desc;
13660   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13661   vec_free (file_name);
13662   if (custom_dev_instance != ~0)
13663     {
13664       mp->renumber = 1;
13665       mp->custom_dev_instance = ntohl (custom_dev_instance);
13666     }
13667
13668   mp->use_custom_mac = use_custom_mac;
13669   clib_memcpy (mp->mac_address, hwaddr, 6);
13670   if (tag)
13671     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13672   vec_free (tag);
13673
13674   S (mp);
13675   W (ret);
13676   return ret;
13677 }
13678
13679 static int
13680 api_modify_vhost_user_if (vat_main_t * vam)
13681 {
13682   unformat_input_t *i = vam->input;
13683   vl_api_modify_vhost_user_if_t *mp;
13684   u8 *file_name;
13685   u8 is_server = 0;
13686   u8 file_name_set = 0;
13687   u32 custom_dev_instance = ~0;
13688   u8 sw_if_index_set = 0;
13689   u32 sw_if_index = (u32) ~ 0;
13690   int ret;
13691
13692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13693     {
13694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13695         sw_if_index_set = 1;
13696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13697         sw_if_index_set = 1;
13698       else if (unformat (i, "socket %s", &file_name))
13699         {
13700           file_name_set = 1;
13701         }
13702       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13703         ;
13704       else if (unformat (i, "server"))
13705         is_server = 1;
13706       else
13707         break;
13708     }
13709
13710   if (sw_if_index_set == 0)
13711     {
13712       errmsg ("missing sw_if_index or interface name");
13713       return -99;
13714     }
13715
13716   if (file_name_set == 0)
13717     {
13718       errmsg ("missing socket file name");
13719       return -99;
13720     }
13721
13722   if (vec_len (file_name) > 255)
13723     {
13724       errmsg ("socket file name too long");
13725       return -99;
13726     }
13727   vec_add1 (file_name, 0);
13728
13729   M (MODIFY_VHOST_USER_IF, mp);
13730
13731   mp->sw_if_index = ntohl (sw_if_index);
13732   mp->is_server = is_server;
13733   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13734   vec_free (file_name);
13735   if (custom_dev_instance != ~0)
13736     {
13737       mp->renumber = 1;
13738       mp->custom_dev_instance = ntohl (custom_dev_instance);
13739     }
13740
13741   S (mp);
13742   W (ret);
13743   return ret;
13744 }
13745
13746 static int
13747 api_delete_vhost_user_if (vat_main_t * vam)
13748 {
13749   unformat_input_t *i = vam->input;
13750   vl_api_delete_vhost_user_if_t *mp;
13751   u32 sw_if_index = ~0;
13752   u8 sw_if_index_set = 0;
13753   int ret;
13754
13755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13756     {
13757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13758         sw_if_index_set = 1;
13759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13760         sw_if_index_set = 1;
13761       else
13762         break;
13763     }
13764
13765   if (sw_if_index_set == 0)
13766     {
13767       errmsg ("missing sw_if_index or interface name");
13768       return -99;
13769     }
13770
13771
13772   M (DELETE_VHOST_USER_IF, mp);
13773
13774   mp->sw_if_index = ntohl (sw_if_index);
13775
13776   S (mp);
13777   W (ret);
13778   return ret;
13779 }
13780
13781 static void vl_api_sw_interface_vhost_user_details_t_handler
13782   (vl_api_sw_interface_vhost_user_details_t * mp)
13783 {
13784   vat_main_t *vam = &vat_main;
13785
13786   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13787          (char *) mp->interface_name,
13788          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13789          clib_net_to_host_u64 (mp->features), mp->is_server,
13790          ntohl (mp->num_regions), (char *) mp->sock_filename);
13791   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13792 }
13793
13794 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13795   (vl_api_sw_interface_vhost_user_details_t * mp)
13796 {
13797   vat_main_t *vam = &vat_main;
13798   vat_json_node_t *node = NULL;
13799
13800   if (VAT_JSON_ARRAY != vam->json_tree.type)
13801     {
13802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13803       vat_json_init_array (&vam->json_tree);
13804     }
13805   node = vat_json_array_add (&vam->json_tree);
13806
13807   vat_json_init_object (node);
13808   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13809   vat_json_object_add_string_copy (node, "interface_name",
13810                                    mp->interface_name);
13811   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13812                             ntohl (mp->virtio_net_hdr_sz));
13813   vat_json_object_add_uint (node, "features",
13814                             clib_net_to_host_u64 (mp->features));
13815   vat_json_object_add_uint (node, "is_server", mp->is_server);
13816   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13817   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13818   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13819 }
13820
13821 static int
13822 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13823 {
13824   vl_api_sw_interface_vhost_user_dump_t *mp;
13825   vl_api_control_ping_t *mp_ping;
13826   int ret;
13827   print (vam->ofp,
13828          "Interface name            idx hdr_sz features server regions filename");
13829
13830   /* Get list of vhost-user interfaces */
13831   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13832   S (mp);
13833
13834   /* Use a control ping for synchronization */
13835   MPING (CONTROL_PING, mp_ping);
13836   S (mp_ping);
13837
13838   W (ret);
13839   return ret;
13840 }
13841
13842 static int
13843 api_show_version (vat_main_t * vam)
13844 {
13845   vl_api_show_version_t *mp;
13846   int ret;
13847
13848   M (SHOW_VERSION, mp);
13849
13850   S (mp);
13851   W (ret);
13852   return ret;
13853 }
13854
13855
13856 static int
13857 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13858 {
13859   unformat_input_t *line_input = vam->input;
13860   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13861   ip4_address_t local4, remote4;
13862   ip6_address_t local6, remote6;
13863   u8 is_add = 1;
13864   u8 ipv4_set = 0, ipv6_set = 0;
13865   u8 local_set = 0;
13866   u8 remote_set = 0;
13867   u8 grp_set = 0;
13868   u32 mcast_sw_if_index = ~0;
13869   u32 encap_vrf_id = 0;
13870   u32 decap_vrf_id = 0;
13871   u8 protocol = ~0;
13872   u32 vni;
13873   u8 vni_set = 0;
13874   int ret;
13875
13876   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13877   clib_memset (&local4, 0, sizeof local4);
13878   clib_memset (&remote4, 0, sizeof remote4);
13879   clib_memset (&local6, 0, sizeof local6);
13880   clib_memset (&remote6, 0, sizeof remote6);
13881
13882   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13883     {
13884       if (unformat (line_input, "del"))
13885         is_add = 0;
13886       else if (unformat (line_input, "local %U",
13887                          unformat_ip4_address, &local4))
13888         {
13889           local_set = 1;
13890           ipv4_set = 1;
13891         }
13892       else if (unformat (line_input, "remote %U",
13893                          unformat_ip4_address, &remote4))
13894         {
13895           remote_set = 1;
13896           ipv4_set = 1;
13897         }
13898       else if (unformat (line_input, "local %U",
13899                          unformat_ip6_address, &local6))
13900         {
13901           local_set = 1;
13902           ipv6_set = 1;
13903         }
13904       else if (unformat (line_input, "remote %U",
13905                          unformat_ip6_address, &remote6))
13906         {
13907           remote_set = 1;
13908           ipv6_set = 1;
13909         }
13910       else if (unformat (line_input, "group %U %U",
13911                          unformat_ip4_address, &remote4,
13912                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13913         {
13914           grp_set = remote_set = 1;
13915           ipv4_set = 1;
13916         }
13917       else if (unformat (line_input, "group %U",
13918                          unformat_ip4_address, &remote4))
13919         {
13920           grp_set = remote_set = 1;
13921           ipv4_set = 1;
13922         }
13923       else if (unformat (line_input, "group %U %U",
13924                          unformat_ip6_address, &remote6,
13925                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13926         {
13927           grp_set = remote_set = 1;
13928           ipv6_set = 1;
13929         }
13930       else if (unformat (line_input, "group %U",
13931                          unformat_ip6_address, &remote6))
13932         {
13933           grp_set = remote_set = 1;
13934           ipv6_set = 1;
13935         }
13936       else
13937         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13938         ;
13939       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13940         ;
13941       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13942         ;
13943       else if (unformat (line_input, "vni %d", &vni))
13944         vni_set = 1;
13945       else if (unformat (line_input, "next-ip4"))
13946         protocol = 1;
13947       else if (unformat (line_input, "next-ip6"))
13948         protocol = 2;
13949       else if (unformat (line_input, "next-ethernet"))
13950         protocol = 3;
13951       else if (unformat (line_input, "next-nsh"))
13952         protocol = 4;
13953       else
13954         {
13955           errmsg ("parse error '%U'", format_unformat_error, line_input);
13956           return -99;
13957         }
13958     }
13959
13960   if (local_set == 0)
13961     {
13962       errmsg ("tunnel local address not specified");
13963       return -99;
13964     }
13965   if (remote_set == 0)
13966     {
13967       errmsg ("tunnel remote address not specified");
13968       return -99;
13969     }
13970   if (grp_set && mcast_sw_if_index == ~0)
13971     {
13972       errmsg ("tunnel nonexistent multicast device");
13973       return -99;
13974     }
13975   if (ipv4_set && ipv6_set)
13976     {
13977       errmsg ("both IPv4 and IPv6 addresses specified");
13978       return -99;
13979     }
13980
13981   if (vni_set == 0)
13982     {
13983       errmsg ("vni not specified");
13984       return -99;
13985     }
13986
13987   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13988
13989
13990   if (ipv6_set)
13991     {
13992       clib_memcpy (&mp->local, &local6, sizeof (local6));
13993       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13994     }
13995   else
13996     {
13997       clib_memcpy (&mp->local, &local4, sizeof (local4));
13998       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13999     }
14000
14001   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14002   mp->encap_vrf_id = ntohl (encap_vrf_id);
14003   mp->decap_vrf_id = ntohl (decap_vrf_id);
14004   mp->protocol = protocol;
14005   mp->vni = ntohl (vni);
14006   mp->is_add = is_add;
14007   mp->is_ipv6 = ipv6_set;
14008
14009   S (mp);
14010   W (ret);
14011   return ret;
14012 }
14013
14014 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14015   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14016 {
14017   vat_main_t *vam = &vat_main;
14018   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14019   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14020
14021   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14022          ntohl (mp->sw_if_index),
14023          format_ip46_address, &local, IP46_TYPE_ANY,
14024          format_ip46_address, &remote, IP46_TYPE_ANY,
14025          ntohl (mp->vni), mp->protocol,
14026          ntohl (mp->mcast_sw_if_index),
14027          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14028 }
14029
14030
14031 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14032   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14033 {
14034   vat_main_t *vam = &vat_main;
14035   vat_json_node_t *node = NULL;
14036   struct in_addr ip4;
14037   struct in6_addr ip6;
14038
14039   if (VAT_JSON_ARRAY != vam->json_tree.type)
14040     {
14041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14042       vat_json_init_array (&vam->json_tree);
14043     }
14044   node = vat_json_array_add (&vam->json_tree);
14045
14046   vat_json_init_object (node);
14047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14048   if (mp->is_ipv6)
14049     {
14050       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14051       vat_json_object_add_ip6 (node, "local", ip6);
14052       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14053       vat_json_object_add_ip6 (node, "remote", ip6);
14054     }
14055   else
14056     {
14057       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14058       vat_json_object_add_ip4 (node, "local", ip4);
14059       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14060       vat_json_object_add_ip4 (node, "remote", ip4);
14061     }
14062   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14063   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14064   vat_json_object_add_uint (node, "mcast_sw_if_index",
14065                             ntohl (mp->mcast_sw_if_index));
14066   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14067   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14068   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14069 }
14070
14071 static int
14072 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14073 {
14074   unformat_input_t *i = vam->input;
14075   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14076   vl_api_control_ping_t *mp_ping;
14077   u32 sw_if_index;
14078   u8 sw_if_index_set = 0;
14079   int ret;
14080
14081   /* Parse args required to build the message */
14082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14083     {
14084       if (unformat (i, "sw_if_index %d", &sw_if_index))
14085         sw_if_index_set = 1;
14086       else
14087         break;
14088     }
14089
14090   if (sw_if_index_set == 0)
14091     {
14092       sw_if_index = ~0;
14093     }
14094
14095   if (!vam->json_output)
14096     {
14097       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14098              "sw_if_index", "local", "remote", "vni",
14099              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14100     }
14101
14102   /* Get list of vxlan-tunnel interfaces */
14103   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14104
14105   mp->sw_if_index = htonl (sw_if_index);
14106
14107   S (mp);
14108
14109   /* Use a control ping for synchronization */
14110   MPING (CONTROL_PING, mp_ping);
14111   S (mp_ping);
14112
14113   W (ret);
14114   return ret;
14115 }
14116
14117 static void vl_api_l2_fib_table_details_t_handler
14118   (vl_api_l2_fib_table_details_t * mp)
14119 {
14120   vat_main_t *vam = &vat_main;
14121
14122   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14123          "       %d       %d     %d",
14124          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14125          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14126          mp->bvi_mac);
14127 }
14128
14129 static void vl_api_l2_fib_table_details_t_handler_json
14130   (vl_api_l2_fib_table_details_t * mp)
14131 {
14132   vat_main_t *vam = &vat_main;
14133   vat_json_node_t *node = NULL;
14134
14135   if (VAT_JSON_ARRAY != vam->json_tree.type)
14136     {
14137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14138       vat_json_init_array (&vam->json_tree);
14139     }
14140   node = vat_json_array_add (&vam->json_tree);
14141
14142   vat_json_init_object (node);
14143   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14144   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14145   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14146   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14147   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14148   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14149 }
14150
14151 static int
14152 api_l2_fib_table_dump (vat_main_t * vam)
14153 {
14154   unformat_input_t *i = vam->input;
14155   vl_api_l2_fib_table_dump_t *mp;
14156   vl_api_control_ping_t *mp_ping;
14157   u32 bd_id;
14158   u8 bd_id_set = 0;
14159   int ret;
14160
14161   /* Parse args required to build the message */
14162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14163     {
14164       if (unformat (i, "bd_id %d", &bd_id))
14165         bd_id_set = 1;
14166       else
14167         break;
14168     }
14169
14170   if (bd_id_set == 0)
14171     {
14172       errmsg ("missing bridge domain");
14173       return -99;
14174     }
14175
14176   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14177
14178   /* Get list of l2 fib entries */
14179   M (L2_FIB_TABLE_DUMP, mp);
14180
14181   mp->bd_id = ntohl (bd_id);
14182   S (mp);
14183
14184   /* Use a control ping for synchronization */
14185   MPING (CONTROL_PING, mp_ping);
14186   S (mp_ping);
14187
14188   W (ret);
14189   return ret;
14190 }
14191
14192
14193 static int
14194 api_interface_name_renumber (vat_main_t * vam)
14195 {
14196   unformat_input_t *line_input = vam->input;
14197   vl_api_interface_name_renumber_t *mp;
14198   u32 sw_if_index = ~0;
14199   u32 new_show_dev_instance = ~0;
14200   int ret;
14201
14202   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14205                     &sw_if_index))
14206         ;
14207       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14208         ;
14209       else if (unformat (line_input, "new_show_dev_instance %d",
14210                          &new_show_dev_instance))
14211         ;
14212       else
14213         break;
14214     }
14215
14216   if (sw_if_index == ~0)
14217     {
14218       errmsg ("missing interface name or sw_if_index");
14219       return -99;
14220     }
14221
14222   if (new_show_dev_instance == ~0)
14223     {
14224       errmsg ("missing new_show_dev_instance");
14225       return -99;
14226     }
14227
14228   M (INTERFACE_NAME_RENUMBER, mp);
14229
14230   mp->sw_if_index = ntohl (sw_if_index);
14231   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14232
14233   S (mp);
14234   W (ret);
14235   return ret;
14236 }
14237
14238 static int
14239 api_ip_probe_neighbor (vat_main_t * vam)
14240 {
14241   unformat_input_t *i = vam->input;
14242   vl_api_ip_probe_neighbor_t *mp;
14243   vl_api_address_t dst_adr;
14244   u8 int_set = 0;
14245   u8 adr_set = 0;
14246   u32 sw_if_index;
14247   int ret;
14248
14249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14250     {
14251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14252         int_set = 1;
14253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14254         int_set = 1;
14255       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14256         adr_set = 1;
14257       else
14258         break;
14259     }
14260
14261   if (int_set == 0)
14262     {
14263       errmsg ("missing interface");
14264       return -99;
14265     }
14266
14267   if (adr_set == 0)
14268     {
14269       errmsg ("missing addresses");
14270       return -99;
14271     }
14272
14273   M (IP_PROBE_NEIGHBOR, mp);
14274
14275   mp->sw_if_index = ntohl (sw_if_index);
14276   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14277
14278   S (mp);
14279   W (ret);
14280   return ret;
14281 }
14282
14283 static int
14284 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14285 {
14286   unformat_input_t *i = vam->input;
14287   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14288   u8 mode = IP_SCAN_V46_NEIGHBORS;
14289   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14290   int ret;
14291
14292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (i, "ip4"))
14295         mode = IP_SCAN_V4_NEIGHBORS;
14296       else if (unformat (i, "ip6"))
14297         mode = IP_SCAN_V6_NEIGHBORS;
14298       if (unformat (i, "both"))
14299         mode = IP_SCAN_V46_NEIGHBORS;
14300       else if (unformat (i, "disable"))
14301         mode = IP_SCAN_DISABLED;
14302       else if (unformat (i, "interval %d", &interval))
14303         ;
14304       else if (unformat (i, "max-time %d", &time))
14305         ;
14306       else if (unformat (i, "max-update %d", &update))
14307         ;
14308       else if (unformat (i, "delay %d", &delay))
14309         ;
14310       else if (unformat (i, "stale %d", &stale))
14311         ;
14312       else
14313         break;
14314     }
14315
14316   if (interval > 255)
14317     {
14318       errmsg ("interval cannot exceed 255 minutes.");
14319       return -99;
14320     }
14321   if (time > 255)
14322     {
14323       errmsg ("max-time cannot exceed 255 usec.");
14324       return -99;
14325     }
14326   if (update > 255)
14327     {
14328       errmsg ("max-update cannot exceed 255.");
14329       return -99;
14330     }
14331   if (delay > 255)
14332     {
14333       errmsg ("delay cannot exceed 255 msec.");
14334       return -99;
14335     }
14336   if (stale > 255)
14337     {
14338       errmsg ("stale cannot exceed 255 minutes.");
14339       return -99;
14340     }
14341
14342   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14343   mp->mode = mode;
14344   mp->scan_interval = interval;
14345   mp->max_proc_time = time;
14346   mp->max_update = update;
14347   mp->scan_int_delay = delay;
14348   mp->stale_threshold = stale;
14349
14350   S (mp);
14351   W (ret);
14352   return ret;
14353 }
14354
14355 static int
14356 api_want_ip4_arp_events (vat_main_t * vam)
14357 {
14358   unformat_input_t *line_input = vam->input;
14359   vl_api_want_ip4_arp_events_t *mp;
14360   ip4_address_t address;
14361   int address_set = 0;
14362   u32 enable_disable = 1;
14363   int ret;
14364
14365   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14366     {
14367       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14368         address_set = 1;
14369       else if (unformat (line_input, "del"))
14370         enable_disable = 0;
14371       else
14372         break;
14373     }
14374
14375   if (address_set == 0)
14376     {
14377       errmsg ("missing addresses");
14378       return -99;
14379     }
14380
14381   M (WANT_IP4_ARP_EVENTS, mp);
14382   mp->enable_disable = enable_disable;
14383   mp->pid = htonl (getpid ());
14384   clib_memcpy (mp->ip, &address, sizeof (address));
14385
14386   S (mp);
14387   W (ret);
14388   return ret;
14389 }
14390
14391 static int
14392 api_want_ip6_nd_events (vat_main_t * vam)
14393 {
14394   unformat_input_t *line_input = vam->input;
14395   vl_api_want_ip6_nd_events_t *mp;
14396   vl_api_ip6_address_t address;
14397   int address_set = 0;
14398   u32 enable_disable = 1;
14399   int ret;
14400
14401   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat
14404           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14405         address_set = 1;
14406       else if (unformat (line_input, "del"))
14407         enable_disable = 0;
14408       else
14409         break;
14410     }
14411
14412   if (address_set == 0)
14413     {
14414       errmsg ("missing addresses");
14415       return -99;
14416     }
14417
14418   M (WANT_IP6_ND_EVENTS, mp);
14419   mp->enable_disable = enable_disable;
14420   mp->pid = htonl (getpid ());
14421   clib_memcpy (&mp->ip, &address, sizeof (address));
14422
14423   S (mp);
14424   W (ret);
14425   return ret;
14426 }
14427
14428 static int
14429 api_want_l2_macs_events (vat_main_t * vam)
14430 {
14431   unformat_input_t *line_input = vam->input;
14432   vl_api_want_l2_macs_events_t *mp;
14433   u8 enable_disable = 1;
14434   u32 scan_delay = 0;
14435   u32 max_macs_in_event = 0;
14436   u32 learn_limit = 0;
14437   int ret;
14438
14439   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14440     {
14441       if (unformat (line_input, "learn-limit %d", &learn_limit))
14442         ;
14443       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14444         ;
14445       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14446         ;
14447       else if (unformat (line_input, "disable"))
14448         enable_disable = 0;
14449       else
14450         break;
14451     }
14452
14453   M (WANT_L2_MACS_EVENTS, mp);
14454   mp->enable_disable = enable_disable;
14455   mp->pid = htonl (getpid ());
14456   mp->learn_limit = htonl (learn_limit);
14457   mp->scan_delay = (u8) scan_delay;
14458   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14459   S (mp);
14460   W (ret);
14461   return ret;
14462 }
14463
14464 static int
14465 api_input_acl_set_interface (vat_main_t * vam)
14466 {
14467   unformat_input_t *i = vam->input;
14468   vl_api_input_acl_set_interface_t *mp;
14469   u32 sw_if_index;
14470   int sw_if_index_set;
14471   u32 ip4_table_index = ~0;
14472   u32 ip6_table_index = ~0;
14473   u32 l2_table_index = ~0;
14474   u8 is_add = 1;
14475   int ret;
14476
14477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14480         sw_if_index_set = 1;
14481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14482         sw_if_index_set = 1;
14483       else if (unformat (i, "del"))
14484         is_add = 0;
14485       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14486         ;
14487       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14488         ;
14489       else if (unformat (i, "l2-table %d", &l2_table_index))
14490         ;
14491       else
14492         {
14493           clib_warning ("parse error '%U'", format_unformat_error, i);
14494           return -99;
14495         }
14496     }
14497
14498   if (sw_if_index_set == 0)
14499     {
14500       errmsg ("missing interface name or sw_if_index");
14501       return -99;
14502     }
14503
14504   M (INPUT_ACL_SET_INTERFACE, mp);
14505
14506   mp->sw_if_index = ntohl (sw_if_index);
14507   mp->ip4_table_index = ntohl (ip4_table_index);
14508   mp->ip6_table_index = ntohl (ip6_table_index);
14509   mp->l2_table_index = ntohl (l2_table_index);
14510   mp->is_add = is_add;
14511
14512   S (mp);
14513   W (ret);
14514   return ret;
14515 }
14516
14517 static int
14518 api_output_acl_set_interface (vat_main_t * vam)
14519 {
14520   unformat_input_t *i = vam->input;
14521   vl_api_output_acl_set_interface_t *mp;
14522   u32 sw_if_index;
14523   int sw_if_index_set;
14524   u32 ip4_table_index = ~0;
14525   u32 ip6_table_index = ~0;
14526   u32 l2_table_index = ~0;
14527   u8 is_add = 1;
14528   int ret;
14529
14530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14531     {
14532       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14533         sw_if_index_set = 1;
14534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14535         sw_if_index_set = 1;
14536       else if (unformat (i, "del"))
14537         is_add = 0;
14538       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14539         ;
14540       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14541         ;
14542       else if (unformat (i, "l2-table %d", &l2_table_index))
14543         ;
14544       else
14545         {
14546           clib_warning ("parse error '%U'", format_unformat_error, i);
14547           return -99;
14548         }
14549     }
14550
14551   if (sw_if_index_set == 0)
14552     {
14553       errmsg ("missing interface name or sw_if_index");
14554       return -99;
14555     }
14556
14557   M (OUTPUT_ACL_SET_INTERFACE, mp);
14558
14559   mp->sw_if_index = ntohl (sw_if_index);
14560   mp->ip4_table_index = ntohl (ip4_table_index);
14561   mp->ip6_table_index = ntohl (ip6_table_index);
14562   mp->l2_table_index = ntohl (l2_table_index);
14563   mp->is_add = is_add;
14564
14565   S (mp);
14566   W (ret);
14567   return ret;
14568 }
14569
14570 static int
14571 api_ip_address_dump (vat_main_t * vam)
14572 {
14573   unformat_input_t *i = vam->input;
14574   vl_api_ip_address_dump_t *mp;
14575   vl_api_control_ping_t *mp_ping;
14576   u32 sw_if_index = ~0;
14577   u8 sw_if_index_set = 0;
14578   u8 ipv4_set = 0;
14579   u8 ipv6_set = 0;
14580   int ret;
14581
14582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14583     {
14584       if (unformat (i, "sw_if_index %d", &sw_if_index))
14585         sw_if_index_set = 1;
14586       else
14587         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14588         sw_if_index_set = 1;
14589       else if (unformat (i, "ipv4"))
14590         ipv4_set = 1;
14591       else if (unformat (i, "ipv6"))
14592         ipv6_set = 1;
14593       else
14594         break;
14595     }
14596
14597   if (ipv4_set && ipv6_set)
14598     {
14599       errmsg ("ipv4 and ipv6 flags cannot be both set");
14600       return -99;
14601     }
14602
14603   if ((!ipv4_set) && (!ipv6_set))
14604     {
14605       errmsg ("no ipv4 nor ipv6 flag set");
14606       return -99;
14607     }
14608
14609   if (sw_if_index_set == 0)
14610     {
14611       errmsg ("missing interface name or sw_if_index");
14612       return -99;
14613     }
14614
14615   vam->current_sw_if_index = sw_if_index;
14616   vam->is_ipv6 = ipv6_set;
14617
14618   M (IP_ADDRESS_DUMP, mp);
14619   mp->sw_if_index = ntohl (sw_if_index);
14620   mp->is_ipv6 = ipv6_set;
14621   S (mp);
14622
14623   /* Use a control ping for synchronization */
14624   MPING (CONTROL_PING, mp_ping);
14625   S (mp_ping);
14626
14627   W (ret);
14628   return ret;
14629 }
14630
14631 static int
14632 api_ip_dump (vat_main_t * vam)
14633 {
14634   vl_api_ip_dump_t *mp;
14635   vl_api_control_ping_t *mp_ping;
14636   unformat_input_t *in = vam->input;
14637   int ipv4_set = 0;
14638   int ipv6_set = 0;
14639   int is_ipv6;
14640   int i;
14641   int ret;
14642
14643   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14644     {
14645       if (unformat (in, "ipv4"))
14646         ipv4_set = 1;
14647       else if (unformat (in, "ipv6"))
14648         ipv6_set = 1;
14649       else
14650         break;
14651     }
14652
14653   if (ipv4_set && ipv6_set)
14654     {
14655       errmsg ("ipv4 and ipv6 flags cannot be both set");
14656       return -99;
14657     }
14658
14659   if ((!ipv4_set) && (!ipv6_set))
14660     {
14661       errmsg ("no ipv4 nor ipv6 flag set");
14662       return -99;
14663     }
14664
14665   is_ipv6 = ipv6_set;
14666   vam->is_ipv6 = is_ipv6;
14667
14668   /* free old data */
14669   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14670     {
14671       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14672     }
14673   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14674
14675   M (IP_DUMP, mp);
14676   mp->is_ipv6 = ipv6_set;
14677   S (mp);
14678
14679   /* Use a control ping for synchronization */
14680   MPING (CONTROL_PING, mp_ping);
14681   S (mp_ping);
14682
14683   W (ret);
14684   return ret;
14685 }
14686
14687 static int
14688 api_ipsec_spd_add_del (vat_main_t * vam)
14689 {
14690   unformat_input_t *i = vam->input;
14691   vl_api_ipsec_spd_add_del_t *mp;
14692   u32 spd_id = ~0;
14693   u8 is_add = 1;
14694   int ret;
14695
14696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14697     {
14698       if (unformat (i, "spd_id %d", &spd_id))
14699         ;
14700       else if (unformat (i, "del"))
14701         is_add = 0;
14702       else
14703         {
14704           clib_warning ("parse error '%U'", format_unformat_error, i);
14705           return -99;
14706         }
14707     }
14708   if (spd_id == ~0)
14709     {
14710       errmsg ("spd_id must be set");
14711       return -99;
14712     }
14713
14714   M (IPSEC_SPD_ADD_DEL, mp);
14715
14716   mp->spd_id = ntohl (spd_id);
14717   mp->is_add = is_add;
14718
14719   S (mp);
14720   W (ret);
14721   return ret;
14722 }
14723
14724 static int
14725 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14726 {
14727   unformat_input_t *i = vam->input;
14728   vl_api_ipsec_interface_add_del_spd_t *mp;
14729   u32 sw_if_index;
14730   u8 sw_if_index_set = 0;
14731   u32 spd_id = (u32) ~ 0;
14732   u8 is_add = 1;
14733   int ret;
14734
14735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14736     {
14737       if (unformat (i, "del"))
14738         is_add = 0;
14739       else if (unformat (i, "spd_id %d", &spd_id))
14740         ;
14741       else
14742         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14743         sw_if_index_set = 1;
14744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14745         sw_if_index_set = 1;
14746       else
14747         {
14748           clib_warning ("parse error '%U'", format_unformat_error, i);
14749           return -99;
14750         }
14751
14752     }
14753
14754   if (spd_id == (u32) ~ 0)
14755     {
14756       errmsg ("spd_id must be set");
14757       return -99;
14758     }
14759
14760   if (sw_if_index_set == 0)
14761     {
14762       errmsg ("missing interface name or sw_if_index");
14763       return -99;
14764     }
14765
14766   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14767
14768   mp->spd_id = ntohl (spd_id);
14769   mp->sw_if_index = ntohl (sw_if_index);
14770   mp->is_add = is_add;
14771
14772   S (mp);
14773   W (ret);
14774   return ret;
14775 }
14776
14777 static int
14778 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14779 {
14780   unformat_input_t *i = vam->input;
14781   vl_api_ipsec_spd_entry_add_del_t *mp;
14782   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14783   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14784   i32 priority = 0;
14785   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14786   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14787   vl_api_address_t laddr_start = { }, laddr_stop =
14788   {
14789   }, raddr_start =
14790   {
14791   }, raddr_stop =
14792   {
14793   };
14794   int ret;
14795
14796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14797     {
14798       if (unformat (i, "del"))
14799         is_add = 0;
14800       if (unformat (i, "outbound"))
14801         is_outbound = 1;
14802       if (unformat (i, "inbound"))
14803         is_outbound = 0;
14804       else if (unformat (i, "spd_id %d", &spd_id))
14805         ;
14806       else if (unformat (i, "sa_id %d", &sa_id))
14807         ;
14808       else if (unformat (i, "priority %d", &priority))
14809         ;
14810       else if (unformat (i, "protocol %d", &protocol))
14811         ;
14812       else if (unformat (i, "lport_start %d", &lport_start))
14813         ;
14814       else if (unformat (i, "lport_stop %d", &lport_stop))
14815         ;
14816       else if (unformat (i, "rport_start %d", &rport_start))
14817         ;
14818       else if (unformat (i, "rport_stop %d", &rport_stop))
14819         ;
14820       else if (unformat (i, "laddr_start %U",
14821                          unformat_vl_api_address, &laddr_start))
14822         is_ip_any = 0;
14823       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14824                          &laddr_stop))
14825         is_ip_any = 0;
14826       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14827                          &raddr_start))
14828         is_ip_any = 0;
14829       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14830                          &raddr_stop))
14831         is_ip_any = 0;
14832       else
14833         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14834         {
14835           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14836             {
14837               clib_warning ("unsupported action: 'resolve'");
14838               return -99;
14839             }
14840         }
14841       else
14842         {
14843           clib_warning ("parse error '%U'", format_unformat_error, i);
14844           return -99;
14845         }
14846
14847     }
14848
14849   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14850
14851   mp->is_add = is_add;
14852
14853   mp->entry.spd_id = ntohl (spd_id);
14854   mp->entry.priority = ntohl (priority);
14855   mp->entry.is_outbound = is_outbound;
14856
14857   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14858                sizeof (vl_api_address_t));
14859   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14860                sizeof (vl_api_address_t));
14861   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14862                sizeof (vl_api_address_t));
14863   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14864                sizeof (vl_api_address_t));
14865
14866   mp->entry.protocol = (u8) protocol;
14867   mp->entry.local_port_start = ntohs ((u16) lport_start);
14868   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14869   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14870   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14871   mp->entry.policy = (u8) policy;
14872   mp->entry.sa_id = ntohl (sa_id);
14873
14874   S (mp);
14875   W (ret);
14876   return ret;
14877 }
14878
14879 static int
14880 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14881 {
14882   unformat_input_t *i = vam->input;
14883   vl_api_ipsec_sad_entry_add_del_t *mp;
14884   u32 sad_id = 0, spi = 0;
14885   u8 *ck = 0, *ik = 0;
14886   u8 is_add = 1;
14887
14888   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14889   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14890   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14891   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14892   vl_api_address_t tun_src, tun_dst;
14893   int ret;
14894
14895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14896     {
14897       if (unformat (i, "del"))
14898         is_add = 0;
14899       else if (unformat (i, "sad_id %d", &sad_id))
14900         ;
14901       else if (unformat (i, "spi %d", &spi))
14902         ;
14903       else if (unformat (i, "esp"))
14904         protocol = IPSEC_API_PROTO_ESP;
14905       else
14906         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14907         {
14908           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14909           if (ADDRESS_IP6 == tun_src.af)
14910             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14911         }
14912       else
14913         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14914         {
14915           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14916           if (ADDRESS_IP6 == tun_src.af)
14917             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14918         }
14919       else
14920         if (unformat (i, "crypto_alg %U",
14921                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14922         ;
14923       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14924         ;
14925       else if (unformat (i, "integ_alg %U",
14926                          unformat_ipsec_api_integ_alg, &integ_alg))
14927         ;
14928       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14929         ;
14930       else
14931         {
14932           clib_warning ("parse error '%U'", format_unformat_error, i);
14933           return -99;
14934         }
14935
14936     }
14937
14938   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14939
14940   mp->is_add = is_add;
14941   mp->entry.sad_id = ntohl (sad_id);
14942   mp->entry.protocol = protocol;
14943   mp->entry.spi = ntohl (spi);
14944   mp->entry.flags = flags;
14945
14946   mp->entry.crypto_algorithm = crypto_alg;
14947   mp->entry.integrity_algorithm = integ_alg;
14948   mp->entry.crypto_key.length = vec_len (ck);
14949   mp->entry.integrity_key.length = vec_len (ik);
14950
14951   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14952     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14953
14954   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14955     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14956
14957   if (ck)
14958     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14959   if (ik)
14960     clib_memcpy (mp->entry.integrity_key.data, ik,
14961                  mp->entry.integrity_key.length);
14962
14963   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14964     {
14965       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14966                    sizeof (mp->entry.tunnel_src));
14967       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14968                    sizeof (mp->entry.tunnel_dst));
14969     }
14970
14971   S (mp);
14972   W (ret);
14973   return ret;
14974 }
14975
14976 static int
14977 api_ipsec_sa_set_key (vat_main_t * vam)
14978 {
14979   unformat_input_t *i = vam->input;
14980   vl_api_ipsec_sa_set_key_t *mp;
14981   u32 sa_id;
14982   u8 *ck = 0, *ik = 0;
14983   int ret;
14984
14985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14986     {
14987       if (unformat (i, "sa_id %d", &sa_id))
14988         ;
14989       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14990         ;
14991       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14992         ;
14993       else
14994         {
14995           clib_warning ("parse error '%U'", format_unformat_error, i);
14996           return -99;
14997         }
14998     }
14999
15000   M (IPSEC_SA_SET_KEY, mp);
15001
15002   mp->sa_id = ntohl (sa_id);
15003   mp->crypto_key.length = vec_len (ck);
15004   mp->integrity_key.length = vec_len (ik);
15005
15006   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15007     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15008
15009   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15010     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15011
15012   if (ck)
15013     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15014   if (ik)
15015     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15016
15017   S (mp);
15018   W (ret);
15019   return ret;
15020 }
15021
15022 static int
15023 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15024 {
15025   unformat_input_t *i = vam->input;
15026   vl_api_ipsec_tunnel_if_add_del_t *mp;
15027   u32 local_spi = 0, remote_spi = 0;
15028   u32 crypto_alg = 0, integ_alg = 0;
15029   u8 *lck = NULL, *rck = NULL;
15030   u8 *lik = NULL, *rik = NULL;
15031   vl_api_address_t local_ip = { 0 };
15032   vl_api_address_t remote_ip = { 0 };
15033   f64 before = 0;
15034   u8 is_add = 1;
15035   u8 esn = 0;
15036   u8 anti_replay = 0;
15037   u8 renumber = 0;
15038   u32 instance = ~0;
15039   u32 count = 1, jj;
15040   int ret;
15041
15042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15043     {
15044       if (unformat (i, "del"))
15045         is_add = 0;
15046       else if (unformat (i, "esn"))
15047         esn = 1;
15048       else if (unformat (i, "anti-replay"))
15049         anti_replay = 1;
15050       else if (unformat (i, "count %d", &count))
15051         ;
15052       else if (unformat (i, "local_spi %d", &local_spi))
15053         ;
15054       else if (unformat (i, "remote_spi %d", &remote_spi))
15055         ;
15056       else
15057         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15058         ;
15059       else
15060         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15061         ;
15062       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15063         ;
15064       else
15065         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15066         ;
15067       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15068         ;
15069       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15070         ;
15071       else
15072         if (unformat
15073             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15074         {
15075           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15076             {
15077               errmsg ("unsupported crypto-alg: '%U'\n",
15078                       format_ipsec_crypto_alg, crypto_alg);
15079               return -99;
15080             }
15081         }
15082       else
15083         if (unformat
15084             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15085         {
15086           if (integ_alg >= IPSEC_INTEG_N_ALG)
15087             {
15088               errmsg ("unsupported integ-alg: '%U'\n",
15089                       format_ipsec_integ_alg, integ_alg);
15090               return -99;
15091             }
15092         }
15093       else if (unformat (i, "instance %u", &instance))
15094         renumber = 1;
15095       else
15096         {
15097           errmsg ("parse error '%U'\n", format_unformat_error, i);
15098           return -99;
15099         }
15100     }
15101
15102   if (count > 1)
15103     {
15104       /* Turn on async mode */
15105       vam->async_mode = 1;
15106       vam->async_errors = 0;
15107       before = vat_time_now (vam);
15108     }
15109
15110   for (jj = 0; jj < count; jj++)
15111     {
15112       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15113
15114       mp->is_add = is_add;
15115       mp->esn = esn;
15116       mp->anti_replay = anti_replay;
15117
15118       if (jj > 0)
15119         increment_vl_address (&remote_ip);
15120
15121       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15122       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15123
15124       mp->local_spi = htonl (local_spi + jj);
15125       mp->remote_spi = htonl (remote_spi + jj);
15126       mp->crypto_alg = (u8) crypto_alg;
15127
15128       mp->local_crypto_key_len = 0;
15129       if (lck)
15130         {
15131           mp->local_crypto_key_len = vec_len (lck);
15132           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15133             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15134           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15135         }
15136
15137       mp->remote_crypto_key_len = 0;
15138       if (rck)
15139         {
15140           mp->remote_crypto_key_len = vec_len (rck);
15141           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15142             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15143           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15144         }
15145
15146       mp->integ_alg = (u8) integ_alg;
15147
15148       mp->local_integ_key_len = 0;
15149       if (lik)
15150         {
15151           mp->local_integ_key_len = vec_len (lik);
15152           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15153             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15154           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15155         }
15156
15157       mp->remote_integ_key_len = 0;
15158       if (rik)
15159         {
15160           mp->remote_integ_key_len = vec_len (rik);
15161           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15162             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15163           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15164         }
15165
15166       if (renumber)
15167         {
15168           mp->renumber = renumber;
15169           mp->show_instance = ntohl (instance);
15170         }
15171       S (mp);
15172     }
15173
15174   /* When testing multiple add/del ops, use a control-ping to sync */
15175   if (count > 1)
15176     {
15177       vl_api_control_ping_t *mp_ping;
15178       f64 after;
15179       f64 timeout;
15180
15181       /* Shut off async mode */
15182       vam->async_mode = 0;
15183
15184       MPING (CONTROL_PING, mp_ping);
15185       S (mp_ping);
15186
15187       timeout = vat_time_now (vam) + 1.0;
15188       while (vat_time_now (vam) < timeout)
15189         if (vam->result_ready == 1)
15190           goto out;
15191       vam->retval = -99;
15192
15193     out:
15194       if (vam->retval == -99)
15195         errmsg ("timeout");
15196
15197       if (vam->async_errors > 0)
15198         {
15199           errmsg ("%d asynchronous errors", vam->async_errors);
15200           vam->retval = -98;
15201         }
15202       vam->async_errors = 0;
15203       after = vat_time_now (vam);
15204
15205       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15206       if (jj > 0)
15207         count = jj;
15208
15209       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15210              count, after - before, count / (after - before));
15211     }
15212   else
15213     {
15214       /* Wait for a reply... */
15215       W (ret);
15216       return ret;
15217     }
15218
15219   return ret;
15220 }
15221
15222 static void
15223 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15224 {
15225   vat_main_t *vam = &vat_main;
15226
15227   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15228          "crypto_key %U integ_alg %u integ_key %U flags %x "
15229          "tunnel_src_addr %U tunnel_dst_addr %U "
15230          "salt %u seq_outbound %lu last_seq_inbound %lu "
15231          "replay_window %lu\n",
15232          ntohl (mp->entry.sad_id),
15233          ntohl (mp->sw_if_index),
15234          ntohl (mp->entry.spi),
15235          ntohl (mp->entry.protocol),
15236          ntohl (mp->entry.crypto_algorithm),
15237          format_hex_bytes, mp->entry.crypto_key.data,
15238          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15239          format_hex_bytes, mp->entry.integrity_key.data,
15240          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15241          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15242          &mp->entry.tunnel_dst, ntohl (mp->salt),
15243          clib_net_to_host_u64 (mp->seq_outbound),
15244          clib_net_to_host_u64 (mp->last_seq_inbound),
15245          clib_net_to_host_u64 (mp->replay_window));
15246 }
15247
15248 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15249 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15250
15251 static void vl_api_ipsec_sa_details_t_handler_json
15252   (vl_api_ipsec_sa_details_t * mp)
15253 {
15254   vat_main_t *vam = &vat_main;
15255   vat_json_node_t *node = NULL;
15256   vl_api_ipsec_sad_flags_t flags;
15257
15258   if (VAT_JSON_ARRAY != vam->json_tree.type)
15259     {
15260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15261       vat_json_init_array (&vam->json_tree);
15262     }
15263   node = vat_json_array_add (&vam->json_tree);
15264
15265   vat_json_init_object (node);
15266   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15268   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15269   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15270   vat_json_object_add_uint (node, "crypto_alg",
15271                             ntohl (mp->entry.crypto_algorithm));
15272   vat_json_object_add_uint (node, "integ_alg",
15273                             ntohl (mp->entry.integrity_algorithm));
15274   flags = ntohl (mp->entry.flags);
15275   vat_json_object_add_uint (node, "use_esn",
15276                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15277   vat_json_object_add_uint (node, "use_anti_replay",
15278                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15279   vat_json_object_add_uint (node, "is_tunnel",
15280                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15281   vat_json_object_add_uint (node, "is_tunnel_ip6",
15282                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15283   vat_json_object_add_uint (node, "udp_encap",
15284                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15285   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15286                              mp->entry.crypto_key.length);
15287   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15288                              mp->entry.integrity_key.length);
15289   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15290   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15291   vat_json_object_add_uint (node, "replay_window",
15292                             clib_net_to_host_u64 (mp->replay_window));
15293 }
15294
15295 static int
15296 api_ipsec_sa_dump (vat_main_t * vam)
15297 {
15298   unformat_input_t *i = vam->input;
15299   vl_api_ipsec_sa_dump_t *mp;
15300   vl_api_control_ping_t *mp_ping;
15301   u32 sa_id = ~0;
15302   int ret;
15303
15304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15305     {
15306       if (unformat (i, "sa_id %d", &sa_id))
15307         ;
15308       else
15309         {
15310           clib_warning ("parse error '%U'", format_unformat_error, i);
15311           return -99;
15312         }
15313     }
15314
15315   M (IPSEC_SA_DUMP, mp);
15316
15317   mp->sa_id = ntohl (sa_id);
15318
15319   S (mp);
15320
15321   /* Use a control ping for synchronization */
15322   M (CONTROL_PING, mp_ping);
15323   S (mp_ping);
15324
15325   W (ret);
15326   return ret;
15327 }
15328
15329 static int
15330 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15331 {
15332   unformat_input_t *i = vam->input;
15333   vl_api_ipsec_tunnel_if_set_key_t *mp;
15334   u32 sw_if_index = ~0;
15335   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15336   u8 *key = 0;
15337   u32 alg = ~0;
15338   int ret;
15339
15340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15341     {
15342       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15343         ;
15344       else
15345         if (unformat
15346             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15347         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15348       else
15349         if (unformat
15350             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15351         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15352       else
15353         if (unformat
15354             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15355         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15356       else
15357         if (unformat
15358             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15359         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15360       else if (unformat (i, "%U", unformat_hex_string, &key))
15361         ;
15362       else
15363         {
15364           clib_warning ("parse error '%U'", format_unformat_error, i);
15365           return -99;
15366         }
15367     }
15368
15369   if (sw_if_index == ~0)
15370     {
15371       errmsg ("interface must be specified");
15372       return -99;
15373     }
15374
15375   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15376     {
15377       errmsg ("key type must be specified");
15378       return -99;
15379     }
15380
15381   if (alg == ~0)
15382     {
15383       errmsg ("algorithm must be specified");
15384       return -99;
15385     }
15386
15387   if (vec_len (key) == 0)
15388     {
15389       errmsg ("key must be specified");
15390       return -99;
15391     }
15392
15393   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15394
15395   mp->sw_if_index = htonl (sw_if_index);
15396   mp->alg = alg;
15397   mp->key_type = key_type;
15398   mp->key_len = vec_len (key);
15399   clib_memcpy (mp->key, key, vec_len (key));
15400
15401   S (mp);
15402   W (ret);
15403
15404   return ret;
15405 }
15406
15407 static int
15408 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15409 {
15410   unformat_input_t *i = vam->input;
15411   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15412   u32 sw_if_index = ~0;
15413   u32 sa_id = ~0;
15414   u8 is_outbound = (u8) ~ 0;
15415   int ret;
15416
15417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15418     {
15419       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15420         ;
15421       else if (unformat (i, "sa_id %d", &sa_id))
15422         ;
15423       else if (unformat (i, "outbound"))
15424         is_outbound = 1;
15425       else if (unformat (i, "inbound"))
15426         is_outbound = 0;
15427       else
15428         {
15429           clib_warning ("parse error '%U'", format_unformat_error, i);
15430           return -99;
15431         }
15432     }
15433
15434   if (sw_if_index == ~0)
15435     {
15436       errmsg ("interface must be specified");
15437       return -99;
15438     }
15439
15440   if (sa_id == ~0)
15441     {
15442       errmsg ("SA ID must be specified");
15443       return -99;
15444     }
15445
15446   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15447
15448   mp->sw_if_index = htonl (sw_if_index);
15449   mp->sa_id = htonl (sa_id);
15450   mp->is_outbound = is_outbound;
15451
15452   S (mp);
15453   W (ret);
15454
15455   return ret;
15456 }
15457
15458 static int
15459 api_get_first_msg_id (vat_main_t * vam)
15460 {
15461   vl_api_get_first_msg_id_t *mp;
15462   unformat_input_t *i = vam->input;
15463   u8 *name;
15464   u8 name_set = 0;
15465   int ret;
15466
15467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15468     {
15469       if (unformat (i, "client %s", &name))
15470         name_set = 1;
15471       else
15472         break;
15473     }
15474
15475   if (name_set == 0)
15476     {
15477       errmsg ("missing client name");
15478       return -99;
15479     }
15480   vec_add1 (name, 0);
15481
15482   if (vec_len (name) > 63)
15483     {
15484       errmsg ("client name too long");
15485       return -99;
15486     }
15487
15488   M (GET_FIRST_MSG_ID, mp);
15489   clib_memcpy (mp->name, name, vec_len (name));
15490   S (mp);
15491   W (ret);
15492   return ret;
15493 }
15494
15495 static int
15496 api_cop_interface_enable_disable (vat_main_t * vam)
15497 {
15498   unformat_input_t *line_input = vam->input;
15499   vl_api_cop_interface_enable_disable_t *mp;
15500   u32 sw_if_index = ~0;
15501   u8 enable_disable = 1;
15502   int ret;
15503
15504   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15505     {
15506       if (unformat (line_input, "disable"))
15507         enable_disable = 0;
15508       if (unformat (line_input, "enable"))
15509         enable_disable = 1;
15510       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15511                          vam, &sw_if_index))
15512         ;
15513       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15514         ;
15515       else
15516         break;
15517     }
15518
15519   if (sw_if_index == ~0)
15520     {
15521       errmsg ("missing interface name or sw_if_index");
15522       return -99;
15523     }
15524
15525   /* Construct the API message */
15526   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15527   mp->sw_if_index = ntohl (sw_if_index);
15528   mp->enable_disable = enable_disable;
15529
15530   /* send it... */
15531   S (mp);
15532   /* Wait for the reply */
15533   W (ret);
15534   return ret;
15535 }
15536
15537 static int
15538 api_cop_whitelist_enable_disable (vat_main_t * vam)
15539 {
15540   unformat_input_t *line_input = vam->input;
15541   vl_api_cop_whitelist_enable_disable_t *mp;
15542   u32 sw_if_index = ~0;
15543   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15544   u32 fib_id = 0;
15545   int ret;
15546
15547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15548     {
15549       if (unformat (line_input, "ip4"))
15550         ip4 = 1;
15551       else if (unformat (line_input, "ip6"))
15552         ip6 = 1;
15553       else if (unformat (line_input, "default"))
15554         default_cop = 1;
15555       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15556                          vam, &sw_if_index))
15557         ;
15558       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15559         ;
15560       else if (unformat (line_input, "fib-id %d", &fib_id))
15561         ;
15562       else
15563         break;
15564     }
15565
15566   if (sw_if_index == ~0)
15567     {
15568       errmsg ("missing interface name or sw_if_index");
15569       return -99;
15570     }
15571
15572   /* Construct the API message */
15573   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15574   mp->sw_if_index = ntohl (sw_if_index);
15575   mp->fib_id = ntohl (fib_id);
15576   mp->ip4 = ip4;
15577   mp->ip6 = ip6;
15578   mp->default_cop = default_cop;
15579
15580   /* send it... */
15581   S (mp);
15582   /* Wait for the reply */
15583   W (ret);
15584   return ret;
15585 }
15586
15587 static int
15588 api_get_node_graph (vat_main_t * vam)
15589 {
15590   vl_api_get_node_graph_t *mp;
15591   int ret;
15592
15593   M (GET_NODE_GRAPH, mp);
15594
15595   /* send it... */
15596   S (mp);
15597   /* Wait for the reply */
15598   W (ret);
15599   return ret;
15600 }
15601
15602 /* *INDENT-OFF* */
15603 /** Used for parsing LISP eids */
15604 typedef CLIB_PACKED(struct{
15605   u8 addr[16];   /**< eid address */
15606   u32 len;       /**< prefix length if IP */
15607   u8 type;      /**< type of eid */
15608 }) lisp_eid_vat_t;
15609 /* *INDENT-ON* */
15610
15611 static uword
15612 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15613 {
15614   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15615
15616   clib_memset (a, 0, sizeof (a[0]));
15617
15618   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15619     {
15620       a->type = 0;              /* ipv4 type */
15621     }
15622   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15623     {
15624       a->type = 1;              /* ipv6 type */
15625     }
15626   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15627     {
15628       a->type = 2;              /* mac type */
15629     }
15630   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15631     {
15632       a->type = 3;              /* NSH type */
15633       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15634       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15635     }
15636   else
15637     {
15638       return 0;
15639     }
15640
15641   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15642     {
15643       return 0;
15644     }
15645
15646   return 1;
15647 }
15648
15649 static int
15650 lisp_eid_size_vat (u8 type)
15651 {
15652   switch (type)
15653     {
15654     case 0:
15655       return 4;
15656     case 1:
15657       return 16;
15658     case 2:
15659       return 6;
15660     case 3:
15661       return 5;
15662     }
15663   return 0;
15664 }
15665
15666 static void
15667 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15668 {
15669   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15670 }
15671
15672 static int
15673 api_one_add_del_locator_set (vat_main_t * vam)
15674 {
15675   unformat_input_t *input = vam->input;
15676   vl_api_one_add_del_locator_set_t *mp;
15677   u8 is_add = 1;
15678   u8 *locator_set_name = NULL;
15679   u8 locator_set_name_set = 0;
15680   vl_api_local_locator_t locator, *locators = 0;
15681   u32 sw_if_index, priority, weight;
15682   u32 data_len = 0;
15683
15684   int ret;
15685   /* Parse args required to build the message */
15686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15687     {
15688       if (unformat (input, "del"))
15689         {
15690           is_add = 0;
15691         }
15692       else if (unformat (input, "locator-set %s", &locator_set_name))
15693         {
15694           locator_set_name_set = 1;
15695         }
15696       else if (unformat (input, "sw_if_index %u p %u w %u",
15697                          &sw_if_index, &priority, &weight))
15698         {
15699           locator.sw_if_index = htonl (sw_if_index);
15700           locator.priority = priority;
15701           locator.weight = weight;
15702           vec_add1 (locators, locator);
15703         }
15704       else
15705         if (unformat
15706             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15707              &sw_if_index, &priority, &weight))
15708         {
15709           locator.sw_if_index = htonl (sw_if_index);
15710           locator.priority = priority;
15711           locator.weight = weight;
15712           vec_add1 (locators, locator);
15713         }
15714       else
15715         break;
15716     }
15717
15718   if (locator_set_name_set == 0)
15719     {
15720       errmsg ("missing locator-set name");
15721       vec_free (locators);
15722       return -99;
15723     }
15724
15725   if (vec_len (locator_set_name) > 64)
15726     {
15727       errmsg ("locator-set name too long");
15728       vec_free (locator_set_name);
15729       vec_free (locators);
15730       return -99;
15731     }
15732   vec_add1 (locator_set_name, 0);
15733
15734   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15735
15736   /* Construct the API message */
15737   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15738
15739   mp->is_add = is_add;
15740   clib_memcpy (mp->locator_set_name, locator_set_name,
15741                vec_len (locator_set_name));
15742   vec_free (locator_set_name);
15743
15744   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15745   if (locators)
15746     clib_memcpy (mp->locators, locators, data_len);
15747   vec_free (locators);
15748
15749   /* send it... */
15750   S (mp);
15751
15752   /* Wait for a reply... */
15753   W (ret);
15754   return ret;
15755 }
15756
15757 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15758
15759 static int
15760 api_one_add_del_locator (vat_main_t * vam)
15761 {
15762   unformat_input_t *input = vam->input;
15763   vl_api_one_add_del_locator_t *mp;
15764   u32 tmp_if_index = ~0;
15765   u32 sw_if_index = ~0;
15766   u8 sw_if_index_set = 0;
15767   u8 sw_if_index_if_name_set = 0;
15768   u32 priority = ~0;
15769   u8 priority_set = 0;
15770   u32 weight = ~0;
15771   u8 weight_set = 0;
15772   u8 is_add = 1;
15773   u8 *locator_set_name = NULL;
15774   u8 locator_set_name_set = 0;
15775   int ret;
15776
15777   /* Parse args required to build the message */
15778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15779     {
15780       if (unformat (input, "del"))
15781         {
15782           is_add = 0;
15783         }
15784       else if (unformat (input, "locator-set %s", &locator_set_name))
15785         {
15786           locator_set_name_set = 1;
15787         }
15788       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15789                          &tmp_if_index))
15790         {
15791           sw_if_index_if_name_set = 1;
15792           sw_if_index = tmp_if_index;
15793         }
15794       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15795         {
15796           sw_if_index_set = 1;
15797           sw_if_index = tmp_if_index;
15798         }
15799       else if (unformat (input, "p %d", &priority))
15800         {
15801           priority_set = 1;
15802         }
15803       else if (unformat (input, "w %d", &weight))
15804         {
15805           weight_set = 1;
15806         }
15807       else
15808         break;
15809     }
15810
15811   if (locator_set_name_set == 0)
15812     {
15813       errmsg ("missing locator-set name");
15814       return -99;
15815     }
15816
15817   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15818     {
15819       errmsg ("missing sw_if_index");
15820       vec_free (locator_set_name);
15821       return -99;
15822     }
15823
15824   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15825     {
15826       errmsg ("cannot use both params interface name and sw_if_index");
15827       vec_free (locator_set_name);
15828       return -99;
15829     }
15830
15831   if (priority_set == 0)
15832     {
15833       errmsg ("missing locator-set priority");
15834       vec_free (locator_set_name);
15835       return -99;
15836     }
15837
15838   if (weight_set == 0)
15839     {
15840       errmsg ("missing locator-set weight");
15841       vec_free (locator_set_name);
15842       return -99;
15843     }
15844
15845   if (vec_len (locator_set_name) > 64)
15846     {
15847       errmsg ("locator-set name too long");
15848       vec_free (locator_set_name);
15849       return -99;
15850     }
15851   vec_add1 (locator_set_name, 0);
15852
15853   /* Construct the API message */
15854   M (ONE_ADD_DEL_LOCATOR, mp);
15855
15856   mp->is_add = is_add;
15857   mp->sw_if_index = ntohl (sw_if_index);
15858   mp->priority = priority;
15859   mp->weight = weight;
15860   clib_memcpy (mp->locator_set_name, locator_set_name,
15861                vec_len (locator_set_name));
15862   vec_free (locator_set_name);
15863
15864   /* send it... */
15865   S (mp);
15866
15867   /* Wait for a reply... */
15868   W (ret);
15869   return ret;
15870 }
15871
15872 #define api_lisp_add_del_locator api_one_add_del_locator
15873
15874 uword
15875 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15876 {
15877   u32 *key_id = va_arg (*args, u32 *);
15878   u8 *s = 0;
15879
15880   if (unformat (input, "%s", &s))
15881     {
15882       if (!strcmp ((char *) s, "sha1"))
15883         key_id[0] = HMAC_SHA_1_96;
15884       else if (!strcmp ((char *) s, "sha256"))
15885         key_id[0] = HMAC_SHA_256_128;
15886       else
15887         {
15888           clib_warning ("invalid key_id: '%s'", s);
15889           key_id[0] = HMAC_NO_KEY;
15890         }
15891     }
15892   else
15893     return 0;
15894
15895   vec_free (s);
15896   return 1;
15897 }
15898
15899 static int
15900 api_one_add_del_local_eid (vat_main_t * vam)
15901 {
15902   unformat_input_t *input = vam->input;
15903   vl_api_one_add_del_local_eid_t *mp;
15904   u8 is_add = 1;
15905   u8 eid_set = 0;
15906   lisp_eid_vat_t _eid, *eid = &_eid;
15907   u8 *locator_set_name = 0;
15908   u8 locator_set_name_set = 0;
15909   u32 vni = 0;
15910   u16 key_id = 0;
15911   u8 *key = 0;
15912   int ret;
15913
15914   /* Parse args required to build the message */
15915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15916     {
15917       if (unformat (input, "del"))
15918         {
15919           is_add = 0;
15920         }
15921       else if (unformat (input, "vni %d", &vni))
15922         {
15923           ;
15924         }
15925       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15926         {
15927           eid_set = 1;
15928         }
15929       else if (unformat (input, "locator-set %s", &locator_set_name))
15930         {
15931           locator_set_name_set = 1;
15932         }
15933       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15934         ;
15935       else if (unformat (input, "secret-key %_%v%_", &key))
15936         ;
15937       else
15938         break;
15939     }
15940
15941   if (locator_set_name_set == 0)
15942     {
15943       errmsg ("missing locator-set name");
15944       return -99;
15945     }
15946
15947   if (0 == eid_set)
15948     {
15949       errmsg ("EID address not set!");
15950       vec_free (locator_set_name);
15951       return -99;
15952     }
15953
15954   if (key && (0 == key_id))
15955     {
15956       errmsg ("invalid key_id!");
15957       return -99;
15958     }
15959
15960   if (vec_len (key) > 64)
15961     {
15962       errmsg ("key too long");
15963       vec_free (key);
15964       return -99;
15965     }
15966
15967   if (vec_len (locator_set_name) > 64)
15968     {
15969       errmsg ("locator-set name too long");
15970       vec_free (locator_set_name);
15971       return -99;
15972     }
15973   vec_add1 (locator_set_name, 0);
15974
15975   /* Construct the API message */
15976   M (ONE_ADD_DEL_LOCAL_EID, mp);
15977
15978   mp->is_add = is_add;
15979   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15980   mp->eid_type = eid->type;
15981   mp->prefix_len = eid->len;
15982   mp->vni = clib_host_to_net_u32 (vni);
15983   mp->key_id = clib_host_to_net_u16 (key_id);
15984   clib_memcpy (mp->locator_set_name, locator_set_name,
15985                vec_len (locator_set_name));
15986   clib_memcpy (mp->key, key, vec_len (key));
15987
15988   vec_free (locator_set_name);
15989   vec_free (key);
15990
15991   /* send it... */
15992   S (mp);
15993
15994   /* Wait for a reply... */
15995   W (ret);
15996   return ret;
15997 }
15998
15999 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16000
16001 static int
16002 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16003 {
16004   u32 dp_table = 0, vni = 0;;
16005   unformat_input_t *input = vam->input;
16006   vl_api_gpe_add_del_fwd_entry_t *mp;
16007   u8 is_add = 1;
16008   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16009   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16010   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16011   u32 action = ~0, w;
16012   ip4_address_t rmt_rloc4, lcl_rloc4;
16013   ip6_address_t rmt_rloc6, lcl_rloc6;
16014   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16015   int ret;
16016
16017   clib_memset (&rloc, 0, sizeof (rloc));
16018
16019   /* Parse args required to build the message */
16020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16021     {
16022       if (unformat (input, "del"))
16023         is_add = 0;
16024       else if (unformat (input, "add"))
16025         is_add = 1;
16026       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16027         {
16028           rmt_eid_set = 1;
16029         }
16030       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16031         {
16032           lcl_eid_set = 1;
16033         }
16034       else if (unformat (input, "vrf %d", &dp_table))
16035         ;
16036       else if (unformat (input, "bd %d", &dp_table))
16037         ;
16038       else if (unformat (input, "vni %d", &vni))
16039         ;
16040       else if (unformat (input, "w %d", &w))
16041         {
16042           if (!curr_rloc)
16043             {
16044               errmsg ("No RLOC configured for setting priority/weight!");
16045               return -99;
16046             }
16047           curr_rloc->weight = w;
16048         }
16049       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16050                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16051         {
16052           rloc.is_ip4 = 1;
16053
16054           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16055           rloc.weight = 0;
16056           vec_add1 (lcl_locs, rloc);
16057
16058           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16059           vec_add1 (rmt_locs, rloc);
16060           /* weight saved in rmt loc */
16061           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16062         }
16063       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16064                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16065         {
16066           rloc.is_ip4 = 0;
16067           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16068           rloc.weight = 0;
16069           vec_add1 (lcl_locs, rloc);
16070
16071           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16072           vec_add1 (rmt_locs, rloc);
16073           /* weight saved in rmt loc */
16074           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16075         }
16076       else if (unformat (input, "action %d", &action))
16077         {
16078           ;
16079         }
16080       else
16081         {
16082           clib_warning ("parse error '%U'", format_unformat_error, input);
16083           return -99;
16084         }
16085     }
16086
16087   if (!rmt_eid_set)
16088     {
16089       errmsg ("remote eid addresses not set");
16090       return -99;
16091     }
16092
16093   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16094     {
16095       errmsg ("eid types don't match");
16096       return -99;
16097     }
16098
16099   if (0 == rmt_locs && (u32) ~ 0 == action)
16100     {
16101       errmsg ("action not set for negative mapping");
16102       return -99;
16103     }
16104
16105   /* Construct the API message */
16106   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16107       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16108
16109   mp->is_add = is_add;
16110   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16111   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16112   mp->eid_type = rmt_eid->type;
16113   mp->dp_table = clib_host_to_net_u32 (dp_table);
16114   mp->vni = clib_host_to_net_u32 (vni);
16115   mp->rmt_len = rmt_eid->len;
16116   mp->lcl_len = lcl_eid->len;
16117   mp->action = action;
16118
16119   if (0 != rmt_locs && 0 != lcl_locs)
16120     {
16121       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16122       clib_memcpy (mp->locs, lcl_locs,
16123                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16124
16125       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16126       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16127                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16128     }
16129   vec_free (lcl_locs);
16130   vec_free (rmt_locs);
16131
16132   /* send it... */
16133   S (mp);
16134
16135   /* Wait for a reply... */
16136   W (ret);
16137   return ret;
16138 }
16139
16140 static int
16141 api_one_add_del_map_server (vat_main_t * vam)
16142 {
16143   unformat_input_t *input = vam->input;
16144   vl_api_one_add_del_map_server_t *mp;
16145   u8 is_add = 1;
16146   u8 ipv4_set = 0;
16147   u8 ipv6_set = 0;
16148   ip4_address_t ipv4;
16149   ip6_address_t ipv6;
16150   int ret;
16151
16152   /* Parse args required to build the message */
16153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16154     {
16155       if (unformat (input, "del"))
16156         {
16157           is_add = 0;
16158         }
16159       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16160         {
16161           ipv4_set = 1;
16162         }
16163       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16164         {
16165           ipv6_set = 1;
16166         }
16167       else
16168         break;
16169     }
16170
16171   if (ipv4_set && ipv6_set)
16172     {
16173       errmsg ("both eid v4 and v6 addresses set");
16174       return -99;
16175     }
16176
16177   if (!ipv4_set && !ipv6_set)
16178     {
16179       errmsg ("eid addresses not set");
16180       return -99;
16181     }
16182
16183   /* Construct the API message */
16184   M (ONE_ADD_DEL_MAP_SERVER, mp);
16185
16186   mp->is_add = is_add;
16187   if (ipv6_set)
16188     {
16189       mp->is_ipv6 = 1;
16190       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16191     }
16192   else
16193     {
16194       mp->is_ipv6 = 0;
16195       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16196     }
16197
16198   /* send it... */
16199   S (mp);
16200
16201   /* Wait for a reply... */
16202   W (ret);
16203   return ret;
16204 }
16205
16206 #define api_lisp_add_del_map_server api_one_add_del_map_server
16207
16208 static int
16209 api_one_add_del_map_resolver (vat_main_t * vam)
16210 {
16211   unformat_input_t *input = vam->input;
16212   vl_api_one_add_del_map_resolver_t *mp;
16213   u8 is_add = 1;
16214   u8 ipv4_set = 0;
16215   u8 ipv6_set = 0;
16216   ip4_address_t ipv4;
16217   ip6_address_t ipv6;
16218   int ret;
16219
16220   /* Parse args required to build the message */
16221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16222     {
16223       if (unformat (input, "del"))
16224         {
16225           is_add = 0;
16226         }
16227       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16228         {
16229           ipv4_set = 1;
16230         }
16231       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16232         {
16233           ipv6_set = 1;
16234         }
16235       else
16236         break;
16237     }
16238
16239   if (ipv4_set && ipv6_set)
16240     {
16241       errmsg ("both eid v4 and v6 addresses set");
16242       return -99;
16243     }
16244
16245   if (!ipv4_set && !ipv6_set)
16246     {
16247       errmsg ("eid addresses not set");
16248       return -99;
16249     }
16250
16251   /* Construct the API message */
16252   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16253
16254   mp->is_add = is_add;
16255   if (ipv6_set)
16256     {
16257       mp->is_ipv6 = 1;
16258       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16259     }
16260   else
16261     {
16262       mp->is_ipv6 = 0;
16263       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16264     }
16265
16266   /* send it... */
16267   S (mp);
16268
16269   /* Wait for a reply... */
16270   W (ret);
16271   return ret;
16272 }
16273
16274 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16275
16276 static int
16277 api_lisp_gpe_enable_disable (vat_main_t * vam)
16278 {
16279   unformat_input_t *input = vam->input;
16280   vl_api_gpe_enable_disable_t *mp;
16281   u8 is_set = 0;
16282   u8 is_en = 1;
16283   int ret;
16284
16285   /* Parse args required to build the message */
16286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16287     {
16288       if (unformat (input, "enable"))
16289         {
16290           is_set = 1;
16291           is_en = 1;
16292         }
16293       else if (unformat (input, "disable"))
16294         {
16295           is_set = 1;
16296           is_en = 0;
16297         }
16298       else
16299         break;
16300     }
16301
16302   if (is_set == 0)
16303     {
16304       errmsg ("Value not set");
16305       return -99;
16306     }
16307
16308   /* Construct the API message */
16309   M (GPE_ENABLE_DISABLE, mp);
16310
16311   mp->is_en = is_en;
16312
16313   /* send it... */
16314   S (mp);
16315
16316   /* Wait for a reply... */
16317   W (ret);
16318   return ret;
16319 }
16320
16321 static int
16322 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16323 {
16324   unformat_input_t *input = vam->input;
16325   vl_api_one_rloc_probe_enable_disable_t *mp;
16326   u8 is_set = 0;
16327   u8 is_en = 0;
16328   int ret;
16329
16330   /* Parse args required to build the message */
16331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16332     {
16333       if (unformat (input, "enable"))
16334         {
16335           is_set = 1;
16336           is_en = 1;
16337         }
16338       else if (unformat (input, "disable"))
16339         is_set = 1;
16340       else
16341         break;
16342     }
16343
16344   if (!is_set)
16345     {
16346       errmsg ("Value not set");
16347       return -99;
16348     }
16349
16350   /* Construct the API message */
16351   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16352
16353   mp->is_enabled = is_en;
16354
16355   /* send it... */
16356   S (mp);
16357
16358   /* Wait for a reply... */
16359   W (ret);
16360   return ret;
16361 }
16362
16363 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16364
16365 static int
16366 api_one_map_register_enable_disable (vat_main_t * vam)
16367 {
16368   unformat_input_t *input = vam->input;
16369   vl_api_one_map_register_enable_disable_t *mp;
16370   u8 is_set = 0;
16371   u8 is_en = 0;
16372   int ret;
16373
16374   /* Parse args required to build the message */
16375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16376     {
16377       if (unformat (input, "enable"))
16378         {
16379           is_set = 1;
16380           is_en = 1;
16381         }
16382       else if (unformat (input, "disable"))
16383         is_set = 1;
16384       else
16385         break;
16386     }
16387
16388   if (!is_set)
16389     {
16390       errmsg ("Value not set");
16391       return -99;
16392     }
16393
16394   /* Construct the API message */
16395   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16396
16397   mp->is_enabled = is_en;
16398
16399   /* send it... */
16400   S (mp);
16401
16402   /* Wait for a reply... */
16403   W (ret);
16404   return ret;
16405 }
16406
16407 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16408
16409 static int
16410 api_one_enable_disable (vat_main_t * vam)
16411 {
16412   unformat_input_t *input = vam->input;
16413   vl_api_one_enable_disable_t *mp;
16414   u8 is_set = 0;
16415   u8 is_en = 0;
16416   int ret;
16417
16418   /* Parse args required to build the message */
16419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16420     {
16421       if (unformat (input, "enable"))
16422         {
16423           is_set = 1;
16424           is_en = 1;
16425         }
16426       else if (unformat (input, "disable"))
16427         {
16428           is_set = 1;
16429         }
16430       else
16431         break;
16432     }
16433
16434   if (!is_set)
16435     {
16436       errmsg ("Value not set");
16437       return -99;
16438     }
16439
16440   /* Construct the API message */
16441   M (ONE_ENABLE_DISABLE, mp);
16442
16443   mp->is_en = is_en;
16444
16445   /* send it... */
16446   S (mp);
16447
16448   /* Wait for a reply... */
16449   W (ret);
16450   return ret;
16451 }
16452
16453 #define api_lisp_enable_disable api_one_enable_disable
16454
16455 static int
16456 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16457 {
16458   unformat_input_t *input = vam->input;
16459   vl_api_one_enable_disable_xtr_mode_t *mp;
16460   u8 is_set = 0;
16461   u8 is_en = 0;
16462   int ret;
16463
16464   /* Parse args required to build the message */
16465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16466     {
16467       if (unformat (input, "enable"))
16468         {
16469           is_set = 1;
16470           is_en = 1;
16471         }
16472       else if (unformat (input, "disable"))
16473         {
16474           is_set = 1;
16475         }
16476       else
16477         break;
16478     }
16479
16480   if (!is_set)
16481     {
16482       errmsg ("Value not set");
16483       return -99;
16484     }
16485
16486   /* Construct the API message */
16487   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16488
16489   mp->is_en = is_en;
16490
16491   /* send it... */
16492   S (mp);
16493
16494   /* Wait for a reply... */
16495   W (ret);
16496   return ret;
16497 }
16498
16499 static int
16500 api_one_show_xtr_mode (vat_main_t * vam)
16501 {
16502   vl_api_one_show_xtr_mode_t *mp;
16503   int ret;
16504
16505   /* Construct the API message */
16506   M (ONE_SHOW_XTR_MODE, mp);
16507
16508   /* send it... */
16509   S (mp);
16510
16511   /* Wait for a reply... */
16512   W (ret);
16513   return ret;
16514 }
16515
16516 static int
16517 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16518 {
16519   unformat_input_t *input = vam->input;
16520   vl_api_one_enable_disable_pitr_mode_t *mp;
16521   u8 is_set = 0;
16522   u8 is_en = 0;
16523   int ret;
16524
16525   /* Parse args required to build the message */
16526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16527     {
16528       if (unformat (input, "enable"))
16529         {
16530           is_set = 1;
16531           is_en = 1;
16532         }
16533       else if (unformat (input, "disable"))
16534         {
16535           is_set = 1;
16536         }
16537       else
16538         break;
16539     }
16540
16541   if (!is_set)
16542     {
16543       errmsg ("Value not set");
16544       return -99;
16545     }
16546
16547   /* Construct the API message */
16548   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16549
16550   mp->is_en = is_en;
16551
16552   /* send it... */
16553   S (mp);
16554
16555   /* Wait for a reply... */
16556   W (ret);
16557   return ret;
16558 }
16559
16560 static int
16561 api_one_show_pitr_mode (vat_main_t * vam)
16562 {
16563   vl_api_one_show_pitr_mode_t *mp;
16564   int ret;
16565
16566   /* Construct the API message */
16567   M (ONE_SHOW_PITR_MODE, mp);
16568
16569   /* send it... */
16570   S (mp);
16571
16572   /* Wait for a reply... */
16573   W (ret);
16574   return ret;
16575 }
16576
16577 static int
16578 api_one_enable_disable_petr_mode (vat_main_t * vam)
16579 {
16580   unformat_input_t *input = vam->input;
16581   vl_api_one_enable_disable_petr_mode_t *mp;
16582   u8 is_set = 0;
16583   u8 is_en = 0;
16584   int ret;
16585
16586   /* Parse args required to build the message */
16587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16588     {
16589       if (unformat (input, "enable"))
16590         {
16591           is_set = 1;
16592           is_en = 1;
16593         }
16594       else if (unformat (input, "disable"))
16595         {
16596           is_set = 1;
16597         }
16598       else
16599         break;
16600     }
16601
16602   if (!is_set)
16603     {
16604       errmsg ("Value not set");
16605       return -99;
16606     }
16607
16608   /* Construct the API message */
16609   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16610
16611   mp->is_en = is_en;
16612
16613   /* send it... */
16614   S (mp);
16615
16616   /* Wait for a reply... */
16617   W (ret);
16618   return ret;
16619 }
16620
16621 static int
16622 api_one_show_petr_mode (vat_main_t * vam)
16623 {
16624   vl_api_one_show_petr_mode_t *mp;
16625   int ret;
16626
16627   /* Construct the API message */
16628   M (ONE_SHOW_PETR_MODE, mp);
16629
16630   /* send it... */
16631   S (mp);
16632
16633   /* Wait for a reply... */
16634   W (ret);
16635   return ret;
16636 }
16637
16638 static int
16639 api_show_one_map_register_state (vat_main_t * vam)
16640 {
16641   vl_api_show_one_map_register_state_t *mp;
16642   int ret;
16643
16644   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16645
16646   /* send */
16647   S (mp);
16648
16649   /* wait for reply */
16650   W (ret);
16651   return ret;
16652 }
16653
16654 #define api_show_lisp_map_register_state api_show_one_map_register_state
16655
16656 static int
16657 api_show_one_rloc_probe_state (vat_main_t * vam)
16658 {
16659   vl_api_show_one_rloc_probe_state_t *mp;
16660   int ret;
16661
16662   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16663
16664   /* send */
16665   S (mp);
16666
16667   /* wait for reply */
16668   W (ret);
16669   return ret;
16670 }
16671
16672 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16673
16674 static int
16675 api_one_add_del_ndp_entry (vat_main_t * vam)
16676 {
16677   vl_api_one_add_del_ndp_entry_t *mp;
16678   unformat_input_t *input = vam->input;
16679   u8 is_add = 1;
16680   u8 mac_set = 0;
16681   u8 bd_set = 0;
16682   u8 ip_set = 0;
16683   u8 mac[6] = { 0, };
16684   u8 ip6[16] = { 0, };
16685   u32 bd = ~0;
16686   int ret;
16687
16688   /* Parse args required to build the message */
16689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16690     {
16691       if (unformat (input, "del"))
16692         is_add = 0;
16693       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16694         mac_set = 1;
16695       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16696         ip_set = 1;
16697       else if (unformat (input, "bd %d", &bd))
16698         bd_set = 1;
16699       else
16700         {
16701           errmsg ("parse error '%U'", format_unformat_error, input);
16702           return -99;
16703         }
16704     }
16705
16706   if (!bd_set || !ip_set || (!mac_set && is_add))
16707     {
16708       errmsg ("Missing BD, IP or MAC!");
16709       return -99;
16710     }
16711
16712   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16713   mp->is_add = is_add;
16714   clib_memcpy (mp->mac, mac, 6);
16715   mp->bd = clib_host_to_net_u32 (bd);
16716   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16717
16718   /* send */
16719   S (mp);
16720
16721   /* wait for reply */
16722   W (ret);
16723   return ret;
16724 }
16725
16726 static int
16727 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16728 {
16729   vl_api_one_add_del_l2_arp_entry_t *mp;
16730   unformat_input_t *input = vam->input;
16731   u8 is_add = 1;
16732   u8 mac_set = 0;
16733   u8 bd_set = 0;
16734   u8 ip_set = 0;
16735   u8 mac[6] = { 0, };
16736   u32 ip4 = 0, bd = ~0;
16737   int ret;
16738
16739   /* Parse args required to build the message */
16740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16741     {
16742       if (unformat (input, "del"))
16743         is_add = 0;
16744       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16745         mac_set = 1;
16746       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16747         ip_set = 1;
16748       else if (unformat (input, "bd %d", &bd))
16749         bd_set = 1;
16750       else
16751         {
16752           errmsg ("parse error '%U'", format_unformat_error, input);
16753           return -99;
16754         }
16755     }
16756
16757   if (!bd_set || !ip_set || (!mac_set && is_add))
16758     {
16759       errmsg ("Missing BD, IP or MAC!");
16760       return -99;
16761     }
16762
16763   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16764   mp->is_add = is_add;
16765   clib_memcpy (mp->mac, mac, 6);
16766   mp->bd = clib_host_to_net_u32 (bd);
16767   mp->ip4 = ip4;
16768
16769   /* send */
16770   S (mp);
16771
16772   /* wait for reply */
16773   W (ret);
16774   return ret;
16775 }
16776
16777 static int
16778 api_one_ndp_bd_get (vat_main_t * vam)
16779 {
16780   vl_api_one_ndp_bd_get_t *mp;
16781   int ret;
16782
16783   M (ONE_NDP_BD_GET, mp);
16784
16785   /* send */
16786   S (mp);
16787
16788   /* wait for reply */
16789   W (ret);
16790   return ret;
16791 }
16792
16793 static int
16794 api_one_ndp_entries_get (vat_main_t * vam)
16795 {
16796   vl_api_one_ndp_entries_get_t *mp;
16797   unformat_input_t *input = vam->input;
16798   u8 bd_set = 0;
16799   u32 bd = ~0;
16800   int ret;
16801
16802   /* Parse args required to build the message */
16803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16804     {
16805       if (unformat (input, "bd %d", &bd))
16806         bd_set = 1;
16807       else
16808         {
16809           errmsg ("parse error '%U'", format_unformat_error, input);
16810           return -99;
16811         }
16812     }
16813
16814   if (!bd_set)
16815     {
16816       errmsg ("Expected bridge domain!");
16817       return -99;
16818     }
16819
16820   M (ONE_NDP_ENTRIES_GET, mp);
16821   mp->bd = clib_host_to_net_u32 (bd);
16822
16823   /* send */
16824   S (mp);
16825
16826   /* wait for reply */
16827   W (ret);
16828   return ret;
16829 }
16830
16831 static int
16832 api_one_l2_arp_bd_get (vat_main_t * vam)
16833 {
16834   vl_api_one_l2_arp_bd_get_t *mp;
16835   int ret;
16836
16837   M (ONE_L2_ARP_BD_GET, mp);
16838
16839   /* send */
16840   S (mp);
16841
16842   /* wait for reply */
16843   W (ret);
16844   return ret;
16845 }
16846
16847 static int
16848 api_one_l2_arp_entries_get (vat_main_t * vam)
16849 {
16850   vl_api_one_l2_arp_entries_get_t *mp;
16851   unformat_input_t *input = vam->input;
16852   u8 bd_set = 0;
16853   u32 bd = ~0;
16854   int ret;
16855
16856   /* Parse args required to build the message */
16857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16858     {
16859       if (unformat (input, "bd %d", &bd))
16860         bd_set = 1;
16861       else
16862         {
16863           errmsg ("parse error '%U'", format_unformat_error, input);
16864           return -99;
16865         }
16866     }
16867
16868   if (!bd_set)
16869     {
16870       errmsg ("Expected bridge domain!");
16871       return -99;
16872     }
16873
16874   M (ONE_L2_ARP_ENTRIES_GET, mp);
16875   mp->bd = clib_host_to_net_u32 (bd);
16876
16877   /* send */
16878   S (mp);
16879
16880   /* wait for reply */
16881   W (ret);
16882   return ret;
16883 }
16884
16885 static int
16886 api_one_stats_enable_disable (vat_main_t * vam)
16887 {
16888   vl_api_one_stats_enable_disable_t *mp;
16889   unformat_input_t *input = vam->input;
16890   u8 is_set = 0;
16891   u8 is_en = 0;
16892   int ret;
16893
16894   /* Parse args required to build the message */
16895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16896     {
16897       if (unformat (input, "enable"))
16898         {
16899           is_set = 1;
16900           is_en = 1;
16901         }
16902       else if (unformat (input, "disable"))
16903         {
16904           is_set = 1;
16905         }
16906       else
16907         break;
16908     }
16909
16910   if (!is_set)
16911     {
16912       errmsg ("Value not set");
16913       return -99;
16914     }
16915
16916   M (ONE_STATS_ENABLE_DISABLE, mp);
16917   mp->is_en = is_en;
16918
16919   /* send */
16920   S (mp);
16921
16922   /* wait for reply */
16923   W (ret);
16924   return ret;
16925 }
16926
16927 static int
16928 api_show_one_stats_enable_disable (vat_main_t * vam)
16929 {
16930   vl_api_show_one_stats_enable_disable_t *mp;
16931   int ret;
16932
16933   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16934
16935   /* send */
16936   S (mp);
16937
16938   /* wait for reply */
16939   W (ret);
16940   return ret;
16941 }
16942
16943 static int
16944 api_show_one_map_request_mode (vat_main_t * vam)
16945 {
16946   vl_api_show_one_map_request_mode_t *mp;
16947   int ret;
16948
16949   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16950
16951   /* send */
16952   S (mp);
16953
16954   /* wait for reply */
16955   W (ret);
16956   return ret;
16957 }
16958
16959 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16960
16961 static int
16962 api_one_map_request_mode (vat_main_t * vam)
16963 {
16964   unformat_input_t *input = vam->input;
16965   vl_api_one_map_request_mode_t *mp;
16966   u8 mode = 0;
16967   int ret;
16968
16969   /* Parse args required to build the message */
16970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16971     {
16972       if (unformat (input, "dst-only"))
16973         mode = 0;
16974       else if (unformat (input, "src-dst"))
16975         mode = 1;
16976       else
16977         {
16978           errmsg ("parse error '%U'", format_unformat_error, input);
16979           return -99;
16980         }
16981     }
16982
16983   M (ONE_MAP_REQUEST_MODE, mp);
16984
16985   mp->mode = mode;
16986
16987   /* send */
16988   S (mp);
16989
16990   /* wait for reply */
16991   W (ret);
16992   return ret;
16993 }
16994
16995 #define api_lisp_map_request_mode api_one_map_request_mode
16996
16997 /**
16998  * Enable/disable ONE proxy ITR.
16999  *
17000  * @param vam vpp API test context
17001  * @return return code
17002  */
17003 static int
17004 api_one_pitr_set_locator_set (vat_main_t * vam)
17005 {
17006   u8 ls_name_set = 0;
17007   unformat_input_t *input = vam->input;
17008   vl_api_one_pitr_set_locator_set_t *mp;
17009   u8 is_add = 1;
17010   u8 *ls_name = 0;
17011   int ret;
17012
17013   /* Parse args required to build the message */
17014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17015     {
17016       if (unformat (input, "del"))
17017         is_add = 0;
17018       else if (unformat (input, "locator-set %s", &ls_name))
17019         ls_name_set = 1;
17020       else
17021         {
17022           errmsg ("parse error '%U'", format_unformat_error, input);
17023           return -99;
17024         }
17025     }
17026
17027   if (!ls_name_set)
17028     {
17029       errmsg ("locator-set name not set!");
17030       return -99;
17031     }
17032
17033   M (ONE_PITR_SET_LOCATOR_SET, mp);
17034
17035   mp->is_add = is_add;
17036   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17037   vec_free (ls_name);
17038
17039   /* send */
17040   S (mp);
17041
17042   /* wait for reply */
17043   W (ret);
17044   return ret;
17045 }
17046
17047 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17048
17049 static int
17050 api_one_nsh_set_locator_set (vat_main_t * vam)
17051 {
17052   u8 ls_name_set = 0;
17053   unformat_input_t *input = vam->input;
17054   vl_api_one_nsh_set_locator_set_t *mp;
17055   u8 is_add = 1;
17056   u8 *ls_name = 0;
17057   int ret;
17058
17059   /* Parse args required to build the message */
17060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17061     {
17062       if (unformat (input, "del"))
17063         is_add = 0;
17064       else if (unformat (input, "ls %s", &ls_name))
17065         ls_name_set = 1;
17066       else
17067         {
17068           errmsg ("parse error '%U'", format_unformat_error, input);
17069           return -99;
17070         }
17071     }
17072
17073   if (!ls_name_set && is_add)
17074     {
17075       errmsg ("locator-set name not set!");
17076       return -99;
17077     }
17078
17079   M (ONE_NSH_SET_LOCATOR_SET, mp);
17080
17081   mp->is_add = is_add;
17082   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17083   vec_free (ls_name);
17084
17085   /* send */
17086   S (mp);
17087
17088   /* wait for reply */
17089   W (ret);
17090   return ret;
17091 }
17092
17093 static int
17094 api_show_one_pitr (vat_main_t * vam)
17095 {
17096   vl_api_show_one_pitr_t *mp;
17097   int ret;
17098
17099   if (!vam->json_output)
17100     {
17101       print (vam->ofp, "%=20s", "lisp status:");
17102     }
17103
17104   M (SHOW_ONE_PITR, mp);
17105   /* send it... */
17106   S (mp);
17107
17108   /* Wait for a reply... */
17109   W (ret);
17110   return ret;
17111 }
17112
17113 #define api_show_lisp_pitr api_show_one_pitr
17114
17115 static int
17116 api_one_use_petr (vat_main_t * vam)
17117 {
17118   unformat_input_t *input = vam->input;
17119   vl_api_one_use_petr_t *mp;
17120   u8 is_add = 0;
17121   ip_address_t ip;
17122   int ret;
17123
17124   clib_memset (&ip, 0, sizeof (ip));
17125
17126   /* Parse args required to build the message */
17127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17128     {
17129       if (unformat (input, "disable"))
17130         is_add = 0;
17131       else
17132         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17133         {
17134           is_add = 1;
17135           ip_addr_version (&ip) = IP4;
17136         }
17137       else
17138         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17139         {
17140           is_add = 1;
17141           ip_addr_version (&ip) = IP6;
17142         }
17143       else
17144         {
17145           errmsg ("parse error '%U'", format_unformat_error, input);
17146           return -99;
17147         }
17148     }
17149
17150   M (ONE_USE_PETR, mp);
17151
17152   mp->is_add = is_add;
17153   if (is_add)
17154     {
17155       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17156       if (mp->is_ip4)
17157         clib_memcpy (mp->address, &ip, 4);
17158       else
17159         clib_memcpy (mp->address, &ip, 16);
17160     }
17161
17162   /* send */
17163   S (mp);
17164
17165   /* wait for reply */
17166   W (ret);
17167   return ret;
17168 }
17169
17170 #define api_lisp_use_petr api_one_use_petr
17171
17172 static int
17173 api_show_one_nsh_mapping (vat_main_t * vam)
17174 {
17175   vl_api_show_one_use_petr_t *mp;
17176   int ret;
17177
17178   if (!vam->json_output)
17179     {
17180       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17181     }
17182
17183   M (SHOW_ONE_NSH_MAPPING, mp);
17184   /* send it... */
17185   S (mp);
17186
17187   /* Wait for a reply... */
17188   W (ret);
17189   return ret;
17190 }
17191
17192 static int
17193 api_show_one_use_petr (vat_main_t * vam)
17194 {
17195   vl_api_show_one_use_petr_t *mp;
17196   int ret;
17197
17198   if (!vam->json_output)
17199     {
17200       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17201     }
17202
17203   M (SHOW_ONE_USE_PETR, mp);
17204   /* send it... */
17205   S (mp);
17206
17207   /* Wait for a reply... */
17208   W (ret);
17209   return ret;
17210 }
17211
17212 #define api_show_lisp_use_petr api_show_one_use_petr
17213
17214 /**
17215  * Add/delete mapping between vni and vrf
17216  */
17217 static int
17218 api_one_eid_table_add_del_map (vat_main_t * vam)
17219 {
17220   unformat_input_t *input = vam->input;
17221   vl_api_one_eid_table_add_del_map_t *mp;
17222   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17223   u32 vni, vrf, bd_index;
17224   int ret;
17225
17226   /* Parse args required to build the message */
17227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17228     {
17229       if (unformat (input, "del"))
17230         is_add = 0;
17231       else if (unformat (input, "vrf %d", &vrf))
17232         vrf_set = 1;
17233       else if (unformat (input, "bd_index %d", &bd_index))
17234         bd_index_set = 1;
17235       else if (unformat (input, "vni %d", &vni))
17236         vni_set = 1;
17237       else
17238         break;
17239     }
17240
17241   if (!vni_set || (!vrf_set && !bd_index_set))
17242     {
17243       errmsg ("missing arguments!");
17244       return -99;
17245     }
17246
17247   if (vrf_set && bd_index_set)
17248     {
17249       errmsg ("error: both vrf and bd entered!");
17250       return -99;
17251     }
17252
17253   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17254
17255   mp->is_add = is_add;
17256   mp->vni = htonl (vni);
17257   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17258   mp->is_l2 = bd_index_set;
17259
17260   /* send */
17261   S (mp);
17262
17263   /* wait for reply */
17264   W (ret);
17265   return ret;
17266 }
17267
17268 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17269
17270 uword
17271 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17272 {
17273   u32 *action = va_arg (*args, u32 *);
17274   u8 *s = 0;
17275
17276   if (unformat (input, "%s", &s))
17277     {
17278       if (!strcmp ((char *) s, "no-action"))
17279         action[0] = 0;
17280       else if (!strcmp ((char *) s, "natively-forward"))
17281         action[0] = 1;
17282       else if (!strcmp ((char *) s, "send-map-request"))
17283         action[0] = 2;
17284       else if (!strcmp ((char *) s, "drop"))
17285         action[0] = 3;
17286       else
17287         {
17288           clib_warning ("invalid action: '%s'", s);
17289           action[0] = 3;
17290         }
17291     }
17292   else
17293     return 0;
17294
17295   vec_free (s);
17296   return 1;
17297 }
17298
17299 /**
17300  * Add/del remote mapping to/from ONE control plane
17301  *
17302  * @param vam vpp API test context
17303  * @return return code
17304  */
17305 static int
17306 api_one_add_del_remote_mapping (vat_main_t * vam)
17307 {
17308   unformat_input_t *input = vam->input;
17309   vl_api_one_add_del_remote_mapping_t *mp;
17310   u32 vni = 0;
17311   lisp_eid_vat_t _eid, *eid = &_eid;
17312   lisp_eid_vat_t _seid, *seid = &_seid;
17313   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17314   u32 action = ~0, p, w, data_len;
17315   ip4_address_t rloc4;
17316   ip6_address_t rloc6;
17317   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17318   int ret;
17319
17320   clib_memset (&rloc, 0, sizeof (rloc));
17321
17322   /* Parse args required to build the message */
17323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17324     {
17325       if (unformat (input, "del-all"))
17326         {
17327           del_all = 1;
17328         }
17329       else if (unformat (input, "del"))
17330         {
17331           is_add = 0;
17332         }
17333       else if (unformat (input, "add"))
17334         {
17335           is_add = 1;
17336         }
17337       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17338         {
17339           eid_set = 1;
17340         }
17341       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17342         {
17343           seid_set = 1;
17344         }
17345       else if (unformat (input, "vni %d", &vni))
17346         {
17347           ;
17348         }
17349       else if (unformat (input, "p %d w %d", &p, &w))
17350         {
17351           if (!curr_rloc)
17352             {
17353               errmsg ("No RLOC configured for setting priority/weight!");
17354               return -99;
17355             }
17356           curr_rloc->priority = p;
17357           curr_rloc->weight = w;
17358         }
17359       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17360         {
17361           rloc.is_ip4 = 1;
17362           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17363           vec_add1 (rlocs, rloc);
17364           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17365         }
17366       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17367         {
17368           rloc.is_ip4 = 0;
17369           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17370           vec_add1 (rlocs, rloc);
17371           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17372         }
17373       else if (unformat (input, "action %U",
17374                          unformat_negative_mapping_action, &action))
17375         {
17376           ;
17377         }
17378       else
17379         {
17380           clib_warning ("parse error '%U'", format_unformat_error, input);
17381           return -99;
17382         }
17383     }
17384
17385   if (0 == eid_set)
17386     {
17387       errmsg ("missing params!");
17388       return -99;
17389     }
17390
17391   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17392     {
17393       errmsg ("no action set for negative map-reply!");
17394       return -99;
17395     }
17396
17397   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17398
17399   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17400   mp->is_add = is_add;
17401   mp->vni = htonl (vni);
17402   mp->action = (u8) action;
17403   mp->is_src_dst = seid_set;
17404   mp->eid_len = eid->len;
17405   mp->seid_len = seid->len;
17406   mp->del_all = del_all;
17407   mp->eid_type = eid->type;
17408   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17409   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17410
17411   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17412   clib_memcpy (mp->rlocs, rlocs, data_len);
17413   vec_free (rlocs);
17414
17415   /* send it... */
17416   S (mp);
17417
17418   /* Wait for a reply... */
17419   W (ret);
17420   return ret;
17421 }
17422
17423 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17424
17425 /**
17426  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17427  * forwarding entries in data-plane accordingly.
17428  *
17429  * @param vam vpp API test context
17430  * @return return code
17431  */
17432 static int
17433 api_one_add_del_adjacency (vat_main_t * vam)
17434 {
17435   unformat_input_t *input = vam->input;
17436   vl_api_one_add_del_adjacency_t *mp;
17437   u32 vni = 0;
17438   ip4_address_t leid4, reid4;
17439   ip6_address_t leid6, reid6;
17440   u8 reid_mac[6] = { 0 };
17441   u8 leid_mac[6] = { 0 };
17442   u8 reid_type, leid_type;
17443   u32 leid_len = 0, reid_len = 0, len;
17444   u8 is_add = 1;
17445   int ret;
17446
17447   leid_type = reid_type = (u8) ~ 0;
17448
17449   /* Parse args required to build the message */
17450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17451     {
17452       if (unformat (input, "del"))
17453         {
17454           is_add = 0;
17455         }
17456       else if (unformat (input, "add"))
17457         {
17458           is_add = 1;
17459         }
17460       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17461                          &reid4, &len))
17462         {
17463           reid_type = 0;        /* ipv4 */
17464           reid_len = len;
17465         }
17466       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17467                          &reid6, &len))
17468         {
17469           reid_type = 1;        /* ipv6 */
17470           reid_len = len;
17471         }
17472       else if (unformat (input, "reid %U", unformat_ethernet_address,
17473                          reid_mac))
17474         {
17475           reid_type = 2;        /* mac */
17476         }
17477       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17478                          &leid4, &len))
17479         {
17480           leid_type = 0;        /* ipv4 */
17481           leid_len = len;
17482         }
17483       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17484                          &leid6, &len))
17485         {
17486           leid_type = 1;        /* ipv6 */
17487           leid_len = len;
17488         }
17489       else if (unformat (input, "leid %U", unformat_ethernet_address,
17490                          leid_mac))
17491         {
17492           leid_type = 2;        /* mac */
17493         }
17494       else if (unformat (input, "vni %d", &vni))
17495         {
17496           ;
17497         }
17498       else
17499         {
17500           errmsg ("parse error '%U'", format_unformat_error, input);
17501           return -99;
17502         }
17503     }
17504
17505   if ((u8) ~ 0 == reid_type)
17506     {
17507       errmsg ("missing params!");
17508       return -99;
17509     }
17510
17511   if (leid_type != reid_type)
17512     {
17513       errmsg ("remote and local EIDs are of different types!");
17514       return -99;
17515     }
17516
17517   M (ONE_ADD_DEL_ADJACENCY, mp);
17518   mp->is_add = is_add;
17519   mp->vni = htonl (vni);
17520   mp->leid_len = leid_len;
17521   mp->reid_len = reid_len;
17522   mp->eid_type = reid_type;
17523
17524   switch (mp->eid_type)
17525     {
17526     case 0:
17527       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17528       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17529       break;
17530     case 1:
17531       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17532       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17533       break;
17534     case 2:
17535       clib_memcpy (mp->leid, leid_mac, 6);
17536       clib_memcpy (mp->reid, reid_mac, 6);
17537       break;
17538     default:
17539       errmsg ("unknown EID type %d!", mp->eid_type);
17540       return 0;
17541     }
17542
17543   /* send it... */
17544   S (mp);
17545
17546   /* Wait for a reply... */
17547   W (ret);
17548   return ret;
17549 }
17550
17551 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17552
17553 uword
17554 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17555 {
17556   u32 *mode = va_arg (*args, u32 *);
17557
17558   if (unformat (input, "lisp"))
17559     *mode = 0;
17560   else if (unformat (input, "vxlan"))
17561     *mode = 1;
17562   else
17563     return 0;
17564
17565   return 1;
17566 }
17567
17568 static int
17569 api_gpe_get_encap_mode (vat_main_t * vam)
17570 {
17571   vl_api_gpe_get_encap_mode_t *mp;
17572   int ret;
17573
17574   /* Construct the API message */
17575   M (GPE_GET_ENCAP_MODE, mp);
17576
17577   /* send it... */
17578   S (mp);
17579
17580   /* Wait for a reply... */
17581   W (ret);
17582   return ret;
17583 }
17584
17585 static int
17586 api_gpe_set_encap_mode (vat_main_t * vam)
17587 {
17588   unformat_input_t *input = vam->input;
17589   vl_api_gpe_set_encap_mode_t *mp;
17590   int ret;
17591   u32 mode = 0;
17592
17593   /* Parse args required to build the message */
17594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17595     {
17596       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17597         ;
17598       else
17599         break;
17600     }
17601
17602   /* Construct the API message */
17603   M (GPE_SET_ENCAP_MODE, mp);
17604
17605   mp->mode = mode;
17606
17607   /* send it... */
17608   S (mp);
17609
17610   /* Wait for a reply... */
17611   W (ret);
17612   return ret;
17613 }
17614
17615 static int
17616 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17617 {
17618   unformat_input_t *input = vam->input;
17619   vl_api_gpe_add_del_iface_t *mp;
17620   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17621   u32 dp_table = 0, vni = 0;
17622   int ret;
17623
17624   /* Parse args required to build the message */
17625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17626     {
17627       if (unformat (input, "up"))
17628         {
17629           action_set = 1;
17630           is_add = 1;
17631         }
17632       else if (unformat (input, "down"))
17633         {
17634           action_set = 1;
17635           is_add = 0;
17636         }
17637       else if (unformat (input, "table_id %d", &dp_table))
17638         {
17639           dp_table_set = 1;
17640         }
17641       else if (unformat (input, "bd_id %d", &dp_table))
17642         {
17643           dp_table_set = 1;
17644           is_l2 = 1;
17645         }
17646       else if (unformat (input, "vni %d", &vni))
17647         {
17648           vni_set = 1;
17649         }
17650       else
17651         break;
17652     }
17653
17654   if (action_set == 0)
17655     {
17656       errmsg ("Action not set");
17657       return -99;
17658     }
17659   if (dp_table_set == 0 || vni_set == 0)
17660     {
17661       errmsg ("vni and dp_table must be set");
17662       return -99;
17663     }
17664
17665   /* Construct the API message */
17666   M (GPE_ADD_DEL_IFACE, mp);
17667
17668   mp->is_add = is_add;
17669   mp->dp_table = clib_host_to_net_u32 (dp_table);
17670   mp->is_l2 = is_l2;
17671   mp->vni = clib_host_to_net_u32 (vni);
17672
17673   /* send it... */
17674   S (mp);
17675
17676   /* Wait for a reply... */
17677   W (ret);
17678   return ret;
17679 }
17680
17681 static int
17682 api_one_map_register_fallback_threshold (vat_main_t * vam)
17683 {
17684   unformat_input_t *input = vam->input;
17685   vl_api_one_map_register_fallback_threshold_t *mp;
17686   u32 value = 0;
17687   u8 is_set = 0;
17688   int ret;
17689
17690   /* Parse args required to build the message */
17691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17692     {
17693       if (unformat (input, "%u", &value))
17694         is_set = 1;
17695       else
17696         {
17697           clib_warning ("parse error '%U'", format_unformat_error, input);
17698           return -99;
17699         }
17700     }
17701
17702   if (!is_set)
17703     {
17704       errmsg ("fallback threshold value is missing!");
17705       return -99;
17706     }
17707
17708   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17709   mp->value = clib_host_to_net_u32 (value);
17710
17711   /* send it... */
17712   S (mp);
17713
17714   /* Wait for a reply... */
17715   W (ret);
17716   return ret;
17717 }
17718
17719 static int
17720 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17721 {
17722   vl_api_show_one_map_register_fallback_threshold_t *mp;
17723   int ret;
17724
17725   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17726
17727   /* send it... */
17728   S (mp);
17729
17730   /* Wait for a reply... */
17731   W (ret);
17732   return ret;
17733 }
17734
17735 uword
17736 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17737 {
17738   u32 *proto = va_arg (*args, u32 *);
17739
17740   if (unformat (input, "udp"))
17741     *proto = 1;
17742   else if (unformat (input, "api"))
17743     *proto = 2;
17744   else
17745     return 0;
17746
17747   return 1;
17748 }
17749
17750 static int
17751 api_one_set_transport_protocol (vat_main_t * vam)
17752 {
17753   unformat_input_t *input = vam->input;
17754   vl_api_one_set_transport_protocol_t *mp;
17755   u8 is_set = 0;
17756   u32 protocol = 0;
17757   int ret;
17758
17759   /* Parse args required to build the message */
17760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17761     {
17762       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17763         is_set = 1;
17764       else
17765         {
17766           clib_warning ("parse error '%U'", format_unformat_error, input);
17767           return -99;
17768         }
17769     }
17770
17771   if (!is_set)
17772     {
17773       errmsg ("Transport protocol missing!");
17774       return -99;
17775     }
17776
17777   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17778   mp->protocol = (u8) protocol;
17779
17780   /* send it... */
17781   S (mp);
17782
17783   /* Wait for a reply... */
17784   W (ret);
17785   return ret;
17786 }
17787
17788 static int
17789 api_one_get_transport_protocol (vat_main_t * vam)
17790 {
17791   vl_api_one_get_transport_protocol_t *mp;
17792   int ret;
17793
17794   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17795
17796   /* send it... */
17797   S (mp);
17798
17799   /* Wait for a reply... */
17800   W (ret);
17801   return ret;
17802 }
17803
17804 static int
17805 api_one_map_register_set_ttl (vat_main_t * vam)
17806 {
17807   unformat_input_t *input = vam->input;
17808   vl_api_one_map_register_set_ttl_t *mp;
17809   u32 ttl = 0;
17810   u8 is_set = 0;
17811   int ret;
17812
17813   /* Parse args required to build the message */
17814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17815     {
17816       if (unformat (input, "%u", &ttl))
17817         is_set = 1;
17818       else
17819         {
17820           clib_warning ("parse error '%U'", format_unformat_error, input);
17821           return -99;
17822         }
17823     }
17824
17825   if (!is_set)
17826     {
17827       errmsg ("TTL value missing!");
17828       return -99;
17829     }
17830
17831   M (ONE_MAP_REGISTER_SET_TTL, mp);
17832   mp->ttl = clib_host_to_net_u32 (ttl);
17833
17834   /* send it... */
17835   S (mp);
17836
17837   /* Wait for a reply... */
17838   W (ret);
17839   return ret;
17840 }
17841
17842 static int
17843 api_show_one_map_register_ttl (vat_main_t * vam)
17844 {
17845   vl_api_show_one_map_register_ttl_t *mp;
17846   int ret;
17847
17848   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17849
17850   /* send it... */
17851   S (mp);
17852
17853   /* Wait for a reply... */
17854   W (ret);
17855   return ret;
17856 }
17857
17858 /**
17859  * Add/del map request itr rlocs from ONE control plane and updates
17860  *
17861  * @param vam vpp API test context
17862  * @return return code
17863  */
17864 static int
17865 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17866 {
17867   unformat_input_t *input = vam->input;
17868   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17869   u8 *locator_set_name = 0;
17870   u8 locator_set_name_set = 0;
17871   u8 is_add = 1;
17872   int ret;
17873
17874   /* Parse args required to build the message */
17875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17876     {
17877       if (unformat (input, "del"))
17878         {
17879           is_add = 0;
17880         }
17881       else if (unformat (input, "%_%v%_", &locator_set_name))
17882         {
17883           locator_set_name_set = 1;
17884         }
17885       else
17886         {
17887           clib_warning ("parse error '%U'", format_unformat_error, input);
17888           return -99;
17889         }
17890     }
17891
17892   if (is_add && !locator_set_name_set)
17893     {
17894       errmsg ("itr-rloc is not set!");
17895       return -99;
17896     }
17897
17898   if (is_add && vec_len (locator_set_name) > 64)
17899     {
17900       errmsg ("itr-rloc locator-set name too long");
17901       vec_free (locator_set_name);
17902       return -99;
17903     }
17904
17905   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17906   mp->is_add = is_add;
17907   if (is_add)
17908     {
17909       clib_memcpy (mp->locator_set_name, locator_set_name,
17910                    vec_len (locator_set_name));
17911     }
17912   else
17913     {
17914       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17915     }
17916   vec_free (locator_set_name);
17917
17918   /* send it... */
17919   S (mp);
17920
17921   /* Wait for a reply... */
17922   W (ret);
17923   return ret;
17924 }
17925
17926 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17927
17928 static int
17929 api_one_locator_dump (vat_main_t * vam)
17930 {
17931   unformat_input_t *input = vam->input;
17932   vl_api_one_locator_dump_t *mp;
17933   vl_api_control_ping_t *mp_ping;
17934   u8 is_index_set = 0, is_name_set = 0;
17935   u8 *ls_name = 0;
17936   u32 ls_index = ~0;
17937   int ret;
17938
17939   /* Parse args required to build the message */
17940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17941     {
17942       if (unformat (input, "ls_name %_%v%_", &ls_name))
17943         {
17944           is_name_set = 1;
17945         }
17946       else if (unformat (input, "ls_index %d", &ls_index))
17947         {
17948           is_index_set = 1;
17949         }
17950       else
17951         {
17952           errmsg ("parse error '%U'", format_unformat_error, input);
17953           return -99;
17954         }
17955     }
17956
17957   if (!is_index_set && !is_name_set)
17958     {
17959       errmsg ("error: expected one of index or name!");
17960       return -99;
17961     }
17962
17963   if (is_index_set && is_name_set)
17964     {
17965       errmsg ("error: only one param expected!");
17966       return -99;
17967     }
17968
17969   if (vec_len (ls_name) > 62)
17970     {
17971       errmsg ("error: locator set name too long!");
17972       return -99;
17973     }
17974
17975   if (!vam->json_output)
17976     {
17977       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17978     }
17979
17980   M (ONE_LOCATOR_DUMP, mp);
17981   mp->is_index_set = is_index_set;
17982
17983   if (is_index_set)
17984     mp->ls_index = clib_host_to_net_u32 (ls_index);
17985   else
17986     {
17987       vec_add1 (ls_name, 0);
17988       strncpy ((char *) mp->ls_name, (char *) ls_name,
17989                sizeof (mp->ls_name) - 1);
17990     }
17991
17992   /* send it... */
17993   S (mp);
17994
17995   /* Use a control ping for synchronization */
17996   MPING (CONTROL_PING, mp_ping);
17997   S (mp_ping);
17998
17999   /* Wait for a reply... */
18000   W (ret);
18001   return ret;
18002 }
18003
18004 #define api_lisp_locator_dump api_one_locator_dump
18005
18006 static int
18007 api_one_locator_set_dump (vat_main_t * vam)
18008 {
18009   vl_api_one_locator_set_dump_t *mp;
18010   vl_api_control_ping_t *mp_ping;
18011   unformat_input_t *input = vam->input;
18012   u8 filter = 0;
18013   int ret;
18014
18015   /* Parse args required to build the message */
18016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18017     {
18018       if (unformat (input, "local"))
18019         {
18020           filter = 1;
18021         }
18022       else if (unformat (input, "remote"))
18023         {
18024           filter = 2;
18025         }
18026       else
18027         {
18028           errmsg ("parse error '%U'", format_unformat_error, input);
18029           return -99;
18030         }
18031     }
18032
18033   if (!vam->json_output)
18034     {
18035       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18036     }
18037
18038   M (ONE_LOCATOR_SET_DUMP, mp);
18039
18040   mp->filter = filter;
18041
18042   /* send it... */
18043   S (mp);
18044
18045   /* Use a control ping for synchronization */
18046   MPING (CONTROL_PING, mp_ping);
18047   S (mp_ping);
18048
18049   /* Wait for a reply... */
18050   W (ret);
18051   return ret;
18052 }
18053
18054 #define api_lisp_locator_set_dump api_one_locator_set_dump
18055
18056 static int
18057 api_one_eid_table_map_dump (vat_main_t * vam)
18058 {
18059   u8 is_l2 = 0;
18060   u8 mode_set = 0;
18061   unformat_input_t *input = vam->input;
18062   vl_api_one_eid_table_map_dump_t *mp;
18063   vl_api_control_ping_t *mp_ping;
18064   int ret;
18065
18066   /* Parse args required to build the message */
18067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18068     {
18069       if (unformat (input, "l2"))
18070         {
18071           is_l2 = 1;
18072           mode_set = 1;
18073         }
18074       else if (unformat (input, "l3"))
18075         {
18076           is_l2 = 0;
18077           mode_set = 1;
18078         }
18079       else
18080         {
18081           errmsg ("parse error '%U'", format_unformat_error, input);
18082           return -99;
18083         }
18084     }
18085
18086   if (!mode_set)
18087     {
18088       errmsg ("expected one of 'l2' or 'l3' parameter!");
18089       return -99;
18090     }
18091
18092   if (!vam->json_output)
18093     {
18094       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18095     }
18096
18097   M (ONE_EID_TABLE_MAP_DUMP, mp);
18098   mp->is_l2 = is_l2;
18099
18100   /* send it... */
18101   S (mp);
18102
18103   /* Use a control ping for synchronization */
18104   MPING (CONTROL_PING, mp_ping);
18105   S (mp_ping);
18106
18107   /* Wait for a reply... */
18108   W (ret);
18109   return ret;
18110 }
18111
18112 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18113
18114 static int
18115 api_one_eid_table_vni_dump (vat_main_t * vam)
18116 {
18117   vl_api_one_eid_table_vni_dump_t *mp;
18118   vl_api_control_ping_t *mp_ping;
18119   int ret;
18120
18121   if (!vam->json_output)
18122     {
18123       print (vam->ofp, "VNI");
18124     }
18125
18126   M (ONE_EID_TABLE_VNI_DUMP, mp);
18127
18128   /* send it... */
18129   S (mp);
18130
18131   /* Use a control ping for synchronization */
18132   MPING (CONTROL_PING, mp_ping);
18133   S (mp_ping);
18134
18135   /* Wait for a reply... */
18136   W (ret);
18137   return ret;
18138 }
18139
18140 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18141
18142 static int
18143 api_one_eid_table_dump (vat_main_t * vam)
18144 {
18145   unformat_input_t *i = vam->input;
18146   vl_api_one_eid_table_dump_t *mp;
18147   vl_api_control_ping_t *mp_ping;
18148   struct in_addr ip4;
18149   struct in6_addr ip6;
18150   u8 mac[6];
18151   u8 eid_type = ~0, eid_set = 0;
18152   u32 prefix_length = ~0, t, vni = 0;
18153   u8 filter = 0;
18154   int ret;
18155   lisp_nsh_api_t nsh;
18156
18157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18158     {
18159       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18160         {
18161           eid_set = 1;
18162           eid_type = 0;
18163           prefix_length = t;
18164         }
18165       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18166         {
18167           eid_set = 1;
18168           eid_type = 1;
18169           prefix_length = t;
18170         }
18171       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18172         {
18173           eid_set = 1;
18174           eid_type = 2;
18175         }
18176       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18177         {
18178           eid_set = 1;
18179           eid_type = 3;
18180         }
18181       else if (unformat (i, "vni %d", &t))
18182         {
18183           vni = t;
18184         }
18185       else if (unformat (i, "local"))
18186         {
18187           filter = 1;
18188         }
18189       else if (unformat (i, "remote"))
18190         {
18191           filter = 2;
18192         }
18193       else
18194         {
18195           errmsg ("parse error '%U'", format_unformat_error, i);
18196           return -99;
18197         }
18198     }
18199
18200   if (!vam->json_output)
18201     {
18202       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18203              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18204     }
18205
18206   M (ONE_EID_TABLE_DUMP, mp);
18207
18208   mp->filter = filter;
18209   if (eid_set)
18210     {
18211       mp->eid_set = 1;
18212       mp->vni = htonl (vni);
18213       mp->eid_type = eid_type;
18214       switch (eid_type)
18215         {
18216         case 0:
18217           mp->prefix_length = prefix_length;
18218           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18219           break;
18220         case 1:
18221           mp->prefix_length = prefix_length;
18222           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18223           break;
18224         case 2:
18225           clib_memcpy (mp->eid, mac, sizeof (mac));
18226           break;
18227         case 3:
18228           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18229           break;
18230         default:
18231           errmsg ("unknown EID type %d!", eid_type);
18232           return -99;
18233         }
18234     }
18235
18236   /* send it... */
18237   S (mp);
18238
18239   /* Use a control ping for synchronization */
18240   MPING (CONTROL_PING, mp_ping);
18241   S (mp_ping);
18242
18243   /* Wait for a reply... */
18244   W (ret);
18245   return ret;
18246 }
18247
18248 #define api_lisp_eid_table_dump api_one_eid_table_dump
18249
18250 static int
18251 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18252 {
18253   unformat_input_t *i = vam->input;
18254   vl_api_gpe_fwd_entries_get_t *mp;
18255   u8 vni_set = 0;
18256   u32 vni = ~0;
18257   int ret;
18258
18259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18260     {
18261       if (unformat (i, "vni %d", &vni))
18262         {
18263           vni_set = 1;
18264         }
18265       else
18266         {
18267           errmsg ("parse error '%U'", format_unformat_error, i);
18268           return -99;
18269         }
18270     }
18271
18272   if (!vni_set)
18273     {
18274       errmsg ("vni not set!");
18275       return -99;
18276     }
18277
18278   if (!vam->json_output)
18279     {
18280       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18281              "leid", "reid");
18282     }
18283
18284   M (GPE_FWD_ENTRIES_GET, mp);
18285   mp->vni = clib_host_to_net_u32 (vni);
18286
18287   /* send it... */
18288   S (mp);
18289
18290   /* Wait for a reply... */
18291   W (ret);
18292   return ret;
18293 }
18294
18295 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18296 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18297 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18298 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18299 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18300 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18301 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18302 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18303
18304 static int
18305 api_one_adjacencies_get (vat_main_t * vam)
18306 {
18307   unformat_input_t *i = vam->input;
18308   vl_api_one_adjacencies_get_t *mp;
18309   u8 vni_set = 0;
18310   u32 vni = ~0;
18311   int ret;
18312
18313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18314     {
18315       if (unformat (i, "vni %d", &vni))
18316         {
18317           vni_set = 1;
18318         }
18319       else
18320         {
18321           errmsg ("parse error '%U'", format_unformat_error, i);
18322           return -99;
18323         }
18324     }
18325
18326   if (!vni_set)
18327     {
18328       errmsg ("vni not set!");
18329       return -99;
18330     }
18331
18332   if (!vam->json_output)
18333     {
18334       print (vam->ofp, "%s %40s", "leid", "reid");
18335     }
18336
18337   M (ONE_ADJACENCIES_GET, mp);
18338   mp->vni = clib_host_to_net_u32 (vni);
18339
18340   /* send it... */
18341   S (mp);
18342
18343   /* Wait for a reply... */
18344   W (ret);
18345   return ret;
18346 }
18347
18348 #define api_lisp_adjacencies_get api_one_adjacencies_get
18349
18350 static int
18351 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18352 {
18353   unformat_input_t *i = vam->input;
18354   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18355   int ret;
18356   u8 ip_family_set = 0, is_ip4 = 1;
18357
18358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18359     {
18360       if (unformat (i, "ip4"))
18361         {
18362           ip_family_set = 1;
18363           is_ip4 = 1;
18364         }
18365       else if (unformat (i, "ip6"))
18366         {
18367           ip_family_set = 1;
18368           is_ip4 = 0;
18369         }
18370       else
18371         {
18372           errmsg ("parse error '%U'", format_unformat_error, i);
18373           return -99;
18374         }
18375     }
18376
18377   if (!ip_family_set)
18378     {
18379       errmsg ("ip family not set!");
18380       return -99;
18381     }
18382
18383   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18384   mp->is_ip4 = is_ip4;
18385
18386   /* send it... */
18387   S (mp);
18388
18389   /* Wait for a reply... */
18390   W (ret);
18391   return ret;
18392 }
18393
18394 static int
18395 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18396 {
18397   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18398   int ret;
18399
18400   if (!vam->json_output)
18401     {
18402       print (vam->ofp, "VNIs");
18403     }
18404
18405   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18406
18407   /* send it... */
18408   S (mp);
18409
18410   /* Wait for a reply... */
18411   W (ret);
18412   return ret;
18413 }
18414
18415 static int
18416 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18417 {
18418   unformat_input_t *i = vam->input;
18419   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18420   int ret = 0;
18421   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18422   struct in_addr ip4;
18423   struct in6_addr ip6;
18424   u32 table_id = 0, nh_sw_if_index = ~0;
18425
18426   clib_memset (&ip4, 0, sizeof (ip4));
18427   clib_memset (&ip6, 0, sizeof (ip6));
18428
18429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18430     {
18431       if (unformat (i, "del"))
18432         is_add = 0;
18433       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18434                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18435         {
18436           ip_set = 1;
18437           is_ip4 = 1;
18438         }
18439       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18440                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18441         {
18442           ip_set = 1;
18443           is_ip4 = 0;
18444         }
18445       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18446         {
18447           ip_set = 1;
18448           is_ip4 = 1;
18449           nh_sw_if_index = ~0;
18450         }
18451       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18452         {
18453           ip_set = 1;
18454           is_ip4 = 0;
18455           nh_sw_if_index = ~0;
18456         }
18457       else if (unformat (i, "table %d", &table_id))
18458         ;
18459       else
18460         {
18461           errmsg ("parse error '%U'", format_unformat_error, i);
18462           return -99;
18463         }
18464     }
18465
18466   if (!ip_set)
18467     {
18468       errmsg ("nh addr not set!");
18469       return -99;
18470     }
18471
18472   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18473   mp->is_add = is_add;
18474   mp->table_id = clib_host_to_net_u32 (table_id);
18475   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18476   mp->is_ip4 = is_ip4;
18477   if (is_ip4)
18478     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18479   else
18480     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18481
18482   /* send it... */
18483   S (mp);
18484
18485   /* Wait for a reply... */
18486   W (ret);
18487   return ret;
18488 }
18489
18490 static int
18491 api_one_map_server_dump (vat_main_t * vam)
18492 {
18493   vl_api_one_map_server_dump_t *mp;
18494   vl_api_control_ping_t *mp_ping;
18495   int ret;
18496
18497   if (!vam->json_output)
18498     {
18499       print (vam->ofp, "%=20s", "Map server");
18500     }
18501
18502   M (ONE_MAP_SERVER_DUMP, mp);
18503   /* send it... */
18504   S (mp);
18505
18506   /* Use a control ping for synchronization */
18507   MPING (CONTROL_PING, mp_ping);
18508   S (mp_ping);
18509
18510   /* Wait for a reply... */
18511   W (ret);
18512   return ret;
18513 }
18514
18515 #define api_lisp_map_server_dump api_one_map_server_dump
18516
18517 static int
18518 api_one_map_resolver_dump (vat_main_t * vam)
18519 {
18520   vl_api_one_map_resolver_dump_t *mp;
18521   vl_api_control_ping_t *mp_ping;
18522   int ret;
18523
18524   if (!vam->json_output)
18525     {
18526       print (vam->ofp, "%=20s", "Map resolver");
18527     }
18528
18529   M (ONE_MAP_RESOLVER_DUMP, mp);
18530   /* send it... */
18531   S (mp);
18532
18533   /* Use a control ping for synchronization */
18534   MPING (CONTROL_PING, mp_ping);
18535   S (mp_ping);
18536
18537   /* Wait for a reply... */
18538   W (ret);
18539   return ret;
18540 }
18541
18542 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18543
18544 static int
18545 api_one_stats_flush (vat_main_t * vam)
18546 {
18547   vl_api_one_stats_flush_t *mp;
18548   int ret = 0;
18549
18550   M (ONE_STATS_FLUSH, mp);
18551   S (mp);
18552   W (ret);
18553   return ret;
18554 }
18555
18556 static int
18557 api_one_stats_dump (vat_main_t * vam)
18558 {
18559   vl_api_one_stats_dump_t *mp;
18560   vl_api_control_ping_t *mp_ping;
18561   int ret;
18562
18563   M (ONE_STATS_DUMP, mp);
18564   /* send it... */
18565   S (mp);
18566
18567   /* Use a control ping for synchronization */
18568   MPING (CONTROL_PING, mp_ping);
18569   S (mp_ping);
18570
18571   /* Wait for a reply... */
18572   W (ret);
18573   return ret;
18574 }
18575
18576 static int
18577 api_show_one_status (vat_main_t * vam)
18578 {
18579   vl_api_show_one_status_t *mp;
18580   int ret;
18581
18582   if (!vam->json_output)
18583     {
18584       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18585     }
18586
18587   M (SHOW_ONE_STATUS, mp);
18588   /* send it... */
18589   S (mp);
18590   /* Wait for a reply... */
18591   W (ret);
18592   return ret;
18593 }
18594
18595 #define api_show_lisp_status api_show_one_status
18596
18597 static int
18598 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18599 {
18600   vl_api_gpe_fwd_entry_path_dump_t *mp;
18601   vl_api_control_ping_t *mp_ping;
18602   unformat_input_t *i = vam->input;
18603   u32 fwd_entry_index = ~0;
18604   int ret;
18605
18606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18607     {
18608       if (unformat (i, "index %d", &fwd_entry_index))
18609         ;
18610       else
18611         break;
18612     }
18613
18614   if (~0 == fwd_entry_index)
18615     {
18616       errmsg ("no index specified!");
18617       return -99;
18618     }
18619
18620   if (!vam->json_output)
18621     {
18622       print (vam->ofp, "first line");
18623     }
18624
18625   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18626
18627   /* send it... */
18628   S (mp);
18629   /* Use a control ping for synchronization */
18630   MPING (CONTROL_PING, mp_ping);
18631   S (mp_ping);
18632
18633   /* Wait for a reply... */
18634   W (ret);
18635   return ret;
18636 }
18637
18638 static int
18639 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18640 {
18641   vl_api_one_get_map_request_itr_rlocs_t *mp;
18642   int ret;
18643
18644   if (!vam->json_output)
18645     {
18646       print (vam->ofp, "%=20s", "itr-rlocs:");
18647     }
18648
18649   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18650   /* send it... */
18651   S (mp);
18652   /* Wait for a reply... */
18653   W (ret);
18654   return ret;
18655 }
18656
18657 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18658
18659 static int
18660 api_af_packet_create (vat_main_t * vam)
18661 {
18662   unformat_input_t *i = vam->input;
18663   vl_api_af_packet_create_t *mp;
18664   u8 *host_if_name = 0;
18665   u8 hw_addr[6];
18666   u8 random_hw_addr = 1;
18667   int ret;
18668
18669   clib_memset (hw_addr, 0, sizeof (hw_addr));
18670
18671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18672     {
18673       if (unformat (i, "name %s", &host_if_name))
18674         vec_add1 (host_if_name, 0);
18675       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18676         random_hw_addr = 0;
18677       else
18678         break;
18679     }
18680
18681   if (!vec_len (host_if_name))
18682     {
18683       errmsg ("host-interface name must be specified");
18684       return -99;
18685     }
18686
18687   if (vec_len (host_if_name) > 64)
18688     {
18689       errmsg ("host-interface name too long");
18690       return -99;
18691     }
18692
18693   M (AF_PACKET_CREATE, mp);
18694
18695   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18696   clib_memcpy (mp->hw_addr, hw_addr, 6);
18697   mp->use_random_hw_addr = random_hw_addr;
18698   vec_free (host_if_name);
18699
18700   S (mp);
18701
18702   /* *INDENT-OFF* */
18703   W2 (ret,
18704       ({
18705         if (ret == 0)
18706           fprintf (vam->ofp ? vam->ofp : stderr,
18707                    " new sw_if_index = %d\n", vam->sw_if_index);
18708       }));
18709   /* *INDENT-ON* */
18710   return ret;
18711 }
18712
18713 static int
18714 api_af_packet_delete (vat_main_t * vam)
18715 {
18716   unformat_input_t *i = vam->input;
18717   vl_api_af_packet_delete_t *mp;
18718   u8 *host_if_name = 0;
18719   int ret;
18720
18721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18722     {
18723       if (unformat (i, "name %s", &host_if_name))
18724         vec_add1 (host_if_name, 0);
18725       else
18726         break;
18727     }
18728
18729   if (!vec_len (host_if_name))
18730     {
18731       errmsg ("host-interface name must be specified");
18732       return -99;
18733     }
18734
18735   if (vec_len (host_if_name) > 64)
18736     {
18737       errmsg ("host-interface name too long");
18738       return -99;
18739     }
18740
18741   M (AF_PACKET_DELETE, mp);
18742
18743   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18744   vec_free (host_if_name);
18745
18746   S (mp);
18747   W (ret);
18748   return ret;
18749 }
18750
18751 static void vl_api_af_packet_details_t_handler
18752   (vl_api_af_packet_details_t * mp)
18753 {
18754   vat_main_t *vam = &vat_main;
18755
18756   print (vam->ofp, "%-16s %d",
18757          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18758 }
18759
18760 static void vl_api_af_packet_details_t_handler_json
18761   (vl_api_af_packet_details_t * mp)
18762 {
18763   vat_main_t *vam = &vat_main;
18764   vat_json_node_t *node = NULL;
18765
18766   if (VAT_JSON_ARRAY != vam->json_tree.type)
18767     {
18768       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18769       vat_json_init_array (&vam->json_tree);
18770     }
18771   node = vat_json_array_add (&vam->json_tree);
18772
18773   vat_json_init_object (node);
18774   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18775   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18776 }
18777
18778 static int
18779 api_af_packet_dump (vat_main_t * vam)
18780 {
18781   vl_api_af_packet_dump_t *mp;
18782   vl_api_control_ping_t *mp_ping;
18783   int ret;
18784
18785   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18786   /* Get list of tap interfaces */
18787   M (AF_PACKET_DUMP, mp);
18788   S (mp);
18789
18790   /* Use a control ping for synchronization */
18791   MPING (CONTROL_PING, mp_ping);
18792   S (mp_ping);
18793
18794   W (ret);
18795   return ret;
18796 }
18797
18798 static int
18799 api_policer_add_del (vat_main_t * vam)
18800 {
18801   unformat_input_t *i = vam->input;
18802   vl_api_policer_add_del_t *mp;
18803   u8 is_add = 1;
18804   u8 *name = 0;
18805   u32 cir = 0;
18806   u32 eir = 0;
18807   u64 cb = 0;
18808   u64 eb = 0;
18809   u8 rate_type = 0;
18810   u8 round_type = 0;
18811   u8 type = 0;
18812   u8 color_aware = 0;
18813   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18814   int ret;
18815
18816   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18817   conform_action.dscp = 0;
18818   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18819   exceed_action.dscp = 0;
18820   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18821   violate_action.dscp = 0;
18822
18823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18824     {
18825       if (unformat (i, "del"))
18826         is_add = 0;
18827       else if (unformat (i, "name %s", &name))
18828         vec_add1 (name, 0);
18829       else if (unformat (i, "cir %u", &cir))
18830         ;
18831       else if (unformat (i, "eir %u", &eir))
18832         ;
18833       else if (unformat (i, "cb %u", &cb))
18834         ;
18835       else if (unformat (i, "eb %u", &eb))
18836         ;
18837       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18838                          &rate_type))
18839         ;
18840       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18841                          &round_type))
18842         ;
18843       else if (unformat (i, "type %U", unformat_policer_type, &type))
18844         ;
18845       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18846                          &conform_action))
18847         ;
18848       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18849                          &exceed_action))
18850         ;
18851       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18852                          &violate_action))
18853         ;
18854       else if (unformat (i, "color-aware"))
18855         color_aware = 1;
18856       else
18857         break;
18858     }
18859
18860   if (!vec_len (name))
18861     {
18862       errmsg ("policer name must be specified");
18863       return -99;
18864     }
18865
18866   if (vec_len (name) > 64)
18867     {
18868       errmsg ("policer name too long");
18869       return -99;
18870     }
18871
18872   M (POLICER_ADD_DEL, mp);
18873
18874   clib_memcpy (mp->name, name, vec_len (name));
18875   vec_free (name);
18876   mp->is_add = is_add;
18877   mp->cir = ntohl (cir);
18878   mp->eir = ntohl (eir);
18879   mp->cb = clib_net_to_host_u64 (cb);
18880   mp->eb = clib_net_to_host_u64 (eb);
18881   mp->rate_type = rate_type;
18882   mp->round_type = round_type;
18883   mp->type = type;
18884   mp->conform_action_type = conform_action.action_type;
18885   mp->conform_dscp = conform_action.dscp;
18886   mp->exceed_action_type = exceed_action.action_type;
18887   mp->exceed_dscp = exceed_action.dscp;
18888   mp->violate_action_type = violate_action.action_type;
18889   mp->violate_dscp = violate_action.dscp;
18890   mp->color_aware = color_aware;
18891
18892   S (mp);
18893   W (ret);
18894   return ret;
18895 }
18896
18897 static int
18898 api_policer_dump (vat_main_t * vam)
18899 {
18900   unformat_input_t *i = vam->input;
18901   vl_api_policer_dump_t *mp;
18902   vl_api_control_ping_t *mp_ping;
18903   u8 *match_name = 0;
18904   u8 match_name_valid = 0;
18905   int ret;
18906
18907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18908     {
18909       if (unformat (i, "name %s", &match_name))
18910         {
18911           vec_add1 (match_name, 0);
18912           match_name_valid = 1;
18913         }
18914       else
18915         break;
18916     }
18917
18918   M (POLICER_DUMP, mp);
18919   mp->match_name_valid = match_name_valid;
18920   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18921   vec_free (match_name);
18922   /* send it... */
18923   S (mp);
18924
18925   /* Use a control ping for synchronization */
18926   MPING (CONTROL_PING, mp_ping);
18927   S (mp_ping);
18928
18929   /* Wait for a reply... */
18930   W (ret);
18931   return ret;
18932 }
18933
18934 static int
18935 api_policer_classify_set_interface (vat_main_t * vam)
18936 {
18937   unformat_input_t *i = vam->input;
18938   vl_api_policer_classify_set_interface_t *mp;
18939   u32 sw_if_index;
18940   int sw_if_index_set;
18941   u32 ip4_table_index = ~0;
18942   u32 ip6_table_index = ~0;
18943   u32 l2_table_index = ~0;
18944   u8 is_add = 1;
18945   int ret;
18946
18947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18948     {
18949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18950         sw_if_index_set = 1;
18951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18952         sw_if_index_set = 1;
18953       else if (unformat (i, "del"))
18954         is_add = 0;
18955       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18956         ;
18957       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18958         ;
18959       else if (unformat (i, "l2-table %d", &l2_table_index))
18960         ;
18961       else
18962         {
18963           clib_warning ("parse error '%U'", format_unformat_error, i);
18964           return -99;
18965         }
18966     }
18967
18968   if (sw_if_index_set == 0)
18969     {
18970       errmsg ("missing interface name or sw_if_index");
18971       return -99;
18972     }
18973
18974   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18975
18976   mp->sw_if_index = ntohl (sw_if_index);
18977   mp->ip4_table_index = ntohl (ip4_table_index);
18978   mp->ip6_table_index = ntohl (ip6_table_index);
18979   mp->l2_table_index = ntohl (l2_table_index);
18980   mp->is_add = is_add;
18981
18982   S (mp);
18983   W (ret);
18984   return ret;
18985 }
18986
18987 static int
18988 api_policer_classify_dump (vat_main_t * vam)
18989 {
18990   unformat_input_t *i = vam->input;
18991   vl_api_policer_classify_dump_t *mp;
18992   vl_api_control_ping_t *mp_ping;
18993   u8 type = POLICER_CLASSIFY_N_TABLES;
18994   int ret;
18995
18996   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18997     ;
18998   else
18999     {
19000       errmsg ("classify table type must be specified");
19001       return -99;
19002     }
19003
19004   if (!vam->json_output)
19005     {
19006       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19007     }
19008
19009   M (POLICER_CLASSIFY_DUMP, mp);
19010   mp->type = type;
19011   /* send it... */
19012   S (mp);
19013
19014   /* Use a control ping for synchronization */
19015   MPING (CONTROL_PING, mp_ping);
19016   S (mp_ping);
19017
19018   /* Wait for a reply... */
19019   W (ret);
19020   return ret;
19021 }
19022
19023 static int
19024 api_netmap_create (vat_main_t * vam)
19025 {
19026   unformat_input_t *i = vam->input;
19027   vl_api_netmap_create_t *mp;
19028   u8 *if_name = 0;
19029   u8 hw_addr[6];
19030   u8 random_hw_addr = 1;
19031   u8 is_pipe = 0;
19032   u8 is_master = 0;
19033   int ret;
19034
19035   clib_memset (hw_addr, 0, sizeof (hw_addr));
19036
19037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19038     {
19039       if (unformat (i, "name %s", &if_name))
19040         vec_add1 (if_name, 0);
19041       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19042         random_hw_addr = 0;
19043       else if (unformat (i, "pipe"))
19044         is_pipe = 1;
19045       else if (unformat (i, "master"))
19046         is_master = 1;
19047       else if (unformat (i, "slave"))
19048         is_master = 0;
19049       else
19050         break;
19051     }
19052
19053   if (!vec_len (if_name))
19054     {
19055       errmsg ("interface name must be specified");
19056       return -99;
19057     }
19058
19059   if (vec_len (if_name) > 64)
19060     {
19061       errmsg ("interface name too long");
19062       return -99;
19063     }
19064
19065   M (NETMAP_CREATE, mp);
19066
19067   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19068   clib_memcpy (mp->hw_addr, hw_addr, 6);
19069   mp->use_random_hw_addr = random_hw_addr;
19070   mp->is_pipe = is_pipe;
19071   mp->is_master = is_master;
19072   vec_free (if_name);
19073
19074   S (mp);
19075   W (ret);
19076   return ret;
19077 }
19078
19079 static int
19080 api_netmap_delete (vat_main_t * vam)
19081 {
19082   unformat_input_t *i = vam->input;
19083   vl_api_netmap_delete_t *mp;
19084   u8 *if_name = 0;
19085   int ret;
19086
19087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19088     {
19089       if (unformat (i, "name %s", &if_name))
19090         vec_add1 (if_name, 0);
19091       else
19092         break;
19093     }
19094
19095   if (!vec_len (if_name))
19096     {
19097       errmsg ("interface name must be specified");
19098       return -99;
19099     }
19100
19101   if (vec_len (if_name) > 64)
19102     {
19103       errmsg ("interface name too long");
19104       return -99;
19105     }
19106
19107   M (NETMAP_DELETE, mp);
19108
19109   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19110   vec_free (if_name);
19111
19112   S (mp);
19113   W (ret);
19114   return ret;
19115 }
19116
19117 static void
19118 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19119 {
19120   if (fp->afi == IP46_TYPE_IP6)
19121     print (vam->ofp,
19122            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19123            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19124            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19125            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19126            format_ip6_address, fp->next_hop);
19127   else if (fp->afi == IP46_TYPE_IP4)
19128     print (vam->ofp,
19129            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19130            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19131            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19132            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19133            format_ip4_address, fp->next_hop);
19134 }
19135
19136 static void
19137 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19138                                  vl_api_fib_path_t * fp)
19139 {
19140   struct in_addr ip4;
19141   struct in6_addr ip6;
19142
19143   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19144   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19145   vat_json_object_add_uint (node, "is_local", fp->is_local);
19146   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19147   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19148   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19149   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19150   if (fp->afi == IP46_TYPE_IP4)
19151     {
19152       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19153       vat_json_object_add_ip4 (node, "next_hop", ip4);
19154     }
19155   else if (fp->afi == IP46_TYPE_IP6)
19156     {
19157       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19158       vat_json_object_add_ip6 (node, "next_hop", ip6);
19159     }
19160 }
19161
19162 static void
19163 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19164 {
19165   vat_main_t *vam = &vat_main;
19166   int count = ntohl (mp->mt_count);
19167   vl_api_fib_path_t *fp;
19168   i32 i;
19169
19170   print (vam->ofp, "[%d]: sw_if_index %d via:",
19171          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19172   fp = mp->mt_paths;
19173   for (i = 0; i < count; i++)
19174     {
19175       vl_api_mpls_fib_path_print (vam, fp);
19176       fp++;
19177     }
19178
19179   print (vam->ofp, "");
19180 }
19181
19182 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19183 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19184
19185 static void
19186 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19187 {
19188   vat_main_t *vam = &vat_main;
19189   vat_json_node_t *node = NULL;
19190   int count = ntohl (mp->mt_count);
19191   vl_api_fib_path_t *fp;
19192   i32 i;
19193
19194   if (VAT_JSON_ARRAY != vam->json_tree.type)
19195     {
19196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19197       vat_json_init_array (&vam->json_tree);
19198     }
19199   node = vat_json_array_add (&vam->json_tree);
19200
19201   vat_json_init_object (node);
19202   vat_json_object_add_uint (node, "tunnel_index",
19203                             ntohl (mp->mt_tunnel_index));
19204   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19205
19206   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19207
19208   fp = mp->mt_paths;
19209   for (i = 0; i < count; i++)
19210     {
19211       vl_api_mpls_fib_path_json_print (node, fp);
19212       fp++;
19213     }
19214 }
19215
19216 static int
19217 api_mpls_tunnel_dump (vat_main_t * vam)
19218 {
19219   vl_api_mpls_tunnel_dump_t *mp;
19220   vl_api_control_ping_t *mp_ping;
19221   u32 sw_if_index = ~0;
19222   int ret;
19223
19224   /* Parse args required to build the message */
19225   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19226     {
19227       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19228         ;
19229     }
19230
19231   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19232
19233   M (MPLS_TUNNEL_DUMP, mp);
19234   mp->sw_if_index = htonl (sw_if_index);
19235   S (mp);
19236
19237   /* Use a control ping for synchronization */
19238   MPING (CONTROL_PING, mp_ping);
19239   S (mp_ping);
19240
19241   W (ret);
19242   return ret;
19243 }
19244
19245 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19246 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19247
19248
19249 static void
19250 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19251 {
19252   vat_main_t *vam = &vat_main;
19253   int count = ntohl (mp->count);
19254   vl_api_fib_path_t *fp;
19255   int i;
19256
19257   print (vam->ofp,
19258          "table-id %d, label %u, ess_bit %u",
19259          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19260   fp = mp->path;
19261   for (i = 0; i < count; i++)
19262     {
19263       vl_api_mpls_fib_path_print (vam, fp);
19264       fp++;
19265     }
19266 }
19267
19268 static void vl_api_mpls_fib_details_t_handler_json
19269   (vl_api_mpls_fib_details_t * mp)
19270 {
19271   vat_main_t *vam = &vat_main;
19272   int count = ntohl (mp->count);
19273   vat_json_node_t *node = NULL;
19274   vl_api_fib_path_t *fp;
19275   int i;
19276
19277   if (VAT_JSON_ARRAY != vam->json_tree.type)
19278     {
19279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19280       vat_json_init_array (&vam->json_tree);
19281     }
19282   node = vat_json_array_add (&vam->json_tree);
19283
19284   vat_json_init_object (node);
19285   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19286   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19287   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19288   vat_json_object_add_uint (node, "path_count", count);
19289   fp = mp->path;
19290   for (i = 0; i < count; i++)
19291     {
19292       vl_api_mpls_fib_path_json_print (node, fp);
19293       fp++;
19294     }
19295 }
19296
19297 static int
19298 api_mpls_fib_dump (vat_main_t * vam)
19299 {
19300   vl_api_mpls_fib_dump_t *mp;
19301   vl_api_control_ping_t *mp_ping;
19302   int ret;
19303
19304   M (MPLS_FIB_DUMP, mp);
19305   S (mp);
19306
19307   /* Use a control ping for synchronization */
19308   MPING (CONTROL_PING, mp_ping);
19309   S (mp_ping);
19310
19311   W (ret);
19312   return ret;
19313 }
19314
19315 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19316 #define vl_api_ip_fib_details_t_print vl_noop_handler
19317
19318 static void
19319 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19320 {
19321   vat_main_t *vam = &vat_main;
19322   int count = ntohl (mp->count);
19323   vl_api_fib_path_t *fp;
19324   int i;
19325
19326   print (vam->ofp,
19327          "table-id %d, prefix %U/%d stats-index %d",
19328          ntohl (mp->table_id), format_ip4_address, mp->address,
19329          mp->address_length, ntohl (mp->stats_index));
19330   fp = mp->path;
19331   for (i = 0; i < count; i++)
19332     {
19333       if (fp->afi == IP46_TYPE_IP6)
19334         print (vam->ofp,
19335                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19336                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19337                "next_hop_table %d",
19338                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19339                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19340                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19341       else if (fp->afi == IP46_TYPE_IP4)
19342         print (vam->ofp,
19343                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19344                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19345                "next_hop_table %d",
19346                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19347                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19348                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19349       fp++;
19350     }
19351 }
19352
19353 static void vl_api_ip_fib_details_t_handler_json
19354   (vl_api_ip_fib_details_t * mp)
19355 {
19356   vat_main_t *vam = &vat_main;
19357   int count = ntohl (mp->count);
19358   vat_json_node_t *node = NULL;
19359   struct in_addr ip4;
19360   struct in6_addr ip6;
19361   vl_api_fib_path_t *fp;
19362   int i;
19363
19364   if (VAT_JSON_ARRAY != vam->json_tree.type)
19365     {
19366       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19367       vat_json_init_array (&vam->json_tree);
19368     }
19369   node = vat_json_array_add (&vam->json_tree);
19370
19371   vat_json_init_object (node);
19372   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19373   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19374   vat_json_object_add_ip4 (node, "prefix", ip4);
19375   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19376   vat_json_object_add_uint (node, "path_count", count);
19377   fp = mp->path;
19378   for (i = 0; i < count; i++)
19379     {
19380       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19381       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19382       vat_json_object_add_uint (node, "is_local", fp->is_local);
19383       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19384       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19385       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19386       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19387       if (fp->afi == IP46_TYPE_IP4)
19388         {
19389           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19390           vat_json_object_add_ip4 (node, "next_hop", ip4);
19391         }
19392       else if (fp->afi == IP46_TYPE_IP6)
19393         {
19394           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19395           vat_json_object_add_ip6 (node, "next_hop", ip6);
19396         }
19397     }
19398 }
19399
19400 static int
19401 api_ip_fib_dump (vat_main_t * vam)
19402 {
19403   vl_api_ip_fib_dump_t *mp;
19404   vl_api_control_ping_t *mp_ping;
19405   int ret;
19406
19407   M (IP_FIB_DUMP, mp);
19408   S (mp);
19409
19410   /* Use a control ping for synchronization */
19411   MPING (CONTROL_PING, mp_ping);
19412   S (mp_ping);
19413
19414   W (ret);
19415   return ret;
19416 }
19417
19418 static int
19419 api_ip_mfib_dump (vat_main_t * vam)
19420 {
19421   vl_api_ip_mfib_dump_t *mp;
19422   vl_api_control_ping_t *mp_ping;
19423   int ret;
19424
19425   M (IP_MFIB_DUMP, mp);
19426   S (mp);
19427
19428   /* Use a control ping for synchronization */
19429   MPING (CONTROL_PING, mp_ping);
19430   S (mp_ping);
19431
19432   W (ret);
19433   return ret;
19434 }
19435
19436 static void vl_api_ip_neighbor_details_t_handler
19437   (vl_api_ip_neighbor_details_t * mp)
19438 {
19439   vat_main_t *vam = &vat_main;
19440
19441   print (vam->ofp, "%c %U %U",
19442          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19443          format_vl_api_mac_address, &mp->neighbor.mac_address,
19444          format_vl_api_address, &mp->neighbor.ip_address);
19445 }
19446
19447 static void vl_api_ip_neighbor_details_t_handler_json
19448   (vl_api_ip_neighbor_details_t * mp)
19449 {
19450
19451   vat_main_t *vam = &vat_main;
19452   vat_json_node_t *node;
19453
19454   if (VAT_JSON_ARRAY != vam->json_tree.type)
19455     {
19456       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19457       vat_json_init_array (&vam->json_tree);
19458     }
19459   node = vat_json_array_add (&vam->json_tree);
19460
19461   vat_json_init_object (node);
19462   vat_json_object_add_string_copy
19463     (node, "flag",
19464      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19465       (u8 *) "static" : (u8 *) "dynamic"));
19466
19467   vat_json_object_add_string_copy (node, "link_layer",
19468                                    format (0, "%U", format_vl_api_mac_address,
19469                                            &mp->neighbor.mac_address));
19470   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19471 }
19472
19473 static int
19474 api_ip_neighbor_dump (vat_main_t * vam)
19475 {
19476   unformat_input_t *i = vam->input;
19477   vl_api_ip_neighbor_dump_t *mp;
19478   vl_api_control_ping_t *mp_ping;
19479   u8 is_ipv6 = 0;
19480   u32 sw_if_index = ~0;
19481   int ret;
19482
19483   /* Parse args required to build the message */
19484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19485     {
19486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19487         ;
19488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19489         ;
19490       else if (unformat (i, "ip6"))
19491         is_ipv6 = 1;
19492       else
19493         break;
19494     }
19495
19496   if (sw_if_index == ~0)
19497     {
19498       errmsg ("missing interface name or sw_if_index");
19499       return -99;
19500     }
19501
19502   M (IP_NEIGHBOR_DUMP, mp);
19503   mp->is_ipv6 = (u8) is_ipv6;
19504   mp->sw_if_index = ntohl (sw_if_index);
19505   S (mp);
19506
19507   /* Use a control ping for synchronization */
19508   MPING (CONTROL_PING, mp_ping);
19509   S (mp_ping);
19510
19511   W (ret);
19512   return ret;
19513 }
19514
19515 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19516 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19517
19518 static void
19519 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19520 {
19521   vat_main_t *vam = &vat_main;
19522   int count = ntohl (mp->count);
19523   vl_api_fib_path_t *fp;
19524   int i;
19525
19526   print (vam->ofp,
19527          "table-id %d, prefix %U/%d stats-index %d",
19528          ntohl (mp->table_id), format_ip6_address, mp->address,
19529          mp->address_length, ntohl (mp->stats_index));
19530   fp = mp->path;
19531   for (i = 0; i < count; i++)
19532     {
19533       if (fp->afi == IP46_TYPE_IP6)
19534         print (vam->ofp,
19535                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19536                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19537                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19538                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19539                format_ip6_address, fp->next_hop);
19540       else if (fp->afi == IP46_TYPE_IP4)
19541         print (vam->ofp,
19542                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19543                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19544                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19545                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19546                format_ip4_address, fp->next_hop);
19547       fp++;
19548     }
19549 }
19550
19551 static void vl_api_ip6_fib_details_t_handler_json
19552   (vl_api_ip6_fib_details_t * mp)
19553 {
19554   vat_main_t *vam = &vat_main;
19555   int count = ntohl (mp->count);
19556   vat_json_node_t *node = NULL;
19557   struct in_addr ip4;
19558   struct in6_addr ip6;
19559   vl_api_fib_path_t *fp;
19560   int i;
19561
19562   if (VAT_JSON_ARRAY != vam->json_tree.type)
19563     {
19564       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19565       vat_json_init_array (&vam->json_tree);
19566     }
19567   node = vat_json_array_add (&vam->json_tree);
19568
19569   vat_json_init_object (node);
19570   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19571   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19572   vat_json_object_add_ip6 (node, "prefix", ip6);
19573   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19574   vat_json_object_add_uint (node, "path_count", count);
19575   fp = mp->path;
19576   for (i = 0; i < count; i++)
19577     {
19578       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19579       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19580       vat_json_object_add_uint (node, "is_local", fp->is_local);
19581       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19582       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19583       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19584       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19585       if (fp->afi == IP46_TYPE_IP4)
19586         {
19587           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19588           vat_json_object_add_ip4 (node, "next_hop", ip4);
19589         }
19590       else if (fp->afi == IP46_TYPE_IP6)
19591         {
19592           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19593           vat_json_object_add_ip6 (node, "next_hop", ip6);
19594         }
19595     }
19596 }
19597
19598 static int
19599 api_ip6_fib_dump (vat_main_t * vam)
19600 {
19601   vl_api_ip6_fib_dump_t *mp;
19602   vl_api_control_ping_t *mp_ping;
19603   int ret;
19604
19605   M (IP6_FIB_DUMP, mp);
19606   S (mp);
19607
19608   /* Use a control ping for synchronization */
19609   MPING (CONTROL_PING, mp_ping);
19610   S (mp_ping);
19611
19612   W (ret);
19613   return ret;
19614 }
19615
19616 static int
19617 api_ip6_mfib_dump (vat_main_t * vam)
19618 {
19619   vl_api_ip6_mfib_dump_t *mp;
19620   vl_api_control_ping_t *mp_ping;
19621   int ret;
19622
19623   M (IP6_MFIB_DUMP, mp);
19624   S (mp);
19625
19626   /* Use a control ping for synchronization */
19627   MPING (CONTROL_PING, mp_ping);
19628   S (mp_ping);
19629
19630   W (ret);
19631   return ret;
19632 }
19633
19634 int
19635 api_classify_table_ids (vat_main_t * vam)
19636 {
19637   vl_api_classify_table_ids_t *mp;
19638   int ret;
19639
19640   /* Construct the API message */
19641   M (CLASSIFY_TABLE_IDS, mp);
19642   mp->context = 0;
19643
19644   S (mp);
19645   W (ret);
19646   return ret;
19647 }
19648
19649 int
19650 api_classify_table_by_interface (vat_main_t * vam)
19651 {
19652   unformat_input_t *input = vam->input;
19653   vl_api_classify_table_by_interface_t *mp;
19654
19655   u32 sw_if_index = ~0;
19656   int ret;
19657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19658     {
19659       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19660         ;
19661       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19662         ;
19663       else
19664         break;
19665     }
19666   if (sw_if_index == ~0)
19667     {
19668       errmsg ("missing interface name or sw_if_index");
19669       return -99;
19670     }
19671
19672   /* Construct the API message */
19673   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19674   mp->context = 0;
19675   mp->sw_if_index = ntohl (sw_if_index);
19676
19677   S (mp);
19678   W (ret);
19679   return ret;
19680 }
19681
19682 int
19683 api_classify_table_info (vat_main_t * vam)
19684 {
19685   unformat_input_t *input = vam->input;
19686   vl_api_classify_table_info_t *mp;
19687
19688   u32 table_id = ~0;
19689   int ret;
19690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19691     {
19692       if (unformat (input, "table_id %d", &table_id))
19693         ;
19694       else
19695         break;
19696     }
19697   if (table_id == ~0)
19698     {
19699       errmsg ("missing table id");
19700       return -99;
19701     }
19702
19703   /* Construct the API message */
19704   M (CLASSIFY_TABLE_INFO, mp);
19705   mp->context = 0;
19706   mp->table_id = ntohl (table_id);
19707
19708   S (mp);
19709   W (ret);
19710   return ret;
19711 }
19712
19713 int
19714 api_classify_session_dump (vat_main_t * vam)
19715 {
19716   unformat_input_t *input = vam->input;
19717   vl_api_classify_session_dump_t *mp;
19718   vl_api_control_ping_t *mp_ping;
19719
19720   u32 table_id = ~0;
19721   int ret;
19722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19723     {
19724       if (unformat (input, "table_id %d", &table_id))
19725         ;
19726       else
19727         break;
19728     }
19729   if (table_id == ~0)
19730     {
19731       errmsg ("missing table id");
19732       return -99;
19733     }
19734
19735   /* Construct the API message */
19736   M (CLASSIFY_SESSION_DUMP, mp);
19737   mp->context = 0;
19738   mp->table_id = ntohl (table_id);
19739   S (mp);
19740
19741   /* Use a control ping for synchronization */
19742   MPING (CONTROL_PING, mp_ping);
19743   S (mp_ping);
19744
19745   W (ret);
19746   return ret;
19747 }
19748
19749 static void
19750 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19751 {
19752   vat_main_t *vam = &vat_main;
19753
19754   print (vam->ofp, "collector_address %U, collector_port %d, "
19755          "src_address %U, vrf_id %d, path_mtu %u, "
19756          "template_interval %u, udp_checksum %d",
19757          format_ip4_address, mp->collector_address,
19758          ntohs (mp->collector_port),
19759          format_ip4_address, mp->src_address,
19760          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19761          ntohl (mp->template_interval), mp->udp_checksum);
19762
19763   vam->retval = 0;
19764   vam->result_ready = 1;
19765 }
19766
19767 static void
19768   vl_api_ipfix_exporter_details_t_handler_json
19769   (vl_api_ipfix_exporter_details_t * mp)
19770 {
19771   vat_main_t *vam = &vat_main;
19772   vat_json_node_t node;
19773   struct in_addr collector_address;
19774   struct in_addr src_address;
19775
19776   vat_json_init_object (&node);
19777   clib_memcpy (&collector_address, &mp->collector_address,
19778                sizeof (collector_address));
19779   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19780   vat_json_object_add_uint (&node, "collector_port",
19781                             ntohs (mp->collector_port));
19782   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19783   vat_json_object_add_ip4 (&node, "src_address", src_address);
19784   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19785   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19786   vat_json_object_add_uint (&node, "template_interval",
19787                             ntohl (mp->template_interval));
19788   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19789
19790   vat_json_print (vam->ofp, &node);
19791   vat_json_free (&node);
19792   vam->retval = 0;
19793   vam->result_ready = 1;
19794 }
19795
19796 int
19797 api_ipfix_exporter_dump (vat_main_t * vam)
19798 {
19799   vl_api_ipfix_exporter_dump_t *mp;
19800   int ret;
19801
19802   /* Construct the API message */
19803   M (IPFIX_EXPORTER_DUMP, mp);
19804   mp->context = 0;
19805
19806   S (mp);
19807   W (ret);
19808   return ret;
19809 }
19810
19811 static int
19812 api_ipfix_classify_stream_dump (vat_main_t * vam)
19813 {
19814   vl_api_ipfix_classify_stream_dump_t *mp;
19815   int ret;
19816
19817   /* Construct the API message */
19818   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19819   mp->context = 0;
19820
19821   S (mp);
19822   W (ret);
19823   return ret;
19824   /* NOTREACHED */
19825   return 0;
19826 }
19827
19828 static void
19829   vl_api_ipfix_classify_stream_details_t_handler
19830   (vl_api_ipfix_classify_stream_details_t * mp)
19831 {
19832   vat_main_t *vam = &vat_main;
19833   print (vam->ofp, "domain_id %d, src_port %d",
19834          ntohl (mp->domain_id), ntohs (mp->src_port));
19835   vam->retval = 0;
19836   vam->result_ready = 1;
19837 }
19838
19839 static void
19840   vl_api_ipfix_classify_stream_details_t_handler_json
19841   (vl_api_ipfix_classify_stream_details_t * mp)
19842 {
19843   vat_main_t *vam = &vat_main;
19844   vat_json_node_t node;
19845
19846   vat_json_init_object (&node);
19847   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19848   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19849
19850   vat_json_print (vam->ofp, &node);
19851   vat_json_free (&node);
19852   vam->retval = 0;
19853   vam->result_ready = 1;
19854 }
19855
19856 static int
19857 api_ipfix_classify_table_dump (vat_main_t * vam)
19858 {
19859   vl_api_ipfix_classify_table_dump_t *mp;
19860   vl_api_control_ping_t *mp_ping;
19861   int ret;
19862
19863   if (!vam->json_output)
19864     {
19865       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19866              "transport_protocol");
19867     }
19868
19869   /* Construct the API message */
19870   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19871
19872   /* send it... */
19873   S (mp);
19874
19875   /* Use a control ping for synchronization */
19876   MPING (CONTROL_PING, mp_ping);
19877   S (mp_ping);
19878
19879   W (ret);
19880   return ret;
19881 }
19882
19883 static void
19884   vl_api_ipfix_classify_table_details_t_handler
19885   (vl_api_ipfix_classify_table_details_t * mp)
19886 {
19887   vat_main_t *vam = &vat_main;
19888   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19889          mp->transport_protocol);
19890 }
19891
19892 static void
19893   vl_api_ipfix_classify_table_details_t_handler_json
19894   (vl_api_ipfix_classify_table_details_t * mp)
19895 {
19896   vat_json_node_t *node = NULL;
19897   vat_main_t *vam = &vat_main;
19898
19899   if (VAT_JSON_ARRAY != vam->json_tree.type)
19900     {
19901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19902       vat_json_init_array (&vam->json_tree);
19903     }
19904
19905   node = vat_json_array_add (&vam->json_tree);
19906   vat_json_init_object (node);
19907
19908   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19909   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19910   vat_json_object_add_uint (node, "transport_protocol",
19911                             mp->transport_protocol);
19912 }
19913
19914 static int
19915 api_sw_interface_span_enable_disable (vat_main_t * vam)
19916 {
19917   unformat_input_t *i = vam->input;
19918   vl_api_sw_interface_span_enable_disable_t *mp;
19919   u32 src_sw_if_index = ~0;
19920   u32 dst_sw_if_index = ~0;
19921   u8 state = 3;
19922   int ret;
19923   u8 is_l2 = 0;
19924
19925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19926     {
19927       if (unformat
19928           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19929         ;
19930       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19931         ;
19932       else
19933         if (unformat
19934             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19935         ;
19936       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19937         ;
19938       else if (unformat (i, "disable"))
19939         state = 0;
19940       else if (unformat (i, "rx"))
19941         state = 1;
19942       else if (unformat (i, "tx"))
19943         state = 2;
19944       else if (unformat (i, "both"))
19945         state = 3;
19946       else if (unformat (i, "l2"))
19947         is_l2 = 1;
19948       else
19949         break;
19950     }
19951
19952   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19953
19954   mp->sw_if_index_from = htonl (src_sw_if_index);
19955   mp->sw_if_index_to = htonl (dst_sw_if_index);
19956   mp->state = state;
19957   mp->is_l2 = is_l2;
19958
19959   S (mp);
19960   W (ret);
19961   return ret;
19962 }
19963
19964 static void
19965 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19966                                             * mp)
19967 {
19968   vat_main_t *vam = &vat_main;
19969   u8 *sw_if_from_name = 0;
19970   u8 *sw_if_to_name = 0;
19971   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19972   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19973   char *states[] = { "none", "rx", "tx", "both" };
19974   hash_pair_t *p;
19975
19976   /* *INDENT-OFF* */
19977   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19978   ({
19979     if ((u32) p->value[0] == sw_if_index_from)
19980       {
19981         sw_if_from_name = (u8 *)(p->key);
19982         if (sw_if_to_name)
19983           break;
19984       }
19985     if ((u32) p->value[0] == sw_if_index_to)
19986       {
19987         sw_if_to_name = (u8 *)(p->key);
19988         if (sw_if_from_name)
19989           break;
19990       }
19991   }));
19992   /* *INDENT-ON* */
19993   print (vam->ofp, "%20s => %20s (%s) %s",
19994          sw_if_from_name, sw_if_to_name, states[mp->state],
19995          mp->is_l2 ? "l2" : "device");
19996 }
19997
19998 static void
19999   vl_api_sw_interface_span_details_t_handler_json
20000   (vl_api_sw_interface_span_details_t * mp)
20001 {
20002   vat_main_t *vam = &vat_main;
20003   vat_json_node_t *node = NULL;
20004   u8 *sw_if_from_name = 0;
20005   u8 *sw_if_to_name = 0;
20006   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20007   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20008   hash_pair_t *p;
20009
20010   /* *INDENT-OFF* */
20011   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20012   ({
20013     if ((u32) p->value[0] == sw_if_index_from)
20014       {
20015         sw_if_from_name = (u8 *)(p->key);
20016         if (sw_if_to_name)
20017           break;
20018       }
20019     if ((u32) p->value[0] == sw_if_index_to)
20020       {
20021         sw_if_to_name = (u8 *)(p->key);
20022         if (sw_if_from_name)
20023           break;
20024       }
20025   }));
20026   /* *INDENT-ON* */
20027
20028   if (VAT_JSON_ARRAY != vam->json_tree.type)
20029     {
20030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20031       vat_json_init_array (&vam->json_tree);
20032     }
20033   node = vat_json_array_add (&vam->json_tree);
20034
20035   vat_json_init_object (node);
20036   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20037   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20038   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20039   if (0 != sw_if_to_name)
20040     {
20041       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20042     }
20043   vat_json_object_add_uint (node, "state", mp->state);
20044   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20045 }
20046
20047 static int
20048 api_sw_interface_span_dump (vat_main_t * vam)
20049 {
20050   unformat_input_t *input = vam->input;
20051   vl_api_sw_interface_span_dump_t *mp;
20052   vl_api_control_ping_t *mp_ping;
20053   u8 is_l2 = 0;
20054   int ret;
20055
20056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20057     {
20058       if (unformat (input, "l2"))
20059         is_l2 = 1;
20060       else
20061         break;
20062     }
20063
20064   M (SW_INTERFACE_SPAN_DUMP, mp);
20065   mp->is_l2 = is_l2;
20066   S (mp);
20067
20068   /* Use a control ping for synchronization */
20069   MPING (CONTROL_PING, mp_ping);
20070   S (mp_ping);
20071
20072   W (ret);
20073   return ret;
20074 }
20075
20076 int
20077 api_pg_create_interface (vat_main_t * vam)
20078 {
20079   unformat_input_t *input = vam->input;
20080   vl_api_pg_create_interface_t *mp;
20081
20082   u32 if_id = ~0;
20083   int ret;
20084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20085     {
20086       if (unformat (input, "if_id %d", &if_id))
20087         ;
20088       else
20089         break;
20090     }
20091   if (if_id == ~0)
20092     {
20093       errmsg ("missing pg interface index");
20094       return -99;
20095     }
20096
20097   /* Construct the API message */
20098   M (PG_CREATE_INTERFACE, mp);
20099   mp->context = 0;
20100   mp->interface_id = ntohl (if_id);
20101
20102   S (mp);
20103   W (ret);
20104   return ret;
20105 }
20106
20107 int
20108 api_pg_capture (vat_main_t * vam)
20109 {
20110   unformat_input_t *input = vam->input;
20111   vl_api_pg_capture_t *mp;
20112
20113   u32 if_id = ~0;
20114   u8 enable = 1;
20115   u32 count = 1;
20116   u8 pcap_file_set = 0;
20117   u8 *pcap_file = 0;
20118   int ret;
20119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20120     {
20121       if (unformat (input, "if_id %d", &if_id))
20122         ;
20123       else if (unformat (input, "pcap %s", &pcap_file))
20124         pcap_file_set = 1;
20125       else if (unformat (input, "count %d", &count))
20126         ;
20127       else if (unformat (input, "disable"))
20128         enable = 0;
20129       else
20130         break;
20131     }
20132   if (if_id == ~0)
20133     {
20134       errmsg ("missing pg interface index");
20135       return -99;
20136     }
20137   if (pcap_file_set > 0)
20138     {
20139       if (vec_len (pcap_file) > 255)
20140         {
20141           errmsg ("pcap file name is too long");
20142           return -99;
20143         }
20144     }
20145
20146   u32 name_len = vec_len (pcap_file);
20147   /* Construct the API message */
20148   M (PG_CAPTURE, mp);
20149   mp->context = 0;
20150   mp->interface_id = ntohl (if_id);
20151   mp->is_enabled = enable;
20152   mp->count = ntohl (count);
20153   mp->pcap_name_length = ntohl (name_len);
20154   if (pcap_file_set != 0)
20155     {
20156       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20157     }
20158   vec_free (pcap_file);
20159
20160   S (mp);
20161   W (ret);
20162   return ret;
20163 }
20164
20165 int
20166 api_pg_enable_disable (vat_main_t * vam)
20167 {
20168   unformat_input_t *input = vam->input;
20169   vl_api_pg_enable_disable_t *mp;
20170
20171   u8 enable = 1;
20172   u8 stream_name_set = 0;
20173   u8 *stream_name = 0;
20174   int ret;
20175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20176     {
20177       if (unformat (input, "stream %s", &stream_name))
20178         stream_name_set = 1;
20179       else if (unformat (input, "disable"))
20180         enable = 0;
20181       else
20182         break;
20183     }
20184
20185   if (stream_name_set > 0)
20186     {
20187       if (vec_len (stream_name) > 255)
20188         {
20189           errmsg ("stream name too long");
20190           return -99;
20191         }
20192     }
20193
20194   u32 name_len = vec_len (stream_name);
20195   /* Construct the API message */
20196   M (PG_ENABLE_DISABLE, mp);
20197   mp->context = 0;
20198   mp->is_enabled = enable;
20199   if (stream_name_set != 0)
20200     {
20201       mp->stream_name_length = ntohl (name_len);
20202       clib_memcpy (mp->stream_name, stream_name, name_len);
20203     }
20204   vec_free (stream_name);
20205
20206   S (mp);
20207   W (ret);
20208   return ret;
20209 }
20210
20211 int
20212 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20213 {
20214   unformat_input_t *input = vam->input;
20215   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20216
20217   u16 *low_ports = 0;
20218   u16 *high_ports = 0;
20219   u16 this_low;
20220   u16 this_hi;
20221   vl_api_prefix_t prefix;
20222   u32 tmp, tmp2;
20223   u8 prefix_set = 0;
20224   u32 vrf_id = ~0;
20225   u8 is_add = 1;
20226   u8 is_ipv6 = 0;
20227   int ret;
20228
20229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20230     {
20231       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20232         prefix_set = 1;
20233       else if (unformat (input, "vrf %d", &vrf_id))
20234         ;
20235       else if (unformat (input, "del"))
20236         is_add = 0;
20237       else if (unformat (input, "port %d", &tmp))
20238         {
20239           if (tmp == 0 || tmp > 65535)
20240             {
20241               errmsg ("port %d out of range", tmp);
20242               return -99;
20243             }
20244           this_low = tmp;
20245           this_hi = this_low + 1;
20246           vec_add1 (low_ports, this_low);
20247           vec_add1 (high_ports, this_hi);
20248         }
20249       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20250         {
20251           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20252             {
20253               errmsg ("incorrect range parameters");
20254               return -99;
20255             }
20256           this_low = tmp;
20257           /* Note: in debug CLI +1 is added to high before
20258              passing to real fn that does "the work"
20259              (ip_source_and_port_range_check_add_del).
20260              This fn is a wrapper around the binary API fn a
20261              control plane will call, which expects this increment
20262              to have occurred. Hence letting the binary API control
20263              plane fn do the increment for consistency between VAT
20264              and other control planes.
20265            */
20266           this_hi = tmp2;
20267           vec_add1 (low_ports, this_low);
20268           vec_add1 (high_ports, this_hi);
20269         }
20270       else
20271         break;
20272     }
20273
20274   if (prefix_set == 0)
20275     {
20276       errmsg ("<address>/<mask> not specified");
20277       return -99;
20278     }
20279
20280   if (vrf_id == ~0)
20281     {
20282       errmsg ("VRF ID required, not specified");
20283       return -99;
20284     }
20285
20286   if (vrf_id == 0)
20287     {
20288       errmsg
20289         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20290       return -99;
20291     }
20292
20293   if (vec_len (low_ports) == 0)
20294     {
20295       errmsg ("At least one port or port range required");
20296       return -99;
20297     }
20298
20299   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20300
20301   mp->is_add = is_add;
20302
20303   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20304
20305   mp->number_of_ranges = vec_len (low_ports);
20306
20307   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20308   vec_free (low_ports);
20309
20310   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20311   vec_free (high_ports);
20312
20313   mp->vrf_id = ntohl (vrf_id);
20314
20315   S (mp);
20316   W (ret);
20317   return ret;
20318 }
20319
20320 int
20321 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20322 {
20323   unformat_input_t *input = vam->input;
20324   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20325   u32 sw_if_index = ~0;
20326   int vrf_set = 0;
20327   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20328   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20329   u8 is_add = 1;
20330   int ret;
20331
20332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20333     {
20334       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20335         ;
20336       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20337         ;
20338       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20339         vrf_set = 1;
20340       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20341         vrf_set = 1;
20342       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20343         vrf_set = 1;
20344       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20345         vrf_set = 1;
20346       else if (unformat (input, "del"))
20347         is_add = 0;
20348       else
20349         break;
20350     }
20351
20352   if (sw_if_index == ~0)
20353     {
20354       errmsg ("Interface required but not specified");
20355       return -99;
20356     }
20357
20358   if (vrf_set == 0)
20359     {
20360       errmsg ("VRF ID required but not specified");
20361       return -99;
20362     }
20363
20364   if (tcp_out_vrf_id == 0
20365       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20366     {
20367       errmsg
20368         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20369       return -99;
20370     }
20371
20372   /* Construct the API message */
20373   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20374
20375   mp->sw_if_index = ntohl (sw_if_index);
20376   mp->is_add = is_add;
20377   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20378   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20379   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20380   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20381
20382   /* send it... */
20383   S (mp);
20384
20385   /* Wait for a reply... */
20386   W (ret);
20387   return ret;
20388 }
20389
20390 static int
20391 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20392 {
20393   unformat_input_t *i = vam->input;
20394   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20395   u32 local_sa_id = 0;
20396   u32 remote_sa_id = 0;
20397   vl_api_ip4_address_t src_address;
20398   vl_api_ip4_address_t dst_address;
20399   u8 is_add = 1;
20400   int ret;
20401
20402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20403     {
20404       if (unformat (i, "local_sa %d", &local_sa_id))
20405         ;
20406       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20407         ;
20408       else
20409         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20410         ;
20411       else
20412         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20413         ;
20414       else if (unformat (i, "del"))
20415         is_add = 0;
20416       else
20417         {
20418           clib_warning ("parse error '%U'", format_unformat_error, i);
20419           return -99;
20420         }
20421     }
20422
20423   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20424
20425   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20426   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20427   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20428   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20429   mp->is_add = is_add;
20430
20431   S (mp);
20432   W (ret);
20433   return ret;
20434 }
20435
20436 static int
20437 api_set_punt (vat_main_t * vam)
20438 {
20439   unformat_input_t *i = vam->input;
20440   vl_api_set_punt_t *mp;
20441   u32 ipv = ~0;
20442   u32 protocol = ~0;
20443   u32 port = ~0;
20444   int is_add = 1;
20445   int ret;
20446
20447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20448     {
20449       if (unformat (i, "ip %d", &ipv))
20450         ;
20451       else if (unformat (i, "protocol %d", &protocol))
20452         ;
20453       else if (unformat (i, "port %d", &port))
20454         ;
20455       else if (unformat (i, "del"))
20456         is_add = 0;
20457       else
20458         {
20459           clib_warning ("parse error '%U'", format_unformat_error, i);
20460           return -99;
20461         }
20462     }
20463
20464   M (SET_PUNT, mp);
20465
20466   mp->is_add = (u8) is_add;
20467   mp->punt.ipv = (u8) ipv;
20468   mp->punt.l4_protocol = (u8) protocol;
20469   mp->punt.l4_port = htons ((u16) port);
20470
20471   S (mp);
20472   W (ret);
20473   return ret;
20474 }
20475
20476 static void vl_api_ipsec_gre_tunnel_details_t_handler
20477   (vl_api_ipsec_gre_tunnel_details_t * mp)
20478 {
20479   vat_main_t *vam = &vat_main;
20480
20481   print (vam->ofp, "%11d%15U%15U%14d%14d",
20482          ntohl (mp->tunnel.sw_if_index),
20483          format_vl_api_ip4_address, mp->tunnel.src,
20484          format_vl_api_ip4_address, mp->tunnel.dst,
20485          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20486 }
20487
20488 static void
20489 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20490                                 const char *name,
20491                                 const vl_api_ip4_address_t addr)
20492 {
20493   struct in_addr ip4;
20494
20495   clib_memcpy (&ip4, addr, sizeof (ip4));
20496   vat_json_object_add_ip4 (node, name, ip4);
20497 }
20498
20499 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20500   (vl_api_ipsec_gre_tunnel_details_t * mp)
20501 {
20502   vat_main_t *vam = &vat_main;
20503   vat_json_node_t *node = NULL;
20504   struct in_addr ip4;
20505
20506   if (VAT_JSON_ARRAY != vam->json_tree.type)
20507     {
20508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20509       vat_json_init_array (&vam->json_tree);
20510     }
20511   node = vat_json_array_add (&vam->json_tree);
20512
20513   vat_json_init_object (node);
20514   vat_json_object_add_uint (node, "sw_if_index",
20515                             ntohl (mp->tunnel.sw_if_index));
20516   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20517   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20518   vat_json_object_add_uint (node, "local_sa_id",
20519                             ntohl (mp->tunnel.local_sa_id));
20520   vat_json_object_add_uint (node, "remote_sa_id",
20521                             ntohl (mp->tunnel.remote_sa_id));
20522 }
20523
20524 static int
20525 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20526 {
20527   unformat_input_t *i = vam->input;
20528   vl_api_ipsec_gre_tunnel_dump_t *mp;
20529   vl_api_control_ping_t *mp_ping;
20530   u32 sw_if_index;
20531   u8 sw_if_index_set = 0;
20532   int ret;
20533
20534   /* Parse args required to build the message */
20535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20536     {
20537       if (unformat (i, "sw_if_index %d", &sw_if_index))
20538         sw_if_index_set = 1;
20539       else
20540         break;
20541     }
20542
20543   if (sw_if_index_set == 0)
20544     {
20545       sw_if_index = ~0;
20546     }
20547
20548   if (!vam->json_output)
20549     {
20550       print (vam->ofp, "%11s%15s%15s%14s%14s",
20551              "sw_if_index", "src_address", "dst_address",
20552              "local_sa_id", "remote_sa_id");
20553     }
20554
20555   /* Get list of gre-tunnel interfaces */
20556   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20557
20558   mp->sw_if_index = htonl (sw_if_index);
20559
20560   S (mp);
20561
20562   /* Use a control ping for synchronization */
20563   MPING (CONTROL_PING, mp_ping);
20564   S (mp_ping);
20565
20566   W (ret);
20567   return ret;
20568 }
20569
20570 static int
20571 api_delete_subif (vat_main_t * vam)
20572 {
20573   unformat_input_t *i = vam->input;
20574   vl_api_delete_subif_t *mp;
20575   u32 sw_if_index = ~0;
20576   int ret;
20577
20578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20579     {
20580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20581         ;
20582       if (unformat (i, "sw_if_index %d", &sw_if_index))
20583         ;
20584       else
20585         break;
20586     }
20587
20588   if (sw_if_index == ~0)
20589     {
20590       errmsg ("missing sw_if_index");
20591       return -99;
20592     }
20593
20594   /* Construct the API message */
20595   M (DELETE_SUBIF, mp);
20596   mp->sw_if_index = ntohl (sw_if_index);
20597
20598   S (mp);
20599   W (ret);
20600   return ret;
20601 }
20602
20603 #define foreach_pbb_vtr_op      \
20604 _("disable",  L2_VTR_DISABLED)  \
20605 _("pop",  L2_VTR_POP_2)         \
20606 _("push",  L2_VTR_PUSH_2)
20607
20608 static int
20609 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20610 {
20611   unformat_input_t *i = vam->input;
20612   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20613   u32 sw_if_index = ~0, vtr_op = ~0;
20614   u16 outer_tag = ~0;
20615   u8 dmac[6], smac[6];
20616   u8 dmac_set = 0, smac_set = 0;
20617   u16 vlanid = 0;
20618   u32 sid = ~0;
20619   u32 tmp;
20620   int ret;
20621
20622   /* Shut up coverity */
20623   clib_memset (dmac, 0, sizeof (dmac));
20624   clib_memset (smac, 0, sizeof (smac));
20625
20626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20627     {
20628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20629         ;
20630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20631         ;
20632       else if (unformat (i, "vtr_op %d", &vtr_op))
20633         ;
20634 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20635       foreach_pbb_vtr_op
20636 #undef _
20637         else if (unformat (i, "translate_pbb_stag"))
20638         {
20639           if (unformat (i, "%d", &tmp))
20640             {
20641               vtr_op = L2_VTR_TRANSLATE_2_1;
20642               outer_tag = tmp;
20643             }
20644           else
20645             {
20646               errmsg
20647                 ("translate_pbb_stag operation requires outer tag definition");
20648               return -99;
20649             }
20650         }
20651       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20652         dmac_set++;
20653       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20654         smac_set++;
20655       else if (unformat (i, "sid %d", &sid))
20656         ;
20657       else if (unformat (i, "vlanid %d", &tmp))
20658         vlanid = tmp;
20659       else
20660         {
20661           clib_warning ("parse error '%U'", format_unformat_error, i);
20662           return -99;
20663         }
20664     }
20665
20666   if ((sw_if_index == ~0) || (vtr_op == ~0))
20667     {
20668       errmsg ("missing sw_if_index or vtr operation");
20669       return -99;
20670     }
20671   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20672       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20673     {
20674       errmsg
20675         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20676       return -99;
20677     }
20678
20679   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20680   mp->sw_if_index = ntohl (sw_if_index);
20681   mp->vtr_op = ntohl (vtr_op);
20682   mp->outer_tag = ntohs (outer_tag);
20683   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20684   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20685   mp->b_vlanid = ntohs (vlanid);
20686   mp->i_sid = ntohl (sid);
20687
20688   S (mp);
20689   W (ret);
20690   return ret;
20691 }
20692
20693 static int
20694 api_flow_classify_set_interface (vat_main_t * vam)
20695 {
20696   unformat_input_t *i = vam->input;
20697   vl_api_flow_classify_set_interface_t *mp;
20698   u32 sw_if_index;
20699   int sw_if_index_set;
20700   u32 ip4_table_index = ~0;
20701   u32 ip6_table_index = ~0;
20702   u8 is_add = 1;
20703   int ret;
20704
20705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20706     {
20707       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20708         sw_if_index_set = 1;
20709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20710         sw_if_index_set = 1;
20711       else if (unformat (i, "del"))
20712         is_add = 0;
20713       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20714         ;
20715       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20716         ;
20717       else
20718         {
20719           clib_warning ("parse error '%U'", format_unformat_error, i);
20720           return -99;
20721         }
20722     }
20723
20724   if (sw_if_index_set == 0)
20725     {
20726       errmsg ("missing interface name or sw_if_index");
20727       return -99;
20728     }
20729
20730   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20731
20732   mp->sw_if_index = ntohl (sw_if_index);
20733   mp->ip4_table_index = ntohl (ip4_table_index);
20734   mp->ip6_table_index = ntohl (ip6_table_index);
20735   mp->is_add = is_add;
20736
20737   S (mp);
20738   W (ret);
20739   return ret;
20740 }
20741
20742 static int
20743 api_flow_classify_dump (vat_main_t * vam)
20744 {
20745   unformat_input_t *i = vam->input;
20746   vl_api_flow_classify_dump_t *mp;
20747   vl_api_control_ping_t *mp_ping;
20748   u8 type = FLOW_CLASSIFY_N_TABLES;
20749   int ret;
20750
20751   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20752     ;
20753   else
20754     {
20755       errmsg ("classify table type must be specified");
20756       return -99;
20757     }
20758
20759   if (!vam->json_output)
20760     {
20761       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20762     }
20763
20764   M (FLOW_CLASSIFY_DUMP, mp);
20765   mp->type = type;
20766   /* send it... */
20767   S (mp);
20768
20769   /* Use a control ping for synchronization */
20770   MPING (CONTROL_PING, mp_ping);
20771   S (mp_ping);
20772
20773   /* Wait for a reply... */
20774   W (ret);
20775   return ret;
20776 }
20777
20778 static int
20779 api_feature_enable_disable (vat_main_t * vam)
20780 {
20781   unformat_input_t *i = vam->input;
20782   vl_api_feature_enable_disable_t *mp;
20783   u8 *arc_name = 0;
20784   u8 *feature_name = 0;
20785   u32 sw_if_index = ~0;
20786   u8 enable = 1;
20787   int ret;
20788
20789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20790     {
20791       if (unformat (i, "arc_name %s", &arc_name))
20792         ;
20793       else if (unformat (i, "feature_name %s", &feature_name))
20794         ;
20795       else
20796         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20797         ;
20798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20799         ;
20800       else if (unformat (i, "disable"))
20801         enable = 0;
20802       else
20803         break;
20804     }
20805
20806   if (arc_name == 0)
20807     {
20808       errmsg ("missing arc name");
20809       return -99;
20810     }
20811   if (vec_len (arc_name) > 63)
20812     {
20813       errmsg ("arc name too long");
20814     }
20815
20816   if (feature_name == 0)
20817     {
20818       errmsg ("missing feature name");
20819       return -99;
20820     }
20821   if (vec_len (feature_name) > 63)
20822     {
20823       errmsg ("feature name too long");
20824     }
20825
20826   if (sw_if_index == ~0)
20827     {
20828       errmsg ("missing interface name or sw_if_index");
20829       return -99;
20830     }
20831
20832   /* Construct the API message */
20833   M (FEATURE_ENABLE_DISABLE, mp);
20834   mp->sw_if_index = ntohl (sw_if_index);
20835   mp->enable = enable;
20836   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20837   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20838   vec_free (arc_name);
20839   vec_free (feature_name);
20840
20841   S (mp);
20842   W (ret);
20843   return ret;
20844 }
20845
20846 static int
20847 api_sw_interface_tag_add_del (vat_main_t * vam)
20848 {
20849   unformat_input_t *i = vam->input;
20850   vl_api_sw_interface_tag_add_del_t *mp;
20851   u32 sw_if_index = ~0;
20852   u8 *tag = 0;
20853   u8 enable = 1;
20854   int ret;
20855
20856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20857     {
20858       if (unformat (i, "tag %s", &tag))
20859         ;
20860       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20861         ;
20862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20863         ;
20864       else if (unformat (i, "del"))
20865         enable = 0;
20866       else
20867         break;
20868     }
20869
20870   if (sw_if_index == ~0)
20871     {
20872       errmsg ("missing interface name or sw_if_index");
20873       return -99;
20874     }
20875
20876   if (enable && (tag == 0))
20877     {
20878       errmsg ("no tag specified");
20879       return -99;
20880     }
20881
20882   /* Construct the API message */
20883   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20884   mp->sw_if_index = ntohl (sw_if_index);
20885   mp->is_add = enable;
20886   if (enable)
20887     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20888   vec_free (tag);
20889
20890   S (mp);
20891   W (ret);
20892   return ret;
20893 }
20894
20895 static void vl_api_l2_xconnect_details_t_handler
20896   (vl_api_l2_xconnect_details_t * mp)
20897 {
20898   vat_main_t *vam = &vat_main;
20899
20900   print (vam->ofp, "%15d%15d",
20901          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20902 }
20903
20904 static void vl_api_l2_xconnect_details_t_handler_json
20905   (vl_api_l2_xconnect_details_t * mp)
20906 {
20907   vat_main_t *vam = &vat_main;
20908   vat_json_node_t *node = NULL;
20909
20910   if (VAT_JSON_ARRAY != vam->json_tree.type)
20911     {
20912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20913       vat_json_init_array (&vam->json_tree);
20914     }
20915   node = vat_json_array_add (&vam->json_tree);
20916
20917   vat_json_init_object (node);
20918   vat_json_object_add_uint (node, "rx_sw_if_index",
20919                             ntohl (mp->rx_sw_if_index));
20920   vat_json_object_add_uint (node, "tx_sw_if_index",
20921                             ntohl (mp->tx_sw_if_index));
20922 }
20923
20924 static int
20925 api_l2_xconnect_dump (vat_main_t * vam)
20926 {
20927   vl_api_l2_xconnect_dump_t *mp;
20928   vl_api_control_ping_t *mp_ping;
20929   int ret;
20930
20931   if (!vam->json_output)
20932     {
20933       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20934     }
20935
20936   M (L2_XCONNECT_DUMP, mp);
20937
20938   S (mp);
20939
20940   /* Use a control ping for synchronization */
20941   MPING (CONTROL_PING, mp_ping);
20942   S (mp_ping);
20943
20944   W (ret);
20945   return ret;
20946 }
20947
20948 static int
20949 api_hw_interface_set_mtu (vat_main_t * vam)
20950 {
20951   unformat_input_t *i = vam->input;
20952   vl_api_hw_interface_set_mtu_t *mp;
20953   u32 sw_if_index = ~0;
20954   u32 mtu = 0;
20955   int ret;
20956
20957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20958     {
20959       if (unformat (i, "mtu %d", &mtu))
20960         ;
20961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20962         ;
20963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20964         ;
20965       else
20966         break;
20967     }
20968
20969   if (sw_if_index == ~0)
20970     {
20971       errmsg ("missing interface name or sw_if_index");
20972       return -99;
20973     }
20974
20975   if (mtu == 0)
20976     {
20977       errmsg ("no mtu specified");
20978       return -99;
20979     }
20980
20981   /* Construct the API message */
20982   M (HW_INTERFACE_SET_MTU, mp);
20983   mp->sw_if_index = ntohl (sw_if_index);
20984   mp->mtu = ntohs ((u16) mtu);
20985
20986   S (mp);
20987   W (ret);
20988   return ret;
20989 }
20990
20991 static int
20992 api_p2p_ethernet_add (vat_main_t * vam)
20993 {
20994   unformat_input_t *i = vam->input;
20995   vl_api_p2p_ethernet_add_t *mp;
20996   u32 parent_if_index = ~0;
20997   u32 sub_id = ~0;
20998   u8 remote_mac[6];
20999   u8 mac_set = 0;
21000   int ret;
21001
21002   clib_memset (remote_mac, 0, sizeof (remote_mac));
21003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21004     {
21005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21006         ;
21007       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21008         ;
21009       else
21010         if (unformat
21011             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21012         mac_set++;
21013       else if (unformat (i, "sub_id %d", &sub_id))
21014         ;
21015       else
21016         {
21017           clib_warning ("parse error '%U'", format_unformat_error, i);
21018           return -99;
21019         }
21020     }
21021
21022   if (parent_if_index == ~0)
21023     {
21024       errmsg ("missing interface name or sw_if_index");
21025       return -99;
21026     }
21027   if (mac_set == 0)
21028     {
21029       errmsg ("missing remote mac address");
21030       return -99;
21031     }
21032   if (sub_id == ~0)
21033     {
21034       errmsg ("missing sub-interface id");
21035       return -99;
21036     }
21037
21038   M (P2P_ETHERNET_ADD, mp);
21039   mp->parent_if_index = ntohl (parent_if_index);
21040   mp->subif_id = ntohl (sub_id);
21041   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21042
21043   S (mp);
21044   W (ret);
21045   return ret;
21046 }
21047
21048 static int
21049 api_p2p_ethernet_del (vat_main_t * vam)
21050 {
21051   unformat_input_t *i = vam->input;
21052   vl_api_p2p_ethernet_del_t *mp;
21053   u32 parent_if_index = ~0;
21054   u8 remote_mac[6];
21055   u8 mac_set = 0;
21056   int ret;
21057
21058   clib_memset (remote_mac, 0, sizeof (remote_mac));
21059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21060     {
21061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21062         ;
21063       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21064         ;
21065       else
21066         if (unformat
21067             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21068         mac_set++;
21069       else
21070         {
21071           clib_warning ("parse error '%U'", format_unformat_error, i);
21072           return -99;
21073         }
21074     }
21075
21076   if (parent_if_index == ~0)
21077     {
21078       errmsg ("missing interface name or sw_if_index");
21079       return -99;
21080     }
21081   if (mac_set == 0)
21082     {
21083       errmsg ("missing remote mac address");
21084       return -99;
21085     }
21086
21087   M (P2P_ETHERNET_DEL, mp);
21088   mp->parent_if_index = ntohl (parent_if_index);
21089   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21090
21091   S (mp);
21092   W (ret);
21093   return ret;
21094 }
21095
21096 static int
21097 api_lldp_config (vat_main_t * vam)
21098 {
21099   unformat_input_t *i = vam->input;
21100   vl_api_lldp_config_t *mp;
21101   int tx_hold = 0;
21102   int tx_interval = 0;
21103   u8 *sys_name = NULL;
21104   int ret;
21105
21106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21107     {
21108       if (unformat (i, "system-name %s", &sys_name))
21109         ;
21110       else if (unformat (i, "tx-hold %d", &tx_hold))
21111         ;
21112       else if (unformat (i, "tx-interval %d", &tx_interval))
21113         ;
21114       else
21115         {
21116           clib_warning ("parse error '%U'", format_unformat_error, i);
21117           return -99;
21118         }
21119     }
21120
21121   vec_add1 (sys_name, 0);
21122
21123   M (LLDP_CONFIG, mp);
21124   mp->tx_hold = htonl (tx_hold);
21125   mp->tx_interval = htonl (tx_interval);
21126   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21127   vec_free (sys_name);
21128
21129   S (mp);
21130   W (ret);
21131   return ret;
21132 }
21133
21134 static int
21135 api_sw_interface_set_lldp (vat_main_t * vam)
21136 {
21137   unformat_input_t *i = vam->input;
21138   vl_api_sw_interface_set_lldp_t *mp;
21139   u32 sw_if_index = ~0;
21140   u32 enable = 1;
21141   u8 *port_desc = NULL, *mgmt_oid = NULL;
21142   ip4_address_t ip4_addr;
21143   ip6_address_t ip6_addr;
21144   int ret;
21145
21146   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21147   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21148
21149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21150     {
21151       if (unformat (i, "disable"))
21152         enable = 0;
21153       else
21154         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21155         ;
21156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21157         ;
21158       else if (unformat (i, "port-desc %s", &port_desc))
21159         ;
21160       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21161         ;
21162       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21163         ;
21164       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21165         ;
21166       else
21167         break;
21168     }
21169
21170   if (sw_if_index == ~0)
21171     {
21172       errmsg ("missing interface name or sw_if_index");
21173       return -99;
21174     }
21175
21176   /* Construct the API message */
21177   vec_add1 (port_desc, 0);
21178   vec_add1 (mgmt_oid, 0);
21179   M (SW_INTERFACE_SET_LLDP, mp);
21180   mp->sw_if_index = ntohl (sw_if_index);
21181   mp->enable = enable;
21182   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21183   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21184   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21185   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21186   vec_free (port_desc);
21187   vec_free (mgmt_oid);
21188
21189   S (mp);
21190   W (ret);
21191   return ret;
21192 }
21193
21194 static int
21195 api_tcp_configure_src_addresses (vat_main_t * vam)
21196 {
21197   vl_api_tcp_configure_src_addresses_t *mp;
21198   unformat_input_t *i = vam->input;
21199   ip4_address_t v4first, v4last;
21200   ip6_address_t v6first, v6last;
21201   u8 range_set = 0;
21202   u32 vrf_id = 0;
21203   int ret;
21204
21205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21206     {
21207       if (unformat (i, "%U - %U",
21208                     unformat_ip4_address, &v4first,
21209                     unformat_ip4_address, &v4last))
21210         {
21211           if (range_set)
21212             {
21213               errmsg ("one range per message (range already set)");
21214               return -99;
21215             }
21216           range_set = 1;
21217         }
21218       else if (unformat (i, "%U - %U",
21219                          unformat_ip6_address, &v6first,
21220                          unformat_ip6_address, &v6last))
21221         {
21222           if (range_set)
21223             {
21224               errmsg ("one range per message (range already set)");
21225               return -99;
21226             }
21227           range_set = 2;
21228         }
21229       else if (unformat (i, "vrf %d", &vrf_id))
21230         ;
21231       else
21232         break;
21233     }
21234
21235   if (range_set == 0)
21236     {
21237       errmsg ("address range not set");
21238       return -99;
21239     }
21240
21241   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21242   mp->vrf_id = ntohl (vrf_id);
21243   /* ipv6? */
21244   if (range_set == 2)
21245     {
21246       mp->is_ipv6 = 1;
21247       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21248       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21249     }
21250   else
21251     {
21252       mp->is_ipv6 = 0;
21253       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21254       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21255     }
21256   S (mp);
21257   W (ret);
21258   return ret;
21259 }
21260
21261 static void vl_api_app_namespace_add_del_reply_t_handler
21262   (vl_api_app_namespace_add_del_reply_t * mp)
21263 {
21264   vat_main_t *vam = &vat_main;
21265   i32 retval = ntohl (mp->retval);
21266   if (vam->async_mode)
21267     {
21268       vam->async_errors += (retval < 0);
21269     }
21270   else
21271     {
21272       vam->retval = retval;
21273       if (retval == 0)
21274         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21275       vam->result_ready = 1;
21276     }
21277 }
21278
21279 static void vl_api_app_namespace_add_del_reply_t_handler_json
21280   (vl_api_app_namespace_add_del_reply_t * mp)
21281 {
21282   vat_main_t *vam = &vat_main;
21283   vat_json_node_t node;
21284
21285   vat_json_init_object (&node);
21286   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21287   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21288
21289   vat_json_print (vam->ofp, &node);
21290   vat_json_free (&node);
21291
21292   vam->retval = ntohl (mp->retval);
21293   vam->result_ready = 1;
21294 }
21295
21296 static int
21297 api_app_namespace_add_del (vat_main_t * vam)
21298 {
21299   vl_api_app_namespace_add_del_t *mp;
21300   unformat_input_t *i = vam->input;
21301   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21302   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21303   u64 secret;
21304   int ret;
21305
21306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21307     {
21308       if (unformat (i, "id %_%v%_", &ns_id))
21309         ;
21310       else if (unformat (i, "secret %lu", &secret))
21311         secret_set = 1;
21312       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21313         sw_if_index_set = 1;
21314       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21315         ;
21316       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21317         ;
21318       else
21319         break;
21320     }
21321   if (!ns_id || !secret_set || !sw_if_index_set)
21322     {
21323       errmsg ("namespace id, secret and sw_if_index must be set");
21324       return -99;
21325     }
21326   if (vec_len (ns_id) > 64)
21327     {
21328       errmsg ("namespace id too long");
21329       return -99;
21330     }
21331   M (APP_NAMESPACE_ADD_DEL, mp);
21332
21333   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21334   mp->namespace_id_len = vec_len (ns_id);
21335   mp->secret = clib_host_to_net_u64 (secret);
21336   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21337   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21338   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21339   vec_free (ns_id);
21340   S (mp);
21341   W (ret);
21342   return ret;
21343 }
21344
21345 static int
21346 api_sock_init_shm (vat_main_t * vam)
21347 {
21348 #if VPP_API_TEST_BUILTIN == 0
21349   unformat_input_t *i = vam->input;
21350   vl_api_shm_elem_config_t *config = 0;
21351   u64 size = 64 << 20;
21352   int rv;
21353
21354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21355     {
21356       if (unformat (i, "size %U", unformat_memory_size, &size))
21357         ;
21358       else
21359         break;
21360     }
21361
21362   /*
21363    * Canned custom ring allocator config.
21364    * Should probably parse all of this
21365    */
21366   vec_validate (config, 6);
21367   config[0].type = VL_API_VLIB_RING;
21368   config[0].size = 256;
21369   config[0].count = 32;
21370
21371   config[1].type = VL_API_VLIB_RING;
21372   config[1].size = 1024;
21373   config[1].count = 16;
21374
21375   config[2].type = VL_API_VLIB_RING;
21376   config[2].size = 4096;
21377   config[2].count = 2;
21378
21379   config[3].type = VL_API_CLIENT_RING;
21380   config[3].size = 256;
21381   config[3].count = 32;
21382
21383   config[4].type = VL_API_CLIENT_RING;
21384   config[4].size = 1024;
21385   config[4].count = 16;
21386
21387   config[5].type = VL_API_CLIENT_RING;
21388   config[5].size = 4096;
21389   config[5].count = 2;
21390
21391   config[6].type = VL_API_QUEUE;
21392   config[6].count = 128;
21393   config[6].size = sizeof (uword);
21394
21395   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21396   if (!rv)
21397     vam->client_index_invalid = 1;
21398   return rv;
21399 #else
21400   return -99;
21401 #endif
21402 }
21403
21404 static int
21405 api_dns_enable_disable (vat_main_t * vam)
21406 {
21407   unformat_input_t *line_input = vam->input;
21408   vl_api_dns_enable_disable_t *mp;
21409   u8 enable_disable = 1;
21410   int ret;
21411
21412   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21413     {
21414       if (unformat (line_input, "disable"))
21415         enable_disable = 0;
21416       if (unformat (line_input, "enable"))
21417         enable_disable = 1;
21418       else
21419         break;
21420     }
21421
21422   /* Construct the API message */
21423   M (DNS_ENABLE_DISABLE, mp);
21424   mp->enable = enable_disable;
21425
21426   /* send it... */
21427   S (mp);
21428   /* Wait for the reply */
21429   W (ret);
21430   return ret;
21431 }
21432
21433 static int
21434 api_dns_resolve_name (vat_main_t * vam)
21435 {
21436   unformat_input_t *line_input = vam->input;
21437   vl_api_dns_resolve_name_t *mp;
21438   u8 *name = 0;
21439   int ret;
21440
21441   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21442     {
21443       if (unformat (line_input, "%s", &name))
21444         ;
21445       else
21446         break;
21447     }
21448
21449   if (vec_len (name) > 127)
21450     {
21451       errmsg ("name too long");
21452       return -99;
21453     }
21454
21455   /* Construct the API message */
21456   M (DNS_RESOLVE_NAME, mp);
21457   memcpy (mp->name, name, vec_len (name));
21458   vec_free (name);
21459
21460   /* send it... */
21461   S (mp);
21462   /* Wait for the reply */
21463   W (ret);
21464   return ret;
21465 }
21466
21467 static int
21468 api_dns_resolve_ip (vat_main_t * vam)
21469 {
21470   unformat_input_t *line_input = vam->input;
21471   vl_api_dns_resolve_ip_t *mp;
21472   int is_ip6 = -1;
21473   ip4_address_t addr4;
21474   ip6_address_t addr6;
21475   int ret;
21476
21477   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21478     {
21479       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21480         is_ip6 = 1;
21481       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21482         is_ip6 = 0;
21483       else
21484         break;
21485     }
21486
21487   if (is_ip6 == -1)
21488     {
21489       errmsg ("missing address");
21490       return -99;
21491     }
21492
21493   /* Construct the API message */
21494   M (DNS_RESOLVE_IP, mp);
21495   mp->is_ip6 = is_ip6;
21496   if (is_ip6)
21497     memcpy (mp->address, &addr6, sizeof (addr6));
21498   else
21499     memcpy (mp->address, &addr4, sizeof (addr4));
21500
21501   /* send it... */
21502   S (mp);
21503   /* Wait for the reply */
21504   W (ret);
21505   return ret;
21506 }
21507
21508 static int
21509 api_dns_name_server_add_del (vat_main_t * vam)
21510 {
21511   unformat_input_t *i = vam->input;
21512   vl_api_dns_name_server_add_del_t *mp;
21513   u8 is_add = 1;
21514   ip6_address_t ip6_server;
21515   ip4_address_t ip4_server;
21516   int ip6_set = 0;
21517   int ip4_set = 0;
21518   int ret = 0;
21519
21520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21521     {
21522       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21523         ip6_set = 1;
21524       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21525         ip4_set = 1;
21526       else if (unformat (i, "del"))
21527         is_add = 0;
21528       else
21529         {
21530           clib_warning ("parse error '%U'", format_unformat_error, i);
21531           return -99;
21532         }
21533     }
21534
21535   if (ip4_set && ip6_set)
21536     {
21537       errmsg ("Only one server address allowed per message");
21538       return -99;
21539     }
21540   if ((ip4_set + ip6_set) == 0)
21541     {
21542       errmsg ("Server address required");
21543       return -99;
21544     }
21545
21546   /* Construct the API message */
21547   M (DNS_NAME_SERVER_ADD_DEL, mp);
21548
21549   if (ip6_set)
21550     {
21551       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21552       mp->is_ip6 = 1;
21553     }
21554   else
21555     {
21556       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21557       mp->is_ip6 = 0;
21558     }
21559
21560   mp->is_add = is_add;
21561
21562   /* send it... */
21563   S (mp);
21564
21565   /* Wait for a reply, return good/bad news  */
21566   W (ret);
21567   return ret;
21568 }
21569
21570 static void
21571 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21572 {
21573   vat_main_t *vam = &vat_main;
21574
21575   if (mp->is_ip4)
21576     {
21577       print (vam->ofp,
21578              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21579              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21580              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21581              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21582              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21583              clib_net_to_host_u32 (mp->action_index), mp->tag);
21584     }
21585   else
21586     {
21587       print (vam->ofp,
21588              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21589              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21590              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21591              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21592              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21593              clib_net_to_host_u32 (mp->action_index), mp->tag);
21594     }
21595 }
21596
21597 static void
21598 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21599                                              mp)
21600 {
21601   vat_main_t *vam = &vat_main;
21602   vat_json_node_t *node = NULL;
21603   struct in6_addr ip6;
21604   struct in_addr ip4;
21605
21606   if (VAT_JSON_ARRAY != vam->json_tree.type)
21607     {
21608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21609       vat_json_init_array (&vam->json_tree);
21610     }
21611   node = vat_json_array_add (&vam->json_tree);
21612   vat_json_init_object (node);
21613
21614   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21615   vat_json_object_add_uint (node, "appns_index",
21616                             clib_net_to_host_u32 (mp->appns_index));
21617   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21618   vat_json_object_add_uint (node, "scope", mp->scope);
21619   vat_json_object_add_uint (node, "action_index",
21620                             clib_net_to_host_u32 (mp->action_index));
21621   vat_json_object_add_uint (node, "lcl_port",
21622                             clib_net_to_host_u16 (mp->lcl_port));
21623   vat_json_object_add_uint (node, "rmt_port",
21624                             clib_net_to_host_u16 (mp->rmt_port));
21625   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21626   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21627   vat_json_object_add_string_copy (node, "tag", mp->tag);
21628   if (mp->is_ip4)
21629     {
21630       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21631       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21632       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21633       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21634     }
21635   else
21636     {
21637       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21638       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21639       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21640       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21641     }
21642 }
21643
21644 static int
21645 api_session_rule_add_del (vat_main_t * vam)
21646 {
21647   vl_api_session_rule_add_del_t *mp;
21648   unformat_input_t *i = vam->input;
21649   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21650   u32 appns_index = 0, scope = 0;
21651   ip4_address_t lcl_ip4, rmt_ip4;
21652   ip6_address_t lcl_ip6, rmt_ip6;
21653   u8 is_ip4 = 1, conn_set = 0;
21654   u8 is_add = 1, *tag = 0;
21655   int ret;
21656
21657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21658     {
21659       if (unformat (i, "del"))
21660         is_add = 0;
21661       else if (unformat (i, "add"))
21662         ;
21663       else if (unformat (i, "proto tcp"))
21664         proto = 0;
21665       else if (unformat (i, "proto udp"))
21666         proto = 1;
21667       else if (unformat (i, "appns %d", &appns_index))
21668         ;
21669       else if (unformat (i, "scope %d", &scope))
21670         ;
21671       else if (unformat (i, "tag %_%v%_", &tag))
21672         ;
21673       else
21674         if (unformat
21675             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21676              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21677              &rmt_port))
21678         {
21679           is_ip4 = 1;
21680           conn_set = 1;
21681         }
21682       else
21683         if (unformat
21684             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21685              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21686              &rmt_port))
21687         {
21688           is_ip4 = 0;
21689           conn_set = 1;
21690         }
21691       else if (unformat (i, "action %d", &action))
21692         ;
21693       else
21694         break;
21695     }
21696   if (proto == ~0 || !conn_set || action == ~0)
21697     {
21698       errmsg ("transport proto, connection and action must be set");
21699       return -99;
21700     }
21701
21702   if (scope > 3)
21703     {
21704       errmsg ("scope should be 0-3");
21705       return -99;
21706     }
21707
21708   M (SESSION_RULE_ADD_DEL, mp);
21709
21710   mp->is_ip4 = is_ip4;
21711   mp->transport_proto = proto;
21712   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21713   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21714   mp->lcl_plen = lcl_plen;
21715   mp->rmt_plen = rmt_plen;
21716   mp->action_index = clib_host_to_net_u32 (action);
21717   mp->appns_index = clib_host_to_net_u32 (appns_index);
21718   mp->scope = scope;
21719   mp->is_add = is_add;
21720   if (is_ip4)
21721     {
21722       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21723       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21724     }
21725   else
21726     {
21727       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21728       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21729     }
21730   if (tag)
21731     {
21732       clib_memcpy (mp->tag, tag, vec_len (tag));
21733       vec_free (tag);
21734     }
21735
21736   S (mp);
21737   W (ret);
21738   return ret;
21739 }
21740
21741 static int
21742 api_session_rules_dump (vat_main_t * vam)
21743 {
21744   vl_api_session_rules_dump_t *mp;
21745   vl_api_control_ping_t *mp_ping;
21746   int ret;
21747
21748   if (!vam->json_output)
21749     {
21750       print (vam->ofp, "%=20s", "Session Rules");
21751     }
21752
21753   M (SESSION_RULES_DUMP, mp);
21754   /* send it... */
21755   S (mp);
21756
21757   /* Use a control ping for synchronization */
21758   MPING (CONTROL_PING, mp_ping);
21759   S (mp_ping);
21760
21761   /* Wait for a reply... */
21762   W (ret);
21763   return ret;
21764 }
21765
21766 static int
21767 api_ip_container_proxy_add_del (vat_main_t * vam)
21768 {
21769   vl_api_ip_container_proxy_add_del_t *mp;
21770   unformat_input_t *i = vam->input;
21771   u32 sw_if_index = ~0;
21772   vl_api_prefix_t pfx = { };
21773   u8 is_add = 1;
21774   int ret;
21775
21776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21777     {
21778       if (unformat (i, "del"))
21779         is_add = 0;
21780       else if (unformat (i, "add"))
21781         ;
21782       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21783         ;
21784       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21785         ;
21786       else
21787         break;
21788     }
21789   if (sw_if_index == ~0 || pfx.address_length == 0)
21790     {
21791       errmsg ("address and sw_if_index must be set");
21792       return -99;
21793     }
21794
21795   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21796
21797   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21798   mp->is_add = is_add;
21799   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21800
21801   S (mp);
21802   W (ret);
21803   return ret;
21804 }
21805
21806 static int
21807 api_qos_record_enable_disable (vat_main_t * vam)
21808 {
21809   unformat_input_t *i = vam->input;
21810   vl_api_qos_record_enable_disable_t *mp;
21811   u32 sw_if_index, qs = 0xff;
21812   u8 sw_if_index_set = 0;
21813   u8 enable = 1;
21814   int ret;
21815
21816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21817     {
21818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21819         sw_if_index_set = 1;
21820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21821         sw_if_index_set = 1;
21822       else if (unformat (i, "%U", unformat_qos_source, &qs))
21823         ;
21824       else if (unformat (i, "disable"))
21825         enable = 0;
21826       else
21827         {
21828           clib_warning ("parse error '%U'", format_unformat_error, i);
21829           return -99;
21830         }
21831     }
21832
21833   if (sw_if_index_set == 0)
21834     {
21835       errmsg ("missing interface name or sw_if_index");
21836       return -99;
21837     }
21838   if (qs == 0xff)
21839     {
21840       errmsg ("input location must be specified");
21841       return -99;
21842     }
21843
21844   M (QOS_RECORD_ENABLE_DISABLE, mp);
21845
21846   mp->sw_if_index = ntohl (sw_if_index);
21847   mp->input_source = qs;
21848   mp->enable = enable;
21849
21850   S (mp);
21851   W (ret);
21852   return ret;
21853 }
21854
21855
21856 static int
21857 q_or_quit (vat_main_t * vam)
21858 {
21859 #if VPP_API_TEST_BUILTIN == 0
21860   longjmp (vam->jump_buf, 1);
21861 #endif
21862   return 0;                     /* not so much */
21863 }
21864
21865 static int
21866 q (vat_main_t * vam)
21867 {
21868   return q_or_quit (vam);
21869 }
21870
21871 static int
21872 quit (vat_main_t * vam)
21873 {
21874   return q_or_quit (vam);
21875 }
21876
21877 static int
21878 comment (vat_main_t * vam)
21879 {
21880   return 0;
21881 }
21882
21883 static int
21884 statseg (vat_main_t * vam)
21885 {
21886   ssvm_private_t *ssvmp = &vam->stat_segment;
21887   ssvm_shared_header_t *shared_header = ssvmp->sh;
21888   vlib_counter_t **counters;
21889   u64 thread0_index1_packets;
21890   u64 thread0_index1_bytes;
21891   f64 vector_rate, input_rate;
21892   uword *p;
21893
21894   uword *counter_vector_by_name;
21895   if (vam->stat_segment_lockp == 0)
21896     {
21897       errmsg ("Stat segment not mapped...");
21898       return -99;
21899     }
21900
21901   /* look up "/if/rx for sw_if_index 1 as a test */
21902
21903   clib_spinlock_lock (vam->stat_segment_lockp);
21904
21905   counter_vector_by_name = (uword *) shared_header->opaque[1];
21906
21907   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21908   if (p == 0)
21909     {
21910       clib_spinlock_unlock (vam->stat_segment_lockp);
21911       errmsg ("/if/tx not found?");
21912       return -99;
21913     }
21914
21915   /* Fish per-thread vector of combined counters from shared memory */
21916   counters = (vlib_counter_t **) p[0];
21917
21918   if (vec_len (counters[0]) < 2)
21919     {
21920       clib_spinlock_unlock (vam->stat_segment_lockp);
21921       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21922       return -99;
21923     }
21924
21925   /* Read thread 0 sw_if_index 1 counter */
21926   thread0_index1_packets = counters[0][1].packets;
21927   thread0_index1_bytes = counters[0][1].bytes;
21928
21929   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21930   if (p == 0)
21931     {
21932       clib_spinlock_unlock (vam->stat_segment_lockp);
21933       errmsg ("vector_rate not found?");
21934       return -99;
21935     }
21936
21937   vector_rate = *(f64 *) (p[0]);
21938   p = hash_get_mem (counter_vector_by_name, "input_rate");
21939   if (p == 0)
21940     {
21941       clib_spinlock_unlock (vam->stat_segment_lockp);
21942       errmsg ("input_rate not found?");
21943       return -99;
21944     }
21945   input_rate = *(f64 *) (p[0]);
21946
21947   clib_spinlock_unlock (vam->stat_segment_lockp);
21948
21949   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21950          vector_rate, input_rate);
21951   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21952          thread0_index1_packets, thread0_index1_bytes);
21953
21954   return 0;
21955 }
21956
21957 static int
21958 cmd_cmp (void *a1, void *a2)
21959 {
21960   u8 **c1 = a1;
21961   u8 **c2 = a2;
21962
21963   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21964 }
21965
21966 static int
21967 help (vat_main_t * vam)
21968 {
21969   u8 **cmds = 0;
21970   u8 *name = 0;
21971   hash_pair_t *p;
21972   unformat_input_t *i = vam->input;
21973   int j;
21974
21975   if (unformat (i, "%s", &name))
21976     {
21977       uword *hs;
21978
21979       vec_add1 (name, 0);
21980
21981       hs = hash_get_mem (vam->help_by_name, name);
21982       if (hs)
21983         print (vam->ofp, "usage: %s %s", name, hs[0]);
21984       else
21985         print (vam->ofp, "No such msg / command '%s'", name);
21986       vec_free (name);
21987       return 0;
21988     }
21989
21990   print (vam->ofp, "Help is available for the following:");
21991
21992     /* *INDENT-OFF* */
21993     hash_foreach_pair (p, vam->function_by_name,
21994     ({
21995       vec_add1 (cmds, (u8 *)(p->key));
21996     }));
21997     /* *INDENT-ON* */
21998
21999   vec_sort_with_function (cmds, cmd_cmp);
22000
22001   for (j = 0; j < vec_len (cmds); j++)
22002     print (vam->ofp, "%s", cmds[j]);
22003
22004   vec_free (cmds);
22005   return 0;
22006 }
22007
22008 static int
22009 set (vat_main_t * vam)
22010 {
22011   u8 *name = 0, *value = 0;
22012   unformat_input_t *i = vam->input;
22013
22014   if (unformat (i, "%s", &name))
22015     {
22016       /* The input buffer is a vector, not a string. */
22017       value = vec_dup (i->buffer);
22018       vec_delete (value, i->index, 0);
22019       /* Almost certainly has a trailing newline */
22020       if (value[vec_len (value) - 1] == '\n')
22021         value[vec_len (value) - 1] = 0;
22022       /* Make sure it's a proper string, one way or the other */
22023       vec_add1 (value, 0);
22024       (void) clib_macro_set_value (&vam->macro_main,
22025                                    (char *) name, (char *) value);
22026     }
22027   else
22028     errmsg ("usage: set <name> <value>");
22029
22030   vec_free (name);
22031   vec_free (value);
22032   return 0;
22033 }
22034
22035 static int
22036 unset (vat_main_t * vam)
22037 {
22038   u8 *name = 0;
22039
22040   if (unformat (vam->input, "%s", &name))
22041     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22042       errmsg ("unset: %s wasn't set", name);
22043   vec_free (name);
22044   return 0;
22045 }
22046
22047 typedef struct
22048 {
22049   u8 *name;
22050   u8 *value;
22051 } macro_sort_t;
22052
22053
22054 static int
22055 macro_sort_cmp (void *a1, void *a2)
22056 {
22057   macro_sort_t *s1 = a1;
22058   macro_sort_t *s2 = a2;
22059
22060   return strcmp ((char *) (s1->name), (char *) (s2->name));
22061 }
22062
22063 static int
22064 dump_macro_table (vat_main_t * vam)
22065 {
22066   macro_sort_t *sort_me = 0, *sm;
22067   int i;
22068   hash_pair_t *p;
22069
22070     /* *INDENT-OFF* */
22071     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22072     ({
22073       vec_add2 (sort_me, sm, 1);
22074       sm->name = (u8 *)(p->key);
22075       sm->value = (u8 *) (p->value[0]);
22076     }));
22077     /* *INDENT-ON* */
22078
22079   vec_sort_with_function (sort_me, macro_sort_cmp);
22080
22081   if (vec_len (sort_me))
22082     print (vam->ofp, "%-15s%s", "Name", "Value");
22083   else
22084     print (vam->ofp, "The macro table is empty...");
22085
22086   for (i = 0; i < vec_len (sort_me); i++)
22087     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22088   return 0;
22089 }
22090
22091 static int
22092 dump_node_table (vat_main_t * vam)
22093 {
22094   int i, j;
22095   vlib_node_t *node, *next_node;
22096
22097   if (vec_len (vam->graph_nodes) == 0)
22098     {
22099       print (vam->ofp, "Node table empty, issue get_node_graph...");
22100       return 0;
22101     }
22102
22103   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22104     {
22105       node = vam->graph_nodes[0][i];
22106       print (vam->ofp, "[%d] %s", i, node->name);
22107       for (j = 0; j < vec_len (node->next_nodes); j++)
22108         {
22109           if (node->next_nodes[j] != ~0)
22110             {
22111               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22112               print (vam->ofp, "  [%d] %s", j, next_node->name);
22113             }
22114         }
22115     }
22116   return 0;
22117 }
22118
22119 static int
22120 value_sort_cmp (void *a1, void *a2)
22121 {
22122   name_sort_t *n1 = a1;
22123   name_sort_t *n2 = a2;
22124
22125   if (n1->value < n2->value)
22126     return -1;
22127   if (n1->value > n2->value)
22128     return 1;
22129   return 0;
22130 }
22131
22132
22133 static int
22134 dump_msg_api_table (vat_main_t * vam)
22135 {
22136   api_main_t *am = &api_main;
22137   name_sort_t *nses = 0, *ns;
22138   hash_pair_t *hp;
22139   int i;
22140
22141   /* *INDENT-OFF* */
22142   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22143   ({
22144     vec_add2 (nses, ns, 1);
22145     ns->name = (u8 *)(hp->key);
22146     ns->value = (u32) hp->value[0];
22147   }));
22148   /* *INDENT-ON* */
22149
22150   vec_sort_with_function (nses, value_sort_cmp);
22151
22152   for (i = 0; i < vec_len (nses); i++)
22153     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22154   vec_free (nses);
22155   return 0;
22156 }
22157
22158 static int
22159 get_msg_id (vat_main_t * vam)
22160 {
22161   u8 *name_and_crc;
22162   u32 message_index;
22163
22164   if (unformat (vam->input, "%s", &name_and_crc))
22165     {
22166       message_index = vl_msg_api_get_msg_index (name_and_crc);
22167       if (message_index == ~0)
22168         {
22169           print (vam->ofp, " '%s' not found", name_and_crc);
22170           return 0;
22171         }
22172       print (vam->ofp, " '%s' has message index %d",
22173              name_and_crc, message_index);
22174       return 0;
22175     }
22176   errmsg ("name_and_crc required...");
22177   return 0;
22178 }
22179
22180 static int
22181 search_node_table (vat_main_t * vam)
22182 {
22183   unformat_input_t *line_input = vam->input;
22184   u8 *node_to_find;
22185   int j;
22186   vlib_node_t *node, *next_node;
22187   uword *p;
22188
22189   if (vam->graph_node_index_by_name == 0)
22190     {
22191       print (vam->ofp, "Node table empty, issue get_node_graph...");
22192       return 0;
22193     }
22194
22195   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22196     {
22197       if (unformat (line_input, "%s", &node_to_find))
22198         {
22199           vec_add1 (node_to_find, 0);
22200           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22201           if (p == 0)
22202             {
22203               print (vam->ofp, "%s not found...", node_to_find);
22204               goto out;
22205             }
22206           node = vam->graph_nodes[0][p[0]];
22207           print (vam->ofp, "[%d] %s", p[0], node->name);
22208           for (j = 0; j < vec_len (node->next_nodes); j++)
22209             {
22210               if (node->next_nodes[j] != ~0)
22211                 {
22212                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22213                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22214                 }
22215             }
22216         }
22217
22218       else
22219         {
22220           clib_warning ("parse error '%U'", format_unformat_error,
22221                         line_input);
22222           return -99;
22223         }
22224
22225     out:
22226       vec_free (node_to_find);
22227
22228     }
22229
22230   return 0;
22231 }
22232
22233
22234 static int
22235 script (vat_main_t * vam)
22236 {
22237 #if (VPP_API_TEST_BUILTIN==0)
22238   u8 *s = 0;
22239   char *save_current_file;
22240   unformat_input_t save_input;
22241   jmp_buf save_jump_buf;
22242   u32 save_line_number;
22243
22244   FILE *new_fp, *save_ifp;
22245
22246   if (unformat (vam->input, "%s", &s))
22247     {
22248       new_fp = fopen ((char *) s, "r");
22249       if (new_fp == 0)
22250         {
22251           errmsg ("Couldn't open script file %s", s);
22252           vec_free (s);
22253           return -99;
22254         }
22255     }
22256   else
22257     {
22258       errmsg ("Missing script name");
22259       return -99;
22260     }
22261
22262   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22263   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22264   save_ifp = vam->ifp;
22265   save_line_number = vam->input_line_number;
22266   save_current_file = (char *) vam->current_file;
22267
22268   vam->input_line_number = 0;
22269   vam->ifp = new_fp;
22270   vam->current_file = s;
22271   do_one_file (vam);
22272
22273   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22274   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22275   vam->ifp = save_ifp;
22276   vam->input_line_number = save_line_number;
22277   vam->current_file = (u8 *) save_current_file;
22278   vec_free (s);
22279
22280   return 0;
22281 #else
22282   clib_warning ("use the exec command...");
22283   return -99;
22284 #endif
22285 }
22286
22287 static int
22288 echo (vat_main_t * vam)
22289 {
22290   print (vam->ofp, "%v", vam->input->buffer);
22291   return 0;
22292 }
22293
22294 /* List of API message constructors, CLI names map to api_xxx */
22295 #define foreach_vpe_api_msg                                             \
22296 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22297 _(sw_interface_dump,"")                                                 \
22298 _(sw_interface_set_flags,                                               \
22299   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22300 _(sw_interface_add_del_address,                                         \
22301   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22302 _(sw_interface_set_rx_mode,                                             \
22303   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22304 _(sw_interface_set_rx_placement,                                        \
22305   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22306 _(sw_interface_rx_placement_dump,                                       \
22307   "[<intfc> | sw_if_index <id>]")                                         \
22308 _(sw_interface_set_table,                                               \
22309   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22310 _(sw_interface_set_mpls_enable,                                         \
22311   "<intfc> | sw_if_index [disable | dis]")                              \
22312 _(sw_interface_set_vpath,                                               \
22313   "<intfc> | sw_if_index <id> enable | disable")                        \
22314 _(sw_interface_set_vxlan_bypass,                                        \
22315   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22316 _(sw_interface_set_geneve_bypass,                                       \
22317   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22318 _(sw_interface_set_l2_xconnect,                                         \
22319   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22320   "enable | disable")                                                   \
22321 _(sw_interface_set_l2_bridge,                                           \
22322   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22323   "[shg <split-horizon-group>] [bvi]\n"                                 \
22324   "enable | disable")                                                   \
22325 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22326 _(bridge_domain_add_del,                                                \
22327   "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") \
22328 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22329 _(l2fib_add_del,                                                        \
22330   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22331 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22332 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22333 _(l2_flags,                                                             \
22334   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22335 _(bridge_flags,                                                         \
22336   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22337 _(tap_create_v2,                                                        \
22338   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22339 _(tap_delete_v2,                                                        \
22340   "<vpp-if-name> | sw_if_index <id>")                                   \
22341 _(sw_interface_tap_v2_dump, "")                                         \
22342 _(virtio_pci_create,                                                    \
22343   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22344 _(virtio_pci_delete,                                                    \
22345   "<vpp-if-name> | sw_if_index <id>")                                   \
22346 _(sw_interface_virtio_pci_dump, "")                                     \
22347 _(bond_create,                                                          \
22348   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22349   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22350   "[id <if-id>]")                                                       \
22351 _(bond_delete,                                                          \
22352   "<vpp-if-name> | sw_if_index <id>")                                   \
22353 _(bond_enslave,                                                         \
22354   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22355 _(bond_detach_slave,                                                    \
22356   "sw_if_index <n>")                                                    \
22357 _(sw_interface_bond_dump, "")                                           \
22358 _(sw_interface_slave_dump,                                              \
22359   "<vpp-if-name> | sw_if_index <id>")                                   \
22360 _(ip_table_add_del,                                                     \
22361   "table <n> [ipv6] [add | del]\n")                                     \
22362 _(ip_add_del_route,                                                     \
22363   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22364   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22365   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22366   "[multipath] [count <n>] [del]")                                      \
22367 _(ip_mroute_add_del,                                                    \
22368   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22369   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22370 _(mpls_table_add_del,                                                   \
22371   "table <n> [add | del]\n")                                            \
22372 _(mpls_route_add_del,                                                   \
22373   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22374   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22375   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22376   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22377   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22378   "[count <n>] [del]")                                                  \
22379 _(mpls_ip_bind_unbind,                                                  \
22380   "<label> <addr/len>")                                                 \
22381 _(mpls_tunnel_add_del,                                                  \
22382   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22383   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22384   "[l2-only]  [out-label <n>]")                                         \
22385 _(sr_mpls_policy_add,                                                   \
22386   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22387 _(sr_mpls_policy_del,                                                   \
22388   "bsid <id>")                                                          \
22389 _(bier_table_add_del,                                                   \
22390   "<label> <sub-domain> <set> <bsl> [del]")                             \
22391 _(bier_route_add_del,                                                   \
22392   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22393   "[<intfc> | sw_if_index <id>]"                                        \
22394   "[weight <n>] [del] [multipath]")                                     \
22395 _(proxy_arp_add_del,                                                    \
22396   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22397 _(proxy_arp_intfc_enable_disable,                                       \
22398   "<intfc> | sw_if_index <id> enable | disable")                        \
22399 _(sw_interface_set_unnumbered,                                          \
22400   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22401 _(ip_neighbor_add_del,                                                  \
22402   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22403   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22404 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22405 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22406   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22407   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22408   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22409 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22410 _(reset_fib, "vrf <n> [ipv6]")                                          \
22411 _(dhcp_proxy_config,                                                    \
22412   "svr <v46-address> src <v46-address>\n"                               \
22413    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22414 _(dhcp_proxy_set_vss,                                                   \
22415   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22416 _(dhcp_proxy_dump, "ip6")                                               \
22417 _(dhcp_client_config,                                                   \
22418   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22419 _(set_ip_flow_hash,                                                     \
22420   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22421 _(sw_interface_ip6_enable_disable,                                      \
22422   "<intfc> | sw_if_index <id> enable | disable")                        \
22423 _(ip6nd_proxy_add_del,                                                  \
22424   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22425 _(ip6nd_proxy_dump, "")                                                 \
22426 _(sw_interface_ip6nd_ra_prefix,                                         \
22427   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22428   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22429   "[nolink] [isno]")                                                    \
22430 _(sw_interface_ip6nd_ra_config,                                         \
22431   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22432   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22433   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22434 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22435 _(l2_patch_add_del,                                                     \
22436   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22437   "enable | disable")                                                   \
22438 _(sr_localsid_add_del,                                                  \
22439   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22440   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22441 _(classify_add_del_table,                                               \
22442   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22443   " [del] [del-chain] mask <mask-value>\n"                              \
22444   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22445   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22446 _(classify_add_del_session,                                             \
22447   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22448   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22449   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22450   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22451 _(classify_set_interface_ip_table,                                      \
22452   "<intfc> | sw_if_index <nn> table <nn>")                              \
22453 _(classify_set_interface_l2_tables,                                     \
22454   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22455   "  [other-table <nn>]")                                               \
22456 _(get_node_index, "node <node-name")                                    \
22457 _(add_node_next, "node <node-name> next <next-node-name>")              \
22458 _(l2tpv3_create_tunnel,                                                 \
22459   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22460   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22461   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22462 _(l2tpv3_set_tunnel_cookies,                                            \
22463   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22464   "[new_remote_cookie <nn>]\n")                                         \
22465 _(l2tpv3_interface_enable_disable,                                      \
22466   "<intfc> | sw_if_index <nn> enable | disable")                        \
22467 _(l2tpv3_set_lookup_key,                                                \
22468   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22469 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22470 _(vxlan_offload_rx,                                                     \
22471   "hw { <interface name> | hw_if_index <nn>} "                          \
22472   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22473 _(vxlan_add_del_tunnel,                                                 \
22474   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22475   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22476   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22477 _(geneve_add_del_tunnel,                                                \
22478   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22479   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22480   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22481 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22482 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22483 _(gre_tunnel_add_del,                                                   \
22484   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22485   "[teb | erspan <session-id>] [del]")                                  \
22486 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22487 _(l2_fib_clear_table, "")                                               \
22488 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22489 _(l2_interface_vlan_tag_rewrite,                                        \
22490   "<intfc> | sw_if_index <nn> \n"                                       \
22491   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22492   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22493 _(create_vhost_user_if,                                                 \
22494         "socket <filename> [server] [renumber <dev_instance>] "         \
22495         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22496         "[mac <mac_address>]")                                          \
22497 _(modify_vhost_user_if,                                                 \
22498         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22499         "[server] [renumber <dev_instance>]")                           \
22500 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22501 _(sw_interface_vhost_user_dump, "")                                     \
22502 _(show_version, "")                                                     \
22503 _(show_threads, "")                                                     \
22504 _(vxlan_gpe_add_del_tunnel,                                             \
22505   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22506   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22507   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22508   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22509 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22510 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22511 _(interface_name_renumber,                                              \
22512   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22513 _(input_acl_set_interface,                                              \
22514   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22515   "  [l2-table <nn>] [del]")                                            \
22516 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22517 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22518   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22519 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22520 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22521 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22522 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22523 _(ip_dump, "ipv4 | ipv6")                                               \
22524 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22525 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22526   "  spid_id <n> ")                                                     \
22527 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22528   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22529   "  integ_alg <alg> integ_key <hex>")                                  \
22530 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22531   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22532   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22533   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22534 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22535 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22536   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22537   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22538   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22539   "  [instance <n>]")     \
22540 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22541 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22542   "  <alg> <hex>\n")                                                    \
22543 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22544 _(delete_loopback,"sw_if_index <nn>")                                   \
22545 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22546 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22547 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22548 _(want_interface_events,  "enable|disable")                             \
22549 _(get_first_msg_id, "client <name>")                                    \
22550 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22551 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22552   "fib-id <nn> [ip4][ip6][default]")                                    \
22553 _(get_node_graph, " ")                                                  \
22554 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22555 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22556 _(ioam_disable, "")                                                     \
22557 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22558                             " sw_if_index <sw_if_index> p <priority> "  \
22559                             "w <weight>] [del]")                        \
22560 _(one_add_del_locator, "locator-set <locator_name> "                    \
22561                         "iface <intf> | sw_if_index <sw_if_index> "     \
22562                         "p <priority> w <weight> [del]")                \
22563 _(one_add_del_local_eid,"vni <vni> eid "                                \
22564                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22565                          "locator-set <locator_name> [del]"             \
22566                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22567 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22568 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22569 _(one_enable_disable, "enable|disable")                                 \
22570 _(one_map_register_enable_disable, "enable|disable")                    \
22571 _(one_map_register_fallback_threshold, "<value>")                       \
22572 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22573 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22574                                "[seid <seid>] "                         \
22575                                "rloc <locator> p <prio> "               \
22576                                "w <weight> [rloc <loc> ... ] "          \
22577                                "action <action> [del-all]")             \
22578 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22579                           "<local-eid>")                                \
22580 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22581 _(one_use_petr, "ip-address> | disable")                                \
22582 _(one_map_request_mode, "src-dst|dst-only")                             \
22583 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22584 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22585 _(one_locator_set_dump, "[local | remote]")                             \
22586 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22587 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22588                        "[local] | [remote]")                            \
22589 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22590 _(one_ndp_bd_get, "")                                                   \
22591 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22592 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22593 _(one_l2_arp_bd_get, "")                                                \
22594 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22595 _(one_stats_enable_disable, "enable|disable")                           \
22596 _(show_one_stats_enable_disable, "")                                    \
22597 _(one_eid_table_vni_dump, "")                                           \
22598 _(one_eid_table_map_dump, "l2|l3")                                      \
22599 _(one_map_resolver_dump, "")                                            \
22600 _(one_map_server_dump, "")                                              \
22601 _(one_adjacencies_get, "vni <vni>")                                     \
22602 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22603 _(show_one_rloc_probe_state, "")                                        \
22604 _(show_one_map_register_state, "")                                      \
22605 _(show_one_status, "")                                                  \
22606 _(one_stats_dump, "")                                                   \
22607 _(one_stats_flush, "")                                                  \
22608 _(one_get_map_request_itr_rlocs, "")                                    \
22609 _(one_map_register_set_ttl, "<ttl>")                                    \
22610 _(one_set_transport_protocol, "udp|api")                                \
22611 _(one_get_transport_protocol, "")                                       \
22612 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22613 _(one_show_xtr_mode, "")                                                \
22614 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22615 _(one_show_pitr_mode, "")                                               \
22616 _(one_enable_disable_petr_mode, "enable|disable")                       \
22617 _(one_show_petr_mode, "")                                               \
22618 _(show_one_nsh_mapping, "")                                             \
22619 _(show_one_pitr, "")                                                    \
22620 _(show_one_use_petr, "")                                                \
22621 _(show_one_map_request_mode, "")                                        \
22622 _(show_one_map_register_ttl, "")                                        \
22623 _(show_one_map_register_fallback_threshold, "")                         \
22624 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22625                             " sw_if_index <sw_if_index> p <priority> "  \
22626                             "w <weight>] [del]")                        \
22627 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22628                         "iface <intf> | sw_if_index <sw_if_index> "     \
22629                         "p <priority> w <weight> [del]")                \
22630 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22631                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22632                          "locator-set <locator_name> [del]"             \
22633                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22634 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22635 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22636 _(lisp_enable_disable, "enable|disable")                                \
22637 _(lisp_map_register_enable_disable, "enable|disable")                   \
22638 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22639 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22640                                "[seid <seid>] "                         \
22641                                "rloc <locator> p <prio> "               \
22642                                "w <weight> [rloc <loc> ... ] "          \
22643                                "action <action> [del-all]")             \
22644 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22645                           "<local-eid>")                                \
22646 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22647 _(lisp_use_petr, "<ip-address> | disable")                              \
22648 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22649 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22650 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22651 _(lisp_locator_set_dump, "[local | remote]")                            \
22652 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22653 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22654                        "[local] | [remote]")                            \
22655 _(lisp_eid_table_vni_dump, "")                                          \
22656 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22657 _(lisp_map_resolver_dump, "")                                           \
22658 _(lisp_map_server_dump, "")                                             \
22659 _(lisp_adjacencies_get, "vni <vni>")                                    \
22660 _(gpe_fwd_entry_vnis_get, "")                                           \
22661 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22662 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22663                                 "[table <table-id>]")                   \
22664 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22665 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22666 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22667 _(gpe_get_encap_mode, "")                                               \
22668 _(lisp_gpe_add_del_iface, "up|down")                                    \
22669 _(lisp_gpe_enable_disable, "enable|disable")                            \
22670 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22671   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22672 _(show_lisp_rloc_probe_state, "")                                       \
22673 _(show_lisp_map_register_state, "")                                     \
22674 _(show_lisp_status, "")                                                 \
22675 _(lisp_get_map_request_itr_rlocs, "")                                   \
22676 _(show_lisp_pitr, "")                                                   \
22677 _(show_lisp_use_petr, "")                                               \
22678 _(show_lisp_map_request_mode, "")                                       \
22679 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22680 _(af_packet_delete, "name <host interface name>")                       \
22681 _(af_packet_dump, "")                                                   \
22682 _(policer_add_del, "name <policer name> <params> [del]")                \
22683 _(policer_dump, "[name <policer name>]")                                \
22684 _(policer_classify_set_interface,                                       \
22685   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22686   "  [l2-table <nn>] [del]")                                            \
22687 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22688 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22689     "[master|slave]")                                                   \
22690 _(netmap_delete, "name <interface name>")                               \
22691 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22692 _(mpls_fib_dump, "")                                                    \
22693 _(classify_table_ids, "")                                               \
22694 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22695 _(classify_table_info, "table_id <nn>")                                 \
22696 _(classify_session_dump, "table_id <nn>")                               \
22697 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22698     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22699     "[template_interval <nn>] [udp_checksum]")                          \
22700 _(ipfix_exporter_dump, "")                                              \
22701 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22702 _(ipfix_classify_stream_dump, "")                                       \
22703 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22704 _(ipfix_classify_table_dump, "")                                        \
22705 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22706 _(sw_interface_span_dump, "[l2]")                                           \
22707 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22708 _(pg_create_interface, "if_id <nn>")                                    \
22709 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22710 _(pg_enable_disable, "[stream <id>] disable")                           \
22711 _(ip_source_and_port_range_check_add_del,                               \
22712   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22713 _(ip_source_and_port_range_check_interface_add_del,                     \
22714   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22715   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22716 _(ipsec_gre_tunnel_add_del,                                             \
22717   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22718 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22719 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22720 _(l2_interface_pbb_tag_rewrite,                                         \
22721   "<intfc> | sw_if_index <nn> \n"                                       \
22722   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22723   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22724 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22725 _(flow_classify_set_interface,                                          \
22726   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22727 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22728 _(ip_fib_dump, "")                                                      \
22729 _(ip_mfib_dump, "")                                                     \
22730 _(ip6_fib_dump, "")                                                     \
22731 _(ip6_mfib_dump, "")                                                    \
22732 _(feature_enable_disable, "arc_name <arc_name> "                        \
22733   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22734 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22735 "[disable]")                                                            \
22736 _(l2_xconnect_dump, "")                                                 \
22737 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22738 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22739 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22740 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22741 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22742 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22743 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22744   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22745 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22746 _(sock_init_shm, "size <nnn>")                                          \
22747 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22748 _(dns_enable_disable, "[enable][disable]")                              \
22749 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22750 _(dns_resolve_name, "<hostname>")                                       \
22751 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22752 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22753 _(dns_resolve_name, "<hostname>")                                       \
22754 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22755   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22756 _(session_rules_dump, "")                                               \
22757 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22758 _(output_acl_set_interface,                                             \
22759   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22760   "  [l2-table <nn>] [del]")                                            \
22761 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22762
22763 /* List of command functions, CLI names map directly to functions */
22764 #define foreach_cli_function                                    \
22765 _(comment, "usage: comment <ignore-rest-of-line>")              \
22766 _(dump_interface_table, "usage: dump_interface_table")          \
22767 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22768 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22769 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22770 _(dump_macro_table, "usage: dump_macro_table ")                 \
22771 _(dump_node_table, "usage: dump_node_table")                    \
22772 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22773 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22774 _(echo, "usage: echo <message>")                                \
22775 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22776 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22777 _(help, "usage: help")                                          \
22778 _(q, "usage: quit")                                             \
22779 _(quit, "usage: quit")                                          \
22780 _(search_node_table, "usage: search_node_table <name>...")      \
22781 _(set, "usage: set <variable-name> <value>")                    \
22782 _(script, "usage: script <file-name>")                          \
22783 _(statseg, "usage: statseg");                                   \
22784 _(unset, "usage: unset <variable-name>")
22785
22786 #define _(N,n)                                  \
22787     static void vl_api_##n##_t_handler_uni      \
22788     (vl_api_##n##_t * mp)                       \
22789     {                                           \
22790         vat_main_t * vam = &vat_main;           \
22791         if (vam->json_output) {                 \
22792             vl_api_##n##_t_handler_json(mp);    \
22793         } else {                                \
22794             vl_api_##n##_t_handler(mp);         \
22795         }                                       \
22796     }
22797 foreach_vpe_api_reply_msg;
22798 #if VPP_API_TEST_BUILTIN == 0
22799 foreach_standalone_reply_msg;
22800 #endif
22801 #undef _
22802
22803 void
22804 vat_api_hookup (vat_main_t * vam)
22805 {
22806 #define _(N,n)                                                  \
22807     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22808                            vl_api_##n##_t_handler_uni,          \
22809                            vl_noop_handler,                     \
22810                            vl_api_##n##_t_endian,               \
22811                            vl_api_##n##_t_print,                \
22812                            sizeof(vl_api_##n##_t), 1);
22813   foreach_vpe_api_reply_msg;
22814 #if VPP_API_TEST_BUILTIN == 0
22815   foreach_standalone_reply_msg;
22816 #endif
22817 #undef _
22818
22819 #if (VPP_API_TEST_BUILTIN==0)
22820   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22821
22822   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22823
22824   vam->function_by_name = hash_create_string (0, sizeof (uword));
22825
22826   vam->help_by_name = hash_create_string (0, sizeof (uword));
22827 #endif
22828
22829   /* API messages we can send */
22830 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22831   foreach_vpe_api_msg;
22832 #undef _
22833
22834   /* Help strings */
22835 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22836   foreach_vpe_api_msg;
22837 #undef _
22838
22839   /* CLI functions */
22840 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22841   foreach_cli_function;
22842 #undef _
22843
22844   /* Help strings */
22845 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22846   foreach_cli_function;
22847 #undef _
22848 }
22849
22850 #if VPP_API_TEST_BUILTIN
22851 static clib_error_t *
22852 vat_api_hookup_shim (vlib_main_t * vm)
22853 {
22854   vat_api_hookup (&vat_main);
22855   return 0;
22856 }
22857
22858 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22859 #endif
22860
22861 /*
22862  * fd.io coding-style-patch-verification: ON
22863  *
22864  * Local Variables:
22865  * eval: (c-set-style "gnu")
22866  * End:
22867  */