IPSEC: tunnel scaling - don't stack the inbould SA
[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_add_del_tunnel_reply_t_handler
2470   (vl_api_gre_add_del_tunnel_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_add_del_tunnel_reply_t_handler_json
2487   (vl_api_gre_add_del_tunnel_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_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_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_add_del_tunnel (vat_main_t * vam)
13296 {
13297   unformat_input_t *line_input = vam->input;
13298   vl_api_gre_add_del_tunnel_t *mp;
13299   ip4_address_t src4, dst4;
13300   ip6_address_t src6, dst6;
13301   u8 is_add = 1;
13302   u8 ipv4_set = 0;
13303   u8 ipv6_set = 0;
13304   u8 t_type = GRE_TUNNEL_TYPE_L3;
13305   u8 src_set = 0;
13306   u8 dst_set = 0;
13307   u32 outer_fib_id = 0;
13308   u32 session_id = 0;
13309   u32 instance = ~0;
13310   int ret;
13311
13312   clib_memset (&src4, 0, sizeof src4);
13313   clib_memset (&dst4, 0, sizeof dst4);
13314   clib_memset (&src6, 0, sizeof src6);
13315   clib_memset (&dst6, 0, sizeof dst6);
13316
13317   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13318     {
13319       if (unformat (line_input, "del"))
13320         is_add = 0;
13321       else if (unformat (line_input, "instance %d", &instance))
13322         ;
13323       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13324         {
13325           src_set = 1;
13326           ipv4_set = 1;
13327         }
13328       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13329         {
13330           dst_set = 1;
13331           ipv4_set = 1;
13332         }
13333       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13334         {
13335           src_set = 1;
13336           ipv6_set = 1;
13337         }
13338       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13339         {
13340           dst_set = 1;
13341           ipv6_set = 1;
13342         }
13343       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13344         ;
13345       else if (unformat (line_input, "teb"))
13346         t_type = GRE_TUNNEL_TYPE_TEB;
13347       else if (unformat (line_input, "erspan %d", &session_id))
13348         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13349       else
13350         {
13351           errmsg ("parse error '%U'", format_unformat_error, line_input);
13352           return -99;
13353         }
13354     }
13355
13356   if (src_set == 0)
13357     {
13358       errmsg ("tunnel src address not specified");
13359       return -99;
13360     }
13361   if (dst_set == 0)
13362     {
13363       errmsg ("tunnel dst address not specified");
13364       return -99;
13365     }
13366   if (ipv4_set && ipv6_set)
13367     {
13368       errmsg ("both IPv4 and IPv6 addresses specified");
13369       return -99;
13370     }
13371
13372
13373   M (GRE_ADD_DEL_TUNNEL, mp);
13374
13375   if (ipv4_set)
13376     {
13377       clib_memcpy (&mp->src_address, &src4, 4);
13378       clib_memcpy (&mp->dst_address, &dst4, 4);
13379     }
13380   else
13381     {
13382       clib_memcpy (&mp->src_address, &src6, 16);
13383       clib_memcpy (&mp->dst_address, &dst6, 16);
13384     }
13385   mp->instance = htonl (instance);
13386   mp->outer_fib_id = htonl (outer_fib_id);
13387   mp->is_add = is_add;
13388   mp->session_id = htons ((u16) session_id);
13389   mp->tunnel_type = t_type;
13390   mp->is_ipv6 = ipv6_set;
13391
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static void vl_api_gre_tunnel_details_t_handler
13398   (vl_api_gre_tunnel_details_t * mp)
13399 {
13400   vat_main_t *vam = &vat_main;
13401   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13402   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13403
13404   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13405          ntohl (mp->sw_if_index),
13406          ntohl (mp->instance),
13407          format_ip46_address, &src, IP46_TYPE_ANY,
13408          format_ip46_address, &dst, IP46_TYPE_ANY,
13409          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13410 }
13411
13412 static void vl_api_gre_tunnel_details_t_handler_json
13413   (vl_api_gre_tunnel_details_t * mp)
13414 {
13415   vat_main_t *vam = &vat_main;
13416   vat_json_node_t *node = NULL;
13417   struct in_addr ip4;
13418   struct in6_addr ip6;
13419
13420   if (VAT_JSON_ARRAY != vam->json_tree.type)
13421     {
13422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13423       vat_json_init_array (&vam->json_tree);
13424     }
13425   node = vat_json_array_add (&vam->json_tree);
13426
13427   vat_json_init_object (node);
13428   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13429   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13430   if (!mp->is_ipv6)
13431     {
13432       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13433       vat_json_object_add_ip4 (node, "src_address", ip4);
13434       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13435       vat_json_object_add_ip4 (node, "dst_address", ip4);
13436     }
13437   else
13438     {
13439       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13440       vat_json_object_add_ip6 (node, "src_address", ip6);
13441       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13442       vat_json_object_add_ip6 (node, "dst_address", ip6);
13443     }
13444   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13445   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13446   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13447   vat_json_object_add_uint (node, "session_id", mp->session_id);
13448 }
13449
13450 static int
13451 api_gre_tunnel_dump (vat_main_t * vam)
13452 {
13453   unformat_input_t *i = vam->input;
13454   vl_api_gre_tunnel_dump_t *mp;
13455   vl_api_control_ping_t *mp_ping;
13456   u32 sw_if_index;
13457   u8 sw_if_index_set = 0;
13458   int ret;
13459
13460   /* Parse args required to build the message */
13461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13462     {
13463       if (unformat (i, "sw_if_index %d", &sw_if_index))
13464         sw_if_index_set = 1;
13465       else
13466         break;
13467     }
13468
13469   if (sw_if_index_set == 0)
13470     {
13471       sw_if_index = ~0;
13472     }
13473
13474   if (!vam->json_output)
13475     {
13476       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13477              "sw_if_index", "instance", "src_address", "dst_address",
13478              "tunnel_type", "outer_fib_id", "session_id");
13479     }
13480
13481   /* Get list of gre-tunnel interfaces */
13482   M (GRE_TUNNEL_DUMP, mp);
13483
13484   mp->sw_if_index = htonl (sw_if_index);
13485
13486   S (mp);
13487
13488   /* Use a control ping for synchronization */
13489   MPING (CONTROL_PING, mp_ping);
13490   S (mp_ping);
13491
13492   W (ret);
13493   return ret;
13494 }
13495
13496 static int
13497 api_l2_fib_clear_table (vat_main_t * vam)
13498 {
13499 //  unformat_input_t * i = vam->input;
13500   vl_api_l2_fib_clear_table_t *mp;
13501   int ret;
13502
13503   M (L2_FIB_CLEAR_TABLE, mp);
13504
13505   S (mp);
13506   W (ret);
13507   return ret;
13508 }
13509
13510 static int
13511 api_l2_interface_efp_filter (vat_main_t * vam)
13512 {
13513   unformat_input_t *i = vam->input;
13514   vl_api_l2_interface_efp_filter_t *mp;
13515   u32 sw_if_index;
13516   u8 enable = 1;
13517   u8 sw_if_index_set = 0;
13518   int ret;
13519
13520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13521     {
13522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13523         sw_if_index_set = 1;
13524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13525         sw_if_index_set = 1;
13526       else if (unformat (i, "enable"))
13527         enable = 1;
13528       else if (unformat (i, "disable"))
13529         enable = 0;
13530       else
13531         {
13532           clib_warning ("parse error '%U'", format_unformat_error, i);
13533           return -99;
13534         }
13535     }
13536
13537   if (sw_if_index_set == 0)
13538     {
13539       errmsg ("missing sw_if_index");
13540       return -99;
13541     }
13542
13543   M (L2_INTERFACE_EFP_FILTER, mp);
13544
13545   mp->sw_if_index = ntohl (sw_if_index);
13546   mp->enable_disable = enable;
13547
13548   S (mp);
13549   W (ret);
13550   return ret;
13551 }
13552
13553 #define foreach_vtr_op                          \
13554 _("disable",  L2_VTR_DISABLED)                  \
13555 _("push-1",  L2_VTR_PUSH_1)                     \
13556 _("push-2",  L2_VTR_PUSH_2)                     \
13557 _("pop-1",  L2_VTR_POP_1)                       \
13558 _("pop-2",  L2_VTR_POP_2)                       \
13559 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13560 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13561 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13562 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13563
13564 static int
13565 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13566 {
13567   unformat_input_t *i = vam->input;
13568   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13569   u32 sw_if_index;
13570   u8 sw_if_index_set = 0;
13571   u8 vtr_op_set = 0;
13572   u32 vtr_op = 0;
13573   u32 push_dot1q = 1;
13574   u32 tag1 = ~0;
13575   u32 tag2 = ~0;
13576   int ret;
13577
13578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13581         sw_if_index_set = 1;
13582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13583         sw_if_index_set = 1;
13584       else if (unformat (i, "vtr_op %d", &vtr_op))
13585         vtr_op_set = 1;
13586 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13587       foreach_vtr_op
13588 #undef _
13589         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13590         ;
13591       else if (unformat (i, "tag1 %d", &tag1))
13592         ;
13593       else if (unformat (i, "tag2 %d", &tag2))
13594         ;
13595       else
13596         {
13597           clib_warning ("parse error '%U'", format_unformat_error, i);
13598           return -99;
13599         }
13600     }
13601
13602   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13603     {
13604       errmsg ("missing vtr operation or sw_if_index");
13605       return -99;
13606     }
13607
13608   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13609   mp->sw_if_index = ntohl (sw_if_index);
13610   mp->vtr_op = ntohl (vtr_op);
13611   mp->push_dot1q = ntohl (push_dot1q);
13612   mp->tag1 = ntohl (tag1);
13613   mp->tag2 = ntohl (tag2);
13614
13615   S (mp);
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static int
13621 api_create_vhost_user_if (vat_main_t * vam)
13622 {
13623   unformat_input_t *i = vam->input;
13624   vl_api_create_vhost_user_if_t *mp;
13625   u8 *file_name;
13626   u8 is_server = 0;
13627   u8 file_name_set = 0;
13628   u32 custom_dev_instance = ~0;
13629   u8 hwaddr[6];
13630   u8 use_custom_mac = 0;
13631   u8 disable_mrg_rxbuf = 0;
13632   u8 disable_indirect_desc = 0;
13633   u8 *tag = 0;
13634   int ret;
13635
13636   /* Shut up coverity */
13637   clib_memset (hwaddr, 0, sizeof (hwaddr));
13638
13639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13640     {
13641       if (unformat (i, "socket %s", &file_name))
13642         {
13643           file_name_set = 1;
13644         }
13645       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13646         ;
13647       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13648         use_custom_mac = 1;
13649       else if (unformat (i, "server"))
13650         is_server = 1;
13651       else if (unformat (i, "disable_mrg_rxbuf"))
13652         disable_mrg_rxbuf = 1;
13653       else if (unformat (i, "disable_indirect_desc"))
13654         disable_indirect_desc = 1;
13655       else if (unformat (i, "tag %s", &tag))
13656         ;
13657       else
13658         break;
13659     }
13660
13661   if (file_name_set == 0)
13662     {
13663       errmsg ("missing socket file name");
13664       return -99;
13665     }
13666
13667   if (vec_len (file_name) > 255)
13668     {
13669       errmsg ("socket file name too long");
13670       return -99;
13671     }
13672   vec_add1 (file_name, 0);
13673
13674   M (CREATE_VHOST_USER_IF, mp);
13675
13676   mp->is_server = is_server;
13677   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13678   mp->disable_indirect_desc = disable_indirect_desc;
13679   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13680   vec_free (file_name);
13681   if (custom_dev_instance != ~0)
13682     {
13683       mp->renumber = 1;
13684       mp->custom_dev_instance = ntohl (custom_dev_instance);
13685     }
13686
13687   mp->use_custom_mac = use_custom_mac;
13688   clib_memcpy (mp->mac_address, hwaddr, 6);
13689   if (tag)
13690     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13691   vec_free (tag);
13692
13693   S (mp);
13694   W (ret);
13695   return ret;
13696 }
13697
13698 static int
13699 api_modify_vhost_user_if (vat_main_t * vam)
13700 {
13701   unformat_input_t *i = vam->input;
13702   vl_api_modify_vhost_user_if_t *mp;
13703   u8 *file_name;
13704   u8 is_server = 0;
13705   u8 file_name_set = 0;
13706   u32 custom_dev_instance = ~0;
13707   u8 sw_if_index_set = 0;
13708   u32 sw_if_index = (u32) ~ 0;
13709   int ret;
13710
13711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13712     {
13713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13714         sw_if_index_set = 1;
13715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13716         sw_if_index_set = 1;
13717       else if (unformat (i, "socket %s", &file_name))
13718         {
13719           file_name_set = 1;
13720         }
13721       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13722         ;
13723       else if (unformat (i, "server"))
13724         is_server = 1;
13725       else
13726         break;
13727     }
13728
13729   if (sw_if_index_set == 0)
13730     {
13731       errmsg ("missing sw_if_index or interface name");
13732       return -99;
13733     }
13734
13735   if (file_name_set == 0)
13736     {
13737       errmsg ("missing socket file name");
13738       return -99;
13739     }
13740
13741   if (vec_len (file_name) > 255)
13742     {
13743       errmsg ("socket file name too long");
13744       return -99;
13745     }
13746   vec_add1 (file_name, 0);
13747
13748   M (MODIFY_VHOST_USER_IF, mp);
13749
13750   mp->sw_if_index = ntohl (sw_if_index);
13751   mp->is_server = is_server;
13752   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13753   vec_free (file_name);
13754   if (custom_dev_instance != ~0)
13755     {
13756       mp->renumber = 1;
13757       mp->custom_dev_instance = ntohl (custom_dev_instance);
13758     }
13759
13760   S (mp);
13761   W (ret);
13762   return ret;
13763 }
13764
13765 static int
13766 api_delete_vhost_user_if (vat_main_t * vam)
13767 {
13768   unformat_input_t *i = vam->input;
13769   vl_api_delete_vhost_user_if_t *mp;
13770   u32 sw_if_index = ~0;
13771   u8 sw_if_index_set = 0;
13772   int ret;
13773
13774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13775     {
13776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13777         sw_if_index_set = 1;
13778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13779         sw_if_index_set = 1;
13780       else
13781         break;
13782     }
13783
13784   if (sw_if_index_set == 0)
13785     {
13786       errmsg ("missing sw_if_index or interface name");
13787       return -99;
13788     }
13789
13790
13791   M (DELETE_VHOST_USER_IF, mp);
13792
13793   mp->sw_if_index = ntohl (sw_if_index);
13794
13795   S (mp);
13796   W (ret);
13797   return ret;
13798 }
13799
13800 static void vl_api_sw_interface_vhost_user_details_t_handler
13801   (vl_api_sw_interface_vhost_user_details_t * mp)
13802 {
13803   vat_main_t *vam = &vat_main;
13804
13805   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13806          (char *) mp->interface_name,
13807          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13808          clib_net_to_host_u64 (mp->features), mp->is_server,
13809          ntohl (mp->num_regions), (char *) mp->sock_filename);
13810   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13811 }
13812
13813 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13814   (vl_api_sw_interface_vhost_user_details_t * mp)
13815 {
13816   vat_main_t *vam = &vat_main;
13817   vat_json_node_t *node = NULL;
13818
13819   if (VAT_JSON_ARRAY != vam->json_tree.type)
13820     {
13821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13822       vat_json_init_array (&vam->json_tree);
13823     }
13824   node = vat_json_array_add (&vam->json_tree);
13825
13826   vat_json_init_object (node);
13827   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13828   vat_json_object_add_string_copy (node, "interface_name",
13829                                    mp->interface_name);
13830   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13831                             ntohl (mp->virtio_net_hdr_sz));
13832   vat_json_object_add_uint (node, "features",
13833                             clib_net_to_host_u64 (mp->features));
13834   vat_json_object_add_uint (node, "is_server", mp->is_server);
13835   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13836   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13837   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13838 }
13839
13840 static int
13841 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13842 {
13843   vl_api_sw_interface_vhost_user_dump_t *mp;
13844   vl_api_control_ping_t *mp_ping;
13845   int ret;
13846   print (vam->ofp,
13847          "Interface name            idx hdr_sz features server regions filename");
13848
13849   /* Get list of vhost-user interfaces */
13850   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13851   S (mp);
13852
13853   /* Use a control ping for synchronization */
13854   MPING (CONTROL_PING, mp_ping);
13855   S (mp_ping);
13856
13857   W (ret);
13858   return ret;
13859 }
13860
13861 static int
13862 api_show_version (vat_main_t * vam)
13863 {
13864   vl_api_show_version_t *mp;
13865   int ret;
13866
13867   M (SHOW_VERSION, mp);
13868
13869   S (mp);
13870   W (ret);
13871   return ret;
13872 }
13873
13874
13875 static int
13876 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13877 {
13878   unformat_input_t *line_input = vam->input;
13879   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13880   ip4_address_t local4, remote4;
13881   ip6_address_t local6, remote6;
13882   u8 is_add = 1;
13883   u8 ipv4_set = 0, ipv6_set = 0;
13884   u8 local_set = 0;
13885   u8 remote_set = 0;
13886   u8 grp_set = 0;
13887   u32 mcast_sw_if_index = ~0;
13888   u32 encap_vrf_id = 0;
13889   u32 decap_vrf_id = 0;
13890   u8 protocol = ~0;
13891   u32 vni;
13892   u8 vni_set = 0;
13893   int ret;
13894
13895   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13896   clib_memset (&local4, 0, sizeof local4);
13897   clib_memset (&remote4, 0, sizeof remote4);
13898   clib_memset (&local6, 0, sizeof local6);
13899   clib_memset (&remote6, 0, sizeof remote6);
13900
13901   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13902     {
13903       if (unformat (line_input, "del"))
13904         is_add = 0;
13905       else if (unformat (line_input, "local %U",
13906                          unformat_ip4_address, &local4))
13907         {
13908           local_set = 1;
13909           ipv4_set = 1;
13910         }
13911       else if (unformat (line_input, "remote %U",
13912                          unformat_ip4_address, &remote4))
13913         {
13914           remote_set = 1;
13915           ipv4_set = 1;
13916         }
13917       else if (unformat (line_input, "local %U",
13918                          unformat_ip6_address, &local6))
13919         {
13920           local_set = 1;
13921           ipv6_set = 1;
13922         }
13923       else if (unformat (line_input, "remote %U",
13924                          unformat_ip6_address, &remote6))
13925         {
13926           remote_set = 1;
13927           ipv6_set = 1;
13928         }
13929       else if (unformat (line_input, "group %U %U",
13930                          unformat_ip4_address, &remote4,
13931                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13932         {
13933           grp_set = remote_set = 1;
13934           ipv4_set = 1;
13935         }
13936       else if (unformat (line_input, "group %U",
13937                          unformat_ip4_address, &remote4))
13938         {
13939           grp_set = remote_set = 1;
13940           ipv4_set = 1;
13941         }
13942       else if (unformat (line_input, "group %U %U",
13943                          unformat_ip6_address, &remote6,
13944                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13945         {
13946           grp_set = remote_set = 1;
13947           ipv6_set = 1;
13948         }
13949       else if (unformat (line_input, "group %U",
13950                          unformat_ip6_address, &remote6))
13951         {
13952           grp_set = remote_set = 1;
13953           ipv6_set = 1;
13954         }
13955       else
13956         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13957         ;
13958       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13959         ;
13960       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13961         ;
13962       else if (unformat (line_input, "vni %d", &vni))
13963         vni_set = 1;
13964       else if (unformat (line_input, "next-ip4"))
13965         protocol = 1;
13966       else if (unformat (line_input, "next-ip6"))
13967         protocol = 2;
13968       else if (unformat (line_input, "next-ethernet"))
13969         protocol = 3;
13970       else if (unformat (line_input, "next-nsh"))
13971         protocol = 4;
13972       else
13973         {
13974           errmsg ("parse error '%U'", format_unformat_error, line_input);
13975           return -99;
13976         }
13977     }
13978
13979   if (local_set == 0)
13980     {
13981       errmsg ("tunnel local address not specified");
13982       return -99;
13983     }
13984   if (remote_set == 0)
13985     {
13986       errmsg ("tunnel remote address not specified");
13987       return -99;
13988     }
13989   if (grp_set && mcast_sw_if_index == ~0)
13990     {
13991       errmsg ("tunnel nonexistent multicast device");
13992       return -99;
13993     }
13994   if (ipv4_set && ipv6_set)
13995     {
13996       errmsg ("both IPv4 and IPv6 addresses specified");
13997       return -99;
13998     }
13999
14000   if (vni_set == 0)
14001     {
14002       errmsg ("vni not specified");
14003       return -99;
14004     }
14005
14006   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14007
14008
14009   if (ipv6_set)
14010     {
14011       clib_memcpy (&mp->local, &local6, sizeof (local6));
14012       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14013     }
14014   else
14015     {
14016       clib_memcpy (&mp->local, &local4, sizeof (local4));
14017       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14018     }
14019
14020   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14021   mp->encap_vrf_id = ntohl (encap_vrf_id);
14022   mp->decap_vrf_id = ntohl (decap_vrf_id);
14023   mp->protocol = protocol;
14024   mp->vni = ntohl (vni);
14025   mp->is_add = is_add;
14026   mp->is_ipv6 = ipv6_set;
14027
14028   S (mp);
14029   W (ret);
14030   return ret;
14031 }
14032
14033 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14034   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14035 {
14036   vat_main_t *vam = &vat_main;
14037   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14038   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14039
14040   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14041          ntohl (mp->sw_if_index),
14042          format_ip46_address, &local, IP46_TYPE_ANY,
14043          format_ip46_address, &remote, IP46_TYPE_ANY,
14044          ntohl (mp->vni), mp->protocol,
14045          ntohl (mp->mcast_sw_if_index),
14046          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14047 }
14048
14049
14050 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14051   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14052 {
14053   vat_main_t *vam = &vat_main;
14054   vat_json_node_t *node = NULL;
14055   struct in_addr ip4;
14056   struct in6_addr ip6;
14057
14058   if (VAT_JSON_ARRAY != vam->json_tree.type)
14059     {
14060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14061       vat_json_init_array (&vam->json_tree);
14062     }
14063   node = vat_json_array_add (&vam->json_tree);
14064
14065   vat_json_init_object (node);
14066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14067   if (mp->is_ipv6)
14068     {
14069       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14070       vat_json_object_add_ip6 (node, "local", ip6);
14071       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14072       vat_json_object_add_ip6 (node, "remote", ip6);
14073     }
14074   else
14075     {
14076       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14077       vat_json_object_add_ip4 (node, "local", ip4);
14078       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14079       vat_json_object_add_ip4 (node, "remote", ip4);
14080     }
14081   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14082   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14083   vat_json_object_add_uint (node, "mcast_sw_if_index",
14084                             ntohl (mp->mcast_sw_if_index));
14085   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14086   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14087   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14088 }
14089
14090 static int
14091 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14092 {
14093   unformat_input_t *i = vam->input;
14094   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14095   vl_api_control_ping_t *mp_ping;
14096   u32 sw_if_index;
14097   u8 sw_if_index_set = 0;
14098   int ret;
14099
14100   /* Parse args required to build the message */
14101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14102     {
14103       if (unformat (i, "sw_if_index %d", &sw_if_index))
14104         sw_if_index_set = 1;
14105       else
14106         break;
14107     }
14108
14109   if (sw_if_index_set == 0)
14110     {
14111       sw_if_index = ~0;
14112     }
14113
14114   if (!vam->json_output)
14115     {
14116       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14117              "sw_if_index", "local", "remote", "vni",
14118              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14119     }
14120
14121   /* Get list of vxlan-tunnel interfaces */
14122   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14123
14124   mp->sw_if_index = htonl (sw_if_index);
14125
14126   S (mp);
14127
14128   /* Use a control ping for synchronization */
14129   MPING (CONTROL_PING, mp_ping);
14130   S (mp_ping);
14131
14132   W (ret);
14133   return ret;
14134 }
14135
14136 static void vl_api_l2_fib_table_details_t_handler
14137   (vl_api_l2_fib_table_details_t * mp)
14138 {
14139   vat_main_t *vam = &vat_main;
14140
14141   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14142          "       %d       %d     %d",
14143          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14144          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14145          mp->bvi_mac);
14146 }
14147
14148 static void vl_api_l2_fib_table_details_t_handler_json
14149   (vl_api_l2_fib_table_details_t * mp)
14150 {
14151   vat_main_t *vam = &vat_main;
14152   vat_json_node_t *node = NULL;
14153
14154   if (VAT_JSON_ARRAY != vam->json_tree.type)
14155     {
14156       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14157       vat_json_init_array (&vam->json_tree);
14158     }
14159   node = vat_json_array_add (&vam->json_tree);
14160
14161   vat_json_init_object (node);
14162   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14163   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14164   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14165   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14166   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14167   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14168 }
14169
14170 static int
14171 api_l2_fib_table_dump (vat_main_t * vam)
14172 {
14173   unformat_input_t *i = vam->input;
14174   vl_api_l2_fib_table_dump_t *mp;
14175   vl_api_control_ping_t *mp_ping;
14176   u32 bd_id;
14177   u8 bd_id_set = 0;
14178   int ret;
14179
14180   /* Parse args required to build the message */
14181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14182     {
14183       if (unformat (i, "bd_id %d", &bd_id))
14184         bd_id_set = 1;
14185       else
14186         break;
14187     }
14188
14189   if (bd_id_set == 0)
14190     {
14191       errmsg ("missing bridge domain");
14192       return -99;
14193     }
14194
14195   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14196
14197   /* Get list of l2 fib entries */
14198   M (L2_FIB_TABLE_DUMP, mp);
14199
14200   mp->bd_id = ntohl (bd_id);
14201   S (mp);
14202
14203   /* Use a control ping for synchronization */
14204   MPING (CONTROL_PING, mp_ping);
14205   S (mp_ping);
14206
14207   W (ret);
14208   return ret;
14209 }
14210
14211
14212 static int
14213 api_interface_name_renumber (vat_main_t * vam)
14214 {
14215   unformat_input_t *line_input = vam->input;
14216   vl_api_interface_name_renumber_t *mp;
14217   u32 sw_if_index = ~0;
14218   u32 new_show_dev_instance = ~0;
14219   int ret;
14220
14221   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14224                     &sw_if_index))
14225         ;
14226       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14227         ;
14228       else if (unformat (line_input, "new_show_dev_instance %d",
14229                          &new_show_dev_instance))
14230         ;
14231       else
14232         break;
14233     }
14234
14235   if (sw_if_index == ~0)
14236     {
14237       errmsg ("missing interface name or sw_if_index");
14238       return -99;
14239     }
14240
14241   if (new_show_dev_instance == ~0)
14242     {
14243       errmsg ("missing new_show_dev_instance");
14244       return -99;
14245     }
14246
14247   M (INTERFACE_NAME_RENUMBER, mp);
14248
14249   mp->sw_if_index = ntohl (sw_if_index);
14250   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14251
14252   S (mp);
14253   W (ret);
14254   return ret;
14255 }
14256
14257 static int
14258 api_ip_probe_neighbor (vat_main_t * vam)
14259 {
14260   unformat_input_t *i = vam->input;
14261   vl_api_ip_probe_neighbor_t *mp;
14262   vl_api_address_t dst_adr;
14263   u8 int_set = 0;
14264   u8 adr_set = 0;
14265   u32 sw_if_index;
14266   int ret;
14267
14268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14269     {
14270       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14271         int_set = 1;
14272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14273         int_set = 1;
14274       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14275         adr_set = 1;
14276       else
14277         break;
14278     }
14279
14280   if (int_set == 0)
14281     {
14282       errmsg ("missing interface");
14283       return -99;
14284     }
14285
14286   if (adr_set == 0)
14287     {
14288       errmsg ("missing addresses");
14289       return -99;
14290     }
14291
14292   M (IP_PROBE_NEIGHBOR, mp);
14293
14294   mp->sw_if_index = ntohl (sw_if_index);
14295   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14296
14297   S (mp);
14298   W (ret);
14299   return ret;
14300 }
14301
14302 static int
14303 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14304 {
14305   unformat_input_t *i = vam->input;
14306   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14307   u8 mode = IP_SCAN_V46_NEIGHBORS;
14308   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14309   int ret;
14310
14311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14312     {
14313       if (unformat (i, "ip4"))
14314         mode = IP_SCAN_V4_NEIGHBORS;
14315       else if (unformat (i, "ip6"))
14316         mode = IP_SCAN_V6_NEIGHBORS;
14317       if (unformat (i, "both"))
14318         mode = IP_SCAN_V46_NEIGHBORS;
14319       else if (unformat (i, "disable"))
14320         mode = IP_SCAN_DISABLED;
14321       else if (unformat (i, "interval %d", &interval))
14322         ;
14323       else if (unformat (i, "max-time %d", &time))
14324         ;
14325       else if (unformat (i, "max-update %d", &update))
14326         ;
14327       else if (unformat (i, "delay %d", &delay))
14328         ;
14329       else if (unformat (i, "stale %d", &stale))
14330         ;
14331       else
14332         break;
14333     }
14334
14335   if (interval > 255)
14336     {
14337       errmsg ("interval cannot exceed 255 minutes.");
14338       return -99;
14339     }
14340   if (time > 255)
14341     {
14342       errmsg ("max-time cannot exceed 255 usec.");
14343       return -99;
14344     }
14345   if (update > 255)
14346     {
14347       errmsg ("max-update cannot exceed 255.");
14348       return -99;
14349     }
14350   if (delay > 255)
14351     {
14352       errmsg ("delay cannot exceed 255 msec.");
14353       return -99;
14354     }
14355   if (stale > 255)
14356     {
14357       errmsg ("stale cannot exceed 255 minutes.");
14358       return -99;
14359     }
14360
14361   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14362   mp->mode = mode;
14363   mp->scan_interval = interval;
14364   mp->max_proc_time = time;
14365   mp->max_update = update;
14366   mp->scan_int_delay = delay;
14367   mp->stale_threshold = stale;
14368
14369   S (mp);
14370   W (ret);
14371   return ret;
14372 }
14373
14374 static int
14375 api_want_ip4_arp_events (vat_main_t * vam)
14376 {
14377   unformat_input_t *line_input = vam->input;
14378   vl_api_want_ip4_arp_events_t *mp;
14379   ip4_address_t address;
14380   int address_set = 0;
14381   u32 enable_disable = 1;
14382   int ret;
14383
14384   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14385     {
14386       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14387         address_set = 1;
14388       else if (unformat (line_input, "del"))
14389         enable_disable = 0;
14390       else
14391         break;
14392     }
14393
14394   if (address_set == 0)
14395     {
14396       errmsg ("missing addresses");
14397       return -99;
14398     }
14399
14400   M (WANT_IP4_ARP_EVENTS, mp);
14401   mp->enable_disable = enable_disable;
14402   mp->pid = htonl (getpid ());
14403   clib_memcpy (mp->ip, &address, sizeof (address));
14404
14405   S (mp);
14406   W (ret);
14407   return ret;
14408 }
14409
14410 static int
14411 api_want_ip6_nd_events (vat_main_t * vam)
14412 {
14413   unformat_input_t *line_input = vam->input;
14414   vl_api_want_ip6_nd_events_t *mp;
14415   vl_api_ip6_address_t address;
14416   int address_set = 0;
14417   u32 enable_disable = 1;
14418   int ret;
14419
14420   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14421     {
14422       if (unformat
14423           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14424         address_set = 1;
14425       else if (unformat (line_input, "del"))
14426         enable_disable = 0;
14427       else
14428         break;
14429     }
14430
14431   if (address_set == 0)
14432     {
14433       errmsg ("missing addresses");
14434       return -99;
14435     }
14436
14437   M (WANT_IP6_ND_EVENTS, mp);
14438   mp->enable_disable = enable_disable;
14439   mp->pid = htonl (getpid ());
14440   clib_memcpy (&mp->ip, &address, sizeof (address));
14441
14442   S (mp);
14443   W (ret);
14444   return ret;
14445 }
14446
14447 static int
14448 api_want_l2_macs_events (vat_main_t * vam)
14449 {
14450   unformat_input_t *line_input = vam->input;
14451   vl_api_want_l2_macs_events_t *mp;
14452   u8 enable_disable = 1;
14453   u32 scan_delay = 0;
14454   u32 max_macs_in_event = 0;
14455   u32 learn_limit = 0;
14456   int ret;
14457
14458   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14459     {
14460       if (unformat (line_input, "learn-limit %d", &learn_limit))
14461         ;
14462       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14463         ;
14464       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14465         ;
14466       else if (unformat (line_input, "disable"))
14467         enable_disable = 0;
14468       else
14469         break;
14470     }
14471
14472   M (WANT_L2_MACS_EVENTS, mp);
14473   mp->enable_disable = enable_disable;
14474   mp->pid = htonl (getpid ());
14475   mp->learn_limit = htonl (learn_limit);
14476   mp->scan_delay = (u8) scan_delay;
14477   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14478   S (mp);
14479   W (ret);
14480   return ret;
14481 }
14482
14483 static int
14484 api_input_acl_set_interface (vat_main_t * vam)
14485 {
14486   unformat_input_t *i = vam->input;
14487   vl_api_input_acl_set_interface_t *mp;
14488   u32 sw_if_index;
14489   int sw_if_index_set;
14490   u32 ip4_table_index = ~0;
14491   u32 ip6_table_index = ~0;
14492   u32 l2_table_index = ~0;
14493   u8 is_add = 1;
14494   int ret;
14495
14496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14497     {
14498       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14499         sw_if_index_set = 1;
14500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14501         sw_if_index_set = 1;
14502       else if (unformat (i, "del"))
14503         is_add = 0;
14504       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14505         ;
14506       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14507         ;
14508       else if (unformat (i, "l2-table %d", &l2_table_index))
14509         ;
14510       else
14511         {
14512           clib_warning ("parse error '%U'", format_unformat_error, i);
14513           return -99;
14514         }
14515     }
14516
14517   if (sw_if_index_set == 0)
14518     {
14519       errmsg ("missing interface name or sw_if_index");
14520       return -99;
14521     }
14522
14523   M (INPUT_ACL_SET_INTERFACE, mp);
14524
14525   mp->sw_if_index = ntohl (sw_if_index);
14526   mp->ip4_table_index = ntohl (ip4_table_index);
14527   mp->ip6_table_index = ntohl (ip6_table_index);
14528   mp->l2_table_index = ntohl (l2_table_index);
14529   mp->is_add = is_add;
14530
14531   S (mp);
14532   W (ret);
14533   return ret;
14534 }
14535
14536 static int
14537 api_output_acl_set_interface (vat_main_t * vam)
14538 {
14539   unformat_input_t *i = vam->input;
14540   vl_api_output_acl_set_interface_t *mp;
14541   u32 sw_if_index;
14542   int sw_if_index_set;
14543   u32 ip4_table_index = ~0;
14544   u32 ip6_table_index = ~0;
14545   u32 l2_table_index = ~0;
14546   u8 is_add = 1;
14547   int ret;
14548
14549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14550     {
14551       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14552         sw_if_index_set = 1;
14553       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14554         sw_if_index_set = 1;
14555       else if (unformat (i, "del"))
14556         is_add = 0;
14557       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14558         ;
14559       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14560         ;
14561       else if (unformat (i, "l2-table %d", &l2_table_index))
14562         ;
14563       else
14564         {
14565           clib_warning ("parse error '%U'", format_unformat_error, i);
14566           return -99;
14567         }
14568     }
14569
14570   if (sw_if_index_set == 0)
14571     {
14572       errmsg ("missing interface name or sw_if_index");
14573       return -99;
14574     }
14575
14576   M (OUTPUT_ACL_SET_INTERFACE, mp);
14577
14578   mp->sw_if_index = ntohl (sw_if_index);
14579   mp->ip4_table_index = ntohl (ip4_table_index);
14580   mp->ip6_table_index = ntohl (ip6_table_index);
14581   mp->l2_table_index = ntohl (l2_table_index);
14582   mp->is_add = is_add;
14583
14584   S (mp);
14585   W (ret);
14586   return ret;
14587 }
14588
14589 static int
14590 api_ip_address_dump (vat_main_t * vam)
14591 {
14592   unformat_input_t *i = vam->input;
14593   vl_api_ip_address_dump_t *mp;
14594   vl_api_control_ping_t *mp_ping;
14595   u32 sw_if_index = ~0;
14596   u8 sw_if_index_set = 0;
14597   u8 ipv4_set = 0;
14598   u8 ipv6_set = 0;
14599   int ret;
14600
14601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14602     {
14603       if (unformat (i, "sw_if_index %d", &sw_if_index))
14604         sw_if_index_set = 1;
14605       else
14606         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14607         sw_if_index_set = 1;
14608       else if (unformat (i, "ipv4"))
14609         ipv4_set = 1;
14610       else if (unformat (i, "ipv6"))
14611         ipv6_set = 1;
14612       else
14613         break;
14614     }
14615
14616   if (ipv4_set && ipv6_set)
14617     {
14618       errmsg ("ipv4 and ipv6 flags cannot be both set");
14619       return -99;
14620     }
14621
14622   if ((!ipv4_set) && (!ipv6_set))
14623     {
14624       errmsg ("no ipv4 nor ipv6 flag set");
14625       return -99;
14626     }
14627
14628   if (sw_if_index_set == 0)
14629     {
14630       errmsg ("missing interface name or sw_if_index");
14631       return -99;
14632     }
14633
14634   vam->current_sw_if_index = sw_if_index;
14635   vam->is_ipv6 = ipv6_set;
14636
14637   M (IP_ADDRESS_DUMP, mp);
14638   mp->sw_if_index = ntohl (sw_if_index);
14639   mp->is_ipv6 = ipv6_set;
14640   S (mp);
14641
14642   /* Use a control ping for synchronization */
14643   MPING (CONTROL_PING, mp_ping);
14644   S (mp_ping);
14645
14646   W (ret);
14647   return ret;
14648 }
14649
14650 static int
14651 api_ip_dump (vat_main_t * vam)
14652 {
14653   vl_api_ip_dump_t *mp;
14654   vl_api_control_ping_t *mp_ping;
14655   unformat_input_t *in = vam->input;
14656   int ipv4_set = 0;
14657   int ipv6_set = 0;
14658   int is_ipv6;
14659   int i;
14660   int ret;
14661
14662   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (in, "ipv4"))
14665         ipv4_set = 1;
14666       else if (unformat (in, "ipv6"))
14667         ipv6_set = 1;
14668       else
14669         break;
14670     }
14671
14672   if (ipv4_set && ipv6_set)
14673     {
14674       errmsg ("ipv4 and ipv6 flags cannot be both set");
14675       return -99;
14676     }
14677
14678   if ((!ipv4_set) && (!ipv6_set))
14679     {
14680       errmsg ("no ipv4 nor ipv6 flag set");
14681       return -99;
14682     }
14683
14684   is_ipv6 = ipv6_set;
14685   vam->is_ipv6 = is_ipv6;
14686
14687   /* free old data */
14688   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14689     {
14690       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14691     }
14692   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14693
14694   M (IP_DUMP, mp);
14695   mp->is_ipv6 = ipv6_set;
14696   S (mp);
14697
14698   /* Use a control ping for synchronization */
14699   MPING (CONTROL_PING, mp_ping);
14700   S (mp_ping);
14701
14702   W (ret);
14703   return ret;
14704 }
14705
14706 static int
14707 api_ipsec_spd_add_del (vat_main_t * vam)
14708 {
14709   unformat_input_t *i = vam->input;
14710   vl_api_ipsec_spd_add_del_t *mp;
14711   u32 spd_id = ~0;
14712   u8 is_add = 1;
14713   int ret;
14714
14715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14716     {
14717       if (unformat (i, "spd_id %d", &spd_id))
14718         ;
14719       else if (unformat (i, "del"))
14720         is_add = 0;
14721       else
14722         {
14723           clib_warning ("parse error '%U'", format_unformat_error, i);
14724           return -99;
14725         }
14726     }
14727   if (spd_id == ~0)
14728     {
14729       errmsg ("spd_id must be set");
14730       return -99;
14731     }
14732
14733   M (IPSEC_SPD_ADD_DEL, mp);
14734
14735   mp->spd_id = ntohl (spd_id);
14736   mp->is_add = is_add;
14737
14738   S (mp);
14739   W (ret);
14740   return ret;
14741 }
14742
14743 static int
14744 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14745 {
14746   unformat_input_t *i = vam->input;
14747   vl_api_ipsec_interface_add_del_spd_t *mp;
14748   u32 sw_if_index;
14749   u8 sw_if_index_set = 0;
14750   u32 spd_id = (u32) ~ 0;
14751   u8 is_add = 1;
14752   int ret;
14753
14754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14755     {
14756       if (unformat (i, "del"))
14757         is_add = 0;
14758       else if (unformat (i, "spd_id %d", &spd_id))
14759         ;
14760       else
14761         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14762         sw_if_index_set = 1;
14763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14764         sw_if_index_set = 1;
14765       else
14766         {
14767           clib_warning ("parse error '%U'", format_unformat_error, i);
14768           return -99;
14769         }
14770
14771     }
14772
14773   if (spd_id == (u32) ~ 0)
14774     {
14775       errmsg ("spd_id must be set");
14776       return -99;
14777     }
14778
14779   if (sw_if_index_set == 0)
14780     {
14781       errmsg ("missing interface name or sw_if_index");
14782       return -99;
14783     }
14784
14785   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14786
14787   mp->spd_id = ntohl (spd_id);
14788   mp->sw_if_index = ntohl (sw_if_index);
14789   mp->is_add = is_add;
14790
14791   S (mp);
14792   W (ret);
14793   return ret;
14794 }
14795
14796 static int
14797 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14798 {
14799   unformat_input_t *i = vam->input;
14800   vl_api_ipsec_spd_entry_add_del_t *mp;
14801   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14802   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14803   i32 priority = 0;
14804   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14805   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14806   vl_api_address_t laddr_start = { }, laddr_stop =
14807   {
14808   }, raddr_start =
14809   {
14810   }, raddr_stop =
14811   {
14812   };
14813   int ret;
14814
14815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14816     {
14817       if (unformat (i, "del"))
14818         is_add = 0;
14819       if (unformat (i, "outbound"))
14820         is_outbound = 1;
14821       if (unformat (i, "inbound"))
14822         is_outbound = 0;
14823       else if (unformat (i, "spd_id %d", &spd_id))
14824         ;
14825       else if (unformat (i, "sa_id %d", &sa_id))
14826         ;
14827       else if (unformat (i, "priority %d", &priority))
14828         ;
14829       else if (unformat (i, "protocol %d", &protocol))
14830         ;
14831       else if (unformat (i, "lport_start %d", &lport_start))
14832         ;
14833       else if (unformat (i, "lport_stop %d", &lport_stop))
14834         ;
14835       else if (unformat (i, "rport_start %d", &rport_start))
14836         ;
14837       else if (unformat (i, "rport_stop %d", &rport_stop))
14838         ;
14839       else if (unformat (i, "laddr_start %U",
14840                          unformat_vl_api_address, &laddr_start))
14841         is_ip_any = 0;
14842       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14843                          &laddr_stop))
14844         is_ip_any = 0;
14845       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14846                          &raddr_start))
14847         is_ip_any = 0;
14848       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14849                          &raddr_stop))
14850         is_ip_any = 0;
14851       else
14852         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14853         {
14854           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14855             {
14856               clib_warning ("unsupported action: 'resolve'");
14857               return -99;
14858             }
14859         }
14860       else
14861         {
14862           clib_warning ("parse error '%U'", format_unformat_error, i);
14863           return -99;
14864         }
14865
14866     }
14867
14868   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14869
14870   mp->is_add = is_add;
14871
14872   mp->entry.spd_id = ntohl (spd_id);
14873   mp->entry.priority = ntohl (priority);
14874   mp->entry.is_outbound = is_outbound;
14875
14876   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14877                sizeof (vl_api_address_t));
14878   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14879                sizeof (vl_api_address_t));
14880   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14881                sizeof (vl_api_address_t));
14882   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14883                sizeof (vl_api_address_t));
14884
14885   mp->entry.protocol = (u8) protocol;
14886   mp->entry.local_port_start = ntohs ((u16) lport_start);
14887   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14888   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14889   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14890   mp->entry.policy = (u8) policy;
14891   mp->entry.sa_id = ntohl (sa_id);
14892
14893   S (mp);
14894   W (ret);
14895   return ret;
14896 }
14897
14898 static int
14899 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14900 {
14901   unformat_input_t *i = vam->input;
14902   vl_api_ipsec_sad_entry_add_del_t *mp;
14903   u32 sad_id = 0, spi = 0;
14904   u8 *ck = 0, *ik = 0;
14905   u8 is_add = 1;
14906
14907   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14908   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14909   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14910   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14911   vl_api_address_t tun_src, tun_dst;
14912   int ret;
14913
14914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14915     {
14916       if (unformat (i, "del"))
14917         is_add = 0;
14918       else if (unformat (i, "sad_id %d", &sad_id))
14919         ;
14920       else if (unformat (i, "spi %d", &spi))
14921         ;
14922       else if (unformat (i, "esp"))
14923         protocol = IPSEC_API_PROTO_ESP;
14924       else
14925         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14926         {
14927           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14928           if (ADDRESS_IP6 == tun_src.af)
14929             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14930         }
14931       else
14932         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14933         {
14934           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14935           if (ADDRESS_IP6 == tun_src.af)
14936             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14937         }
14938       else
14939         if (unformat (i, "crypto_alg %U",
14940                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14941         ;
14942       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14943         ;
14944       else if (unformat (i, "integ_alg %U",
14945                          unformat_ipsec_api_integ_alg, &integ_alg))
14946         ;
14947       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14948         ;
14949       else
14950         {
14951           clib_warning ("parse error '%U'", format_unformat_error, i);
14952           return -99;
14953         }
14954
14955     }
14956
14957   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14958
14959   mp->is_add = is_add;
14960   mp->entry.sad_id = ntohl (sad_id);
14961   mp->entry.protocol = protocol;
14962   mp->entry.spi = ntohl (spi);
14963   mp->entry.flags = flags;
14964
14965   mp->entry.crypto_algorithm = crypto_alg;
14966   mp->entry.integrity_algorithm = integ_alg;
14967   mp->entry.crypto_key.length = vec_len (ck);
14968   mp->entry.integrity_key.length = vec_len (ik);
14969
14970   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14971     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14972
14973   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14974     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14975
14976   if (ck)
14977     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14978   if (ik)
14979     clib_memcpy (mp->entry.integrity_key.data, ik,
14980                  mp->entry.integrity_key.length);
14981
14982   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14983     {
14984       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14985                    sizeof (mp->entry.tunnel_src));
14986       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14987                    sizeof (mp->entry.tunnel_dst));
14988     }
14989
14990   S (mp);
14991   W (ret);
14992   return ret;
14993 }
14994
14995 static int
14996 api_ipsec_sa_set_key (vat_main_t * vam)
14997 {
14998   unformat_input_t *i = vam->input;
14999   vl_api_ipsec_sa_set_key_t *mp;
15000   u32 sa_id;
15001   u8 *ck = 0, *ik = 0;
15002   int ret;
15003
15004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15005     {
15006       if (unformat (i, "sa_id %d", &sa_id))
15007         ;
15008       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15009         ;
15010       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15011         ;
15012       else
15013         {
15014           clib_warning ("parse error '%U'", format_unformat_error, i);
15015           return -99;
15016         }
15017     }
15018
15019   M (IPSEC_SA_SET_KEY, mp);
15020
15021   mp->sa_id = ntohl (sa_id);
15022   mp->crypto_key.length = vec_len (ck);
15023   mp->integrity_key.length = vec_len (ik);
15024
15025   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15026     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15027
15028   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15029     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15030
15031   if (ck)
15032     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15033   if (ik)
15034     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15035
15036   S (mp);
15037   W (ret);
15038   return ret;
15039 }
15040
15041 static int
15042 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15043 {
15044   unformat_input_t *i = vam->input;
15045   vl_api_ipsec_tunnel_if_add_del_t *mp;
15046   u32 local_spi = 0, remote_spi = 0;
15047   u32 crypto_alg = 0, integ_alg = 0;
15048   u8 *lck = NULL, *rck = NULL;
15049   u8 *lik = NULL, *rik = NULL;
15050   vl_api_address_t local_ip = { 0 };
15051   vl_api_address_t remote_ip = { 0 };
15052   f64 before = 0;
15053   u8 is_add = 1;
15054   u8 esn = 0;
15055   u8 anti_replay = 0;
15056   u8 renumber = 0;
15057   u32 instance = ~0;
15058   u32 count = 1, jj;
15059   int ret;
15060
15061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (i, "del"))
15064         is_add = 0;
15065       else if (unformat (i, "esn"))
15066         esn = 1;
15067       else if (unformat (i, "anti-replay"))
15068         anti_replay = 1;
15069       else if (unformat (i, "count %d", &count))
15070         ;
15071       else if (unformat (i, "local_spi %d", &local_spi))
15072         ;
15073       else if (unformat (i, "remote_spi %d", &remote_spi))
15074         ;
15075       else
15076         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15077         ;
15078       else
15079         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15080         ;
15081       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15082         ;
15083       else
15084         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15085         ;
15086       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15087         ;
15088       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15089         ;
15090       else
15091         if (unformat
15092             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15093         {
15094           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15095             {
15096               errmsg ("unsupported crypto-alg: '%U'\n",
15097                       format_ipsec_crypto_alg, crypto_alg);
15098               return -99;
15099             }
15100         }
15101       else
15102         if (unformat
15103             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15104         {
15105           if (integ_alg >= IPSEC_INTEG_N_ALG)
15106             {
15107               errmsg ("unsupported integ-alg: '%U'\n",
15108                       format_ipsec_integ_alg, integ_alg);
15109               return -99;
15110             }
15111         }
15112       else if (unformat (i, "instance %u", &instance))
15113         renumber = 1;
15114       else
15115         {
15116           errmsg ("parse error '%U'\n", format_unformat_error, i);
15117           return -99;
15118         }
15119     }
15120
15121   if (count > 1)
15122     {
15123       /* Turn on async mode */
15124       vam->async_mode = 1;
15125       vam->async_errors = 0;
15126       before = vat_time_now (vam);
15127     }
15128
15129   for (jj = 0; jj < count; jj++)
15130     {
15131       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15132
15133       mp->is_add = is_add;
15134       mp->esn = esn;
15135       mp->anti_replay = anti_replay;
15136
15137       if (jj > 0)
15138         increment_vl_address (&remote_ip);
15139
15140       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15141       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15142
15143       mp->local_spi = htonl (local_spi + jj);
15144       mp->remote_spi = htonl (remote_spi + jj);
15145       mp->crypto_alg = (u8) crypto_alg;
15146
15147       mp->local_crypto_key_len = 0;
15148       if (lck)
15149         {
15150           mp->local_crypto_key_len = vec_len (lck);
15151           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15152             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15153           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15154         }
15155
15156       mp->remote_crypto_key_len = 0;
15157       if (rck)
15158         {
15159           mp->remote_crypto_key_len = vec_len (rck);
15160           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15161             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15162           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15163         }
15164
15165       mp->integ_alg = (u8) integ_alg;
15166
15167       mp->local_integ_key_len = 0;
15168       if (lik)
15169         {
15170           mp->local_integ_key_len = vec_len (lik);
15171           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15172             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15173           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15174         }
15175
15176       mp->remote_integ_key_len = 0;
15177       if (rik)
15178         {
15179           mp->remote_integ_key_len = vec_len (rik);
15180           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15181             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15182           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15183         }
15184
15185       if (renumber)
15186         {
15187           mp->renumber = renumber;
15188           mp->show_instance = ntohl (instance);
15189         }
15190       S (mp);
15191     }
15192
15193   /* When testing multiple add/del ops, use a control-ping to sync */
15194   if (count > 1)
15195     {
15196       vl_api_control_ping_t *mp_ping;
15197       f64 after;
15198       f64 timeout;
15199
15200       /* Shut off async mode */
15201       vam->async_mode = 0;
15202
15203       MPING (CONTROL_PING, mp_ping);
15204       S (mp_ping);
15205
15206       timeout = vat_time_now (vam) + 1.0;
15207       while (vat_time_now (vam) < timeout)
15208         if (vam->result_ready == 1)
15209           goto out;
15210       vam->retval = -99;
15211
15212     out:
15213       if (vam->retval == -99)
15214         errmsg ("timeout");
15215
15216       if (vam->async_errors > 0)
15217         {
15218           errmsg ("%d asynchronous errors", vam->async_errors);
15219           vam->retval = -98;
15220         }
15221       vam->async_errors = 0;
15222       after = vat_time_now (vam);
15223
15224       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15225       if (jj > 0)
15226         count = jj;
15227
15228       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15229              count, after - before, count / (after - before));
15230     }
15231   else
15232     {
15233       /* Wait for a reply... */
15234       W (ret);
15235       return ret;
15236     }
15237
15238   return ret;
15239 }
15240
15241 static void
15242 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15243 {
15244   vat_main_t *vam = &vat_main;
15245
15246   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15247          "crypto_key %U integ_alg %u integ_key %U flags %x "
15248          "tunnel_src_addr %U tunnel_dst_addr %U "
15249          "salt %u seq_outbound %lu last_seq_inbound %lu "
15250          "replay_window %lu\n",
15251          ntohl (mp->entry.sad_id),
15252          ntohl (mp->sw_if_index),
15253          ntohl (mp->entry.spi),
15254          ntohl (mp->entry.protocol),
15255          ntohl (mp->entry.crypto_algorithm),
15256          format_hex_bytes, mp->entry.crypto_key.data,
15257          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15258          format_hex_bytes, mp->entry.integrity_key.data,
15259          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15260          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15261          &mp->entry.tunnel_dst, ntohl (mp->salt),
15262          clib_net_to_host_u64 (mp->seq_outbound),
15263          clib_net_to_host_u64 (mp->last_seq_inbound),
15264          clib_net_to_host_u64 (mp->replay_window));
15265 }
15266
15267 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15268 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15269
15270 static void
15271 vat_json_object_add_address (vat_json_node_t * node,
15272                              const vl_api_address_t * addr)
15273 {
15274   if (ADDRESS_IP6 == addr->af)
15275     {
15276       struct in6_addr ip6;
15277
15278       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
15279       vat_json_object_add_ip6 (node, "ip_address", ip6);
15280     }
15281   else
15282     {
15283       struct in_addr ip4;
15284
15285       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
15286       vat_json_object_add_ip4 (node, "ip_address", ip4);
15287     }
15288 }
15289
15290 static void vl_api_ipsec_sa_details_t_handler_json
15291   (vl_api_ipsec_sa_details_t * mp)
15292 {
15293   vat_main_t *vam = &vat_main;
15294   vat_json_node_t *node = NULL;
15295   vl_api_ipsec_sad_flags_t flags;
15296
15297   if (VAT_JSON_ARRAY != vam->json_tree.type)
15298     {
15299       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15300       vat_json_init_array (&vam->json_tree);
15301     }
15302   node = vat_json_array_add (&vam->json_tree);
15303
15304   vat_json_init_object (node);
15305   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15306   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15307   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15308   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15309   vat_json_object_add_uint (node, "crypto_alg",
15310                             ntohl (mp->entry.crypto_algorithm));
15311   vat_json_object_add_uint (node, "integ_alg",
15312                             ntohl (mp->entry.integrity_algorithm));
15313   flags = ntohl (mp->entry.flags);
15314   vat_json_object_add_uint (node, "use_esn",
15315                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15316   vat_json_object_add_uint (node, "use_anti_replay",
15317                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15318   vat_json_object_add_uint (node, "is_tunnel",
15319                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15320   vat_json_object_add_uint (node, "is_tunnel_ip6",
15321                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15322   vat_json_object_add_uint (node, "udp_encap",
15323                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15324   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15325                              mp->entry.crypto_key.length);
15326   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15327                              mp->entry.integrity_key.length);
15328   vat_json_object_add_address (node, &mp->entry.tunnel_src);
15329   vat_json_object_add_address (node, &mp->entry.tunnel_dst);
15330   vat_json_object_add_uint (node, "replay_window",
15331                             clib_net_to_host_u64 (mp->replay_window));
15332 }
15333
15334 static int
15335 api_ipsec_sa_dump (vat_main_t * vam)
15336 {
15337   unformat_input_t *i = vam->input;
15338   vl_api_ipsec_sa_dump_t *mp;
15339   vl_api_control_ping_t *mp_ping;
15340   u32 sa_id = ~0;
15341   int ret;
15342
15343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15344     {
15345       if (unformat (i, "sa_id %d", &sa_id))
15346         ;
15347       else
15348         {
15349           clib_warning ("parse error '%U'", format_unformat_error, i);
15350           return -99;
15351         }
15352     }
15353
15354   M (IPSEC_SA_DUMP, mp);
15355
15356   mp->sa_id = ntohl (sa_id);
15357
15358   S (mp);
15359
15360   /* Use a control ping for synchronization */
15361   M (CONTROL_PING, mp_ping);
15362   S (mp_ping);
15363
15364   W (ret);
15365   return ret;
15366 }
15367
15368 static int
15369 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15370 {
15371   unformat_input_t *i = vam->input;
15372   vl_api_ipsec_tunnel_if_set_key_t *mp;
15373   u32 sw_if_index = ~0;
15374   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15375   u8 *key = 0;
15376   u32 alg = ~0;
15377   int ret;
15378
15379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15380     {
15381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15382         ;
15383       else
15384         if (unformat
15385             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15386         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15387       else
15388         if (unformat
15389             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15390         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15391       else
15392         if (unformat
15393             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15394         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15395       else
15396         if (unformat
15397             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15398         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15399       else if (unformat (i, "%U", unformat_hex_string, &key))
15400         ;
15401       else
15402         {
15403           clib_warning ("parse error '%U'", format_unformat_error, i);
15404           return -99;
15405         }
15406     }
15407
15408   if (sw_if_index == ~0)
15409     {
15410       errmsg ("interface must be specified");
15411       return -99;
15412     }
15413
15414   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15415     {
15416       errmsg ("key type must be specified");
15417       return -99;
15418     }
15419
15420   if (alg == ~0)
15421     {
15422       errmsg ("algorithm must be specified");
15423       return -99;
15424     }
15425
15426   if (vec_len (key) == 0)
15427     {
15428       errmsg ("key must be specified");
15429       return -99;
15430     }
15431
15432   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15433
15434   mp->sw_if_index = htonl (sw_if_index);
15435   mp->alg = alg;
15436   mp->key_type = key_type;
15437   mp->key_len = vec_len (key);
15438   clib_memcpy (mp->key, key, vec_len (key));
15439
15440   S (mp);
15441   W (ret);
15442
15443   return ret;
15444 }
15445
15446 static int
15447 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15448 {
15449   unformat_input_t *i = vam->input;
15450   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15451   u32 sw_if_index = ~0;
15452   u32 sa_id = ~0;
15453   u8 is_outbound = (u8) ~ 0;
15454   int ret;
15455
15456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15457     {
15458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15459         ;
15460       else if (unformat (i, "sa_id %d", &sa_id))
15461         ;
15462       else if (unformat (i, "outbound"))
15463         is_outbound = 1;
15464       else if (unformat (i, "inbound"))
15465         is_outbound = 0;
15466       else
15467         {
15468           clib_warning ("parse error '%U'", format_unformat_error, i);
15469           return -99;
15470         }
15471     }
15472
15473   if (sw_if_index == ~0)
15474     {
15475       errmsg ("interface must be specified");
15476       return -99;
15477     }
15478
15479   if (sa_id == ~0)
15480     {
15481       errmsg ("SA ID must be specified");
15482       return -99;
15483     }
15484
15485   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15486
15487   mp->sw_if_index = htonl (sw_if_index);
15488   mp->sa_id = htonl (sa_id);
15489   mp->is_outbound = is_outbound;
15490
15491   S (mp);
15492   W (ret);
15493
15494   return ret;
15495 }
15496
15497 static int
15498 api_get_first_msg_id (vat_main_t * vam)
15499 {
15500   vl_api_get_first_msg_id_t *mp;
15501   unformat_input_t *i = vam->input;
15502   u8 *name;
15503   u8 name_set = 0;
15504   int ret;
15505
15506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15507     {
15508       if (unformat (i, "client %s", &name))
15509         name_set = 1;
15510       else
15511         break;
15512     }
15513
15514   if (name_set == 0)
15515     {
15516       errmsg ("missing client name");
15517       return -99;
15518     }
15519   vec_add1 (name, 0);
15520
15521   if (vec_len (name) > 63)
15522     {
15523       errmsg ("client name too long");
15524       return -99;
15525     }
15526
15527   M (GET_FIRST_MSG_ID, mp);
15528   clib_memcpy (mp->name, name, vec_len (name));
15529   S (mp);
15530   W (ret);
15531   return ret;
15532 }
15533
15534 static int
15535 api_cop_interface_enable_disable (vat_main_t * vam)
15536 {
15537   unformat_input_t *line_input = vam->input;
15538   vl_api_cop_interface_enable_disable_t *mp;
15539   u32 sw_if_index = ~0;
15540   u8 enable_disable = 1;
15541   int ret;
15542
15543   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15544     {
15545       if (unformat (line_input, "disable"))
15546         enable_disable = 0;
15547       if (unformat (line_input, "enable"))
15548         enable_disable = 1;
15549       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15550                          vam, &sw_if_index))
15551         ;
15552       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15553         ;
15554       else
15555         break;
15556     }
15557
15558   if (sw_if_index == ~0)
15559     {
15560       errmsg ("missing interface name or sw_if_index");
15561       return -99;
15562     }
15563
15564   /* Construct the API message */
15565   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15566   mp->sw_if_index = ntohl (sw_if_index);
15567   mp->enable_disable = enable_disable;
15568
15569   /* send it... */
15570   S (mp);
15571   /* Wait for the reply */
15572   W (ret);
15573   return ret;
15574 }
15575
15576 static int
15577 api_cop_whitelist_enable_disable (vat_main_t * vam)
15578 {
15579   unformat_input_t *line_input = vam->input;
15580   vl_api_cop_whitelist_enable_disable_t *mp;
15581   u32 sw_if_index = ~0;
15582   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15583   u32 fib_id = 0;
15584   int ret;
15585
15586   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15587     {
15588       if (unformat (line_input, "ip4"))
15589         ip4 = 1;
15590       else if (unformat (line_input, "ip6"))
15591         ip6 = 1;
15592       else if (unformat (line_input, "default"))
15593         default_cop = 1;
15594       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15595                          vam, &sw_if_index))
15596         ;
15597       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15598         ;
15599       else if (unformat (line_input, "fib-id %d", &fib_id))
15600         ;
15601       else
15602         break;
15603     }
15604
15605   if (sw_if_index == ~0)
15606     {
15607       errmsg ("missing interface name or sw_if_index");
15608       return -99;
15609     }
15610
15611   /* Construct the API message */
15612   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15613   mp->sw_if_index = ntohl (sw_if_index);
15614   mp->fib_id = ntohl (fib_id);
15615   mp->ip4 = ip4;
15616   mp->ip6 = ip6;
15617   mp->default_cop = default_cop;
15618
15619   /* send it... */
15620   S (mp);
15621   /* Wait for the reply */
15622   W (ret);
15623   return ret;
15624 }
15625
15626 static int
15627 api_get_node_graph (vat_main_t * vam)
15628 {
15629   vl_api_get_node_graph_t *mp;
15630   int ret;
15631
15632   M (GET_NODE_GRAPH, mp);
15633
15634   /* send it... */
15635   S (mp);
15636   /* Wait for the reply */
15637   W (ret);
15638   return ret;
15639 }
15640
15641 /* *INDENT-OFF* */
15642 /** Used for parsing LISP eids */
15643 typedef CLIB_PACKED(struct{
15644   u8 addr[16];   /**< eid address */
15645   u32 len;       /**< prefix length if IP */
15646   u8 type;      /**< type of eid */
15647 }) lisp_eid_vat_t;
15648 /* *INDENT-ON* */
15649
15650 static uword
15651 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15652 {
15653   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15654
15655   clib_memset (a, 0, sizeof (a[0]));
15656
15657   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15658     {
15659       a->type = 0;              /* ipv4 type */
15660     }
15661   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15662     {
15663       a->type = 1;              /* ipv6 type */
15664     }
15665   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15666     {
15667       a->type = 2;              /* mac type */
15668     }
15669   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15670     {
15671       a->type = 3;              /* NSH type */
15672       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15673       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15674     }
15675   else
15676     {
15677       return 0;
15678     }
15679
15680   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15681     {
15682       return 0;
15683     }
15684
15685   return 1;
15686 }
15687
15688 static int
15689 lisp_eid_size_vat (u8 type)
15690 {
15691   switch (type)
15692     {
15693     case 0:
15694       return 4;
15695     case 1:
15696       return 16;
15697     case 2:
15698       return 6;
15699     case 3:
15700       return 5;
15701     }
15702   return 0;
15703 }
15704
15705 static void
15706 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15707 {
15708   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15709 }
15710
15711 static int
15712 api_one_add_del_locator_set (vat_main_t * vam)
15713 {
15714   unformat_input_t *input = vam->input;
15715   vl_api_one_add_del_locator_set_t *mp;
15716   u8 is_add = 1;
15717   u8 *locator_set_name = NULL;
15718   u8 locator_set_name_set = 0;
15719   vl_api_local_locator_t locator, *locators = 0;
15720   u32 sw_if_index, priority, weight;
15721   u32 data_len = 0;
15722
15723   int ret;
15724   /* Parse args required to build the message */
15725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15726     {
15727       if (unformat (input, "del"))
15728         {
15729           is_add = 0;
15730         }
15731       else if (unformat (input, "locator-set %s", &locator_set_name))
15732         {
15733           locator_set_name_set = 1;
15734         }
15735       else if (unformat (input, "sw_if_index %u p %u w %u",
15736                          &sw_if_index, &priority, &weight))
15737         {
15738           locator.sw_if_index = htonl (sw_if_index);
15739           locator.priority = priority;
15740           locator.weight = weight;
15741           vec_add1 (locators, locator);
15742         }
15743       else
15744         if (unformat
15745             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15746              &sw_if_index, &priority, &weight))
15747         {
15748           locator.sw_if_index = htonl (sw_if_index);
15749           locator.priority = priority;
15750           locator.weight = weight;
15751           vec_add1 (locators, locator);
15752         }
15753       else
15754         break;
15755     }
15756
15757   if (locator_set_name_set == 0)
15758     {
15759       errmsg ("missing locator-set name");
15760       vec_free (locators);
15761       return -99;
15762     }
15763
15764   if (vec_len (locator_set_name) > 64)
15765     {
15766       errmsg ("locator-set name too long");
15767       vec_free (locator_set_name);
15768       vec_free (locators);
15769       return -99;
15770     }
15771   vec_add1 (locator_set_name, 0);
15772
15773   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15774
15775   /* Construct the API message */
15776   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15777
15778   mp->is_add = is_add;
15779   clib_memcpy (mp->locator_set_name, locator_set_name,
15780                vec_len (locator_set_name));
15781   vec_free (locator_set_name);
15782
15783   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15784   if (locators)
15785     clib_memcpy (mp->locators, locators, data_len);
15786   vec_free (locators);
15787
15788   /* send it... */
15789   S (mp);
15790
15791   /* Wait for a reply... */
15792   W (ret);
15793   return ret;
15794 }
15795
15796 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15797
15798 static int
15799 api_one_add_del_locator (vat_main_t * vam)
15800 {
15801   unformat_input_t *input = vam->input;
15802   vl_api_one_add_del_locator_t *mp;
15803   u32 tmp_if_index = ~0;
15804   u32 sw_if_index = ~0;
15805   u8 sw_if_index_set = 0;
15806   u8 sw_if_index_if_name_set = 0;
15807   u32 priority = ~0;
15808   u8 priority_set = 0;
15809   u32 weight = ~0;
15810   u8 weight_set = 0;
15811   u8 is_add = 1;
15812   u8 *locator_set_name = NULL;
15813   u8 locator_set_name_set = 0;
15814   int ret;
15815
15816   /* Parse args required to build the message */
15817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15818     {
15819       if (unformat (input, "del"))
15820         {
15821           is_add = 0;
15822         }
15823       else if (unformat (input, "locator-set %s", &locator_set_name))
15824         {
15825           locator_set_name_set = 1;
15826         }
15827       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15828                          &tmp_if_index))
15829         {
15830           sw_if_index_if_name_set = 1;
15831           sw_if_index = tmp_if_index;
15832         }
15833       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15834         {
15835           sw_if_index_set = 1;
15836           sw_if_index = tmp_if_index;
15837         }
15838       else if (unformat (input, "p %d", &priority))
15839         {
15840           priority_set = 1;
15841         }
15842       else if (unformat (input, "w %d", &weight))
15843         {
15844           weight_set = 1;
15845         }
15846       else
15847         break;
15848     }
15849
15850   if (locator_set_name_set == 0)
15851     {
15852       errmsg ("missing locator-set name");
15853       return -99;
15854     }
15855
15856   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15857     {
15858       errmsg ("missing sw_if_index");
15859       vec_free (locator_set_name);
15860       return -99;
15861     }
15862
15863   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15864     {
15865       errmsg ("cannot use both params interface name and sw_if_index");
15866       vec_free (locator_set_name);
15867       return -99;
15868     }
15869
15870   if (priority_set == 0)
15871     {
15872       errmsg ("missing locator-set priority");
15873       vec_free (locator_set_name);
15874       return -99;
15875     }
15876
15877   if (weight_set == 0)
15878     {
15879       errmsg ("missing locator-set weight");
15880       vec_free (locator_set_name);
15881       return -99;
15882     }
15883
15884   if (vec_len (locator_set_name) > 64)
15885     {
15886       errmsg ("locator-set name too long");
15887       vec_free (locator_set_name);
15888       return -99;
15889     }
15890   vec_add1 (locator_set_name, 0);
15891
15892   /* Construct the API message */
15893   M (ONE_ADD_DEL_LOCATOR, mp);
15894
15895   mp->is_add = is_add;
15896   mp->sw_if_index = ntohl (sw_if_index);
15897   mp->priority = priority;
15898   mp->weight = weight;
15899   clib_memcpy (mp->locator_set_name, locator_set_name,
15900                vec_len (locator_set_name));
15901   vec_free (locator_set_name);
15902
15903   /* send it... */
15904   S (mp);
15905
15906   /* Wait for a reply... */
15907   W (ret);
15908   return ret;
15909 }
15910
15911 #define api_lisp_add_del_locator api_one_add_del_locator
15912
15913 uword
15914 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15915 {
15916   u32 *key_id = va_arg (*args, u32 *);
15917   u8 *s = 0;
15918
15919   if (unformat (input, "%s", &s))
15920     {
15921       if (!strcmp ((char *) s, "sha1"))
15922         key_id[0] = HMAC_SHA_1_96;
15923       else if (!strcmp ((char *) s, "sha256"))
15924         key_id[0] = HMAC_SHA_256_128;
15925       else
15926         {
15927           clib_warning ("invalid key_id: '%s'", s);
15928           key_id[0] = HMAC_NO_KEY;
15929         }
15930     }
15931   else
15932     return 0;
15933
15934   vec_free (s);
15935   return 1;
15936 }
15937
15938 static int
15939 api_one_add_del_local_eid (vat_main_t * vam)
15940 {
15941   unformat_input_t *input = vam->input;
15942   vl_api_one_add_del_local_eid_t *mp;
15943   u8 is_add = 1;
15944   u8 eid_set = 0;
15945   lisp_eid_vat_t _eid, *eid = &_eid;
15946   u8 *locator_set_name = 0;
15947   u8 locator_set_name_set = 0;
15948   u32 vni = 0;
15949   u16 key_id = 0;
15950   u8 *key = 0;
15951   int ret;
15952
15953   /* Parse args required to build the message */
15954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15955     {
15956       if (unformat (input, "del"))
15957         {
15958           is_add = 0;
15959         }
15960       else if (unformat (input, "vni %d", &vni))
15961         {
15962           ;
15963         }
15964       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15965         {
15966           eid_set = 1;
15967         }
15968       else if (unformat (input, "locator-set %s", &locator_set_name))
15969         {
15970           locator_set_name_set = 1;
15971         }
15972       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15973         ;
15974       else if (unformat (input, "secret-key %_%v%_", &key))
15975         ;
15976       else
15977         break;
15978     }
15979
15980   if (locator_set_name_set == 0)
15981     {
15982       errmsg ("missing locator-set name");
15983       return -99;
15984     }
15985
15986   if (0 == eid_set)
15987     {
15988       errmsg ("EID address not set!");
15989       vec_free (locator_set_name);
15990       return -99;
15991     }
15992
15993   if (key && (0 == key_id))
15994     {
15995       errmsg ("invalid key_id!");
15996       return -99;
15997     }
15998
15999   if (vec_len (key) > 64)
16000     {
16001       errmsg ("key too long");
16002       vec_free (key);
16003       return -99;
16004     }
16005
16006   if (vec_len (locator_set_name) > 64)
16007     {
16008       errmsg ("locator-set name too long");
16009       vec_free (locator_set_name);
16010       return -99;
16011     }
16012   vec_add1 (locator_set_name, 0);
16013
16014   /* Construct the API message */
16015   M (ONE_ADD_DEL_LOCAL_EID, mp);
16016
16017   mp->is_add = is_add;
16018   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16019   mp->eid_type = eid->type;
16020   mp->prefix_len = eid->len;
16021   mp->vni = clib_host_to_net_u32 (vni);
16022   mp->key_id = clib_host_to_net_u16 (key_id);
16023   clib_memcpy (mp->locator_set_name, locator_set_name,
16024                vec_len (locator_set_name));
16025   clib_memcpy (mp->key, key, vec_len (key));
16026
16027   vec_free (locator_set_name);
16028   vec_free (key);
16029
16030   /* send it... */
16031   S (mp);
16032
16033   /* Wait for a reply... */
16034   W (ret);
16035   return ret;
16036 }
16037
16038 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16039
16040 static int
16041 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16042 {
16043   u32 dp_table = 0, vni = 0;;
16044   unformat_input_t *input = vam->input;
16045   vl_api_gpe_add_del_fwd_entry_t *mp;
16046   u8 is_add = 1;
16047   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16048   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16049   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16050   u32 action = ~0, w;
16051   ip4_address_t rmt_rloc4, lcl_rloc4;
16052   ip6_address_t rmt_rloc6, lcl_rloc6;
16053   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16054   int ret;
16055
16056   clib_memset (&rloc, 0, sizeof (rloc));
16057
16058   /* Parse args required to build the message */
16059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16060     {
16061       if (unformat (input, "del"))
16062         is_add = 0;
16063       else if (unformat (input, "add"))
16064         is_add = 1;
16065       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16066         {
16067           rmt_eid_set = 1;
16068         }
16069       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16070         {
16071           lcl_eid_set = 1;
16072         }
16073       else if (unformat (input, "vrf %d", &dp_table))
16074         ;
16075       else if (unformat (input, "bd %d", &dp_table))
16076         ;
16077       else if (unformat (input, "vni %d", &vni))
16078         ;
16079       else if (unformat (input, "w %d", &w))
16080         {
16081           if (!curr_rloc)
16082             {
16083               errmsg ("No RLOC configured for setting priority/weight!");
16084               return -99;
16085             }
16086           curr_rloc->weight = w;
16087         }
16088       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16089                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16090         {
16091           rloc.is_ip4 = 1;
16092
16093           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16094           rloc.weight = 0;
16095           vec_add1 (lcl_locs, rloc);
16096
16097           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16098           vec_add1 (rmt_locs, rloc);
16099           /* weight saved in rmt loc */
16100           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16101         }
16102       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16103                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16104         {
16105           rloc.is_ip4 = 0;
16106           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16107           rloc.weight = 0;
16108           vec_add1 (lcl_locs, rloc);
16109
16110           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16111           vec_add1 (rmt_locs, rloc);
16112           /* weight saved in rmt loc */
16113           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16114         }
16115       else if (unformat (input, "action %d", &action))
16116         {
16117           ;
16118         }
16119       else
16120         {
16121           clib_warning ("parse error '%U'", format_unformat_error, input);
16122           return -99;
16123         }
16124     }
16125
16126   if (!rmt_eid_set)
16127     {
16128       errmsg ("remote eid addresses not set");
16129       return -99;
16130     }
16131
16132   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16133     {
16134       errmsg ("eid types don't match");
16135       return -99;
16136     }
16137
16138   if (0 == rmt_locs && (u32) ~ 0 == action)
16139     {
16140       errmsg ("action not set for negative mapping");
16141       return -99;
16142     }
16143
16144   /* Construct the API message */
16145   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16146       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16147
16148   mp->is_add = is_add;
16149   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16150   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16151   mp->eid_type = rmt_eid->type;
16152   mp->dp_table = clib_host_to_net_u32 (dp_table);
16153   mp->vni = clib_host_to_net_u32 (vni);
16154   mp->rmt_len = rmt_eid->len;
16155   mp->lcl_len = lcl_eid->len;
16156   mp->action = action;
16157
16158   if (0 != rmt_locs && 0 != lcl_locs)
16159     {
16160       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16161       clib_memcpy (mp->locs, lcl_locs,
16162                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16163
16164       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16165       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16166                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16167     }
16168   vec_free (lcl_locs);
16169   vec_free (rmt_locs);
16170
16171   /* send it... */
16172   S (mp);
16173
16174   /* Wait for a reply... */
16175   W (ret);
16176   return ret;
16177 }
16178
16179 static int
16180 api_one_add_del_map_server (vat_main_t * vam)
16181 {
16182   unformat_input_t *input = vam->input;
16183   vl_api_one_add_del_map_server_t *mp;
16184   u8 is_add = 1;
16185   u8 ipv4_set = 0;
16186   u8 ipv6_set = 0;
16187   ip4_address_t ipv4;
16188   ip6_address_t ipv6;
16189   int ret;
16190
16191   /* Parse args required to build the message */
16192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16193     {
16194       if (unformat (input, "del"))
16195         {
16196           is_add = 0;
16197         }
16198       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16199         {
16200           ipv4_set = 1;
16201         }
16202       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16203         {
16204           ipv6_set = 1;
16205         }
16206       else
16207         break;
16208     }
16209
16210   if (ipv4_set && ipv6_set)
16211     {
16212       errmsg ("both eid v4 and v6 addresses set");
16213       return -99;
16214     }
16215
16216   if (!ipv4_set && !ipv6_set)
16217     {
16218       errmsg ("eid addresses not set");
16219       return -99;
16220     }
16221
16222   /* Construct the API message */
16223   M (ONE_ADD_DEL_MAP_SERVER, mp);
16224
16225   mp->is_add = is_add;
16226   if (ipv6_set)
16227     {
16228       mp->is_ipv6 = 1;
16229       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16230     }
16231   else
16232     {
16233       mp->is_ipv6 = 0;
16234       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16235     }
16236
16237   /* send it... */
16238   S (mp);
16239
16240   /* Wait for a reply... */
16241   W (ret);
16242   return ret;
16243 }
16244
16245 #define api_lisp_add_del_map_server api_one_add_del_map_server
16246
16247 static int
16248 api_one_add_del_map_resolver (vat_main_t * vam)
16249 {
16250   unformat_input_t *input = vam->input;
16251   vl_api_one_add_del_map_resolver_t *mp;
16252   u8 is_add = 1;
16253   u8 ipv4_set = 0;
16254   u8 ipv6_set = 0;
16255   ip4_address_t ipv4;
16256   ip6_address_t ipv6;
16257   int ret;
16258
16259   /* Parse args required to build the message */
16260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16261     {
16262       if (unformat (input, "del"))
16263         {
16264           is_add = 0;
16265         }
16266       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16267         {
16268           ipv4_set = 1;
16269         }
16270       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16271         {
16272           ipv6_set = 1;
16273         }
16274       else
16275         break;
16276     }
16277
16278   if (ipv4_set && ipv6_set)
16279     {
16280       errmsg ("both eid v4 and v6 addresses set");
16281       return -99;
16282     }
16283
16284   if (!ipv4_set && !ipv6_set)
16285     {
16286       errmsg ("eid addresses not set");
16287       return -99;
16288     }
16289
16290   /* Construct the API message */
16291   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16292
16293   mp->is_add = is_add;
16294   if (ipv6_set)
16295     {
16296       mp->is_ipv6 = 1;
16297       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16298     }
16299   else
16300     {
16301       mp->is_ipv6 = 0;
16302       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16303     }
16304
16305   /* send it... */
16306   S (mp);
16307
16308   /* Wait for a reply... */
16309   W (ret);
16310   return ret;
16311 }
16312
16313 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16314
16315 static int
16316 api_lisp_gpe_enable_disable (vat_main_t * vam)
16317 {
16318   unformat_input_t *input = vam->input;
16319   vl_api_gpe_enable_disable_t *mp;
16320   u8 is_set = 0;
16321   u8 is_en = 1;
16322   int ret;
16323
16324   /* Parse args required to build the message */
16325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (input, "enable"))
16328         {
16329           is_set = 1;
16330           is_en = 1;
16331         }
16332       else if (unformat (input, "disable"))
16333         {
16334           is_set = 1;
16335           is_en = 0;
16336         }
16337       else
16338         break;
16339     }
16340
16341   if (is_set == 0)
16342     {
16343       errmsg ("Value not set");
16344       return -99;
16345     }
16346
16347   /* Construct the API message */
16348   M (GPE_ENABLE_DISABLE, mp);
16349
16350   mp->is_en = is_en;
16351
16352   /* send it... */
16353   S (mp);
16354
16355   /* Wait for a reply... */
16356   W (ret);
16357   return ret;
16358 }
16359
16360 static int
16361 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16362 {
16363   unformat_input_t *input = vam->input;
16364   vl_api_one_rloc_probe_enable_disable_t *mp;
16365   u8 is_set = 0;
16366   u8 is_en = 0;
16367   int ret;
16368
16369   /* Parse args required to build the message */
16370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16371     {
16372       if (unformat (input, "enable"))
16373         {
16374           is_set = 1;
16375           is_en = 1;
16376         }
16377       else if (unformat (input, "disable"))
16378         is_set = 1;
16379       else
16380         break;
16381     }
16382
16383   if (!is_set)
16384     {
16385       errmsg ("Value not set");
16386       return -99;
16387     }
16388
16389   /* Construct the API message */
16390   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16391
16392   mp->is_enabled = is_en;
16393
16394   /* send it... */
16395   S (mp);
16396
16397   /* Wait for a reply... */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16403
16404 static int
16405 api_one_map_register_enable_disable (vat_main_t * vam)
16406 {
16407   unformat_input_t *input = vam->input;
16408   vl_api_one_map_register_enable_disable_t *mp;
16409   u8 is_set = 0;
16410   u8 is_en = 0;
16411   int ret;
16412
16413   /* Parse args required to build the message */
16414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16415     {
16416       if (unformat (input, "enable"))
16417         {
16418           is_set = 1;
16419           is_en = 1;
16420         }
16421       else if (unformat (input, "disable"))
16422         is_set = 1;
16423       else
16424         break;
16425     }
16426
16427   if (!is_set)
16428     {
16429       errmsg ("Value not set");
16430       return -99;
16431     }
16432
16433   /* Construct the API message */
16434   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16435
16436   mp->is_enabled = is_en;
16437
16438   /* send it... */
16439   S (mp);
16440
16441   /* Wait for a reply... */
16442   W (ret);
16443   return ret;
16444 }
16445
16446 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16447
16448 static int
16449 api_one_enable_disable (vat_main_t * vam)
16450 {
16451   unformat_input_t *input = vam->input;
16452   vl_api_one_enable_disable_t *mp;
16453   u8 is_set = 0;
16454   u8 is_en = 0;
16455   int ret;
16456
16457   /* Parse args required to build the message */
16458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16459     {
16460       if (unformat (input, "enable"))
16461         {
16462           is_set = 1;
16463           is_en = 1;
16464         }
16465       else if (unformat (input, "disable"))
16466         {
16467           is_set = 1;
16468         }
16469       else
16470         break;
16471     }
16472
16473   if (!is_set)
16474     {
16475       errmsg ("Value not set");
16476       return -99;
16477     }
16478
16479   /* Construct the API message */
16480   M (ONE_ENABLE_DISABLE, mp);
16481
16482   mp->is_en = is_en;
16483
16484   /* send it... */
16485   S (mp);
16486
16487   /* Wait for a reply... */
16488   W (ret);
16489   return ret;
16490 }
16491
16492 #define api_lisp_enable_disable api_one_enable_disable
16493
16494 static int
16495 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16496 {
16497   unformat_input_t *input = vam->input;
16498   vl_api_one_enable_disable_xtr_mode_t *mp;
16499   u8 is_set = 0;
16500   u8 is_en = 0;
16501   int ret;
16502
16503   /* Parse args required to build the message */
16504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16505     {
16506       if (unformat (input, "enable"))
16507         {
16508           is_set = 1;
16509           is_en = 1;
16510         }
16511       else if (unformat (input, "disable"))
16512         {
16513           is_set = 1;
16514         }
16515       else
16516         break;
16517     }
16518
16519   if (!is_set)
16520     {
16521       errmsg ("Value not set");
16522       return -99;
16523     }
16524
16525   /* Construct the API message */
16526   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16527
16528   mp->is_en = is_en;
16529
16530   /* send it... */
16531   S (mp);
16532
16533   /* Wait for a reply... */
16534   W (ret);
16535   return ret;
16536 }
16537
16538 static int
16539 api_one_show_xtr_mode (vat_main_t * vam)
16540 {
16541   vl_api_one_show_xtr_mode_t *mp;
16542   int ret;
16543
16544   /* Construct the API message */
16545   M (ONE_SHOW_XTR_MODE, mp);
16546
16547   /* send it... */
16548   S (mp);
16549
16550   /* Wait for a reply... */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 static int
16556 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16557 {
16558   unformat_input_t *input = vam->input;
16559   vl_api_one_enable_disable_pitr_mode_t *mp;
16560   u8 is_set = 0;
16561   u8 is_en = 0;
16562   int ret;
16563
16564   /* Parse args required to build the message */
16565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16566     {
16567       if (unformat (input, "enable"))
16568         {
16569           is_set = 1;
16570           is_en = 1;
16571         }
16572       else if (unformat (input, "disable"))
16573         {
16574           is_set = 1;
16575         }
16576       else
16577         break;
16578     }
16579
16580   if (!is_set)
16581     {
16582       errmsg ("Value not set");
16583       return -99;
16584     }
16585
16586   /* Construct the API message */
16587   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16588
16589   mp->is_en = is_en;
16590
16591   /* send it... */
16592   S (mp);
16593
16594   /* Wait for a reply... */
16595   W (ret);
16596   return ret;
16597 }
16598
16599 static int
16600 api_one_show_pitr_mode (vat_main_t * vam)
16601 {
16602   vl_api_one_show_pitr_mode_t *mp;
16603   int ret;
16604
16605   /* Construct the API message */
16606   M (ONE_SHOW_PITR_MODE, mp);
16607
16608   /* send it... */
16609   S (mp);
16610
16611   /* Wait for a reply... */
16612   W (ret);
16613   return ret;
16614 }
16615
16616 static int
16617 api_one_enable_disable_petr_mode (vat_main_t * vam)
16618 {
16619   unformat_input_t *input = vam->input;
16620   vl_api_one_enable_disable_petr_mode_t *mp;
16621   u8 is_set = 0;
16622   u8 is_en = 0;
16623   int ret;
16624
16625   /* Parse args required to build the message */
16626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16627     {
16628       if (unformat (input, "enable"))
16629         {
16630           is_set = 1;
16631           is_en = 1;
16632         }
16633       else if (unformat (input, "disable"))
16634         {
16635           is_set = 1;
16636         }
16637       else
16638         break;
16639     }
16640
16641   if (!is_set)
16642     {
16643       errmsg ("Value not set");
16644       return -99;
16645     }
16646
16647   /* Construct the API message */
16648   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16649
16650   mp->is_en = is_en;
16651
16652   /* send it... */
16653   S (mp);
16654
16655   /* Wait for a reply... */
16656   W (ret);
16657   return ret;
16658 }
16659
16660 static int
16661 api_one_show_petr_mode (vat_main_t * vam)
16662 {
16663   vl_api_one_show_petr_mode_t *mp;
16664   int ret;
16665
16666   /* Construct the API message */
16667   M (ONE_SHOW_PETR_MODE, mp);
16668
16669   /* send it... */
16670   S (mp);
16671
16672   /* Wait for a reply... */
16673   W (ret);
16674   return ret;
16675 }
16676
16677 static int
16678 api_show_one_map_register_state (vat_main_t * vam)
16679 {
16680   vl_api_show_one_map_register_state_t *mp;
16681   int ret;
16682
16683   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16684
16685   /* send */
16686   S (mp);
16687
16688   /* wait for reply */
16689   W (ret);
16690   return ret;
16691 }
16692
16693 #define api_show_lisp_map_register_state api_show_one_map_register_state
16694
16695 static int
16696 api_show_one_rloc_probe_state (vat_main_t * vam)
16697 {
16698   vl_api_show_one_rloc_probe_state_t *mp;
16699   int ret;
16700
16701   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16702
16703   /* send */
16704   S (mp);
16705
16706   /* wait for reply */
16707   W (ret);
16708   return ret;
16709 }
16710
16711 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16712
16713 static int
16714 api_one_add_del_ndp_entry (vat_main_t * vam)
16715 {
16716   vl_api_one_add_del_ndp_entry_t *mp;
16717   unformat_input_t *input = vam->input;
16718   u8 is_add = 1;
16719   u8 mac_set = 0;
16720   u8 bd_set = 0;
16721   u8 ip_set = 0;
16722   u8 mac[6] = { 0, };
16723   u8 ip6[16] = { 0, };
16724   u32 bd = ~0;
16725   int ret;
16726
16727   /* Parse args required to build the message */
16728   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16729     {
16730       if (unformat (input, "del"))
16731         is_add = 0;
16732       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16733         mac_set = 1;
16734       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16735         ip_set = 1;
16736       else if (unformat (input, "bd %d", &bd))
16737         bd_set = 1;
16738       else
16739         {
16740           errmsg ("parse error '%U'", format_unformat_error, input);
16741           return -99;
16742         }
16743     }
16744
16745   if (!bd_set || !ip_set || (!mac_set && is_add))
16746     {
16747       errmsg ("Missing BD, IP or MAC!");
16748       return -99;
16749     }
16750
16751   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16752   mp->is_add = is_add;
16753   clib_memcpy (mp->mac, mac, 6);
16754   mp->bd = clib_host_to_net_u32 (bd);
16755   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16756
16757   /* send */
16758   S (mp);
16759
16760   /* wait for reply */
16761   W (ret);
16762   return ret;
16763 }
16764
16765 static int
16766 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16767 {
16768   vl_api_one_add_del_l2_arp_entry_t *mp;
16769   unformat_input_t *input = vam->input;
16770   u8 is_add = 1;
16771   u8 mac_set = 0;
16772   u8 bd_set = 0;
16773   u8 ip_set = 0;
16774   u8 mac[6] = { 0, };
16775   u32 ip4 = 0, bd = ~0;
16776   int ret;
16777
16778   /* Parse args required to build the message */
16779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16780     {
16781       if (unformat (input, "del"))
16782         is_add = 0;
16783       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16784         mac_set = 1;
16785       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16786         ip_set = 1;
16787       else if (unformat (input, "bd %d", &bd))
16788         bd_set = 1;
16789       else
16790         {
16791           errmsg ("parse error '%U'", format_unformat_error, input);
16792           return -99;
16793         }
16794     }
16795
16796   if (!bd_set || !ip_set || (!mac_set && is_add))
16797     {
16798       errmsg ("Missing BD, IP or MAC!");
16799       return -99;
16800     }
16801
16802   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16803   mp->is_add = is_add;
16804   clib_memcpy (mp->mac, mac, 6);
16805   mp->bd = clib_host_to_net_u32 (bd);
16806   mp->ip4 = ip4;
16807
16808   /* send */
16809   S (mp);
16810
16811   /* wait for reply */
16812   W (ret);
16813   return ret;
16814 }
16815
16816 static int
16817 api_one_ndp_bd_get (vat_main_t * vam)
16818 {
16819   vl_api_one_ndp_bd_get_t *mp;
16820   int ret;
16821
16822   M (ONE_NDP_BD_GET, mp);
16823
16824   /* send */
16825   S (mp);
16826
16827   /* wait for reply */
16828   W (ret);
16829   return ret;
16830 }
16831
16832 static int
16833 api_one_ndp_entries_get (vat_main_t * vam)
16834 {
16835   vl_api_one_ndp_entries_get_t *mp;
16836   unformat_input_t *input = vam->input;
16837   u8 bd_set = 0;
16838   u32 bd = ~0;
16839   int ret;
16840
16841   /* Parse args required to build the message */
16842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16843     {
16844       if (unformat (input, "bd %d", &bd))
16845         bd_set = 1;
16846       else
16847         {
16848           errmsg ("parse error '%U'", format_unformat_error, input);
16849           return -99;
16850         }
16851     }
16852
16853   if (!bd_set)
16854     {
16855       errmsg ("Expected bridge domain!");
16856       return -99;
16857     }
16858
16859   M (ONE_NDP_ENTRIES_GET, mp);
16860   mp->bd = clib_host_to_net_u32 (bd);
16861
16862   /* send */
16863   S (mp);
16864
16865   /* wait for reply */
16866   W (ret);
16867   return ret;
16868 }
16869
16870 static int
16871 api_one_l2_arp_bd_get (vat_main_t * vam)
16872 {
16873   vl_api_one_l2_arp_bd_get_t *mp;
16874   int ret;
16875
16876   M (ONE_L2_ARP_BD_GET, mp);
16877
16878   /* send */
16879   S (mp);
16880
16881   /* wait for reply */
16882   W (ret);
16883   return ret;
16884 }
16885
16886 static int
16887 api_one_l2_arp_entries_get (vat_main_t * vam)
16888 {
16889   vl_api_one_l2_arp_entries_get_t *mp;
16890   unformat_input_t *input = vam->input;
16891   u8 bd_set = 0;
16892   u32 bd = ~0;
16893   int ret;
16894
16895   /* Parse args required to build the message */
16896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16897     {
16898       if (unformat (input, "bd %d", &bd))
16899         bd_set = 1;
16900       else
16901         {
16902           errmsg ("parse error '%U'", format_unformat_error, input);
16903           return -99;
16904         }
16905     }
16906
16907   if (!bd_set)
16908     {
16909       errmsg ("Expected bridge domain!");
16910       return -99;
16911     }
16912
16913   M (ONE_L2_ARP_ENTRIES_GET, mp);
16914   mp->bd = clib_host_to_net_u32 (bd);
16915
16916   /* send */
16917   S (mp);
16918
16919   /* wait for reply */
16920   W (ret);
16921   return ret;
16922 }
16923
16924 static int
16925 api_one_stats_enable_disable (vat_main_t * vam)
16926 {
16927   vl_api_one_stats_enable_disable_t *mp;
16928   unformat_input_t *input = vam->input;
16929   u8 is_set = 0;
16930   u8 is_en = 0;
16931   int ret;
16932
16933   /* Parse args required to build the message */
16934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16935     {
16936       if (unformat (input, "enable"))
16937         {
16938           is_set = 1;
16939           is_en = 1;
16940         }
16941       else if (unformat (input, "disable"))
16942         {
16943           is_set = 1;
16944         }
16945       else
16946         break;
16947     }
16948
16949   if (!is_set)
16950     {
16951       errmsg ("Value not set");
16952       return -99;
16953     }
16954
16955   M (ONE_STATS_ENABLE_DISABLE, mp);
16956   mp->is_en = is_en;
16957
16958   /* send */
16959   S (mp);
16960
16961   /* wait for reply */
16962   W (ret);
16963   return ret;
16964 }
16965
16966 static int
16967 api_show_one_stats_enable_disable (vat_main_t * vam)
16968 {
16969   vl_api_show_one_stats_enable_disable_t *mp;
16970   int ret;
16971
16972   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16973
16974   /* send */
16975   S (mp);
16976
16977   /* wait for reply */
16978   W (ret);
16979   return ret;
16980 }
16981
16982 static int
16983 api_show_one_map_request_mode (vat_main_t * vam)
16984 {
16985   vl_api_show_one_map_request_mode_t *mp;
16986   int ret;
16987
16988   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16989
16990   /* send */
16991   S (mp);
16992
16993   /* wait for reply */
16994   W (ret);
16995   return ret;
16996 }
16997
16998 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16999
17000 static int
17001 api_one_map_request_mode (vat_main_t * vam)
17002 {
17003   unformat_input_t *input = vam->input;
17004   vl_api_one_map_request_mode_t *mp;
17005   u8 mode = 0;
17006   int ret;
17007
17008   /* Parse args required to build the message */
17009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17010     {
17011       if (unformat (input, "dst-only"))
17012         mode = 0;
17013       else if (unformat (input, "src-dst"))
17014         mode = 1;
17015       else
17016         {
17017           errmsg ("parse error '%U'", format_unformat_error, input);
17018           return -99;
17019         }
17020     }
17021
17022   M (ONE_MAP_REQUEST_MODE, mp);
17023
17024   mp->mode = mode;
17025
17026   /* send */
17027   S (mp);
17028
17029   /* wait for reply */
17030   W (ret);
17031   return ret;
17032 }
17033
17034 #define api_lisp_map_request_mode api_one_map_request_mode
17035
17036 /**
17037  * Enable/disable ONE proxy ITR.
17038  *
17039  * @param vam vpp API test context
17040  * @return return code
17041  */
17042 static int
17043 api_one_pitr_set_locator_set (vat_main_t * vam)
17044 {
17045   u8 ls_name_set = 0;
17046   unformat_input_t *input = vam->input;
17047   vl_api_one_pitr_set_locator_set_t *mp;
17048   u8 is_add = 1;
17049   u8 *ls_name = 0;
17050   int ret;
17051
17052   /* Parse args required to build the message */
17053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17054     {
17055       if (unformat (input, "del"))
17056         is_add = 0;
17057       else if (unformat (input, "locator-set %s", &ls_name))
17058         ls_name_set = 1;
17059       else
17060         {
17061           errmsg ("parse error '%U'", format_unformat_error, input);
17062           return -99;
17063         }
17064     }
17065
17066   if (!ls_name_set)
17067     {
17068       errmsg ("locator-set name not set!");
17069       return -99;
17070     }
17071
17072   M (ONE_PITR_SET_LOCATOR_SET, mp);
17073
17074   mp->is_add = is_add;
17075   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17076   vec_free (ls_name);
17077
17078   /* send */
17079   S (mp);
17080
17081   /* wait for reply */
17082   W (ret);
17083   return ret;
17084 }
17085
17086 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17087
17088 static int
17089 api_one_nsh_set_locator_set (vat_main_t * vam)
17090 {
17091   u8 ls_name_set = 0;
17092   unformat_input_t *input = vam->input;
17093   vl_api_one_nsh_set_locator_set_t *mp;
17094   u8 is_add = 1;
17095   u8 *ls_name = 0;
17096   int ret;
17097
17098   /* Parse args required to build the message */
17099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17100     {
17101       if (unformat (input, "del"))
17102         is_add = 0;
17103       else if (unformat (input, "ls %s", &ls_name))
17104         ls_name_set = 1;
17105       else
17106         {
17107           errmsg ("parse error '%U'", format_unformat_error, input);
17108           return -99;
17109         }
17110     }
17111
17112   if (!ls_name_set && is_add)
17113     {
17114       errmsg ("locator-set name not set!");
17115       return -99;
17116     }
17117
17118   M (ONE_NSH_SET_LOCATOR_SET, mp);
17119
17120   mp->is_add = is_add;
17121   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17122   vec_free (ls_name);
17123
17124   /* send */
17125   S (mp);
17126
17127   /* wait for reply */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 static int
17133 api_show_one_pitr (vat_main_t * vam)
17134 {
17135   vl_api_show_one_pitr_t *mp;
17136   int ret;
17137
17138   if (!vam->json_output)
17139     {
17140       print (vam->ofp, "%=20s", "lisp status:");
17141     }
17142
17143   M (SHOW_ONE_PITR, mp);
17144   /* send it... */
17145   S (mp);
17146
17147   /* Wait for a reply... */
17148   W (ret);
17149   return ret;
17150 }
17151
17152 #define api_show_lisp_pitr api_show_one_pitr
17153
17154 static int
17155 api_one_use_petr (vat_main_t * vam)
17156 {
17157   unformat_input_t *input = vam->input;
17158   vl_api_one_use_petr_t *mp;
17159   u8 is_add = 0;
17160   ip_address_t ip;
17161   int ret;
17162
17163   clib_memset (&ip, 0, sizeof (ip));
17164
17165   /* Parse args required to build the message */
17166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17167     {
17168       if (unformat (input, "disable"))
17169         is_add = 0;
17170       else
17171         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17172         {
17173           is_add = 1;
17174           ip_addr_version (&ip) = IP4;
17175         }
17176       else
17177         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17178         {
17179           is_add = 1;
17180           ip_addr_version (&ip) = IP6;
17181         }
17182       else
17183         {
17184           errmsg ("parse error '%U'", format_unformat_error, input);
17185           return -99;
17186         }
17187     }
17188
17189   M (ONE_USE_PETR, mp);
17190
17191   mp->is_add = is_add;
17192   if (is_add)
17193     {
17194       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17195       if (mp->is_ip4)
17196         clib_memcpy (mp->address, &ip, 4);
17197       else
17198         clib_memcpy (mp->address, &ip, 16);
17199     }
17200
17201   /* send */
17202   S (mp);
17203
17204   /* wait for reply */
17205   W (ret);
17206   return ret;
17207 }
17208
17209 #define api_lisp_use_petr api_one_use_petr
17210
17211 static int
17212 api_show_one_nsh_mapping (vat_main_t * vam)
17213 {
17214   vl_api_show_one_use_petr_t *mp;
17215   int ret;
17216
17217   if (!vam->json_output)
17218     {
17219       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17220     }
17221
17222   M (SHOW_ONE_NSH_MAPPING, mp);
17223   /* send it... */
17224   S (mp);
17225
17226   /* Wait for a reply... */
17227   W (ret);
17228   return ret;
17229 }
17230
17231 static int
17232 api_show_one_use_petr (vat_main_t * vam)
17233 {
17234   vl_api_show_one_use_petr_t *mp;
17235   int ret;
17236
17237   if (!vam->json_output)
17238     {
17239       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17240     }
17241
17242   M (SHOW_ONE_USE_PETR, mp);
17243   /* send it... */
17244   S (mp);
17245
17246   /* Wait for a reply... */
17247   W (ret);
17248   return ret;
17249 }
17250
17251 #define api_show_lisp_use_petr api_show_one_use_petr
17252
17253 /**
17254  * Add/delete mapping between vni and vrf
17255  */
17256 static int
17257 api_one_eid_table_add_del_map (vat_main_t * vam)
17258 {
17259   unformat_input_t *input = vam->input;
17260   vl_api_one_eid_table_add_del_map_t *mp;
17261   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17262   u32 vni, vrf, bd_index;
17263   int ret;
17264
17265   /* Parse args required to build the message */
17266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17267     {
17268       if (unformat (input, "del"))
17269         is_add = 0;
17270       else if (unformat (input, "vrf %d", &vrf))
17271         vrf_set = 1;
17272       else if (unformat (input, "bd_index %d", &bd_index))
17273         bd_index_set = 1;
17274       else if (unformat (input, "vni %d", &vni))
17275         vni_set = 1;
17276       else
17277         break;
17278     }
17279
17280   if (!vni_set || (!vrf_set && !bd_index_set))
17281     {
17282       errmsg ("missing arguments!");
17283       return -99;
17284     }
17285
17286   if (vrf_set && bd_index_set)
17287     {
17288       errmsg ("error: both vrf and bd entered!");
17289       return -99;
17290     }
17291
17292   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17293
17294   mp->is_add = is_add;
17295   mp->vni = htonl (vni);
17296   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17297   mp->is_l2 = bd_index_set;
17298
17299   /* send */
17300   S (mp);
17301
17302   /* wait for reply */
17303   W (ret);
17304   return ret;
17305 }
17306
17307 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17308
17309 uword
17310 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17311 {
17312   u32 *action = va_arg (*args, u32 *);
17313   u8 *s = 0;
17314
17315   if (unformat (input, "%s", &s))
17316     {
17317       if (!strcmp ((char *) s, "no-action"))
17318         action[0] = 0;
17319       else if (!strcmp ((char *) s, "natively-forward"))
17320         action[0] = 1;
17321       else if (!strcmp ((char *) s, "send-map-request"))
17322         action[0] = 2;
17323       else if (!strcmp ((char *) s, "drop"))
17324         action[0] = 3;
17325       else
17326         {
17327           clib_warning ("invalid action: '%s'", s);
17328           action[0] = 3;
17329         }
17330     }
17331   else
17332     return 0;
17333
17334   vec_free (s);
17335   return 1;
17336 }
17337
17338 /**
17339  * Add/del remote mapping to/from ONE control plane
17340  *
17341  * @param vam vpp API test context
17342  * @return return code
17343  */
17344 static int
17345 api_one_add_del_remote_mapping (vat_main_t * vam)
17346 {
17347   unformat_input_t *input = vam->input;
17348   vl_api_one_add_del_remote_mapping_t *mp;
17349   u32 vni = 0;
17350   lisp_eid_vat_t _eid, *eid = &_eid;
17351   lisp_eid_vat_t _seid, *seid = &_seid;
17352   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17353   u32 action = ~0, p, w, data_len;
17354   ip4_address_t rloc4;
17355   ip6_address_t rloc6;
17356   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17357   int ret;
17358
17359   clib_memset (&rloc, 0, sizeof (rloc));
17360
17361   /* Parse args required to build the message */
17362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17363     {
17364       if (unformat (input, "del-all"))
17365         {
17366           del_all = 1;
17367         }
17368       else if (unformat (input, "del"))
17369         {
17370           is_add = 0;
17371         }
17372       else if (unformat (input, "add"))
17373         {
17374           is_add = 1;
17375         }
17376       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17377         {
17378           eid_set = 1;
17379         }
17380       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17381         {
17382           seid_set = 1;
17383         }
17384       else if (unformat (input, "vni %d", &vni))
17385         {
17386           ;
17387         }
17388       else if (unformat (input, "p %d w %d", &p, &w))
17389         {
17390           if (!curr_rloc)
17391             {
17392               errmsg ("No RLOC configured for setting priority/weight!");
17393               return -99;
17394             }
17395           curr_rloc->priority = p;
17396           curr_rloc->weight = w;
17397         }
17398       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17399         {
17400           rloc.is_ip4 = 1;
17401           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17402           vec_add1 (rlocs, rloc);
17403           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17404         }
17405       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17406         {
17407           rloc.is_ip4 = 0;
17408           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17409           vec_add1 (rlocs, rloc);
17410           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17411         }
17412       else if (unformat (input, "action %U",
17413                          unformat_negative_mapping_action, &action))
17414         {
17415           ;
17416         }
17417       else
17418         {
17419           clib_warning ("parse error '%U'", format_unformat_error, input);
17420           return -99;
17421         }
17422     }
17423
17424   if (0 == eid_set)
17425     {
17426       errmsg ("missing params!");
17427       return -99;
17428     }
17429
17430   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17431     {
17432       errmsg ("no action set for negative map-reply!");
17433       return -99;
17434     }
17435
17436   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17437
17438   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17439   mp->is_add = is_add;
17440   mp->vni = htonl (vni);
17441   mp->action = (u8) action;
17442   mp->is_src_dst = seid_set;
17443   mp->eid_len = eid->len;
17444   mp->seid_len = seid->len;
17445   mp->del_all = del_all;
17446   mp->eid_type = eid->type;
17447   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17448   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17449
17450   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17451   clib_memcpy (mp->rlocs, rlocs, data_len);
17452   vec_free (rlocs);
17453
17454   /* send it... */
17455   S (mp);
17456
17457   /* Wait for a reply... */
17458   W (ret);
17459   return ret;
17460 }
17461
17462 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17463
17464 /**
17465  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17466  * forwarding entries in data-plane accordingly.
17467  *
17468  * @param vam vpp API test context
17469  * @return return code
17470  */
17471 static int
17472 api_one_add_del_adjacency (vat_main_t * vam)
17473 {
17474   unformat_input_t *input = vam->input;
17475   vl_api_one_add_del_adjacency_t *mp;
17476   u32 vni = 0;
17477   ip4_address_t leid4, reid4;
17478   ip6_address_t leid6, reid6;
17479   u8 reid_mac[6] = { 0 };
17480   u8 leid_mac[6] = { 0 };
17481   u8 reid_type, leid_type;
17482   u32 leid_len = 0, reid_len = 0, len;
17483   u8 is_add = 1;
17484   int ret;
17485
17486   leid_type = reid_type = (u8) ~ 0;
17487
17488   /* Parse args required to build the message */
17489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17490     {
17491       if (unformat (input, "del"))
17492         {
17493           is_add = 0;
17494         }
17495       else if (unformat (input, "add"))
17496         {
17497           is_add = 1;
17498         }
17499       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17500                          &reid4, &len))
17501         {
17502           reid_type = 0;        /* ipv4 */
17503           reid_len = len;
17504         }
17505       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17506                          &reid6, &len))
17507         {
17508           reid_type = 1;        /* ipv6 */
17509           reid_len = len;
17510         }
17511       else if (unformat (input, "reid %U", unformat_ethernet_address,
17512                          reid_mac))
17513         {
17514           reid_type = 2;        /* mac */
17515         }
17516       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17517                          &leid4, &len))
17518         {
17519           leid_type = 0;        /* ipv4 */
17520           leid_len = len;
17521         }
17522       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17523                          &leid6, &len))
17524         {
17525           leid_type = 1;        /* ipv6 */
17526           leid_len = len;
17527         }
17528       else if (unformat (input, "leid %U", unformat_ethernet_address,
17529                          leid_mac))
17530         {
17531           leid_type = 2;        /* mac */
17532         }
17533       else if (unformat (input, "vni %d", &vni))
17534         {
17535           ;
17536         }
17537       else
17538         {
17539           errmsg ("parse error '%U'", format_unformat_error, input);
17540           return -99;
17541         }
17542     }
17543
17544   if ((u8) ~ 0 == reid_type)
17545     {
17546       errmsg ("missing params!");
17547       return -99;
17548     }
17549
17550   if (leid_type != reid_type)
17551     {
17552       errmsg ("remote and local EIDs are of different types!");
17553       return -99;
17554     }
17555
17556   M (ONE_ADD_DEL_ADJACENCY, mp);
17557   mp->is_add = is_add;
17558   mp->vni = htonl (vni);
17559   mp->leid_len = leid_len;
17560   mp->reid_len = reid_len;
17561   mp->eid_type = reid_type;
17562
17563   switch (mp->eid_type)
17564     {
17565     case 0:
17566       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17567       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17568       break;
17569     case 1:
17570       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17571       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17572       break;
17573     case 2:
17574       clib_memcpy (mp->leid, leid_mac, 6);
17575       clib_memcpy (mp->reid, reid_mac, 6);
17576       break;
17577     default:
17578       errmsg ("unknown EID type %d!", mp->eid_type);
17579       return 0;
17580     }
17581
17582   /* send it... */
17583   S (mp);
17584
17585   /* Wait for a reply... */
17586   W (ret);
17587   return ret;
17588 }
17589
17590 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17591
17592 uword
17593 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17594 {
17595   u32 *mode = va_arg (*args, u32 *);
17596
17597   if (unformat (input, "lisp"))
17598     *mode = 0;
17599   else if (unformat (input, "vxlan"))
17600     *mode = 1;
17601   else
17602     return 0;
17603
17604   return 1;
17605 }
17606
17607 static int
17608 api_gpe_get_encap_mode (vat_main_t * vam)
17609 {
17610   vl_api_gpe_get_encap_mode_t *mp;
17611   int ret;
17612
17613   /* Construct the API message */
17614   M (GPE_GET_ENCAP_MODE, mp);
17615
17616   /* send it... */
17617   S (mp);
17618
17619   /* Wait for a reply... */
17620   W (ret);
17621   return ret;
17622 }
17623
17624 static int
17625 api_gpe_set_encap_mode (vat_main_t * vam)
17626 {
17627   unformat_input_t *input = vam->input;
17628   vl_api_gpe_set_encap_mode_t *mp;
17629   int ret;
17630   u32 mode = 0;
17631
17632   /* Parse args required to build the message */
17633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17634     {
17635       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17636         ;
17637       else
17638         break;
17639     }
17640
17641   /* Construct the API message */
17642   M (GPE_SET_ENCAP_MODE, mp);
17643
17644   mp->mode = mode;
17645
17646   /* send it... */
17647   S (mp);
17648
17649   /* Wait for a reply... */
17650   W (ret);
17651   return ret;
17652 }
17653
17654 static int
17655 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17656 {
17657   unformat_input_t *input = vam->input;
17658   vl_api_gpe_add_del_iface_t *mp;
17659   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17660   u32 dp_table = 0, vni = 0;
17661   int ret;
17662
17663   /* Parse args required to build the message */
17664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17665     {
17666       if (unformat (input, "up"))
17667         {
17668           action_set = 1;
17669           is_add = 1;
17670         }
17671       else if (unformat (input, "down"))
17672         {
17673           action_set = 1;
17674           is_add = 0;
17675         }
17676       else if (unformat (input, "table_id %d", &dp_table))
17677         {
17678           dp_table_set = 1;
17679         }
17680       else if (unformat (input, "bd_id %d", &dp_table))
17681         {
17682           dp_table_set = 1;
17683           is_l2 = 1;
17684         }
17685       else if (unformat (input, "vni %d", &vni))
17686         {
17687           vni_set = 1;
17688         }
17689       else
17690         break;
17691     }
17692
17693   if (action_set == 0)
17694     {
17695       errmsg ("Action not set");
17696       return -99;
17697     }
17698   if (dp_table_set == 0 || vni_set == 0)
17699     {
17700       errmsg ("vni and dp_table must be set");
17701       return -99;
17702     }
17703
17704   /* Construct the API message */
17705   M (GPE_ADD_DEL_IFACE, mp);
17706
17707   mp->is_add = is_add;
17708   mp->dp_table = clib_host_to_net_u32 (dp_table);
17709   mp->is_l2 = is_l2;
17710   mp->vni = clib_host_to_net_u32 (vni);
17711
17712   /* send it... */
17713   S (mp);
17714
17715   /* Wait for a reply... */
17716   W (ret);
17717   return ret;
17718 }
17719
17720 static int
17721 api_one_map_register_fallback_threshold (vat_main_t * vam)
17722 {
17723   unformat_input_t *input = vam->input;
17724   vl_api_one_map_register_fallback_threshold_t *mp;
17725   u32 value = 0;
17726   u8 is_set = 0;
17727   int ret;
17728
17729   /* Parse args required to build the message */
17730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17731     {
17732       if (unformat (input, "%u", &value))
17733         is_set = 1;
17734       else
17735         {
17736           clib_warning ("parse error '%U'", format_unformat_error, input);
17737           return -99;
17738         }
17739     }
17740
17741   if (!is_set)
17742     {
17743       errmsg ("fallback threshold value is missing!");
17744       return -99;
17745     }
17746
17747   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17748   mp->value = clib_host_to_net_u32 (value);
17749
17750   /* send it... */
17751   S (mp);
17752
17753   /* Wait for a reply... */
17754   W (ret);
17755   return ret;
17756 }
17757
17758 static int
17759 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17760 {
17761   vl_api_show_one_map_register_fallback_threshold_t *mp;
17762   int ret;
17763
17764   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17765
17766   /* send it... */
17767   S (mp);
17768
17769   /* Wait for a reply... */
17770   W (ret);
17771   return ret;
17772 }
17773
17774 uword
17775 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17776 {
17777   u32 *proto = va_arg (*args, u32 *);
17778
17779   if (unformat (input, "udp"))
17780     *proto = 1;
17781   else if (unformat (input, "api"))
17782     *proto = 2;
17783   else
17784     return 0;
17785
17786   return 1;
17787 }
17788
17789 static int
17790 api_one_set_transport_protocol (vat_main_t * vam)
17791 {
17792   unformat_input_t *input = vam->input;
17793   vl_api_one_set_transport_protocol_t *mp;
17794   u8 is_set = 0;
17795   u32 protocol = 0;
17796   int ret;
17797
17798   /* Parse args required to build the message */
17799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17800     {
17801       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17802         is_set = 1;
17803       else
17804         {
17805           clib_warning ("parse error '%U'", format_unformat_error, input);
17806           return -99;
17807         }
17808     }
17809
17810   if (!is_set)
17811     {
17812       errmsg ("Transport protocol missing!");
17813       return -99;
17814     }
17815
17816   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17817   mp->protocol = (u8) protocol;
17818
17819   /* send it... */
17820   S (mp);
17821
17822   /* Wait for a reply... */
17823   W (ret);
17824   return ret;
17825 }
17826
17827 static int
17828 api_one_get_transport_protocol (vat_main_t * vam)
17829 {
17830   vl_api_one_get_transport_protocol_t *mp;
17831   int ret;
17832
17833   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17834
17835   /* send it... */
17836   S (mp);
17837
17838   /* Wait for a reply... */
17839   W (ret);
17840   return ret;
17841 }
17842
17843 static int
17844 api_one_map_register_set_ttl (vat_main_t * vam)
17845 {
17846   unformat_input_t *input = vam->input;
17847   vl_api_one_map_register_set_ttl_t *mp;
17848   u32 ttl = 0;
17849   u8 is_set = 0;
17850   int ret;
17851
17852   /* Parse args required to build the message */
17853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17854     {
17855       if (unformat (input, "%u", &ttl))
17856         is_set = 1;
17857       else
17858         {
17859           clib_warning ("parse error '%U'", format_unformat_error, input);
17860           return -99;
17861         }
17862     }
17863
17864   if (!is_set)
17865     {
17866       errmsg ("TTL value missing!");
17867       return -99;
17868     }
17869
17870   M (ONE_MAP_REGISTER_SET_TTL, mp);
17871   mp->ttl = clib_host_to_net_u32 (ttl);
17872
17873   /* send it... */
17874   S (mp);
17875
17876   /* Wait for a reply... */
17877   W (ret);
17878   return ret;
17879 }
17880
17881 static int
17882 api_show_one_map_register_ttl (vat_main_t * vam)
17883 {
17884   vl_api_show_one_map_register_ttl_t *mp;
17885   int ret;
17886
17887   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17888
17889   /* send it... */
17890   S (mp);
17891
17892   /* Wait for a reply... */
17893   W (ret);
17894   return ret;
17895 }
17896
17897 /**
17898  * Add/del map request itr rlocs from ONE control plane and updates
17899  *
17900  * @param vam vpp API test context
17901  * @return return code
17902  */
17903 static int
17904 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17905 {
17906   unformat_input_t *input = vam->input;
17907   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17908   u8 *locator_set_name = 0;
17909   u8 locator_set_name_set = 0;
17910   u8 is_add = 1;
17911   int ret;
17912
17913   /* Parse args required to build the message */
17914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17915     {
17916       if (unformat (input, "del"))
17917         {
17918           is_add = 0;
17919         }
17920       else if (unformat (input, "%_%v%_", &locator_set_name))
17921         {
17922           locator_set_name_set = 1;
17923         }
17924       else
17925         {
17926           clib_warning ("parse error '%U'", format_unformat_error, input);
17927           return -99;
17928         }
17929     }
17930
17931   if (is_add && !locator_set_name_set)
17932     {
17933       errmsg ("itr-rloc is not set!");
17934       return -99;
17935     }
17936
17937   if (is_add && vec_len (locator_set_name) > 64)
17938     {
17939       errmsg ("itr-rloc locator-set name too long");
17940       vec_free (locator_set_name);
17941       return -99;
17942     }
17943
17944   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17945   mp->is_add = is_add;
17946   if (is_add)
17947     {
17948       clib_memcpy (mp->locator_set_name, locator_set_name,
17949                    vec_len (locator_set_name));
17950     }
17951   else
17952     {
17953       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17954     }
17955   vec_free (locator_set_name);
17956
17957   /* send it... */
17958   S (mp);
17959
17960   /* Wait for a reply... */
17961   W (ret);
17962   return ret;
17963 }
17964
17965 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17966
17967 static int
17968 api_one_locator_dump (vat_main_t * vam)
17969 {
17970   unformat_input_t *input = vam->input;
17971   vl_api_one_locator_dump_t *mp;
17972   vl_api_control_ping_t *mp_ping;
17973   u8 is_index_set = 0, is_name_set = 0;
17974   u8 *ls_name = 0;
17975   u32 ls_index = ~0;
17976   int ret;
17977
17978   /* Parse args required to build the message */
17979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17980     {
17981       if (unformat (input, "ls_name %_%v%_", &ls_name))
17982         {
17983           is_name_set = 1;
17984         }
17985       else if (unformat (input, "ls_index %d", &ls_index))
17986         {
17987           is_index_set = 1;
17988         }
17989       else
17990         {
17991           errmsg ("parse error '%U'", format_unformat_error, input);
17992           return -99;
17993         }
17994     }
17995
17996   if (!is_index_set && !is_name_set)
17997     {
17998       errmsg ("error: expected one of index or name!");
17999       return -99;
18000     }
18001
18002   if (is_index_set && is_name_set)
18003     {
18004       errmsg ("error: only one param expected!");
18005       return -99;
18006     }
18007
18008   if (vec_len (ls_name) > 62)
18009     {
18010       errmsg ("error: locator set name too long!");
18011       return -99;
18012     }
18013
18014   if (!vam->json_output)
18015     {
18016       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18017     }
18018
18019   M (ONE_LOCATOR_DUMP, mp);
18020   mp->is_index_set = is_index_set;
18021
18022   if (is_index_set)
18023     mp->ls_index = clib_host_to_net_u32 (ls_index);
18024   else
18025     {
18026       vec_add1 (ls_name, 0);
18027       strncpy ((char *) mp->ls_name, (char *) ls_name,
18028                sizeof (mp->ls_name) - 1);
18029     }
18030
18031   /* send it... */
18032   S (mp);
18033
18034   /* Use a control ping for synchronization */
18035   MPING (CONTROL_PING, mp_ping);
18036   S (mp_ping);
18037
18038   /* Wait for a reply... */
18039   W (ret);
18040   return ret;
18041 }
18042
18043 #define api_lisp_locator_dump api_one_locator_dump
18044
18045 static int
18046 api_one_locator_set_dump (vat_main_t * vam)
18047 {
18048   vl_api_one_locator_set_dump_t *mp;
18049   vl_api_control_ping_t *mp_ping;
18050   unformat_input_t *input = vam->input;
18051   u8 filter = 0;
18052   int ret;
18053
18054   /* Parse args required to build the message */
18055   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18056     {
18057       if (unformat (input, "local"))
18058         {
18059           filter = 1;
18060         }
18061       else if (unformat (input, "remote"))
18062         {
18063           filter = 2;
18064         }
18065       else
18066         {
18067           errmsg ("parse error '%U'", format_unformat_error, input);
18068           return -99;
18069         }
18070     }
18071
18072   if (!vam->json_output)
18073     {
18074       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18075     }
18076
18077   M (ONE_LOCATOR_SET_DUMP, mp);
18078
18079   mp->filter = filter;
18080
18081   /* send it... */
18082   S (mp);
18083
18084   /* Use a control ping for synchronization */
18085   MPING (CONTROL_PING, mp_ping);
18086   S (mp_ping);
18087
18088   /* Wait for a reply... */
18089   W (ret);
18090   return ret;
18091 }
18092
18093 #define api_lisp_locator_set_dump api_one_locator_set_dump
18094
18095 static int
18096 api_one_eid_table_map_dump (vat_main_t * vam)
18097 {
18098   u8 is_l2 = 0;
18099   u8 mode_set = 0;
18100   unformat_input_t *input = vam->input;
18101   vl_api_one_eid_table_map_dump_t *mp;
18102   vl_api_control_ping_t *mp_ping;
18103   int ret;
18104
18105   /* Parse args required to build the message */
18106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18107     {
18108       if (unformat (input, "l2"))
18109         {
18110           is_l2 = 1;
18111           mode_set = 1;
18112         }
18113       else if (unformat (input, "l3"))
18114         {
18115           is_l2 = 0;
18116           mode_set = 1;
18117         }
18118       else
18119         {
18120           errmsg ("parse error '%U'", format_unformat_error, input);
18121           return -99;
18122         }
18123     }
18124
18125   if (!mode_set)
18126     {
18127       errmsg ("expected one of 'l2' or 'l3' parameter!");
18128       return -99;
18129     }
18130
18131   if (!vam->json_output)
18132     {
18133       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18134     }
18135
18136   M (ONE_EID_TABLE_MAP_DUMP, mp);
18137   mp->is_l2 = is_l2;
18138
18139   /* send it... */
18140   S (mp);
18141
18142   /* Use a control ping for synchronization */
18143   MPING (CONTROL_PING, mp_ping);
18144   S (mp_ping);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18152
18153 static int
18154 api_one_eid_table_vni_dump (vat_main_t * vam)
18155 {
18156   vl_api_one_eid_table_vni_dump_t *mp;
18157   vl_api_control_ping_t *mp_ping;
18158   int ret;
18159
18160   if (!vam->json_output)
18161     {
18162       print (vam->ofp, "VNI");
18163     }
18164
18165   M (ONE_EID_TABLE_VNI_DUMP, mp);
18166
18167   /* send it... */
18168   S (mp);
18169
18170   /* Use a control ping for synchronization */
18171   MPING (CONTROL_PING, mp_ping);
18172   S (mp_ping);
18173
18174   /* Wait for a reply... */
18175   W (ret);
18176   return ret;
18177 }
18178
18179 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18180
18181 static int
18182 api_one_eid_table_dump (vat_main_t * vam)
18183 {
18184   unformat_input_t *i = vam->input;
18185   vl_api_one_eid_table_dump_t *mp;
18186   vl_api_control_ping_t *mp_ping;
18187   struct in_addr ip4;
18188   struct in6_addr ip6;
18189   u8 mac[6];
18190   u8 eid_type = ~0, eid_set = 0;
18191   u32 prefix_length = ~0, t, vni = 0;
18192   u8 filter = 0;
18193   int ret;
18194   lisp_nsh_api_t nsh;
18195
18196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18197     {
18198       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18199         {
18200           eid_set = 1;
18201           eid_type = 0;
18202           prefix_length = t;
18203         }
18204       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18205         {
18206           eid_set = 1;
18207           eid_type = 1;
18208           prefix_length = t;
18209         }
18210       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18211         {
18212           eid_set = 1;
18213           eid_type = 2;
18214         }
18215       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18216         {
18217           eid_set = 1;
18218           eid_type = 3;
18219         }
18220       else if (unformat (i, "vni %d", &t))
18221         {
18222           vni = t;
18223         }
18224       else if (unformat (i, "local"))
18225         {
18226           filter = 1;
18227         }
18228       else if (unformat (i, "remote"))
18229         {
18230           filter = 2;
18231         }
18232       else
18233         {
18234           errmsg ("parse error '%U'", format_unformat_error, i);
18235           return -99;
18236         }
18237     }
18238
18239   if (!vam->json_output)
18240     {
18241       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18242              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18243     }
18244
18245   M (ONE_EID_TABLE_DUMP, mp);
18246
18247   mp->filter = filter;
18248   if (eid_set)
18249     {
18250       mp->eid_set = 1;
18251       mp->vni = htonl (vni);
18252       mp->eid_type = eid_type;
18253       switch (eid_type)
18254         {
18255         case 0:
18256           mp->prefix_length = prefix_length;
18257           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18258           break;
18259         case 1:
18260           mp->prefix_length = prefix_length;
18261           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18262           break;
18263         case 2:
18264           clib_memcpy (mp->eid, mac, sizeof (mac));
18265           break;
18266         case 3:
18267           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18268           break;
18269         default:
18270           errmsg ("unknown EID type %d!", eid_type);
18271           return -99;
18272         }
18273     }
18274
18275   /* send it... */
18276   S (mp);
18277
18278   /* Use a control ping for synchronization */
18279   MPING (CONTROL_PING, mp_ping);
18280   S (mp_ping);
18281
18282   /* Wait for a reply... */
18283   W (ret);
18284   return ret;
18285 }
18286
18287 #define api_lisp_eid_table_dump api_one_eid_table_dump
18288
18289 static int
18290 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18291 {
18292   unformat_input_t *i = vam->input;
18293   vl_api_gpe_fwd_entries_get_t *mp;
18294   u8 vni_set = 0;
18295   u32 vni = ~0;
18296   int ret;
18297
18298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18299     {
18300       if (unformat (i, "vni %d", &vni))
18301         {
18302           vni_set = 1;
18303         }
18304       else
18305         {
18306           errmsg ("parse error '%U'", format_unformat_error, i);
18307           return -99;
18308         }
18309     }
18310
18311   if (!vni_set)
18312     {
18313       errmsg ("vni not set!");
18314       return -99;
18315     }
18316
18317   if (!vam->json_output)
18318     {
18319       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18320              "leid", "reid");
18321     }
18322
18323   M (GPE_FWD_ENTRIES_GET, mp);
18324   mp->vni = clib_host_to_net_u32 (vni);
18325
18326   /* send it... */
18327   S (mp);
18328
18329   /* Wait for a reply... */
18330   W (ret);
18331   return ret;
18332 }
18333
18334 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18335 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18336 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18337 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18338 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18339 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18340 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18341 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18342
18343 static int
18344 api_one_adjacencies_get (vat_main_t * vam)
18345 {
18346   unformat_input_t *i = vam->input;
18347   vl_api_one_adjacencies_get_t *mp;
18348   u8 vni_set = 0;
18349   u32 vni = ~0;
18350   int ret;
18351
18352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18353     {
18354       if (unformat (i, "vni %d", &vni))
18355         {
18356           vni_set = 1;
18357         }
18358       else
18359         {
18360           errmsg ("parse error '%U'", format_unformat_error, i);
18361           return -99;
18362         }
18363     }
18364
18365   if (!vni_set)
18366     {
18367       errmsg ("vni not set!");
18368       return -99;
18369     }
18370
18371   if (!vam->json_output)
18372     {
18373       print (vam->ofp, "%s %40s", "leid", "reid");
18374     }
18375
18376   M (ONE_ADJACENCIES_GET, mp);
18377   mp->vni = clib_host_to_net_u32 (vni);
18378
18379   /* send it... */
18380   S (mp);
18381
18382   /* Wait for a reply... */
18383   W (ret);
18384   return ret;
18385 }
18386
18387 #define api_lisp_adjacencies_get api_one_adjacencies_get
18388
18389 static int
18390 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18391 {
18392   unformat_input_t *i = vam->input;
18393   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18394   int ret;
18395   u8 ip_family_set = 0, is_ip4 = 1;
18396
18397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18398     {
18399       if (unformat (i, "ip4"))
18400         {
18401           ip_family_set = 1;
18402           is_ip4 = 1;
18403         }
18404       else if (unformat (i, "ip6"))
18405         {
18406           ip_family_set = 1;
18407           is_ip4 = 0;
18408         }
18409       else
18410         {
18411           errmsg ("parse error '%U'", format_unformat_error, i);
18412           return -99;
18413         }
18414     }
18415
18416   if (!ip_family_set)
18417     {
18418       errmsg ("ip family not set!");
18419       return -99;
18420     }
18421
18422   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18423   mp->is_ip4 = is_ip4;
18424
18425   /* send it... */
18426   S (mp);
18427
18428   /* Wait for a reply... */
18429   W (ret);
18430   return ret;
18431 }
18432
18433 static int
18434 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18435 {
18436   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18437   int ret;
18438
18439   if (!vam->json_output)
18440     {
18441       print (vam->ofp, "VNIs");
18442     }
18443
18444   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18445
18446   /* send it... */
18447   S (mp);
18448
18449   /* Wait for a reply... */
18450   W (ret);
18451   return ret;
18452 }
18453
18454 static int
18455 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18456 {
18457   unformat_input_t *i = vam->input;
18458   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18459   int ret = 0;
18460   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18461   struct in_addr ip4;
18462   struct in6_addr ip6;
18463   u32 table_id = 0, nh_sw_if_index = ~0;
18464
18465   clib_memset (&ip4, 0, sizeof (ip4));
18466   clib_memset (&ip6, 0, sizeof (ip6));
18467
18468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18469     {
18470       if (unformat (i, "del"))
18471         is_add = 0;
18472       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18473                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18474         {
18475           ip_set = 1;
18476           is_ip4 = 1;
18477         }
18478       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18479                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18480         {
18481           ip_set = 1;
18482           is_ip4 = 0;
18483         }
18484       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18485         {
18486           ip_set = 1;
18487           is_ip4 = 1;
18488           nh_sw_if_index = ~0;
18489         }
18490       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18491         {
18492           ip_set = 1;
18493           is_ip4 = 0;
18494           nh_sw_if_index = ~0;
18495         }
18496       else if (unformat (i, "table %d", &table_id))
18497         ;
18498       else
18499         {
18500           errmsg ("parse error '%U'", format_unformat_error, i);
18501           return -99;
18502         }
18503     }
18504
18505   if (!ip_set)
18506     {
18507       errmsg ("nh addr not set!");
18508       return -99;
18509     }
18510
18511   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18512   mp->is_add = is_add;
18513   mp->table_id = clib_host_to_net_u32 (table_id);
18514   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18515   mp->is_ip4 = is_ip4;
18516   if (is_ip4)
18517     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18518   else
18519     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18520
18521   /* send it... */
18522   S (mp);
18523
18524   /* Wait for a reply... */
18525   W (ret);
18526   return ret;
18527 }
18528
18529 static int
18530 api_one_map_server_dump (vat_main_t * vam)
18531 {
18532   vl_api_one_map_server_dump_t *mp;
18533   vl_api_control_ping_t *mp_ping;
18534   int ret;
18535
18536   if (!vam->json_output)
18537     {
18538       print (vam->ofp, "%=20s", "Map server");
18539     }
18540
18541   M (ONE_MAP_SERVER_DUMP, mp);
18542   /* send it... */
18543   S (mp);
18544
18545   /* Use a control ping for synchronization */
18546   MPING (CONTROL_PING, mp_ping);
18547   S (mp_ping);
18548
18549   /* Wait for a reply... */
18550   W (ret);
18551   return ret;
18552 }
18553
18554 #define api_lisp_map_server_dump api_one_map_server_dump
18555
18556 static int
18557 api_one_map_resolver_dump (vat_main_t * vam)
18558 {
18559   vl_api_one_map_resolver_dump_t *mp;
18560   vl_api_control_ping_t *mp_ping;
18561   int ret;
18562
18563   if (!vam->json_output)
18564     {
18565       print (vam->ofp, "%=20s", "Map resolver");
18566     }
18567
18568   M (ONE_MAP_RESOLVER_DUMP, mp);
18569   /* send it... */
18570   S (mp);
18571
18572   /* Use a control ping for synchronization */
18573   MPING (CONTROL_PING, mp_ping);
18574   S (mp_ping);
18575
18576   /* Wait for a reply... */
18577   W (ret);
18578   return ret;
18579 }
18580
18581 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18582
18583 static int
18584 api_one_stats_flush (vat_main_t * vam)
18585 {
18586   vl_api_one_stats_flush_t *mp;
18587   int ret = 0;
18588
18589   M (ONE_STATS_FLUSH, mp);
18590   S (mp);
18591   W (ret);
18592   return ret;
18593 }
18594
18595 static int
18596 api_one_stats_dump (vat_main_t * vam)
18597 {
18598   vl_api_one_stats_dump_t *mp;
18599   vl_api_control_ping_t *mp_ping;
18600   int ret;
18601
18602   M (ONE_STATS_DUMP, mp);
18603   /* send it... */
18604   S (mp);
18605
18606   /* Use a control ping for synchronization */
18607   MPING (CONTROL_PING, mp_ping);
18608   S (mp_ping);
18609
18610   /* Wait for a reply... */
18611   W (ret);
18612   return ret;
18613 }
18614
18615 static int
18616 api_show_one_status (vat_main_t * vam)
18617 {
18618   vl_api_show_one_status_t *mp;
18619   int ret;
18620
18621   if (!vam->json_output)
18622     {
18623       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18624     }
18625
18626   M (SHOW_ONE_STATUS, mp);
18627   /* send it... */
18628   S (mp);
18629   /* Wait for a reply... */
18630   W (ret);
18631   return ret;
18632 }
18633
18634 #define api_show_lisp_status api_show_one_status
18635
18636 static int
18637 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18638 {
18639   vl_api_gpe_fwd_entry_path_dump_t *mp;
18640   vl_api_control_ping_t *mp_ping;
18641   unformat_input_t *i = vam->input;
18642   u32 fwd_entry_index = ~0;
18643   int ret;
18644
18645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18646     {
18647       if (unformat (i, "index %d", &fwd_entry_index))
18648         ;
18649       else
18650         break;
18651     }
18652
18653   if (~0 == fwd_entry_index)
18654     {
18655       errmsg ("no index specified!");
18656       return -99;
18657     }
18658
18659   if (!vam->json_output)
18660     {
18661       print (vam->ofp, "first line");
18662     }
18663
18664   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18665
18666   /* send it... */
18667   S (mp);
18668   /* Use a control ping for synchronization */
18669   MPING (CONTROL_PING, mp_ping);
18670   S (mp_ping);
18671
18672   /* Wait for a reply... */
18673   W (ret);
18674   return ret;
18675 }
18676
18677 static int
18678 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18679 {
18680   vl_api_one_get_map_request_itr_rlocs_t *mp;
18681   int ret;
18682
18683   if (!vam->json_output)
18684     {
18685       print (vam->ofp, "%=20s", "itr-rlocs:");
18686     }
18687
18688   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18689   /* send it... */
18690   S (mp);
18691   /* Wait for a reply... */
18692   W (ret);
18693   return ret;
18694 }
18695
18696 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18697
18698 static int
18699 api_af_packet_create (vat_main_t * vam)
18700 {
18701   unformat_input_t *i = vam->input;
18702   vl_api_af_packet_create_t *mp;
18703   u8 *host_if_name = 0;
18704   u8 hw_addr[6];
18705   u8 random_hw_addr = 1;
18706   int ret;
18707
18708   clib_memset (hw_addr, 0, sizeof (hw_addr));
18709
18710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18711     {
18712       if (unformat (i, "name %s", &host_if_name))
18713         vec_add1 (host_if_name, 0);
18714       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18715         random_hw_addr = 0;
18716       else
18717         break;
18718     }
18719
18720   if (!vec_len (host_if_name))
18721     {
18722       errmsg ("host-interface name must be specified");
18723       return -99;
18724     }
18725
18726   if (vec_len (host_if_name) > 64)
18727     {
18728       errmsg ("host-interface name too long");
18729       return -99;
18730     }
18731
18732   M (AF_PACKET_CREATE, mp);
18733
18734   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18735   clib_memcpy (mp->hw_addr, hw_addr, 6);
18736   mp->use_random_hw_addr = random_hw_addr;
18737   vec_free (host_if_name);
18738
18739   S (mp);
18740
18741   /* *INDENT-OFF* */
18742   W2 (ret,
18743       ({
18744         if (ret == 0)
18745           fprintf (vam->ofp ? vam->ofp : stderr,
18746                    " new sw_if_index = %d\n", vam->sw_if_index);
18747       }));
18748   /* *INDENT-ON* */
18749   return ret;
18750 }
18751
18752 static int
18753 api_af_packet_delete (vat_main_t * vam)
18754 {
18755   unformat_input_t *i = vam->input;
18756   vl_api_af_packet_delete_t *mp;
18757   u8 *host_if_name = 0;
18758   int ret;
18759
18760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18761     {
18762       if (unformat (i, "name %s", &host_if_name))
18763         vec_add1 (host_if_name, 0);
18764       else
18765         break;
18766     }
18767
18768   if (!vec_len (host_if_name))
18769     {
18770       errmsg ("host-interface name must be specified");
18771       return -99;
18772     }
18773
18774   if (vec_len (host_if_name) > 64)
18775     {
18776       errmsg ("host-interface name too long");
18777       return -99;
18778     }
18779
18780   M (AF_PACKET_DELETE, mp);
18781
18782   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18783   vec_free (host_if_name);
18784
18785   S (mp);
18786   W (ret);
18787   return ret;
18788 }
18789
18790 static void vl_api_af_packet_details_t_handler
18791   (vl_api_af_packet_details_t * mp)
18792 {
18793   vat_main_t *vam = &vat_main;
18794
18795   print (vam->ofp, "%-16s %d",
18796          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18797 }
18798
18799 static void vl_api_af_packet_details_t_handler_json
18800   (vl_api_af_packet_details_t * mp)
18801 {
18802   vat_main_t *vam = &vat_main;
18803   vat_json_node_t *node = NULL;
18804
18805   if (VAT_JSON_ARRAY != vam->json_tree.type)
18806     {
18807       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18808       vat_json_init_array (&vam->json_tree);
18809     }
18810   node = vat_json_array_add (&vam->json_tree);
18811
18812   vat_json_init_object (node);
18813   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18814   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18815 }
18816
18817 static int
18818 api_af_packet_dump (vat_main_t * vam)
18819 {
18820   vl_api_af_packet_dump_t *mp;
18821   vl_api_control_ping_t *mp_ping;
18822   int ret;
18823
18824   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18825   /* Get list of tap interfaces */
18826   M (AF_PACKET_DUMP, mp);
18827   S (mp);
18828
18829   /* Use a control ping for synchronization */
18830   MPING (CONTROL_PING, mp_ping);
18831   S (mp_ping);
18832
18833   W (ret);
18834   return ret;
18835 }
18836
18837 static int
18838 api_policer_add_del (vat_main_t * vam)
18839 {
18840   unformat_input_t *i = vam->input;
18841   vl_api_policer_add_del_t *mp;
18842   u8 is_add = 1;
18843   u8 *name = 0;
18844   u32 cir = 0;
18845   u32 eir = 0;
18846   u64 cb = 0;
18847   u64 eb = 0;
18848   u8 rate_type = 0;
18849   u8 round_type = 0;
18850   u8 type = 0;
18851   u8 color_aware = 0;
18852   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18853   int ret;
18854
18855   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18856   conform_action.dscp = 0;
18857   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18858   exceed_action.dscp = 0;
18859   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18860   violate_action.dscp = 0;
18861
18862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18863     {
18864       if (unformat (i, "del"))
18865         is_add = 0;
18866       else if (unformat (i, "name %s", &name))
18867         vec_add1 (name, 0);
18868       else if (unformat (i, "cir %u", &cir))
18869         ;
18870       else if (unformat (i, "eir %u", &eir))
18871         ;
18872       else if (unformat (i, "cb %u", &cb))
18873         ;
18874       else if (unformat (i, "eb %u", &eb))
18875         ;
18876       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18877                          &rate_type))
18878         ;
18879       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18880                          &round_type))
18881         ;
18882       else if (unformat (i, "type %U", unformat_policer_type, &type))
18883         ;
18884       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18885                          &conform_action))
18886         ;
18887       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18888                          &exceed_action))
18889         ;
18890       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18891                          &violate_action))
18892         ;
18893       else if (unformat (i, "color-aware"))
18894         color_aware = 1;
18895       else
18896         break;
18897     }
18898
18899   if (!vec_len (name))
18900     {
18901       errmsg ("policer name must be specified");
18902       return -99;
18903     }
18904
18905   if (vec_len (name) > 64)
18906     {
18907       errmsg ("policer name too long");
18908       return -99;
18909     }
18910
18911   M (POLICER_ADD_DEL, mp);
18912
18913   clib_memcpy (mp->name, name, vec_len (name));
18914   vec_free (name);
18915   mp->is_add = is_add;
18916   mp->cir = ntohl (cir);
18917   mp->eir = ntohl (eir);
18918   mp->cb = clib_net_to_host_u64 (cb);
18919   mp->eb = clib_net_to_host_u64 (eb);
18920   mp->rate_type = rate_type;
18921   mp->round_type = round_type;
18922   mp->type = type;
18923   mp->conform_action_type = conform_action.action_type;
18924   mp->conform_dscp = conform_action.dscp;
18925   mp->exceed_action_type = exceed_action.action_type;
18926   mp->exceed_dscp = exceed_action.dscp;
18927   mp->violate_action_type = violate_action.action_type;
18928   mp->violate_dscp = violate_action.dscp;
18929   mp->color_aware = color_aware;
18930
18931   S (mp);
18932   W (ret);
18933   return ret;
18934 }
18935
18936 static int
18937 api_policer_dump (vat_main_t * vam)
18938 {
18939   unformat_input_t *i = vam->input;
18940   vl_api_policer_dump_t *mp;
18941   vl_api_control_ping_t *mp_ping;
18942   u8 *match_name = 0;
18943   u8 match_name_valid = 0;
18944   int ret;
18945
18946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18947     {
18948       if (unformat (i, "name %s", &match_name))
18949         {
18950           vec_add1 (match_name, 0);
18951           match_name_valid = 1;
18952         }
18953       else
18954         break;
18955     }
18956
18957   M (POLICER_DUMP, mp);
18958   mp->match_name_valid = match_name_valid;
18959   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18960   vec_free (match_name);
18961   /* send it... */
18962   S (mp);
18963
18964   /* Use a control ping for synchronization */
18965   MPING (CONTROL_PING, mp_ping);
18966   S (mp_ping);
18967
18968   /* Wait for a reply... */
18969   W (ret);
18970   return ret;
18971 }
18972
18973 static int
18974 api_policer_classify_set_interface (vat_main_t * vam)
18975 {
18976   unformat_input_t *i = vam->input;
18977   vl_api_policer_classify_set_interface_t *mp;
18978   u32 sw_if_index;
18979   int sw_if_index_set;
18980   u32 ip4_table_index = ~0;
18981   u32 ip6_table_index = ~0;
18982   u32 l2_table_index = ~0;
18983   u8 is_add = 1;
18984   int ret;
18985
18986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18987     {
18988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18989         sw_if_index_set = 1;
18990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18991         sw_if_index_set = 1;
18992       else if (unformat (i, "del"))
18993         is_add = 0;
18994       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18995         ;
18996       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18997         ;
18998       else if (unformat (i, "l2-table %d", &l2_table_index))
18999         ;
19000       else
19001         {
19002           clib_warning ("parse error '%U'", format_unformat_error, i);
19003           return -99;
19004         }
19005     }
19006
19007   if (sw_if_index_set == 0)
19008     {
19009       errmsg ("missing interface name or sw_if_index");
19010       return -99;
19011     }
19012
19013   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19014
19015   mp->sw_if_index = ntohl (sw_if_index);
19016   mp->ip4_table_index = ntohl (ip4_table_index);
19017   mp->ip6_table_index = ntohl (ip6_table_index);
19018   mp->l2_table_index = ntohl (l2_table_index);
19019   mp->is_add = is_add;
19020
19021   S (mp);
19022   W (ret);
19023   return ret;
19024 }
19025
19026 static int
19027 api_policer_classify_dump (vat_main_t * vam)
19028 {
19029   unformat_input_t *i = vam->input;
19030   vl_api_policer_classify_dump_t *mp;
19031   vl_api_control_ping_t *mp_ping;
19032   u8 type = POLICER_CLASSIFY_N_TABLES;
19033   int ret;
19034
19035   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19036     ;
19037   else
19038     {
19039       errmsg ("classify table type must be specified");
19040       return -99;
19041     }
19042
19043   if (!vam->json_output)
19044     {
19045       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19046     }
19047
19048   M (POLICER_CLASSIFY_DUMP, mp);
19049   mp->type = type;
19050   /* send it... */
19051   S (mp);
19052
19053   /* Use a control ping for synchronization */
19054   MPING (CONTROL_PING, mp_ping);
19055   S (mp_ping);
19056
19057   /* Wait for a reply... */
19058   W (ret);
19059   return ret;
19060 }
19061
19062 static int
19063 api_netmap_create (vat_main_t * vam)
19064 {
19065   unformat_input_t *i = vam->input;
19066   vl_api_netmap_create_t *mp;
19067   u8 *if_name = 0;
19068   u8 hw_addr[6];
19069   u8 random_hw_addr = 1;
19070   u8 is_pipe = 0;
19071   u8 is_master = 0;
19072   int ret;
19073
19074   clib_memset (hw_addr, 0, sizeof (hw_addr));
19075
19076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19077     {
19078       if (unformat (i, "name %s", &if_name))
19079         vec_add1 (if_name, 0);
19080       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19081         random_hw_addr = 0;
19082       else if (unformat (i, "pipe"))
19083         is_pipe = 1;
19084       else if (unformat (i, "master"))
19085         is_master = 1;
19086       else if (unformat (i, "slave"))
19087         is_master = 0;
19088       else
19089         break;
19090     }
19091
19092   if (!vec_len (if_name))
19093     {
19094       errmsg ("interface name must be specified");
19095       return -99;
19096     }
19097
19098   if (vec_len (if_name) > 64)
19099     {
19100       errmsg ("interface name too long");
19101       return -99;
19102     }
19103
19104   M (NETMAP_CREATE, mp);
19105
19106   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19107   clib_memcpy (mp->hw_addr, hw_addr, 6);
19108   mp->use_random_hw_addr = random_hw_addr;
19109   mp->is_pipe = is_pipe;
19110   mp->is_master = is_master;
19111   vec_free (if_name);
19112
19113   S (mp);
19114   W (ret);
19115   return ret;
19116 }
19117
19118 static int
19119 api_netmap_delete (vat_main_t * vam)
19120 {
19121   unformat_input_t *i = vam->input;
19122   vl_api_netmap_delete_t *mp;
19123   u8 *if_name = 0;
19124   int ret;
19125
19126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19127     {
19128       if (unformat (i, "name %s", &if_name))
19129         vec_add1 (if_name, 0);
19130       else
19131         break;
19132     }
19133
19134   if (!vec_len (if_name))
19135     {
19136       errmsg ("interface name must be specified");
19137       return -99;
19138     }
19139
19140   if (vec_len (if_name) > 64)
19141     {
19142       errmsg ("interface name too long");
19143       return -99;
19144     }
19145
19146   M (NETMAP_DELETE, mp);
19147
19148   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19149   vec_free (if_name);
19150
19151   S (mp);
19152   W (ret);
19153   return ret;
19154 }
19155
19156 static void
19157 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19158 {
19159   if (fp->afi == IP46_TYPE_IP6)
19160     print (vam->ofp,
19161            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19162            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19163            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19164            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19165            format_ip6_address, fp->next_hop);
19166   else if (fp->afi == IP46_TYPE_IP4)
19167     print (vam->ofp,
19168            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19169            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19170            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19171            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19172            format_ip4_address, fp->next_hop);
19173 }
19174
19175 static void
19176 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19177                                  vl_api_fib_path_t * fp)
19178 {
19179   struct in_addr ip4;
19180   struct in6_addr ip6;
19181
19182   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19183   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19184   vat_json_object_add_uint (node, "is_local", fp->is_local);
19185   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19186   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19187   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19188   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19189   if (fp->afi == IP46_TYPE_IP4)
19190     {
19191       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19192       vat_json_object_add_ip4 (node, "next_hop", ip4);
19193     }
19194   else if (fp->afi == IP46_TYPE_IP6)
19195     {
19196       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19197       vat_json_object_add_ip6 (node, "next_hop", ip6);
19198     }
19199 }
19200
19201 static void
19202 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19203 {
19204   vat_main_t *vam = &vat_main;
19205   int count = ntohl (mp->mt_count);
19206   vl_api_fib_path_t *fp;
19207   i32 i;
19208
19209   print (vam->ofp, "[%d]: sw_if_index %d via:",
19210          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19211   fp = mp->mt_paths;
19212   for (i = 0; i < count; i++)
19213     {
19214       vl_api_mpls_fib_path_print (vam, fp);
19215       fp++;
19216     }
19217
19218   print (vam->ofp, "");
19219 }
19220
19221 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19222 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19223
19224 static void
19225 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19226 {
19227   vat_main_t *vam = &vat_main;
19228   vat_json_node_t *node = NULL;
19229   int count = ntohl (mp->mt_count);
19230   vl_api_fib_path_t *fp;
19231   i32 i;
19232
19233   if (VAT_JSON_ARRAY != vam->json_tree.type)
19234     {
19235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19236       vat_json_init_array (&vam->json_tree);
19237     }
19238   node = vat_json_array_add (&vam->json_tree);
19239
19240   vat_json_init_object (node);
19241   vat_json_object_add_uint (node, "tunnel_index",
19242                             ntohl (mp->mt_tunnel_index));
19243   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19244
19245   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19246
19247   fp = mp->mt_paths;
19248   for (i = 0; i < count; i++)
19249     {
19250       vl_api_mpls_fib_path_json_print (node, fp);
19251       fp++;
19252     }
19253 }
19254
19255 static int
19256 api_mpls_tunnel_dump (vat_main_t * vam)
19257 {
19258   vl_api_mpls_tunnel_dump_t *mp;
19259   vl_api_control_ping_t *mp_ping;
19260   u32 sw_if_index = ~0;
19261   int ret;
19262
19263   /* Parse args required to build the message */
19264   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19265     {
19266       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19267         ;
19268     }
19269
19270   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19271
19272   M (MPLS_TUNNEL_DUMP, mp);
19273   mp->sw_if_index = htonl (sw_if_index);
19274   S (mp);
19275
19276   /* Use a control ping for synchronization */
19277   MPING (CONTROL_PING, mp_ping);
19278   S (mp_ping);
19279
19280   W (ret);
19281   return ret;
19282 }
19283
19284 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19285 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19286
19287
19288 static void
19289 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19290 {
19291   vat_main_t *vam = &vat_main;
19292   int count = ntohl (mp->count);
19293   vl_api_fib_path_t *fp;
19294   int i;
19295
19296   print (vam->ofp,
19297          "table-id %d, label %u, ess_bit %u",
19298          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19299   fp = mp->path;
19300   for (i = 0; i < count; i++)
19301     {
19302       vl_api_mpls_fib_path_print (vam, fp);
19303       fp++;
19304     }
19305 }
19306
19307 static void vl_api_mpls_fib_details_t_handler_json
19308   (vl_api_mpls_fib_details_t * mp)
19309 {
19310   vat_main_t *vam = &vat_main;
19311   int count = ntohl (mp->count);
19312   vat_json_node_t *node = NULL;
19313   vl_api_fib_path_t *fp;
19314   int i;
19315
19316   if (VAT_JSON_ARRAY != vam->json_tree.type)
19317     {
19318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19319       vat_json_init_array (&vam->json_tree);
19320     }
19321   node = vat_json_array_add (&vam->json_tree);
19322
19323   vat_json_init_object (node);
19324   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19325   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19326   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19327   vat_json_object_add_uint (node, "path_count", count);
19328   fp = mp->path;
19329   for (i = 0; i < count; i++)
19330     {
19331       vl_api_mpls_fib_path_json_print (node, fp);
19332       fp++;
19333     }
19334 }
19335
19336 static int
19337 api_mpls_fib_dump (vat_main_t * vam)
19338 {
19339   vl_api_mpls_fib_dump_t *mp;
19340   vl_api_control_ping_t *mp_ping;
19341   int ret;
19342
19343   M (MPLS_FIB_DUMP, mp);
19344   S (mp);
19345
19346   /* Use a control ping for synchronization */
19347   MPING (CONTROL_PING, mp_ping);
19348   S (mp_ping);
19349
19350   W (ret);
19351   return ret;
19352 }
19353
19354 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19355 #define vl_api_ip_fib_details_t_print vl_noop_handler
19356
19357 static void
19358 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19359 {
19360   vat_main_t *vam = &vat_main;
19361   int count = ntohl (mp->count);
19362   vl_api_fib_path_t *fp;
19363   int i;
19364
19365   print (vam->ofp,
19366          "table-id %d, prefix %U/%d stats-index %d",
19367          ntohl (mp->table_id), format_ip4_address, mp->address,
19368          mp->address_length, ntohl (mp->stats_index));
19369   fp = mp->path;
19370   for (i = 0; i < count; i++)
19371     {
19372       if (fp->afi == IP46_TYPE_IP6)
19373         print (vam->ofp,
19374                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19375                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19376                "next_hop_table %d",
19377                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19378                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19379                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19380       else if (fp->afi == IP46_TYPE_IP4)
19381         print (vam->ofp,
19382                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19383                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19384                "next_hop_table %d",
19385                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19386                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19387                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19388       fp++;
19389     }
19390 }
19391
19392 static void vl_api_ip_fib_details_t_handler_json
19393   (vl_api_ip_fib_details_t * mp)
19394 {
19395   vat_main_t *vam = &vat_main;
19396   int count = ntohl (mp->count);
19397   vat_json_node_t *node = NULL;
19398   struct in_addr ip4;
19399   struct in6_addr ip6;
19400   vl_api_fib_path_t *fp;
19401   int i;
19402
19403   if (VAT_JSON_ARRAY != vam->json_tree.type)
19404     {
19405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19406       vat_json_init_array (&vam->json_tree);
19407     }
19408   node = vat_json_array_add (&vam->json_tree);
19409
19410   vat_json_init_object (node);
19411   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19412   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19413   vat_json_object_add_ip4 (node, "prefix", ip4);
19414   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19415   vat_json_object_add_uint (node, "path_count", count);
19416   fp = mp->path;
19417   for (i = 0; i < count; i++)
19418     {
19419       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19420       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19421       vat_json_object_add_uint (node, "is_local", fp->is_local);
19422       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19423       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19424       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19425       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19426       if (fp->afi == IP46_TYPE_IP4)
19427         {
19428           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19429           vat_json_object_add_ip4 (node, "next_hop", ip4);
19430         }
19431       else if (fp->afi == IP46_TYPE_IP6)
19432         {
19433           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19434           vat_json_object_add_ip6 (node, "next_hop", ip6);
19435         }
19436     }
19437 }
19438
19439 static int
19440 api_ip_fib_dump (vat_main_t * vam)
19441 {
19442   vl_api_ip_fib_dump_t *mp;
19443   vl_api_control_ping_t *mp_ping;
19444   int ret;
19445
19446   M (IP_FIB_DUMP, mp);
19447   S (mp);
19448
19449   /* Use a control ping for synchronization */
19450   MPING (CONTROL_PING, mp_ping);
19451   S (mp_ping);
19452
19453   W (ret);
19454   return ret;
19455 }
19456
19457 static int
19458 api_ip_mfib_dump (vat_main_t * vam)
19459 {
19460   vl_api_ip_mfib_dump_t *mp;
19461   vl_api_control_ping_t *mp_ping;
19462   int ret;
19463
19464   M (IP_MFIB_DUMP, mp);
19465   S (mp);
19466
19467   /* Use a control ping for synchronization */
19468   MPING (CONTROL_PING, mp_ping);
19469   S (mp_ping);
19470
19471   W (ret);
19472   return ret;
19473 }
19474
19475 static void vl_api_ip_neighbor_details_t_handler
19476   (vl_api_ip_neighbor_details_t * mp)
19477 {
19478   vat_main_t *vam = &vat_main;
19479
19480   print (vam->ofp, "%c %U %U",
19481          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19482          format_vl_api_mac_address, &mp->neighbor.mac_address,
19483          format_vl_api_address, &mp->neighbor.ip_address);
19484 }
19485
19486 static void vl_api_ip_neighbor_details_t_handler_json
19487   (vl_api_ip_neighbor_details_t * mp)
19488 {
19489
19490   vat_main_t *vam = &vat_main;
19491   vat_json_node_t *node;
19492
19493   if (VAT_JSON_ARRAY != vam->json_tree.type)
19494     {
19495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19496       vat_json_init_array (&vam->json_tree);
19497     }
19498   node = vat_json_array_add (&vam->json_tree);
19499
19500   vat_json_init_object (node);
19501   vat_json_object_add_string_copy
19502     (node, "flag",
19503      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19504       (u8 *) "static" : (u8 *) "dynamic"));
19505
19506   vat_json_object_add_string_copy (node, "link_layer",
19507                                    format (0, "%U", format_vl_api_mac_address,
19508                                            &mp->neighbor.mac_address));
19509   vat_json_object_add_address (node, &mp->neighbor.ip_address);
19510 }
19511
19512 static int
19513 api_ip_neighbor_dump (vat_main_t * vam)
19514 {
19515   unformat_input_t *i = vam->input;
19516   vl_api_ip_neighbor_dump_t *mp;
19517   vl_api_control_ping_t *mp_ping;
19518   u8 is_ipv6 = 0;
19519   u32 sw_if_index = ~0;
19520   int ret;
19521
19522   /* Parse args required to build the message */
19523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19524     {
19525       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19526         ;
19527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19528         ;
19529       else if (unformat (i, "ip6"))
19530         is_ipv6 = 1;
19531       else
19532         break;
19533     }
19534
19535   if (sw_if_index == ~0)
19536     {
19537       errmsg ("missing interface name or sw_if_index");
19538       return -99;
19539     }
19540
19541   M (IP_NEIGHBOR_DUMP, mp);
19542   mp->is_ipv6 = (u8) is_ipv6;
19543   mp->sw_if_index = ntohl (sw_if_index);
19544   S (mp);
19545
19546   /* Use a control ping for synchronization */
19547   MPING (CONTROL_PING, mp_ping);
19548   S (mp_ping);
19549
19550   W (ret);
19551   return ret;
19552 }
19553
19554 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19555 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19556
19557 static void
19558 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19559 {
19560   vat_main_t *vam = &vat_main;
19561   int count = ntohl (mp->count);
19562   vl_api_fib_path_t *fp;
19563   int i;
19564
19565   print (vam->ofp,
19566          "table-id %d, prefix %U/%d stats-index %d",
19567          ntohl (mp->table_id), format_ip6_address, mp->address,
19568          mp->address_length, ntohl (mp->stats_index));
19569   fp = mp->path;
19570   for (i = 0; i < count; i++)
19571     {
19572       if (fp->afi == IP46_TYPE_IP6)
19573         print (vam->ofp,
19574                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19575                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19576                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19577                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19578                format_ip6_address, fp->next_hop);
19579       else if (fp->afi == IP46_TYPE_IP4)
19580         print (vam->ofp,
19581                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19582                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19583                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19584                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19585                format_ip4_address, fp->next_hop);
19586       fp++;
19587     }
19588 }
19589
19590 static void vl_api_ip6_fib_details_t_handler_json
19591   (vl_api_ip6_fib_details_t * mp)
19592 {
19593   vat_main_t *vam = &vat_main;
19594   int count = ntohl (mp->count);
19595   vat_json_node_t *node = NULL;
19596   struct in_addr ip4;
19597   struct in6_addr ip6;
19598   vl_api_fib_path_t *fp;
19599   int i;
19600
19601   if (VAT_JSON_ARRAY != vam->json_tree.type)
19602     {
19603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19604       vat_json_init_array (&vam->json_tree);
19605     }
19606   node = vat_json_array_add (&vam->json_tree);
19607
19608   vat_json_init_object (node);
19609   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19610   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19611   vat_json_object_add_ip6 (node, "prefix", ip6);
19612   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19613   vat_json_object_add_uint (node, "path_count", count);
19614   fp = mp->path;
19615   for (i = 0; i < count; i++)
19616     {
19617       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19618       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19619       vat_json_object_add_uint (node, "is_local", fp->is_local);
19620       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19621       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19622       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19623       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19624       if (fp->afi == IP46_TYPE_IP4)
19625         {
19626           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19627           vat_json_object_add_ip4 (node, "next_hop", ip4);
19628         }
19629       else if (fp->afi == IP46_TYPE_IP6)
19630         {
19631           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19632           vat_json_object_add_ip6 (node, "next_hop", ip6);
19633         }
19634     }
19635 }
19636
19637 static int
19638 api_ip6_fib_dump (vat_main_t * vam)
19639 {
19640   vl_api_ip6_fib_dump_t *mp;
19641   vl_api_control_ping_t *mp_ping;
19642   int ret;
19643
19644   M (IP6_FIB_DUMP, mp);
19645   S (mp);
19646
19647   /* Use a control ping for synchronization */
19648   MPING (CONTROL_PING, mp_ping);
19649   S (mp_ping);
19650
19651   W (ret);
19652   return ret;
19653 }
19654
19655 static int
19656 api_ip6_mfib_dump (vat_main_t * vam)
19657 {
19658   vl_api_ip6_mfib_dump_t *mp;
19659   vl_api_control_ping_t *mp_ping;
19660   int ret;
19661
19662   M (IP6_MFIB_DUMP, mp);
19663   S (mp);
19664
19665   /* Use a control ping for synchronization */
19666   MPING (CONTROL_PING, mp_ping);
19667   S (mp_ping);
19668
19669   W (ret);
19670   return ret;
19671 }
19672
19673 int
19674 api_classify_table_ids (vat_main_t * vam)
19675 {
19676   vl_api_classify_table_ids_t *mp;
19677   int ret;
19678
19679   /* Construct the API message */
19680   M (CLASSIFY_TABLE_IDS, mp);
19681   mp->context = 0;
19682
19683   S (mp);
19684   W (ret);
19685   return ret;
19686 }
19687
19688 int
19689 api_classify_table_by_interface (vat_main_t * vam)
19690 {
19691   unformat_input_t *input = vam->input;
19692   vl_api_classify_table_by_interface_t *mp;
19693
19694   u32 sw_if_index = ~0;
19695   int ret;
19696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19697     {
19698       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19699         ;
19700       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19701         ;
19702       else
19703         break;
19704     }
19705   if (sw_if_index == ~0)
19706     {
19707       errmsg ("missing interface name or sw_if_index");
19708       return -99;
19709     }
19710
19711   /* Construct the API message */
19712   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19713   mp->context = 0;
19714   mp->sw_if_index = ntohl (sw_if_index);
19715
19716   S (mp);
19717   W (ret);
19718   return ret;
19719 }
19720
19721 int
19722 api_classify_table_info (vat_main_t * vam)
19723 {
19724   unformat_input_t *input = vam->input;
19725   vl_api_classify_table_info_t *mp;
19726
19727   u32 table_id = ~0;
19728   int ret;
19729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19730     {
19731       if (unformat (input, "table_id %d", &table_id))
19732         ;
19733       else
19734         break;
19735     }
19736   if (table_id == ~0)
19737     {
19738       errmsg ("missing table id");
19739       return -99;
19740     }
19741
19742   /* Construct the API message */
19743   M (CLASSIFY_TABLE_INFO, mp);
19744   mp->context = 0;
19745   mp->table_id = ntohl (table_id);
19746
19747   S (mp);
19748   W (ret);
19749   return ret;
19750 }
19751
19752 int
19753 api_classify_session_dump (vat_main_t * vam)
19754 {
19755   unformat_input_t *input = vam->input;
19756   vl_api_classify_session_dump_t *mp;
19757   vl_api_control_ping_t *mp_ping;
19758
19759   u32 table_id = ~0;
19760   int ret;
19761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19762     {
19763       if (unformat (input, "table_id %d", &table_id))
19764         ;
19765       else
19766         break;
19767     }
19768   if (table_id == ~0)
19769     {
19770       errmsg ("missing table id");
19771       return -99;
19772     }
19773
19774   /* Construct the API message */
19775   M (CLASSIFY_SESSION_DUMP, mp);
19776   mp->context = 0;
19777   mp->table_id = ntohl (table_id);
19778   S (mp);
19779
19780   /* Use a control ping for synchronization */
19781   MPING (CONTROL_PING, mp_ping);
19782   S (mp_ping);
19783
19784   W (ret);
19785   return ret;
19786 }
19787
19788 static void
19789 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19790 {
19791   vat_main_t *vam = &vat_main;
19792
19793   print (vam->ofp, "collector_address %U, collector_port %d, "
19794          "src_address %U, vrf_id %d, path_mtu %u, "
19795          "template_interval %u, udp_checksum %d",
19796          format_ip4_address, mp->collector_address,
19797          ntohs (mp->collector_port),
19798          format_ip4_address, mp->src_address,
19799          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19800          ntohl (mp->template_interval), mp->udp_checksum);
19801
19802   vam->retval = 0;
19803   vam->result_ready = 1;
19804 }
19805
19806 static void
19807   vl_api_ipfix_exporter_details_t_handler_json
19808   (vl_api_ipfix_exporter_details_t * mp)
19809 {
19810   vat_main_t *vam = &vat_main;
19811   vat_json_node_t node;
19812   struct in_addr collector_address;
19813   struct in_addr src_address;
19814
19815   vat_json_init_object (&node);
19816   clib_memcpy (&collector_address, &mp->collector_address,
19817                sizeof (collector_address));
19818   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19819   vat_json_object_add_uint (&node, "collector_port",
19820                             ntohs (mp->collector_port));
19821   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19822   vat_json_object_add_ip4 (&node, "src_address", src_address);
19823   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19824   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19825   vat_json_object_add_uint (&node, "template_interval",
19826                             ntohl (mp->template_interval));
19827   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19828
19829   vat_json_print (vam->ofp, &node);
19830   vat_json_free (&node);
19831   vam->retval = 0;
19832   vam->result_ready = 1;
19833 }
19834
19835 int
19836 api_ipfix_exporter_dump (vat_main_t * vam)
19837 {
19838   vl_api_ipfix_exporter_dump_t *mp;
19839   int ret;
19840
19841   /* Construct the API message */
19842   M (IPFIX_EXPORTER_DUMP, mp);
19843   mp->context = 0;
19844
19845   S (mp);
19846   W (ret);
19847   return ret;
19848 }
19849
19850 static int
19851 api_ipfix_classify_stream_dump (vat_main_t * vam)
19852 {
19853   vl_api_ipfix_classify_stream_dump_t *mp;
19854   int ret;
19855
19856   /* Construct the API message */
19857   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19858   mp->context = 0;
19859
19860   S (mp);
19861   W (ret);
19862   return ret;
19863   /* NOTREACHED */
19864   return 0;
19865 }
19866
19867 static void
19868   vl_api_ipfix_classify_stream_details_t_handler
19869   (vl_api_ipfix_classify_stream_details_t * mp)
19870 {
19871   vat_main_t *vam = &vat_main;
19872   print (vam->ofp, "domain_id %d, src_port %d",
19873          ntohl (mp->domain_id), ntohs (mp->src_port));
19874   vam->retval = 0;
19875   vam->result_ready = 1;
19876 }
19877
19878 static void
19879   vl_api_ipfix_classify_stream_details_t_handler_json
19880   (vl_api_ipfix_classify_stream_details_t * mp)
19881 {
19882   vat_main_t *vam = &vat_main;
19883   vat_json_node_t node;
19884
19885   vat_json_init_object (&node);
19886   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19887   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19888
19889   vat_json_print (vam->ofp, &node);
19890   vat_json_free (&node);
19891   vam->retval = 0;
19892   vam->result_ready = 1;
19893 }
19894
19895 static int
19896 api_ipfix_classify_table_dump (vat_main_t * vam)
19897 {
19898   vl_api_ipfix_classify_table_dump_t *mp;
19899   vl_api_control_ping_t *mp_ping;
19900   int ret;
19901
19902   if (!vam->json_output)
19903     {
19904       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19905              "transport_protocol");
19906     }
19907
19908   /* Construct the API message */
19909   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19910
19911   /* send it... */
19912   S (mp);
19913
19914   /* Use a control ping for synchronization */
19915   MPING (CONTROL_PING, mp_ping);
19916   S (mp_ping);
19917
19918   W (ret);
19919   return ret;
19920 }
19921
19922 static void
19923   vl_api_ipfix_classify_table_details_t_handler
19924   (vl_api_ipfix_classify_table_details_t * mp)
19925 {
19926   vat_main_t *vam = &vat_main;
19927   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19928          mp->transport_protocol);
19929 }
19930
19931 static void
19932   vl_api_ipfix_classify_table_details_t_handler_json
19933   (vl_api_ipfix_classify_table_details_t * mp)
19934 {
19935   vat_json_node_t *node = NULL;
19936   vat_main_t *vam = &vat_main;
19937
19938   if (VAT_JSON_ARRAY != vam->json_tree.type)
19939     {
19940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19941       vat_json_init_array (&vam->json_tree);
19942     }
19943
19944   node = vat_json_array_add (&vam->json_tree);
19945   vat_json_init_object (node);
19946
19947   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19948   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19949   vat_json_object_add_uint (node, "transport_protocol",
19950                             mp->transport_protocol);
19951 }
19952
19953 static int
19954 api_sw_interface_span_enable_disable (vat_main_t * vam)
19955 {
19956   unformat_input_t *i = vam->input;
19957   vl_api_sw_interface_span_enable_disable_t *mp;
19958   u32 src_sw_if_index = ~0;
19959   u32 dst_sw_if_index = ~0;
19960   u8 state = 3;
19961   int ret;
19962   u8 is_l2 = 0;
19963
19964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19965     {
19966       if (unformat
19967           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19968         ;
19969       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19970         ;
19971       else
19972         if (unformat
19973             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19974         ;
19975       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19976         ;
19977       else if (unformat (i, "disable"))
19978         state = 0;
19979       else if (unformat (i, "rx"))
19980         state = 1;
19981       else if (unformat (i, "tx"))
19982         state = 2;
19983       else if (unformat (i, "both"))
19984         state = 3;
19985       else if (unformat (i, "l2"))
19986         is_l2 = 1;
19987       else
19988         break;
19989     }
19990
19991   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19992
19993   mp->sw_if_index_from = htonl (src_sw_if_index);
19994   mp->sw_if_index_to = htonl (dst_sw_if_index);
19995   mp->state = state;
19996   mp->is_l2 = is_l2;
19997
19998   S (mp);
19999   W (ret);
20000   return ret;
20001 }
20002
20003 static void
20004 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20005                                             * mp)
20006 {
20007   vat_main_t *vam = &vat_main;
20008   u8 *sw_if_from_name = 0;
20009   u8 *sw_if_to_name = 0;
20010   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20011   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20012   char *states[] = { "none", "rx", "tx", "both" };
20013   hash_pair_t *p;
20014
20015   /* *INDENT-OFF* */
20016   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20017   ({
20018     if ((u32) p->value[0] == sw_if_index_from)
20019       {
20020         sw_if_from_name = (u8 *)(p->key);
20021         if (sw_if_to_name)
20022           break;
20023       }
20024     if ((u32) p->value[0] == sw_if_index_to)
20025       {
20026         sw_if_to_name = (u8 *)(p->key);
20027         if (sw_if_from_name)
20028           break;
20029       }
20030   }));
20031   /* *INDENT-ON* */
20032   print (vam->ofp, "%20s => %20s (%s) %s",
20033          sw_if_from_name, sw_if_to_name, states[mp->state],
20034          mp->is_l2 ? "l2" : "device");
20035 }
20036
20037 static void
20038   vl_api_sw_interface_span_details_t_handler_json
20039   (vl_api_sw_interface_span_details_t * mp)
20040 {
20041   vat_main_t *vam = &vat_main;
20042   vat_json_node_t *node = NULL;
20043   u8 *sw_if_from_name = 0;
20044   u8 *sw_if_to_name = 0;
20045   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20046   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20047   hash_pair_t *p;
20048
20049   /* *INDENT-OFF* */
20050   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20051   ({
20052     if ((u32) p->value[0] == sw_if_index_from)
20053       {
20054         sw_if_from_name = (u8 *)(p->key);
20055         if (sw_if_to_name)
20056           break;
20057       }
20058     if ((u32) p->value[0] == sw_if_index_to)
20059       {
20060         sw_if_to_name = (u8 *)(p->key);
20061         if (sw_if_from_name)
20062           break;
20063       }
20064   }));
20065   /* *INDENT-ON* */
20066
20067   if (VAT_JSON_ARRAY != vam->json_tree.type)
20068     {
20069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20070       vat_json_init_array (&vam->json_tree);
20071     }
20072   node = vat_json_array_add (&vam->json_tree);
20073
20074   vat_json_init_object (node);
20075   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20076   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20077   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20078   if (0 != sw_if_to_name)
20079     {
20080       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20081     }
20082   vat_json_object_add_uint (node, "state", mp->state);
20083   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20084 }
20085
20086 static int
20087 api_sw_interface_span_dump (vat_main_t * vam)
20088 {
20089   unformat_input_t *input = vam->input;
20090   vl_api_sw_interface_span_dump_t *mp;
20091   vl_api_control_ping_t *mp_ping;
20092   u8 is_l2 = 0;
20093   int ret;
20094
20095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20096     {
20097       if (unformat (input, "l2"))
20098         is_l2 = 1;
20099       else
20100         break;
20101     }
20102
20103   M (SW_INTERFACE_SPAN_DUMP, mp);
20104   mp->is_l2 = is_l2;
20105   S (mp);
20106
20107   /* Use a control ping for synchronization */
20108   MPING (CONTROL_PING, mp_ping);
20109   S (mp_ping);
20110
20111   W (ret);
20112   return ret;
20113 }
20114
20115 int
20116 api_pg_create_interface (vat_main_t * vam)
20117 {
20118   unformat_input_t *input = vam->input;
20119   vl_api_pg_create_interface_t *mp;
20120
20121   u32 if_id = ~0;
20122   int ret;
20123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20124     {
20125       if (unformat (input, "if_id %d", &if_id))
20126         ;
20127       else
20128         break;
20129     }
20130   if (if_id == ~0)
20131     {
20132       errmsg ("missing pg interface index");
20133       return -99;
20134     }
20135
20136   /* Construct the API message */
20137   M (PG_CREATE_INTERFACE, mp);
20138   mp->context = 0;
20139   mp->interface_id = ntohl (if_id);
20140
20141   S (mp);
20142   W (ret);
20143   return ret;
20144 }
20145
20146 int
20147 api_pg_capture (vat_main_t * vam)
20148 {
20149   unformat_input_t *input = vam->input;
20150   vl_api_pg_capture_t *mp;
20151
20152   u32 if_id = ~0;
20153   u8 enable = 1;
20154   u32 count = 1;
20155   u8 pcap_file_set = 0;
20156   u8 *pcap_file = 0;
20157   int ret;
20158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20159     {
20160       if (unformat (input, "if_id %d", &if_id))
20161         ;
20162       else if (unformat (input, "pcap %s", &pcap_file))
20163         pcap_file_set = 1;
20164       else if (unformat (input, "count %d", &count))
20165         ;
20166       else if (unformat (input, "disable"))
20167         enable = 0;
20168       else
20169         break;
20170     }
20171   if (if_id == ~0)
20172     {
20173       errmsg ("missing pg interface index");
20174       return -99;
20175     }
20176   if (pcap_file_set > 0)
20177     {
20178       if (vec_len (pcap_file) > 255)
20179         {
20180           errmsg ("pcap file name is too long");
20181           return -99;
20182         }
20183     }
20184
20185   u32 name_len = vec_len (pcap_file);
20186   /* Construct the API message */
20187   M (PG_CAPTURE, mp);
20188   mp->context = 0;
20189   mp->interface_id = ntohl (if_id);
20190   mp->is_enabled = enable;
20191   mp->count = ntohl (count);
20192   mp->pcap_name_length = ntohl (name_len);
20193   if (pcap_file_set != 0)
20194     {
20195       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20196     }
20197   vec_free (pcap_file);
20198
20199   S (mp);
20200   W (ret);
20201   return ret;
20202 }
20203
20204 int
20205 api_pg_enable_disable (vat_main_t * vam)
20206 {
20207   unformat_input_t *input = vam->input;
20208   vl_api_pg_enable_disable_t *mp;
20209
20210   u8 enable = 1;
20211   u8 stream_name_set = 0;
20212   u8 *stream_name = 0;
20213   int ret;
20214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20215     {
20216       if (unformat (input, "stream %s", &stream_name))
20217         stream_name_set = 1;
20218       else if (unformat (input, "disable"))
20219         enable = 0;
20220       else
20221         break;
20222     }
20223
20224   if (stream_name_set > 0)
20225     {
20226       if (vec_len (stream_name) > 255)
20227         {
20228           errmsg ("stream name too long");
20229           return -99;
20230         }
20231     }
20232
20233   u32 name_len = vec_len (stream_name);
20234   /* Construct the API message */
20235   M (PG_ENABLE_DISABLE, mp);
20236   mp->context = 0;
20237   mp->is_enabled = enable;
20238   if (stream_name_set != 0)
20239     {
20240       mp->stream_name_length = ntohl (name_len);
20241       clib_memcpy (mp->stream_name, stream_name, name_len);
20242     }
20243   vec_free (stream_name);
20244
20245   S (mp);
20246   W (ret);
20247   return ret;
20248 }
20249
20250 int
20251 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20252 {
20253   unformat_input_t *input = vam->input;
20254   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20255
20256   u16 *low_ports = 0;
20257   u16 *high_ports = 0;
20258   u16 this_low;
20259   u16 this_hi;
20260   vl_api_prefix_t prefix;
20261   u32 tmp, tmp2;
20262   u8 prefix_set = 0;
20263   u32 vrf_id = ~0;
20264   u8 is_add = 1;
20265   u8 is_ipv6 = 0;
20266   int ret;
20267
20268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20269     {
20270       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20271         prefix_set = 1;
20272       else if (unformat (input, "vrf %d", &vrf_id))
20273         ;
20274       else if (unformat (input, "del"))
20275         is_add = 0;
20276       else if (unformat (input, "port %d", &tmp))
20277         {
20278           if (tmp == 0 || tmp > 65535)
20279             {
20280               errmsg ("port %d out of range", tmp);
20281               return -99;
20282             }
20283           this_low = tmp;
20284           this_hi = this_low + 1;
20285           vec_add1 (low_ports, this_low);
20286           vec_add1 (high_ports, this_hi);
20287         }
20288       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20289         {
20290           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20291             {
20292               errmsg ("incorrect range parameters");
20293               return -99;
20294             }
20295           this_low = tmp;
20296           /* Note: in debug CLI +1 is added to high before
20297              passing to real fn that does "the work"
20298              (ip_source_and_port_range_check_add_del).
20299              This fn is a wrapper around the binary API fn a
20300              control plane will call, which expects this increment
20301              to have occurred. Hence letting the binary API control
20302              plane fn do the increment for consistency between VAT
20303              and other control planes.
20304            */
20305           this_hi = tmp2;
20306           vec_add1 (low_ports, this_low);
20307           vec_add1 (high_ports, this_hi);
20308         }
20309       else
20310         break;
20311     }
20312
20313   if (prefix_set == 0)
20314     {
20315       errmsg ("<address>/<mask> not specified");
20316       return -99;
20317     }
20318
20319   if (vrf_id == ~0)
20320     {
20321       errmsg ("VRF ID required, not specified");
20322       return -99;
20323     }
20324
20325   if (vrf_id == 0)
20326     {
20327       errmsg
20328         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20329       return -99;
20330     }
20331
20332   if (vec_len (low_ports) == 0)
20333     {
20334       errmsg ("At least one port or port range required");
20335       return -99;
20336     }
20337
20338   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20339
20340   mp->is_add = is_add;
20341
20342   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20343
20344   mp->number_of_ranges = vec_len (low_ports);
20345
20346   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20347   vec_free (low_ports);
20348
20349   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20350   vec_free (high_ports);
20351
20352   mp->vrf_id = ntohl (vrf_id);
20353
20354   S (mp);
20355   W (ret);
20356   return ret;
20357 }
20358
20359 int
20360 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20361 {
20362   unformat_input_t *input = vam->input;
20363   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20364   u32 sw_if_index = ~0;
20365   int vrf_set = 0;
20366   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20367   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20368   u8 is_add = 1;
20369   int ret;
20370
20371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20372     {
20373       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20374         ;
20375       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20376         ;
20377       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20378         vrf_set = 1;
20379       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20380         vrf_set = 1;
20381       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20382         vrf_set = 1;
20383       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20384         vrf_set = 1;
20385       else if (unformat (input, "del"))
20386         is_add = 0;
20387       else
20388         break;
20389     }
20390
20391   if (sw_if_index == ~0)
20392     {
20393       errmsg ("Interface required but not specified");
20394       return -99;
20395     }
20396
20397   if (vrf_set == 0)
20398     {
20399       errmsg ("VRF ID required but not specified");
20400       return -99;
20401     }
20402
20403   if (tcp_out_vrf_id == 0
20404       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20405     {
20406       errmsg
20407         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20408       return -99;
20409     }
20410
20411   /* Construct the API message */
20412   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20413
20414   mp->sw_if_index = ntohl (sw_if_index);
20415   mp->is_add = is_add;
20416   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20417   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20418   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20419   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20420
20421   /* send it... */
20422   S (mp);
20423
20424   /* Wait for a reply... */
20425   W (ret);
20426   return ret;
20427 }
20428
20429 static int
20430 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20431 {
20432   unformat_input_t *i = vam->input;
20433   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20434   u32 local_sa_id = 0;
20435   u32 remote_sa_id = 0;
20436   vl_api_ip4_address_t src_address;
20437   vl_api_ip4_address_t dst_address;
20438   u8 is_add = 1;
20439   int ret;
20440
20441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20442     {
20443       if (unformat (i, "local_sa %d", &local_sa_id))
20444         ;
20445       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20446         ;
20447       else
20448         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20449         ;
20450       else
20451         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20452         ;
20453       else if (unformat (i, "del"))
20454         is_add = 0;
20455       else
20456         {
20457           clib_warning ("parse error '%U'", format_unformat_error, i);
20458           return -99;
20459         }
20460     }
20461
20462   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20463
20464   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20465   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20466   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20467   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20468   mp->is_add = is_add;
20469
20470   S (mp);
20471   W (ret);
20472   return ret;
20473 }
20474
20475 static int
20476 api_set_punt (vat_main_t * vam)
20477 {
20478   unformat_input_t *i = vam->input;
20479   vl_api_set_punt_t *mp;
20480   u32 ipv = ~0;
20481   u32 protocol = ~0;
20482   u32 port = ~0;
20483   int is_add = 1;
20484   int ret;
20485
20486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20487     {
20488       if (unformat (i, "ip %d", &ipv))
20489         ;
20490       else if (unformat (i, "protocol %d", &protocol))
20491         ;
20492       else if (unformat (i, "port %d", &port))
20493         ;
20494       else if (unformat (i, "del"))
20495         is_add = 0;
20496       else
20497         {
20498           clib_warning ("parse error '%U'", format_unformat_error, i);
20499           return -99;
20500         }
20501     }
20502
20503   M (SET_PUNT, mp);
20504
20505   mp->is_add = (u8) is_add;
20506   mp->punt.ipv = (u8) ipv;
20507   mp->punt.l4_protocol = (u8) protocol;
20508   mp->punt.l4_port = htons ((u16) port);
20509
20510   S (mp);
20511   W (ret);
20512   return ret;
20513 }
20514
20515 static void vl_api_ipsec_gre_tunnel_details_t_handler
20516   (vl_api_ipsec_gre_tunnel_details_t * mp)
20517 {
20518   vat_main_t *vam = &vat_main;
20519
20520   print (vam->ofp, "%11d%15U%15U%14d%14d",
20521          ntohl (mp->tunnel.sw_if_index),
20522          format_vl_api_ip4_address, mp->tunnel.src,
20523          format_vl_api_ip4_address, mp->tunnel.dst,
20524          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20525 }
20526
20527 static void
20528 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20529                                 const char *name,
20530                                 const vl_api_ip4_address_t addr)
20531 {
20532   struct in_addr ip4;
20533
20534   clib_memcpy (&ip4, addr, sizeof (ip4));
20535   vat_json_object_add_ip4 (node, name, ip4);
20536 }
20537
20538 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20539   (vl_api_ipsec_gre_tunnel_details_t * mp)
20540 {
20541   vat_main_t *vam = &vat_main;
20542   vat_json_node_t *node = NULL;
20543   struct in_addr ip4;
20544
20545   if (VAT_JSON_ARRAY != vam->json_tree.type)
20546     {
20547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20548       vat_json_init_array (&vam->json_tree);
20549     }
20550   node = vat_json_array_add (&vam->json_tree);
20551
20552   vat_json_init_object (node);
20553   vat_json_object_add_uint (node, "sw_if_index",
20554                             ntohl (mp->tunnel.sw_if_index));
20555   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20556   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20557   vat_json_object_add_uint (node, "local_sa_id",
20558                             ntohl (mp->tunnel.local_sa_id));
20559   vat_json_object_add_uint (node, "remote_sa_id",
20560                             ntohl (mp->tunnel.remote_sa_id));
20561 }
20562
20563 static int
20564 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20565 {
20566   unformat_input_t *i = vam->input;
20567   vl_api_ipsec_gre_tunnel_dump_t *mp;
20568   vl_api_control_ping_t *mp_ping;
20569   u32 sw_if_index;
20570   u8 sw_if_index_set = 0;
20571   int ret;
20572
20573   /* Parse args required to build the message */
20574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20575     {
20576       if (unformat (i, "sw_if_index %d", &sw_if_index))
20577         sw_if_index_set = 1;
20578       else
20579         break;
20580     }
20581
20582   if (sw_if_index_set == 0)
20583     {
20584       sw_if_index = ~0;
20585     }
20586
20587   if (!vam->json_output)
20588     {
20589       print (vam->ofp, "%11s%15s%15s%14s%14s",
20590              "sw_if_index", "src_address", "dst_address",
20591              "local_sa_id", "remote_sa_id");
20592     }
20593
20594   /* Get list of gre-tunnel interfaces */
20595   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20596
20597   mp->sw_if_index = htonl (sw_if_index);
20598
20599   S (mp);
20600
20601   /* Use a control ping for synchronization */
20602   MPING (CONTROL_PING, mp_ping);
20603   S (mp_ping);
20604
20605   W (ret);
20606   return ret;
20607 }
20608
20609 static int
20610 api_delete_subif (vat_main_t * vam)
20611 {
20612   unformat_input_t *i = vam->input;
20613   vl_api_delete_subif_t *mp;
20614   u32 sw_if_index = ~0;
20615   int ret;
20616
20617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20618     {
20619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20620         ;
20621       if (unformat (i, "sw_if_index %d", &sw_if_index))
20622         ;
20623       else
20624         break;
20625     }
20626
20627   if (sw_if_index == ~0)
20628     {
20629       errmsg ("missing sw_if_index");
20630       return -99;
20631     }
20632
20633   /* Construct the API message */
20634   M (DELETE_SUBIF, mp);
20635   mp->sw_if_index = ntohl (sw_if_index);
20636
20637   S (mp);
20638   W (ret);
20639   return ret;
20640 }
20641
20642 #define foreach_pbb_vtr_op      \
20643 _("disable",  L2_VTR_DISABLED)  \
20644 _("pop",  L2_VTR_POP_2)         \
20645 _("push",  L2_VTR_PUSH_2)
20646
20647 static int
20648 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20649 {
20650   unformat_input_t *i = vam->input;
20651   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20652   u32 sw_if_index = ~0, vtr_op = ~0;
20653   u16 outer_tag = ~0;
20654   u8 dmac[6], smac[6];
20655   u8 dmac_set = 0, smac_set = 0;
20656   u16 vlanid = 0;
20657   u32 sid = ~0;
20658   u32 tmp;
20659   int ret;
20660
20661   /* Shut up coverity */
20662   clib_memset (dmac, 0, sizeof (dmac));
20663   clib_memset (smac, 0, sizeof (smac));
20664
20665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20666     {
20667       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20668         ;
20669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20670         ;
20671       else if (unformat (i, "vtr_op %d", &vtr_op))
20672         ;
20673 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20674       foreach_pbb_vtr_op
20675 #undef _
20676         else if (unformat (i, "translate_pbb_stag"))
20677         {
20678           if (unformat (i, "%d", &tmp))
20679             {
20680               vtr_op = L2_VTR_TRANSLATE_2_1;
20681               outer_tag = tmp;
20682             }
20683           else
20684             {
20685               errmsg
20686                 ("translate_pbb_stag operation requires outer tag definition");
20687               return -99;
20688             }
20689         }
20690       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20691         dmac_set++;
20692       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20693         smac_set++;
20694       else if (unformat (i, "sid %d", &sid))
20695         ;
20696       else if (unformat (i, "vlanid %d", &tmp))
20697         vlanid = tmp;
20698       else
20699         {
20700           clib_warning ("parse error '%U'", format_unformat_error, i);
20701           return -99;
20702         }
20703     }
20704
20705   if ((sw_if_index == ~0) || (vtr_op == ~0))
20706     {
20707       errmsg ("missing sw_if_index or vtr operation");
20708       return -99;
20709     }
20710   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20711       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20712     {
20713       errmsg
20714         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20715       return -99;
20716     }
20717
20718   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20719   mp->sw_if_index = ntohl (sw_if_index);
20720   mp->vtr_op = ntohl (vtr_op);
20721   mp->outer_tag = ntohs (outer_tag);
20722   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20723   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20724   mp->b_vlanid = ntohs (vlanid);
20725   mp->i_sid = ntohl (sid);
20726
20727   S (mp);
20728   W (ret);
20729   return ret;
20730 }
20731
20732 static int
20733 api_flow_classify_set_interface (vat_main_t * vam)
20734 {
20735   unformat_input_t *i = vam->input;
20736   vl_api_flow_classify_set_interface_t *mp;
20737   u32 sw_if_index;
20738   int sw_if_index_set;
20739   u32 ip4_table_index = ~0;
20740   u32 ip6_table_index = ~0;
20741   u8 is_add = 1;
20742   int ret;
20743
20744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20745     {
20746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20747         sw_if_index_set = 1;
20748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20749         sw_if_index_set = 1;
20750       else if (unformat (i, "del"))
20751         is_add = 0;
20752       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20753         ;
20754       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20755         ;
20756       else
20757         {
20758           clib_warning ("parse error '%U'", format_unformat_error, i);
20759           return -99;
20760         }
20761     }
20762
20763   if (sw_if_index_set == 0)
20764     {
20765       errmsg ("missing interface name or sw_if_index");
20766       return -99;
20767     }
20768
20769   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20770
20771   mp->sw_if_index = ntohl (sw_if_index);
20772   mp->ip4_table_index = ntohl (ip4_table_index);
20773   mp->ip6_table_index = ntohl (ip6_table_index);
20774   mp->is_add = is_add;
20775
20776   S (mp);
20777   W (ret);
20778   return ret;
20779 }
20780
20781 static int
20782 api_flow_classify_dump (vat_main_t * vam)
20783 {
20784   unformat_input_t *i = vam->input;
20785   vl_api_flow_classify_dump_t *mp;
20786   vl_api_control_ping_t *mp_ping;
20787   u8 type = FLOW_CLASSIFY_N_TABLES;
20788   int ret;
20789
20790   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20791     ;
20792   else
20793     {
20794       errmsg ("classify table type must be specified");
20795       return -99;
20796     }
20797
20798   if (!vam->json_output)
20799     {
20800       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20801     }
20802
20803   M (FLOW_CLASSIFY_DUMP, mp);
20804   mp->type = type;
20805   /* send it... */
20806   S (mp);
20807
20808   /* Use a control ping for synchronization */
20809   MPING (CONTROL_PING, mp_ping);
20810   S (mp_ping);
20811
20812   /* Wait for a reply... */
20813   W (ret);
20814   return ret;
20815 }
20816
20817 static int
20818 api_feature_enable_disable (vat_main_t * vam)
20819 {
20820   unformat_input_t *i = vam->input;
20821   vl_api_feature_enable_disable_t *mp;
20822   u8 *arc_name = 0;
20823   u8 *feature_name = 0;
20824   u32 sw_if_index = ~0;
20825   u8 enable = 1;
20826   int ret;
20827
20828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20829     {
20830       if (unformat (i, "arc_name %s", &arc_name))
20831         ;
20832       else if (unformat (i, "feature_name %s", &feature_name))
20833         ;
20834       else
20835         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20836         ;
20837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20838         ;
20839       else if (unformat (i, "disable"))
20840         enable = 0;
20841       else
20842         break;
20843     }
20844
20845   if (arc_name == 0)
20846     {
20847       errmsg ("missing arc name");
20848       return -99;
20849     }
20850   if (vec_len (arc_name) > 63)
20851     {
20852       errmsg ("arc name too long");
20853     }
20854
20855   if (feature_name == 0)
20856     {
20857       errmsg ("missing feature name");
20858       return -99;
20859     }
20860   if (vec_len (feature_name) > 63)
20861     {
20862       errmsg ("feature name too long");
20863     }
20864
20865   if (sw_if_index == ~0)
20866     {
20867       errmsg ("missing interface name or sw_if_index");
20868       return -99;
20869     }
20870
20871   /* Construct the API message */
20872   M (FEATURE_ENABLE_DISABLE, mp);
20873   mp->sw_if_index = ntohl (sw_if_index);
20874   mp->enable = enable;
20875   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20876   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20877   vec_free (arc_name);
20878   vec_free (feature_name);
20879
20880   S (mp);
20881   W (ret);
20882   return ret;
20883 }
20884
20885 static int
20886 api_sw_interface_tag_add_del (vat_main_t * vam)
20887 {
20888   unformat_input_t *i = vam->input;
20889   vl_api_sw_interface_tag_add_del_t *mp;
20890   u32 sw_if_index = ~0;
20891   u8 *tag = 0;
20892   u8 enable = 1;
20893   int ret;
20894
20895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20896     {
20897       if (unformat (i, "tag %s", &tag))
20898         ;
20899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20900         ;
20901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20902         ;
20903       else if (unformat (i, "del"))
20904         enable = 0;
20905       else
20906         break;
20907     }
20908
20909   if (sw_if_index == ~0)
20910     {
20911       errmsg ("missing interface name or sw_if_index");
20912       return -99;
20913     }
20914
20915   if (enable && (tag == 0))
20916     {
20917       errmsg ("no tag specified");
20918       return -99;
20919     }
20920
20921   /* Construct the API message */
20922   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20923   mp->sw_if_index = ntohl (sw_if_index);
20924   mp->is_add = enable;
20925   if (enable)
20926     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20927   vec_free (tag);
20928
20929   S (mp);
20930   W (ret);
20931   return ret;
20932 }
20933
20934 static void vl_api_l2_xconnect_details_t_handler
20935   (vl_api_l2_xconnect_details_t * mp)
20936 {
20937   vat_main_t *vam = &vat_main;
20938
20939   print (vam->ofp, "%15d%15d",
20940          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20941 }
20942
20943 static void vl_api_l2_xconnect_details_t_handler_json
20944   (vl_api_l2_xconnect_details_t * mp)
20945 {
20946   vat_main_t *vam = &vat_main;
20947   vat_json_node_t *node = NULL;
20948
20949   if (VAT_JSON_ARRAY != vam->json_tree.type)
20950     {
20951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20952       vat_json_init_array (&vam->json_tree);
20953     }
20954   node = vat_json_array_add (&vam->json_tree);
20955
20956   vat_json_init_object (node);
20957   vat_json_object_add_uint (node, "rx_sw_if_index",
20958                             ntohl (mp->rx_sw_if_index));
20959   vat_json_object_add_uint (node, "tx_sw_if_index",
20960                             ntohl (mp->tx_sw_if_index));
20961 }
20962
20963 static int
20964 api_l2_xconnect_dump (vat_main_t * vam)
20965 {
20966   vl_api_l2_xconnect_dump_t *mp;
20967   vl_api_control_ping_t *mp_ping;
20968   int ret;
20969
20970   if (!vam->json_output)
20971     {
20972       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20973     }
20974
20975   M (L2_XCONNECT_DUMP, mp);
20976
20977   S (mp);
20978
20979   /* Use a control ping for synchronization */
20980   MPING (CONTROL_PING, mp_ping);
20981   S (mp_ping);
20982
20983   W (ret);
20984   return ret;
20985 }
20986
20987 static int
20988 api_hw_interface_set_mtu (vat_main_t * vam)
20989 {
20990   unformat_input_t *i = vam->input;
20991   vl_api_hw_interface_set_mtu_t *mp;
20992   u32 sw_if_index = ~0;
20993   u32 mtu = 0;
20994   int ret;
20995
20996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20997     {
20998       if (unformat (i, "mtu %d", &mtu))
20999         ;
21000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21001         ;
21002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21003         ;
21004       else
21005         break;
21006     }
21007
21008   if (sw_if_index == ~0)
21009     {
21010       errmsg ("missing interface name or sw_if_index");
21011       return -99;
21012     }
21013
21014   if (mtu == 0)
21015     {
21016       errmsg ("no mtu specified");
21017       return -99;
21018     }
21019
21020   /* Construct the API message */
21021   M (HW_INTERFACE_SET_MTU, mp);
21022   mp->sw_if_index = ntohl (sw_if_index);
21023   mp->mtu = ntohs ((u16) mtu);
21024
21025   S (mp);
21026   W (ret);
21027   return ret;
21028 }
21029
21030 static int
21031 api_p2p_ethernet_add (vat_main_t * vam)
21032 {
21033   unformat_input_t *i = vam->input;
21034   vl_api_p2p_ethernet_add_t *mp;
21035   u32 parent_if_index = ~0;
21036   u32 sub_id = ~0;
21037   u8 remote_mac[6];
21038   u8 mac_set = 0;
21039   int ret;
21040
21041   clib_memset (remote_mac, 0, sizeof (remote_mac));
21042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21043     {
21044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21045         ;
21046       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21047         ;
21048       else
21049         if (unformat
21050             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21051         mac_set++;
21052       else if (unformat (i, "sub_id %d", &sub_id))
21053         ;
21054       else
21055         {
21056           clib_warning ("parse error '%U'", format_unformat_error, i);
21057           return -99;
21058         }
21059     }
21060
21061   if (parent_if_index == ~0)
21062     {
21063       errmsg ("missing interface name or sw_if_index");
21064       return -99;
21065     }
21066   if (mac_set == 0)
21067     {
21068       errmsg ("missing remote mac address");
21069       return -99;
21070     }
21071   if (sub_id == ~0)
21072     {
21073       errmsg ("missing sub-interface id");
21074       return -99;
21075     }
21076
21077   M (P2P_ETHERNET_ADD, mp);
21078   mp->parent_if_index = ntohl (parent_if_index);
21079   mp->subif_id = ntohl (sub_id);
21080   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21081
21082   S (mp);
21083   W (ret);
21084   return ret;
21085 }
21086
21087 static int
21088 api_p2p_ethernet_del (vat_main_t * vam)
21089 {
21090   unformat_input_t *i = vam->input;
21091   vl_api_p2p_ethernet_del_t *mp;
21092   u32 parent_if_index = ~0;
21093   u8 remote_mac[6];
21094   u8 mac_set = 0;
21095   int ret;
21096
21097   clib_memset (remote_mac, 0, sizeof (remote_mac));
21098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21099     {
21100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21101         ;
21102       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21103         ;
21104       else
21105         if (unformat
21106             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21107         mac_set++;
21108       else
21109         {
21110           clib_warning ("parse error '%U'", format_unformat_error, i);
21111           return -99;
21112         }
21113     }
21114
21115   if (parent_if_index == ~0)
21116     {
21117       errmsg ("missing interface name or sw_if_index");
21118       return -99;
21119     }
21120   if (mac_set == 0)
21121     {
21122       errmsg ("missing remote mac address");
21123       return -99;
21124     }
21125
21126   M (P2P_ETHERNET_DEL, mp);
21127   mp->parent_if_index = ntohl (parent_if_index);
21128   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21129
21130   S (mp);
21131   W (ret);
21132   return ret;
21133 }
21134
21135 static int
21136 api_lldp_config (vat_main_t * vam)
21137 {
21138   unformat_input_t *i = vam->input;
21139   vl_api_lldp_config_t *mp;
21140   int tx_hold = 0;
21141   int tx_interval = 0;
21142   u8 *sys_name = NULL;
21143   int ret;
21144
21145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21146     {
21147       if (unformat (i, "system-name %s", &sys_name))
21148         ;
21149       else if (unformat (i, "tx-hold %d", &tx_hold))
21150         ;
21151       else if (unformat (i, "tx-interval %d", &tx_interval))
21152         ;
21153       else
21154         {
21155           clib_warning ("parse error '%U'", format_unformat_error, i);
21156           return -99;
21157         }
21158     }
21159
21160   vec_add1 (sys_name, 0);
21161
21162   M (LLDP_CONFIG, mp);
21163   mp->tx_hold = htonl (tx_hold);
21164   mp->tx_interval = htonl (tx_interval);
21165   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21166   vec_free (sys_name);
21167
21168   S (mp);
21169   W (ret);
21170   return ret;
21171 }
21172
21173 static int
21174 api_sw_interface_set_lldp (vat_main_t * vam)
21175 {
21176   unformat_input_t *i = vam->input;
21177   vl_api_sw_interface_set_lldp_t *mp;
21178   u32 sw_if_index = ~0;
21179   u32 enable = 1;
21180   u8 *port_desc = NULL, *mgmt_oid = NULL;
21181   ip4_address_t ip4_addr;
21182   ip6_address_t ip6_addr;
21183   int ret;
21184
21185   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21186   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21187
21188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21189     {
21190       if (unformat (i, "disable"))
21191         enable = 0;
21192       else
21193         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21194         ;
21195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21196         ;
21197       else if (unformat (i, "port-desc %s", &port_desc))
21198         ;
21199       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21200         ;
21201       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21202         ;
21203       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21204         ;
21205       else
21206         break;
21207     }
21208
21209   if (sw_if_index == ~0)
21210     {
21211       errmsg ("missing interface name or sw_if_index");
21212       return -99;
21213     }
21214
21215   /* Construct the API message */
21216   vec_add1 (port_desc, 0);
21217   vec_add1 (mgmt_oid, 0);
21218   M (SW_INTERFACE_SET_LLDP, mp);
21219   mp->sw_if_index = ntohl (sw_if_index);
21220   mp->enable = enable;
21221   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21222   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21223   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21224   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21225   vec_free (port_desc);
21226   vec_free (mgmt_oid);
21227
21228   S (mp);
21229   W (ret);
21230   return ret;
21231 }
21232
21233 static int
21234 api_tcp_configure_src_addresses (vat_main_t * vam)
21235 {
21236   vl_api_tcp_configure_src_addresses_t *mp;
21237   unformat_input_t *i = vam->input;
21238   ip4_address_t v4first, v4last;
21239   ip6_address_t v6first, v6last;
21240   u8 range_set = 0;
21241   u32 vrf_id = 0;
21242   int ret;
21243
21244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21245     {
21246       if (unformat (i, "%U - %U",
21247                     unformat_ip4_address, &v4first,
21248                     unformat_ip4_address, &v4last))
21249         {
21250           if (range_set)
21251             {
21252               errmsg ("one range per message (range already set)");
21253               return -99;
21254             }
21255           range_set = 1;
21256         }
21257       else if (unformat (i, "%U - %U",
21258                          unformat_ip6_address, &v6first,
21259                          unformat_ip6_address, &v6last))
21260         {
21261           if (range_set)
21262             {
21263               errmsg ("one range per message (range already set)");
21264               return -99;
21265             }
21266           range_set = 2;
21267         }
21268       else if (unformat (i, "vrf %d", &vrf_id))
21269         ;
21270       else
21271         break;
21272     }
21273
21274   if (range_set == 0)
21275     {
21276       errmsg ("address range not set");
21277       return -99;
21278     }
21279
21280   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21281   mp->vrf_id = ntohl (vrf_id);
21282   /* ipv6? */
21283   if (range_set == 2)
21284     {
21285       mp->is_ipv6 = 1;
21286       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21287       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21288     }
21289   else
21290     {
21291       mp->is_ipv6 = 0;
21292       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21293       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21294     }
21295   S (mp);
21296   W (ret);
21297   return ret;
21298 }
21299
21300 static void vl_api_app_namespace_add_del_reply_t_handler
21301   (vl_api_app_namespace_add_del_reply_t * mp)
21302 {
21303   vat_main_t *vam = &vat_main;
21304   i32 retval = ntohl (mp->retval);
21305   if (vam->async_mode)
21306     {
21307       vam->async_errors += (retval < 0);
21308     }
21309   else
21310     {
21311       vam->retval = retval;
21312       if (retval == 0)
21313         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21314       vam->result_ready = 1;
21315     }
21316 }
21317
21318 static void vl_api_app_namespace_add_del_reply_t_handler_json
21319   (vl_api_app_namespace_add_del_reply_t * mp)
21320 {
21321   vat_main_t *vam = &vat_main;
21322   vat_json_node_t node;
21323
21324   vat_json_init_object (&node);
21325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21326   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21327
21328   vat_json_print (vam->ofp, &node);
21329   vat_json_free (&node);
21330
21331   vam->retval = ntohl (mp->retval);
21332   vam->result_ready = 1;
21333 }
21334
21335 static int
21336 api_app_namespace_add_del (vat_main_t * vam)
21337 {
21338   vl_api_app_namespace_add_del_t *mp;
21339   unformat_input_t *i = vam->input;
21340   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21341   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21342   u64 secret;
21343   int ret;
21344
21345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21346     {
21347       if (unformat (i, "id %_%v%_", &ns_id))
21348         ;
21349       else if (unformat (i, "secret %lu", &secret))
21350         secret_set = 1;
21351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21352         sw_if_index_set = 1;
21353       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21354         ;
21355       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21356         ;
21357       else
21358         break;
21359     }
21360   if (!ns_id || !secret_set || !sw_if_index_set)
21361     {
21362       errmsg ("namespace id, secret and sw_if_index must be set");
21363       return -99;
21364     }
21365   if (vec_len (ns_id) > 64)
21366     {
21367       errmsg ("namespace id too long");
21368       return -99;
21369     }
21370   M (APP_NAMESPACE_ADD_DEL, mp);
21371
21372   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21373   mp->namespace_id_len = vec_len (ns_id);
21374   mp->secret = clib_host_to_net_u64 (secret);
21375   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21376   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21377   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21378   vec_free (ns_id);
21379   S (mp);
21380   W (ret);
21381   return ret;
21382 }
21383
21384 static int
21385 api_sock_init_shm (vat_main_t * vam)
21386 {
21387 #if VPP_API_TEST_BUILTIN == 0
21388   unformat_input_t *i = vam->input;
21389   vl_api_shm_elem_config_t *config = 0;
21390   u64 size = 64 << 20;
21391   int rv;
21392
21393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21394     {
21395       if (unformat (i, "size %U", unformat_memory_size, &size))
21396         ;
21397       else
21398         break;
21399     }
21400
21401   /*
21402    * Canned custom ring allocator config.
21403    * Should probably parse all of this
21404    */
21405   vec_validate (config, 6);
21406   config[0].type = VL_API_VLIB_RING;
21407   config[0].size = 256;
21408   config[0].count = 32;
21409
21410   config[1].type = VL_API_VLIB_RING;
21411   config[1].size = 1024;
21412   config[1].count = 16;
21413
21414   config[2].type = VL_API_VLIB_RING;
21415   config[2].size = 4096;
21416   config[2].count = 2;
21417
21418   config[3].type = VL_API_CLIENT_RING;
21419   config[3].size = 256;
21420   config[3].count = 32;
21421
21422   config[4].type = VL_API_CLIENT_RING;
21423   config[4].size = 1024;
21424   config[4].count = 16;
21425
21426   config[5].type = VL_API_CLIENT_RING;
21427   config[5].size = 4096;
21428   config[5].count = 2;
21429
21430   config[6].type = VL_API_QUEUE;
21431   config[6].count = 128;
21432   config[6].size = sizeof (uword);
21433
21434   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21435   if (!rv)
21436     vam->client_index_invalid = 1;
21437   return rv;
21438 #else
21439   return -99;
21440 #endif
21441 }
21442
21443 static int
21444 api_dns_enable_disable (vat_main_t * vam)
21445 {
21446   unformat_input_t *line_input = vam->input;
21447   vl_api_dns_enable_disable_t *mp;
21448   u8 enable_disable = 1;
21449   int ret;
21450
21451   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21452     {
21453       if (unformat (line_input, "disable"))
21454         enable_disable = 0;
21455       if (unformat (line_input, "enable"))
21456         enable_disable = 1;
21457       else
21458         break;
21459     }
21460
21461   /* Construct the API message */
21462   M (DNS_ENABLE_DISABLE, mp);
21463   mp->enable = enable_disable;
21464
21465   /* send it... */
21466   S (mp);
21467   /* Wait for the reply */
21468   W (ret);
21469   return ret;
21470 }
21471
21472 static int
21473 api_dns_resolve_name (vat_main_t * vam)
21474 {
21475   unformat_input_t *line_input = vam->input;
21476   vl_api_dns_resolve_name_t *mp;
21477   u8 *name = 0;
21478   int ret;
21479
21480   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21481     {
21482       if (unformat (line_input, "%s", &name))
21483         ;
21484       else
21485         break;
21486     }
21487
21488   if (vec_len (name) > 127)
21489     {
21490       errmsg ("name too long");
21491       return -99;
21492     }
21493
21494   /* Construct the API message */
21495   M (DNS_RESOLVE_NAME, mp);
21496   memcpy (mp->name, name, vec_len (name));
21497   vec_free (name);
21498
21499   /* send it... */
21500   S (mp);
21501   /* Wait for the reply */
21502   W (ret);
21503   return ret;
21504 }
21505
21506 static int
21507 api_dns_resolve_ip (vat_main_t * vam)
21508 {
21509   unformat_input_t *line_input = vam->input;
21510   vl_api_dns_resolve_ip_t *mp;
21511   int is_ip6 = -1;
21512   ip4_address_t addr4;
21513   ip6_address_t addr6;
21514   int ret;
21515
21516   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21517     {
21518       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21519         is_ip6 = 1;
21520       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21521         is_ip6 = 0;
21522       else
21523         break;
21524     }
21525
21526   if (is_ip6 == -1)
21527     {
21528       errmsg ("missing address");
21529       return -99;
21530     }
21531
21532   /* Construct the API message */
21533   M (DNS_RESOLVE_IP, mp);
21534   mp->is_ip6 = is_ip6;
21535   if (is_ip6)
21536     memcpy (mp->address, &addr6, sizeof (addr6));
21537   else
21538     memcpy (mp->address, &addr4, sizeof (addr4));
21539
21540   /* send it... */
21541   S (mp);
21542   /* Wait for the reply */
21543   W (ret);
21544   return ret;
21545 }
21546
21547 static int
21548 api_dns_name_server_add_del (vat_main_t * vam)
21549 {
21550   unformat_input_t *i = vam->input;
21551   vl_api_dns_name_server_add_del_t *mp;
21552   u8 is_add = 1;
21553   ip6_address_t ip6_server;
21554   ip4_address_t ip4_server;
21555   int ip6_set = 0;
21556   int ip4_set = 0;
21557   int ret = 0;
21558
21559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21560     {
21561       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21562         ip6_set = 1;
21563       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21564         ip4_set = 1;
21565       else if (unformat (i, "del"))
21566         is_add = 0;
21567       else
21568         {
21569           clib_warning ("parse error '%U'", format_unformat_error, i);
21570           return -99;
21571         }
21572     }
21573
21574   if (ip4_set && ip6_set)
21575     {
21576       errmsg ("Only one server address allowed per message");
21577       return -99;
21578     }
21579   if ((ip4_set + ip6_set) == 0)
21580     {
21581       errmsg ("Server address required");
21582       return -99;
21583     }
21584
21585   /* Construct the API message */
21586   M (DNS_NAME_SERVER_ADD_DEL, mp);
21587
21588   if (ip6_set)
21589     {
21590       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21591       mp->is_ip6 = 1;
21592     }
21593   else
21594     {
21595       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21596       mp->is_ip6 = 0;
21597     }
21598
21599   mp->is_add = is_add;
21600
21601   /* send it... */
21602   S (mp);
21603
21604   /* Wait for a reply, return good/bad news  */
21605   W (ret);
21606   return ret;
21607 }
21608
21609 static void
21610 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21611 {
21612   vat_main_t *vam = &vat_main;
21613
21614   if (mp->is_ip4)
21615     {
21616       print (vam->ofp,
21617              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21618              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21619              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21620              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21621              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21622              clib_net_to_host_u32 (mp->action_index), mp->tag);
21623     }
21624   else
21625     {
21626       print (vam->ofp,
21627              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21628              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21629              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21630              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21631              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21632              clib_net_to_host_u32 (mp->action_index), mp->tag);
21633     }
21634 }
21635
21636 static void
21637 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21638                                              mp)
21639 {
21640   vat_main_t *vam = &vat_main;
21641   vat_json_node_t *node = NULL;
21642   struct in6_addr ip6;
21643   struct in_addr ip4;
21644
21645   if (VAT_JSON_ARRAY != vam->json_tree.type)
21646     {
21647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21648       vat_json_init_array (&vam->json_tree);
21649     }
21650   node = vat_json_array_add (&vam->json_tree);
21651   vat_json_init_object (node);
21652
21653   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21654   vat_json_object_add_uint (node, "appns_index",
21655                             clib_net_to_host_u32 (mp->appns_index));
21656   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21657   vat_json_object_add_uint (node, "scope", mp->scope);
21658   vat_json_object_add_uint (node, "action_index",
21659                             clib_net_to_host_u32 (mp->action_index));
21660   vat_json_object_add_uint (node, "lcl_port",
21661                             clib_net_to_host_u16 (mp->lcl_port));
21662   vat_json_object_add_uint (node, "rmt_port",
21663                             clib_net_to_host_u16 (mp->rmt_port));
21664   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21665   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21666   vat_json_object_add_string_copy (node, "tag", mp->tag);
21667   if (mp->is_ip4)
21668     {
21669       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21670       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21671       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21672       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21673     }
21674   else
21675     {
21676       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21677       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21678       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21679       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21680     }
21681 }
21682
21683 static int
21684 api_session_rule_add_del (vat_main_t * vam)
21685 {
21686   vl_api_session_rule_add_del_t *mp;
21687   unformat_input_t *i = vam->input;
21688   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21689   u32 appns_index = 0, scope = 0;
21690   ip4_address_t lcl_ip4, rmt_ip4;
21691   ip6_address_t lcl_ip6, rmt_ip6;
21692   u8 is_ip4 = 1, conn_set = 0;
21693   u8 is_add = 1, *tag = 0;
21694   int ret;
21695
21696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21697     {
21698       if (unformat (i, "del"))
21699         is_add = 0;
21700       else if (unformat (i, "add"))
21701         ;
21702       else if (unformat (i, "proto tcp"))
21703         proto = 0;
21704       else if (unformat (i, "proto udp"))
21705         proto = 1;
21706       else if (unformat (i, "appns %d", &appns_index))
21707         ;
21708       else if (unformat (i, "scope %d", &scope))
21709         ;
21710       else if (unformat (i, "tag %_%v%_", &tag))
21711         ;
21712       else
21713         if (unformat
21714             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21715              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21716              &rmt_port))
21717         {
21718           is_ip4 = 1;
21719           conn_set = 1;
21720         }
21721       else
21722         if (unformat
21723             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21724              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21725              &rmt_port))
21726         {
21727           is_ip4 = 0;
21728           conn_set = 1;
21729         }
21730       else if (unformat (i, "action %d", &action))
21731         ;
21732       else
21733         break;
21734     }
21735   if (proto == ~0 || !conn_set || action == ~0)
21736     {
21737       errmsg ("transport proto, connection and action must be set");
21738       return -99;
21739     }
21740
21741   if (scope > 3)
21742     {
21743       errmsg ("scope should be 0-3");
21744       return -99;
21745     }
21746
21747   M (SESSION_RULE_ADD_DEL, mp);
21748
21749   mp->is_ip4 = is_ip4;
21750   mp->transport_proto = proto;
21751   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21752   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21753   mp->lcl_plen = lcl_plen;
21754   mp->rmt_plen = rmt_plen;
21755   mp->action_index = clib_host_to_net_u32 (action);
21756   mp->appns_index = clib_host_to_net_u32 (appns_index);
21757   mp->scope = scope;
21758   mp->is_add = is_add;
21759   if (is_ip4)
21760     {
21761       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21762       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21763     }
21764   else
21765     {
21766       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21767       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21768     }
21769   if (tag)
21770     {
21771       clib_memcpy (mp->tag, tag, vec_len (tag));
21772       vec_free (tag);
21773     }
21774
21775   S (mp);
21776   W (ret);
21777   return ret;
21778 }
21779
21780 static int
21781 api_session_rules_dump (vat_main_t * vam)
21782 {
21783   vl_api_session_rules_dump_t *mp;
21784   vl_api_control_ping_t *mp_ping;
21785   int ret;
21786
21787   if (!vam->json_output)
21788     {
21789       print (vam->ofp, "%=20s", "Session Rules");
21790     }
21791
21792   M (SESSION_RULES_DUMP, mp);
21793   /* send it... */
21794   S (mp);
21795
21796   /* Use a control ping for synchronization */
21797   MPING (CONTROL_PING, mp_ping);
21798   S (mp_ping);
21799
21800   /* Wait for a reply... */
21801   W (ret);
21802   return ret;
21803 }
21804
21805 static int
21806 api_ip_container_proxy_add_del (vat_main_t * vam)
21807 {
21808   vl_api_ip_container_proxy_add_del_t *mp;
21809   unformat_input_t *i = vam->input;
21810   u32 sw_if_index = ~0;
21811   vl_api_prefix_t pfx = { };
21812   u8 is_add = 1;
21813   int ret;
21814
21815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21816     {
21817       if (unformat (i, "del"))
21818         is_add = 0;
21819       else if (unformat (i, "add"))
21820         ;
21821       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21822         ;
21823       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21824         ;
21825       else
21826         break;
21827     }
21828   if (sw_if_index == ~0 || pfx.address_length == 0)
21829     {
21830       errmsg ("address and sw_if_index must be set");
21831       return -99;
21832     }
21833
21834   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21835
21836   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21837   mp->is_add = is_add;
21838   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21839
21840   S (mp);
21841   W (ret);
21842   return ret;
21843 }
21844
21845 static int
21846 api_qos_record_enable_disable (vat_main_t * vam)
21847 {
21848   unformat_input_t *i = vam->input;
21849   vl_api_qos_record_enable_disable_t *mp;
21850   u32 sw_if_index, qs = 0xff;
21851   u8 sw_if_index_set = 0;
21852   u8 enable = 1;
21853   int ret;
21854
21855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21856     {
21857       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21858         sw_if_index_set = 1;
21859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21860         sw_if_index_set = 1;
21861       else if (unformat (i, "%U", unformat_qos_source, &qs))
21862         ;
21863       else if (unformat (i, "disable"))
21864         enable = 0;
21865       else
21866         {
21867           clib_warning ("parse error '%U'", format_unformat_error, i);
21868           return -99;
21869         }
21870     }
21871
21872   if (sw_if_index_set == 0)
21873     {
21874       errmsg ("missing interface name or sw_if_index");
21875       return -99;
21876     }
21877   if (qs == 0xff)
21878     {
21879       errmsg ("input location must be specified");
21880       return -99;
21881     }
21882
21883   M (QOS_RECORD_ENABLE_DISABLE, mp);
21884
21885   mp->sw_if_index = ntohl (sw_if_index);
21886   mp->input_source = qs;
21887   mp->enable = enable;
21888
21889   S (mp);
21890   W (ret);
21891   return ret;
21892 }
21893
21894
21895 static int
21896 q_or_quit (vat_main_t * vam)
21897 {
21898 #if VPP_API_TEST_BUILTIN == 0
21899   longjmp (vam->jump_buf, 1);
21900 #endif
21901   return 0;                     /* not so much */
21902 }
21903
21904 static int
21905 q (vat_main_t * vam)
21906 {
21907   return q_or_quit (vam);
21908 }
21909
21910 static int
21911 quit (vat_main_t * vam)
21912 {
21913   return q_or_quit (vam);
21914 }
21915
21916 static int
21917 comment (vat_main_t * vam)
21918 {
21919   return 0;
21920 }
21921
21922 static int
21923 statseg (vat_main_t * vam)
21924 {
21925   ssvm_private_t *ssvmp = &vam->stat_segment;
21926   ssvm_shared_header_t *shared_header = ssvmp->sh;
21927   vlib_counter_t **counters;
21928   u64 thread0_index1_packets;
21929   u64 thread0_index1_bytes;
21930   f64 vector_rate, input_rate;
21931   uword *p;
21932
21933   uword *counter_vector_by_name;
21934   if (vam->stat_segment_lockp == 0)
21935     {
21936       errmsg ("Stat segment not mapped...");
21937       return -99;
21938     }
21939
21940   /* look up "/if/rx for sw_if_index 1 as a test */
21941
21942   clib_spinlock_lock (vam->stat_segment_lockp);
21943
21944   counter_vector_by_name = (uword *) shared_header->opaque[1];
21945
21946   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21947   if (p == 0)
21948     {
21949       clib_spinlock_unlock (vam->stat_segment_lockp);
21950       errmsg ("/if/tx not found?");
21951       return -99;
21952     }
21953
21954   /* Fish per-thread vector of combined counters from shared memory */
21955   counters = (vlib_counter_t **) p[0];
21956
21957   if (vec_len (counters[0]) < 2)
21958     {
21959       clib_spinlock_unlock (vam->stat_segment_lockp);
21960       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21961       return -99;
21962     }
21963
21964   /* Read thread 0 sw_if_index 1 counter */
21965   thread0_index1_packets = counters[0][1].packets;
21966   thread0_index1_bytes = counters[0][1].bytes;
21967
21968   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21969   if (p == 0)
21970     {
21971       clib_spinlock_unlock (vam->stat_segment_lockp);
21972       errmsg ("vector_rate not found?");
21973       return -99;
21974     }
21975
21976   vector_rate = *(f64 *) (p[0]);
21977   p = hash_get_mem (counter_vector_by_name, "input_rate");
21978   if (p == 0)
21979     {
21980       clib_spinlock_unlock (vam->stat_segment_lockp);
21981       errmsg ("input_rate not found?");
21982       return -99;
21983     }
21984   input_rate = *(f64 *) (p[0]);
21985
21986   clib_spinlock_unlock (vam->stat_segment_lockp);
21987
21988   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21989          vector_rate, input_rate);
21990   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21991          thread0_index1_packets, thread0_index1_bytes);
21992
21993   return 0;
21994 }
21995
21996 static int
21997 cmd_cmp (void *a1, void *a2)
21998 {
21999   u8 **c1 = a1;
22000   u8 **c2 = a2;
22001
22002   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22003 }
22004
22005 static int
22006 help (vat_main_t * vam)
22007 {
22008   u8 **cmds = 0;
22009   u8 *name = 0;
22010   hash_pair_t *p;
22011   unformat_input_t *i = vam->input;
22012   int j;
22013
22014   if (unformat (i, "%s", &name))
22015     {
22016       uword *hs;
22017
22018       vec_add1 (name, 0);
22019
22020       hs = hash_get_mem (vam->help_by_name, name);
22021       if (hs)
22022         print (vam->ofp, "usage: %s %s", name, hs[0]);
22023       else
22024         print (vam->ofp, "No such msg / command '%s'", name);
22025       vec_free (name);
22026       return 0;
22027     }
22028
22029   print (vam->ofp, "Help is available for the following:");
22030
22031     /* *INDENT-OFF* */
22032     hash_foreach_pair (p, vam->function_by_name,
22033     ({
22034       vec_add1 (cmds, (u8 *)(p->key));
22035     }));
22036     /* *INDENT-ON* */
22037
22038   vec_sort_with_function (cmds, cmd_cmp);
22039
22040   for (j = 0; j < vec_len (cmds); j++)
22041     print (vam->ofp, "%s", cmds[j]);
22042
22043   vec_free (cmds);
22044   return 0;
22045 }
22046
22047 static int
22048 set (vat_main_t * vam)
22049 {
22050   u8 *name = 0, *value = 0;
22051   unformat_input_t *i = vam->input;
22052
22053   if (unformat (i, "%s", &name))
22054     {
22055       /* The input buffer is a vector, not a string. */
22056       value = vec_dup (i->buffer);
22057       vec_delete (value, i->index, 0);
22058       /* Almost certainly has a trailing newline */
22059       if (value[vec_len (value) - 1] == '\n')
22060         value[vec_len (value) - 1] = 0;
22061       /* Make sure it's a proper string, one way or the other */
22062       vec_add1 (value, 0);
22063       (void) clib_macro_set_value (&vam->macro_main,
22064                                    (char *) name, (char *) value);
22065     }
22066   else
22067     errmsg ("usage: set <name> <value>");
22068
22069   vec_free (name);
22070   vec_free (value);
22071   return 0;
22072 }
22073
22074 static int
22075 unset (vat_main_t * vam)
22076 {
22077   u8 *name = 0;
22078
22079   if (unformat (vam->input, "%s", &name))
22080     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22081       errmsg ("unset: %s wasn't set", name);
22082   vec_free (name);
22083   return 0;
22084 }
22085
22086 typedef struct
22087 {
22088   u8 *name;
22089   u8 *value;
22090 } macro_sort_t;
22091
22092
22093 static int
22094 macro_sort_cmp (void *a1, void *a2)
22095 {
22096   macro_sort_t *s1 = a1;
22097   macro_sort_t *s2 = a2;
22098
22099   return strcmp ((char *) (s1->name), (char *) (s2->name));
22100 }
22101
22102 static int
22103 dump_macro_table (vat_main_t * vam)
22104 {
22105   macro_sort_t *sort_me = 0, *sm;
22106   int i;
22107   hash_pair_t *p;
22108
22109     /* *INDENT-OFF* */
22110     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22111     ({
22112       vec_add2 (sort_me, sm, 1);
22113       sm->name = (u8 *)(p->key);
22114       sm->value = (u8 *) (p->value[0]);
22115     }));
22116     /* *INDENT-ON* */
22117
22118   vec_sort_with_function (sort_me, macro_sort_cmp);
22119
22120   if (vec_len (sort_me))
22121     print (vam->ofp, "%-15s%s", "Name", "Value");
22122   else
22123     print (vam->ofp, "The macro table is empty...");
22124
22125   for (i = 0; i < vec_len (sort_me); i++)
22126     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22127   return 0;
22128 }
22129
22130 static int
22131 dump_node_table (vat_main_t * vam)
22132 {
22133   int i, j;
22134   vlib_node_t *node, *next_node;
22135
22136   if (vec_len (vam->graph_nodes) == 0)
22137     {
22138       print (vam->ofp, "Node table empty, issue get_node_graph...");
22139       return 0;
22140     }
22141
22142   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22143     {
22144       node = vam->graph_nodes[0][i];
22145       print (vam->ofp, "[%d] %s", i, node->name);
22146       for (j = 0; j < vec_len (node->next_nodes); j++)
22147         {
22148           if (node->next_nodes[j] != ~0)
22149             {
22150               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22151               print (vam->ofp, "  [%d] %s", j, next_node->name);
22152             }
22153         }
22154     }
22155   return 0;
22156 }
22157
22158 static int
22159 value_sort_cmp (void *a1, void *a2)
22160 {
22161   name_sort_t *n1 = a1;
22162   name_sort_t *n2 = a2;
22163
22164   if (n1->value < n2->value)
22165     return -1;
22166   if (n1->value > n2->value)
22167     return 1;
22168   return 0;
22169 }
22170
22171
22172 static int
22173 dump_msg_api_table (vat_main_t * vam)
22174 {
22175   api_main_t *am = &api_main;
22176   name_sort_t *nses = 0, *ns;
22177   hash_pair_t *hp;
22178   int i;
22179
22180   /* *INDENT-OFF* */
22181   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22182   ({
22183     vec_add2 (nses, ns, 1);
22184     ns->name = (u8 *)(hp->key);
22185     ns->value = (u32) hp->value[0];
22186   }));
22187   /* *INDENT-ON* */
22188
22189   vec_sort_with_function (nses, value_sort_cmp);
22190
22191   for (i = 0; i < vec_len (nses); i++)
22192     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22193   vec_free (nses);
22194   return 0;
22195 }
22196
22197 static int
22198 get_msg_id (vat_main_t * vam)
22199 {
22200   u8 *name_and_crc;
22201   u32 message_index;
22202
22203   if (unformat (vam->input, "%s", &name_and_crc))
22204     {
22205       message_index = vl_msg_api_get_msg_index (name_and_crc);
22206       if (message_index == ~0)
22207         {
22208           print (vam->ofp, " '%s' not found", name_and_crc);
22209           return 0;
22210         }
22211       print (vam->ofp, " '%s' has message index %d",
22212              name_and_crc, message_index);
22213       return 0;
22214     }
22215   errmsg ("name_and_crc required...");
22216   return 0;
22217 }
22218
22219 static int
22220 search_node_table (vat_main_t * vam)
22221 {
22222   unformat_input_t *line_input = vam->input;
22223   u8 *node_to_find;
22224   int j;
22225   vlib_node_t *node, *next_node;
22226   uword *p;
22227
22228   if (vam->graph_node_index_by_name == 0)
22229     {
22230       print (vam->ofp, "Node table empty, issue get_node_graph...");
22231       return 0;
22232     }
22233
22234   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22235     {
22236       if (unformat (line_input, "%s", &node_to_find))
22237         {
22238           vec_add1 (node_to_find, 0);
22239           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22240           if (p == 0)
22241             {
22242               print (vam->ofp, "%s not found...", node_to_find);
22243               goto out;
22244             }
22245           node = vam->graph_nodes[0][p[0]];
22246           print (vam->ofp, "[%d] %s", p[0], node->name);
22247           for (j = 0; j < vec_len (node->next_nodes); j++)
22248             {
22249               if (node->next_nodes[j] != ~0)
22250                 {
22251                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22252                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22253                 }
22254             }
22255         }
22256
22257       else
22258         {
22259           clib_warning ("parse error '%U'", format_unformat_error,
22260                         line_input);
22261           return -99;
22262         }
22263
22264     out:
22265       vec_free (node_to_find);
22266
22267     }
22268
22269   return 0;
22270 }
22271
22272
22273 static int
22274 script (vat_main_t * vam)
22275 {
22276 #if (VPP_API_TEST_BUILTIN==0)
22277   u8 *s = 0;
22278   char *save_current_file;
22279   unformat_input_t save_input;
22280   jmp_buf save_jump_buf;
22281   u32 save_line_number;
22282
22283   FILE *new_fp, *save_ifp;
22284
22285   if (unformat (vam->input, "%s", &s))
22286     {
22287       new_fp = fopen ((char *) s, "r");
22288       if (new_fp == 0)
22289         {
22290           errmsg ("Couldn't open script file %s", s);
22291           vec_free (s);
22292           return -99;
22293         }
22294     }
22295   else
22296     {
22297       errmsg ("Missing script name");
22298       return -99;
22299     }
22300
22301   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22302   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22303   save_ifp = vam->ifp;
22304   save_line_number = vam->input_line_number;
22305   save_current_file = (char *) vam->current_file;
22306
22307   vam->input_line_number = 0;
22308   vam->ifp = new_fp;
22309   vam->current_file = s;
22310   do_one_file (vam);
22311
22312   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22313   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22314   vam->ifp = save_ifp;
22315   vam->input_line_number = save_line_number;
22316   vam->current_file = (u8 *) save_current_file;
22317   vec_free (s);
22318
22319   return 0;
22320 #else
22321   clib_warning ("use the exec command...");
22322   return -99;
22323 #endif
22324 }
22325
22326 static int
22327 echo (vat_main_t * vam)
22328 {
22329   print (vam->ofp, "%v", vam->input->buffer);
22330   return 0;
22331 }
22332
22333 /* List of API message constructors, CLI names map to api_xxx */
22334 #define foreach_vpe_api_msg                                             \
22335 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22336 _(sw_interface_dump,"")                                                 \
22337 _(sw_interface_set_flags,                                               \
22338   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22339 _(sw_interface_add_del_address,                                         \
22340   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22341 _(sw_interface_set_rx_mode,                                             \
22342   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22343 _(sw_interface_set_rx_placement,                                        \
22344   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22345 _(sw_interface_rx_placement_dump,                                       \
22346   "[<intfc> | sw_if_index <id>]")                                         \
22347 _(sw_interface_set_table,                                               \
22348   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22349 _(sw_interface_set_mpls_enable,                                         \
22350   "<intfc> | sw_if_index [disable | dis]")                              \
22351 _(sw_interface_set_vpath,                                               \
22352   "<intfc> | sw_if_index <id> enable | disable")                        \
22353 _(sw_interface_set_vxlan_bypass,                                        \
22354   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22355 _(sw_interface_set_geneve_bypass,                                       \
22356   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22357 _(sw_interface_set_l2_xconnect,                                         \
22358   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22359   "enable | disable")                                                   \
22360 _(sw_interface_set_l2_bridge,                                           \
22361   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22362   "[shg <split-horizon-group>] [bvi]\n"                                 \
22363   "enable | disable")                                                   \
22364 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22365 _(bridge_domain_add_del,                                                \
22366   "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") \
22367 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22368 _(l2fib_add_del,                                                        \
22369   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22370 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22371 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22372 _(l2_flags,                                                             \
22373   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22374 _(bridge_flags,                                                         \
22375   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22376 _(tap_create_v2,                                                        \
22377   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22378 _(tap_delete_v2,                                                        \
22379   "<vpp-if-name> | sw_if_index <id>")                                   \
22380 _(sw_interface_tap_v2_dump, "")                                         \
22381 _(virtio_pci_create,                                                    \
22382   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22383 _(virtio_pci_delete,                                                    \
22384   "<vpp-if-name> | sw_if_index <id>")                                   \
22385 _(sw_interface_virtio_pci_dump, "")                                     \
22386 _(bond_create,                                                          \
22387   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22388   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22389   "[id <if-id>]")                                                       \
22390 _(bond_delete,                                                          \
22391   "<vpp-if-name> | sw_if_index <id>")                                   \
22392 _(bond_enslave,                                                         \
22393   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22394 _(bond_detach_slave,                                                    \
22395   "sw_if_index <n>")                                                    \
22396 _(sw_interface_bond_dump, "")                                           \
22397 _(sw_interface_slave_dump,                                              \
22398   "<vpp-if-name> | sw_if_index <id>")                                   \
22399 _(ip_table_add_del,                                                     \
22400   "table <n> [ipv6] [add | del]\n")                                     \
22401 _(ip_add_del_route,                                                     \
22402   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22403   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22404   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22405   "[multipath] [count <n>] [del]")                                      \
22406 _(ip_mroute_add_del,                                                    \
22407   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22408   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22409 _(mpls_table_add_del,                                                   \
22410   "table <n> [add | del]\n")                                            \
22411 _(mpls_route_add_del,                                                   \
22412   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22413   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22414   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22415   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22416   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22417   "[count <n>] [del]")                                                  \
22418 _(mpls_ip_bind_unbind,                                                  \
22419   "<label> <addr/len>")                                                 \
22420 _(mpls_tunnel_add_del,                                                  \
22421   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22422   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22423   "[l2-only]  [out-label <n>]")                                         \
22424 _(sr_mpls_policy_add,                                                   \
22425   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22426 _(sr_mpls_policy_del,                                                   \
22427   "bsid <id>")                                                          \
22428 _(bier_table_add_del,                                                   \
22429   "<label> <sub-domain> <set> <bsl> [del]")                             \
22430 _(bier_route_add_del,                                                   \
22431   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22432   "[<intfc> | sw_if_index <id>]"                                        \
22433   "[weight <n>] [del] [multipath]")                                     \
22434 _(proxy_arp_add_del,                                                    \
22435   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22436 _(proxy_arp_intfc_enable_disable,                                       \
22437   "<intfc> | sw_if_index <id> enable | disable")                        \
22438 _(sw_interface_set_unnumbered,                                          \
22439   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22440 _(ip_neighbor_add_del,                                                  \
22441   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22442   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22443 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22444 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22445   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22446   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22447   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22448 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22449 _(reset_fib, "vrf <n> [ipv6]")                                          \
22450 _(dhcp_proxy_config,                                                    \
22451   "svr <v46-address> src <v46-address>\n"                               \
22452    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22453 _(dhcp_proxy_set_vss,                                                   \
22454   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22455 _(dhcp_proxy_dump, "ip6")                                               \
22456 _(dhcp_client_config,                                                   \
22457   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22458 _(set_ip_flow_hash,                                                     \
22459   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22460 _(sw_interface_ip6_enable_disable,                                      \
22461   "<intfc> | sw_if_index <id> enable | disable")                        \
22462 _(ip6nd_proxy_add_del,                                                  \
22463   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22464 _(ip6nd_proxy_dump, "")                                                 \
22465 _(sw_interface_ip6nd_ra_prefix,                                         \
22466   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22467   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22468   "[nolink] [isno]")                                                    \
22469 _(sw_interface_ip6nd_ra_config,                                         \
22470   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22471   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22472   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22473 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22474 _(l2_patch_add_del,                                                     \
22475   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22476   "enable | disable")                                                   \
22477 _(sr_localsid_add_del,                                                  \
22478   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22479   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22480 _(classify_add_del_table,                                               \
22481   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22482   " [del] [del-chain] mask <mask-value>\n"                              \
22483   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22484   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22485 _(classify_add_del_session,                                             \
22486   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22487   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22488   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22489   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22490 _(classify_set_interface_ip_table,                                      \
22491   "<intfc> | sw_if_index <nn> table <nn>")                              \
22492 _(classify_set_interface_l2_tables,                                     \
22493   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22494   "  [other-table <nn>]")                                               \
22495 _(get_node_index, "node <node-name")                                    \
22496 _(add_node_next, "node <node-name> next <next-node-name>")              \
22497 _(l2tpv3_create_tunnel,                                                 \
22498   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22499   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22500   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22501 _(l2tpv3_set_tunnel_cookies,                                            \
22502   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22503   "[new_remote_cookie <nn>]\n")                                         \
22504 _(l2tpv3_interface_enable_disable,                                      \
22505   "<intfc> | sw_if_index <nn> enable | disable")                        \
22506 _(l2tpv3_set_lookup_key,                                                \
22507   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22508 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22509 _(vxlan_offload_rx,                                                     \
22510   "hw { <interface name> | hw_if_index <nn>} "                          \
22511   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22512 _(vxlan_add_del_tunnel,                                                 \
22513   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22514   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22515   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22516 _(geneve_add_del_tunnel,                                                \
22517   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22518   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22519   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22520 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22521 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22522 _(gre_add_del_tunnel,                                                   \
22523   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22524   "[teb | erspan <session-id>] [del]")                                  \
22525 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22526 _(l2_fib_clear_table, "")                                               \
22527 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22528 _(l2_interface_vlan_tag_rewrite,                                        \
22529   "<intfc> | sw_if_index <nn> \n"                                       \
22530   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22531   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22532 _(create_vhost_user_if,                                                 \
22533         "socket <filename> [server] [renumber <dev_instance>] "         \
22534         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22535         "[mac <mac_address>]")                                          \
22536 _(modify_vhost_user_if,                                                 \
22537         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22538         "[server] [renumber <dev_instance>]")                           \
22539 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22540 _(sw_interface_vhost_user_dump, "")                                     \
22541 _(show_version, "")                                                     \
22542 _(show_threads, "")                                                     \
22543 _(vxlan_gpe_add_del_tunnel,                                             \
22544   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22545   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22546   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22547   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22548 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22549 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22550 _(interface_name_renumber,                                              \
22551   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22552 _(input_acl_set_interface,                                              \
22553   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22554   "  [l2-table <nn>] [del]")                                            \
22555 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22556 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22557   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22558 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22559 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22560 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22561 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22562 _(ip_dump, "ipv4 | ipv6")                                               \
22563 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22564 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22565   "  spid_id <n> ")                                                     \
22566 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22567   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22568   "  integ_alg <alg> integ_key <hex>")                                  \
22569 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22570   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22571   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22572   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22573 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22574 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22575   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22576   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22577   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22578   "  [instance <n>]")     \
22579 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22580 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22581   "  <alg> <hex>\n")                                                    \
22582 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22583 _(delete_loopback,"sw_if_index <nn>")                                   \
22584 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22585 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22586 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22587 _(want_interface_events,  "enable|disable")                             \
22588 _(get_first_msg_id, "client <name>")                                    \
22589 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22590 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22591   "fib-id <nn> [ip4][ip6][default]")                                    \
22592 _(get_node_graph, " ")                                                  \
22593 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22594 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22595 _(ioam_disable, "")                                                     \
22596 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22597                             " sw_if_index <sw_if_index> p <priority> "  \
22598                             "w <weight>] [del]")                        \
22599 _(one_add_del_locator, "locator-set <locator_name> "                    \
22600                         "iface <intf> | sw_if_index <sw_if_index> "     \
22601                         "p <priority> w <weight> [del]")                \
22602 _(one_add_del_local_eid,"vni <vni> eid "                                \
22603                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22604                          "locator-set <locator_name> [del]"             \
22605                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22606 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22607 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22608 _(one_enable_disable, "enable|disable")                                 \
22609 _(one_map_register_enable_disable, "enable|disable")                    \
22610 _(one_map_register_fallback_threshold, "<value>")                       \
22611 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22612 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22613                                "[seid <seid>] "                         \
22614                                "rloc <locator> p <prio> "               \
22615                                "w <weight> [rloc <loc> ... ] "          \
22616                                "action <action> [del-all]")             \
22617 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22618                           "<local-eid>")                                \
22619 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22620 _(one_use_petr, "ip-address> | disable")                                \
22621 _(one_map_request_mode, "src-dst|dst-only")                             \
22622 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22623 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22624 _(one_locator_set_dump, "[local | remote]")                             \
22625 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22626 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22627                        "[local] | [remote]")                            \
22628 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22629 _(one_ndp_bd_get, "")                                                   \
22630 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22631 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22632 _(one_l2_arp_bd_get, "")                                                \
22633 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22634 _(one_stats_enable_disable, "enable|disable")                           \
22635 _(show_one_stats_enable_disable, "")                                    \
22636 _(one_eid_table_vni_dump, "")                                           \
22637 _(one_eid_table_map_dump, "l2|l3")                                      \
22638 _(one_map_resolver_dump, "")                                            \
22639 _(one_map_server_dump, "")                                              \
22640 _(one_adjacencies_get, "vni <vni>")                                     \
22641 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22642 _(show_one_rloc_probe_state, "")                                        \
22643 _(show_one_map_register_state, "")                                      \
22644 _(show_one_status, "")                                                  \
22645 _(one_stats_dump, "")                                                   \
22646 _(one_stats_flush, "")                                                  \
22647 _(one_get_map_request_itr_rlocs, "")                                    \
22648 _(one_map_register_set_ttl, "<ttl>")                                    \
22649 _(one_set_transport_protocol, "udp|api")                                \
22650 _(one_get_transport_protocol, "")                                       \
22651 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22652 _(one_show_xtr_mode, "")                                                \
22653 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22654 _(one_show_pitr_mode, "")                                               \
22655 _(one_enable_disable_petr_mode, "enable|disable")                       \
22656 _(one_show_petr_mode, "")                                               \
22657 _(show_one_nsh_mapping, "")                                             \
22658 _(show_one_pitr, "")                                                    \
22659 _(show_one_use_petr, "")                                                \
22660 _(show_one_map_request_mode, "")                                        \
22661 _(show_one_map_register_ttl, "")                                        \
22662 _(show_one_map_register_fallback_threshold, "")                         \
22663 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22664                             " sw_if_index <sw_if_index> p <priority> "  \
22665                             "w <weight>] [del]")                        \
22666 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22667                         "iface <intf> | sw_if_index <sw_if_index> "     \
22668                         "p <priority> w <weight> [del]")                \
22669 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22670                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22671                          "locator-set <locator_name> [del]"             \
22672                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22673 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22674 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22675 _(lisp_enable_disable, "enable|disable")                                \
22676 _(lisp_map_register_enable_disable, "enable|disable")                   \
22677 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22678 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22679                                "[seid <seid>] "                         \
22680                                "rloc <locator> p <prio> "               \
22681                                "w <weight> [rloc <loc> ... ] "          \
22682                                "action <action> [del-all]")             \
22683 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22684                           "<local-eid>")                                \
22685 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22686 _(lisp_use_petr, "<ip-address> | disable")                              \
22687 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22688 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22689 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22690 _(lisp_locator_set_dump, "[local | remote]")                            \
22691 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22692 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22693                        "[local] | [remote]")                            \
22694 _(lisp_eid_table_vni_dump, "")                                          \
22695 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22696 _(lisp_map_resolver_dump, "")                                           \
22697 _(lisp_map_server_dump, "")                                             \
22698 _(lisp_adjacencies_get, "vni <vni>")                                    \
22699 _(gpe_fwd_entry_vnis_get, "")                                           \
22700 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22701 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22702                                 "[table <table-id>]")                   \
22703 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22704 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22705 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22706 _(gpe_get_encap_mode, "")                                               \
22707 _(lisp_gpe_add_del_iface, "up|down")                                    \
22708 _(lisp_gpe_enable_disable, "enable|disable")                            \
22709 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22710   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22711 _(show_lisp_rloc_probe_state, "")                                       \
22712 _(show_lisp_map_register_state, "")                                     \
22713 _(show_lisp_status, "")                                                 \
22714 _(lisp_get_map_request_itr_rlocs, "")                                   \
22715 _(show_lisp_pitr, "")                                                   \
22716 _(show_lisp_use_petr, "")                                               \
22717 _(show_lisp_map_request_mode, "")                                       \
22718 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22719 _(af_packet_delete, "name <host interface name>")                       \
22720 _(af_packet_dump, "")                                                   \
22721 _(policer_add_del, "name <policer name> <params> [del]")                \
22722 _(policer_dump, "[name <policer name>]")                                \
22723 _(policer_classify_set_interface,                                       \
22724   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22725   "  [l2-table <nn>] [del]")                                            \
22726 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22727 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22728     "[master|slave]")                                                   \
22729 _(netmap_delete, "name <interface name>")                               \
22730 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22731 _(mpls_fib_dump, "")                                                    \
22732 _(classify_table_ids, "")                                               \
22733 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22734 _(classify_table_info, "table_id <nn>")                                 \
22735 _(classify_session_dump, "table_id <nn>")                               \
22736 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22737     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22738     "[template_interval <nn>] [udp_checksum]")                          \
22739 _(ipfix_exporter_dump, "")                                              \
22740 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22741 _(ipfix_classify_stream_dump, "")                                       \
22742 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22743 _(ipfix_classify_table_dump, "")                                        \
22744 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22745 _(sw_interface_span_dump, "[l2]")                                           \
22746 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22747 _(pg_create_interface, "if_id <nn>")                                    \
22748 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22749 _(pg_enable_disable, "[stream <id>] disable")                           \
22750 _(ip_source_and_port_range_check_add_del,                               \
22751   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22752 _(ip_source_and_port_range_check_interface_add_del,                     \
22753   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22754   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22755 _(ipsec_gre_tunnel_add_del,                                             \
22756   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22757 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22758 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22759 _(l2_interface_pbb_tag_rewrite,                                         \
22760   "<intfc> | sw_if_index <nn> \n"                                       \
22761   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22762   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22763 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22764 _(flow_classify_set_interface,                                          \
22765   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22766 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22767 _(ip_fib_dump, "")                                                      \
22768 _(ip_mfib_dump, "")                                                     \
22769 _(ip6_fib_dump, "")                                                     \
22770 _(ip6_mfib_dump, "")                                                    \
22771 _(feature_enable_disable, "arc_name <arc_name> "                        \
22772   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22773 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22774 "[disable]")                                                            \
22775 _(l2_xconnect_dump, "")                                                 \
22776 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22777 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22778 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22779 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22780 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22781 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22782 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22783   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22784 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22785 _(sock_init_shm, "size <nnn>")                                          \
22786 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22787 _(dns_enable_disable, "[enable][disable]")                              \
22788 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22789 _(dns_resolve_name, "<hostname>")                                       \
22790 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22791 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22792 _(dns_resolve_name, "<hostname>")                                       \
22793 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22794   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22795 _(session_rules_dump, "")                                               \
22796 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22797 _(output_acl_set_interface,                                             \
22798   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22799   "  [l2-table <nn>] [del]")                                            \
22800 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22801
22802 /* List of command functions, CLI names map directly to functions */
22803 #define foreach_cli_function                                    \
22804 _(comment, "usage: comment <ignore-rest-of-line>")              \
22805 _(dump_interface_table, "usage: dump_interface_table")          \
22806 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22807 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22808 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22809 _(dump_macro_table, "usage: dump_macro_table ")                 \
22810 _(dump_node_table, "usage: dump_node_table")                    \
22811 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22812 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22813 _(echo, "usage: echo <message>")                                \
22814 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22815 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22816 _(help, "usage: help")                                          \
22817 _(q, "usage: quit")                                             \
22818 _(quit, "usage: quit")                                          \
22819 _(search_node_table, "usage: search_node_table <name>...")      \
22820 _(set, "usage: set <variable-name> <value>")                    \
22821 _(script, "usage: script <file-name>")                          \
22822 _(statseg, "usage: statseg");                                   \
22823 _(unset, "usage: unset <variable-name>")
22824
22825 #define _(N,n)                                  \
22826     static void vl_api_##n##_t_handler_uni      \
22827     (vl_api_##n##_t * mp)                       \
22828     {                                           \
22829         vat_main_t * vam = &vat_main;           \
22830         if (vam->json_output) {                 \
22831             vl_api_##n##_t_handler_json(mp);    \
22832         } else {                                \
22833             vl_api_##n##_t_handler(mp);         \
22834         }                                       \
22835     }
22836 foreach_vpe_api_reply_msg;
22837 #if VPP_API_TEST_BUILTIN == 0
22838 foreach_standalone_reply_msg;
22839 #endif
22840 #undef _
22841
22842 void
22843 vat_api_hookup (vat_main_t * vam)
22844 {
22845 #define _(N,n)                                                  \
22846     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22847                            vl_api_##n##_t_handler_uni,          \
22848                            vl_noop_handler,                     \
22849                            vl_api_##n##_t_endian,               \
22850                            vl_api_##n##_t_print,                \
22851                            sizeof(vl_api_##n##_t), 1);
22852   foreach_vpe_api_reply_msg;
22853 #if VPP_API_TEST_BUILTIN == 0
22854   foreach_standalone_reply_msg;
22855 #endif
22856 #undef _
22857
22858 #if (VPP_API_TEST_BUILTIN==0)
22859   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22860
22861   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22862
22863   vam->function_by_name = hash_create_string (0, sizeof (uword));
22864
22865   vam->help_by_name = hash_create_string (0, sizeof (uword));
22866 #endif
22867
22868   /* API messages we can send */
22869 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22870   foreach_vpe_api_msg;
22871 #undef _
22872
22873   /* Help strings */
22874 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22875   foreach_vpe_api_msg;
22876 #undef _
22877
22878   /* CLI functions */
22879 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22880   foreach_cli_function;
22881 #undef _
22882
22883   /* Help strings */
22884 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22885   foreach_cli_function;
22886 #undef _
22887 }
22888
22889 #if VPP_API_TEST_BUILTIN
22890 static clib_error_t *
22891 vat_api_hookup_shim (vlib_main_t * vm)
22892 {
22893   vat_api_hookup (&vat_main);
22894   return 0;
22895 }
22896
22897 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22898 #endif
22899
22900 /*
22901  * fd.io coding-style-patch-verification: ON
22902  *
22903  * Local Variables:
22904  * eval: (c-set-style "gnu")
22905  * End:
22906  */