VPP-1649: fix coverity warning in api_format.c
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #define vl_print(handle, ...)
77 #define vl_printfun
78 #include <vpp/api/vpe_all_api_h.h>
79 #undef vl_printfun
80
81 #define __plugin_msg_base 0
82 #include <vlibapi/vat_helper_macros.h>
83
84 #if VPP_API_TEST_BUILTIN == 0
85 #include <netdb.h>
86
87 u32
88 vl (void *p)
89 {
90   return vec_len (p);
91 }
92
93 int
94 vat_socket_connect (vat_main_t * vam)
95 {
96   int rv;
97   vam->socket_client_main = &socket_client_main;
98   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
99                                       "vpp_api_test",
100                                       0 /* default socket rx, tx buffer */ )))
101     return rv;
102   /* vpp expects the client index in network order */
103   vam->my_client_index = htonl (socket_client_main.client_index);
104   return 0;
105 }
106 #else /* vpp built-in case, we don't do sockets... */
107 int
108 vat_socket_connect (vat_main_t * vam)
109 {
110   return 0;
111 }
112
113 int
114 vl_socket_client_read (int wait)
115 {
116   return -1;
117 };
118
119 int
120 vl_socket_client_write ()
121 {
122   return -1;
123 };
124
125 void *
126 vl_socket_client_msg_alloc (int nbytes)
127 {
128   return 0;
129 }
130 #endif
131
132
133 f64
134 vat_time_now (vat_main_t * vam)
135 {
136 #if VPP_API_TEST_BUILTIN
137   return vlib_time_now (vam->vlib_main);
138 #else
139   return clib_time_now (&vam->clib_time);
140 #endif
141 }
142
143 void
144 errmsg (char *fmt, ...)
145 {
146   vat_main_t *vam = &vat_main;
147   va_list va;
148   u8 *s;
149
150   va_start (va, fmt);
151   s = va_format (0, fmt, &va);
152   va_end (va);
153
154   vec_add1 (s, 0);
155
156 #if VPP_API_TEST_BUILTIN
157   vlib_cli_output (vam->vlib_main, (char *) s);
158 #else
159   {
160     if (vam->ifp != stdin)
161       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162                vam->input_line_number);
163     fformat (vam->ofp, (char *) s);
164     fflush (vam->ofp);
165   }
166 #endif
167
168   vec_free (s);
169 }
170
171 #if VPP_API_TEST_BUILTIN == 0
172 static uword
173 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
174 {
175   vat_main_t *vam = va_arg (*args, vat_main_t *);
176   u32 *result = va_arg (*args, u32 *);
177   u8 *if_name;
178   uword *p;
179
180   if (!unformat (input, "%s", &if_name))
181     return 0;
182
183   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
184   if (p == 0)
185     return 0;
186   *result = p[0];
187   return 1;
188 }
189
190 static uword
191 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
192 {
193   return 0;
194 }
195
196 /* Parse an IP4 address %d.%d.%d.%d. */
197 uword
198 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 {
200   u8 *result = va_arg (*args, u8 *);
201   unsigned a[4];
202
203   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
204     return 0;
205
206   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
207     return 0;
208
209   result[0] = a[0];
210   result[1] = a[1];
211   result[2] = a[2];
212   result[3] = a[3];
213
214   return 1;
215 }
216
217 uword
218 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 {
220   u8 *result = va_arg (*args, u8 *);
221   u32 i, a[6];
222
223   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
224                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
225     return 0;
226
227   /* Check range. */
228   for (i = 0; i < 6; i++)
229     if (a[i] >= (1 << 8))
230       return 0;
231
232   for (i = 0; i < 6; i++)
233     result[i] = a[i];
234
235   return 1;
236 }
237
238 /* Returns ethernet type as an int in host byte order. */
239 uword
240 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
241                                         va_list * args)
242 {
243   u16 *result = va_arg (*args, u16 *);
244   int type;
245
246   /* Numeric type. */
247   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248     {
249       if (type >= (1 << 16))
250         return 0;
251       *result = type;
252       return 1;
253     }
254   return 0;
255 }
256
257 /* Parse an IP6 address. */
258 uword
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 {
261   ip6_address_t *result = va_arg (*args, ip6_address_t *);
262   u16 hex_quads[8];
263   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264   uword c, n_colon, double_colon_index;
265
266   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267   double_colon_index = ARRAY_LEN (hex_quads);
268   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269     {
270       hex_digit = 16;
271       if (c >= '0' && c <= '9')
272         hex_digit = c - '0';
273       else if (c >= 'a' && c <= 'f')
274         hex_digit = c + 10 - 'a';
275       else if (c >= 'A' && c <= 'F')
276         hex_digit = c + 10 - 'A';
277       else if (c == ':' && n_colon < 2)
278         n_colon++;
279       else
280         {
281           unformat_put_input (input);
282           break;
283         }
284
285       /* Too many hex quads. */
286       if (n_hex_quads >= ARRAY_LEN (hex_quads))
287         return 0;
288
289       if (hex_digit < 16)
290         {
291           hex_quad = (hex_quad << 4) | hex_digit;
292
293           /* Hex quad must fit in 16 bits. */
294           if (n_hex_digits >= 4)
295             return 0;
296
297           n_colon = 0;
298           n_hex_digits++;
299         }
300
301       /* Save position of :: */
302       if (n_colon == 2)
303         {
304           /* More than one :: ? */
305           if (double_colon_index < ARRAY_LEN (hex_quads))
306             return 0;
307           double_colon_index = n_hex_quads;
308         }
309
310       if (n_colon > 0 && n_hex_digits > 0)
311         {
312           hex_quads[n_hex_quads++] = hex_quad;
313           hex_quad = 0;
314           n_hex_digits = 0;
315         }
316     }
317
318   if (n_hex_digits > 0)
319     hex_quads[n_hex_quads++] = hex_quad;
320
321   {
322     word i;
323
324     /* Expand :: to appropriate number of zero hex quads. */
325     if (double_colon_index < ARRAY_LEN (hex_quads))
326       {
327         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328
329         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330           hex_quads[n_zero + i] = hex_quads[i];
331
332         for (i = 0; i < n_zero; i++)
333           hex_quads[double_colon_index + i] = 0;
334
335         n_hex_quads = ARRAY_LEN (hex_quads);
336       }
337
338     /* Too few hex quads given. */
339     if (n_hex_quads < ARRAY_LEN (hex_quads))
340       return 0;
341
342     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
344
345     return 1;
346   }
347 }
348
349 uword
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 {
352   u32 *r = va_arg (*args, u32 *);
353
354   if (0);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356   foreach_ipsec_policy_action
357 #undef _
358     else
359     return 0;
360   return 1;
361 }
362
363 u8 *
364 format_ipsec_crypto_alg (u8 * s, va_list * args)
365 {
366   u32 i = va_arg (*args, u32);
367   u8 *t = 0;
368
369   switch (i)
370     {
371 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
372       foreach_ipsec_crypto_alg
373 #undef _
374     default:
375       return format (s, "unknown");
376     }
377   return format (s, "%s", t);
378 }
379
380 u8 *
381 format_ipsec_integ_alg (u8 * s, va_list * args)
382 {
383   u32 i = va_arg (*args, u32);
384   u8 *t = 0;
385
386   switch (i)
387     {
388 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
389       foreach_ipsec_integ_alg
390 #undef _
391     default:
392       return format (s, "unknown");
393     }
394   return format (s, "%s", t);
395 }
396
397 #else /* VPP_API_TEST_BUILTIN == 1 */
398 static uword
399 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
400 {
401   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
402   vnet_main_t *vnm = vnet_get_main ();
403   u32 *result = va_arg (*args, u32 *);
404
405   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
406 }
407
408 static uword
409 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
416 }
417
418 #endif /* VPP_API_TEST_BUILTIN */
419
420 uword
421 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
422 {
423   u32 *r = va_arg (*args, u32 *);
424
425   if (0);
426 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
427   foreach_ipsec_crypto_alg
428 #undef _
429     else
430     return 0;
431   return 1;
432 }
433
434 uword
435 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
436 {
437   u32 *r = va_arg (*args, u32 *);
438
439   if (0);
440 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
441   foreach_ipsec_integ_alg
442 #undef _
443     else
444     return 0;
445   return 1;
446 }
447
448 static uword
449 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
450 {
451   u8 *r = va_arg (*args, u8 *);
452
453   if (unformat (input, "kbps"))
454     *r = SSE2_QOS_RATE_KBPS;
455   else if (unformat (input, "pps"))
456     *r = SSE2_QOS_RATE_PPS;
457   else
458     return 0;
459   return 1;
460 }
461
462 static uword
463 unformat_policer_round_type (unformat_input_t * input, va_list * args)
464 {
465   u8 *r = va_arg (*args, u8 *);
466
467   if (unformat (input, "closest"))
468     *r = SSE2_QOS_ROUND_TO_CLOSEST;
469   else if (unformat (input, "up"))
470     *r = SSE2_QOS_ROUND_TO_UP;
471   else if (unformat (input, "down"))
472     *r = SSE2_QOS_ROUND_TO_DOWN;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "1r2c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R2C;
485   else if (unformat (input, "1r3c"))
486     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
487   else if (unformat (input, "2r3c-2698"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
489   else if (unformat (input, "2r3c-4115"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
491   else if (unformat (input, "2r3c-mef5cf1"))
492     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
493   else
494     return 0;
495   return 1;
496 }
497
498 static uword
499 unformat_dscp (unformat_input_t * input, va_list * va)
500 {
501   u8 *r = va_arg (*va, u8 *);
502
503   if (0);
504 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
505   foreach_vnet_dscp
506 #undef _
507     else
508     return 0;
509   return 1;
510 }
511
512 static uword
513 unformat_policer_action_type (unformat_input_t * input, va_list * va)
514 {
515   sse2_qos_pol_action_params_st *a
516     = va_arg (*va, sse2_qos_pol_action_params_st *);
517
518   if (unformat (input, "drop"))
519     a->action_type = SSE2_QOS_ACTION_DROP;
520   else if (unformat (input, "transmit"))
521     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
522   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
523     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
524   else
525     return 0;
526   return 1;
527 }
528
529 static uword
530 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
531 {
532   u32 *r = va_arg (*va, u32 *);
533   u32 tid;
534
535   if (unformat (input, "ip4"))
536     tid = POLICER_CLASSIFY_TABLE_IP4;
537   else if (unformat (input, "ip6"))
538     tid = POLICER_CLASSIFY_TABLE_IP6;
539   else if (unformat (input, "l2"))
540     tid = POLICER_CLASSIFY_TABLE_L2;
541   else
542     return 0;
543
544   *r = tid;
545   return 1;
546 }
547
548 static uword
549 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
550 {
551   u32 *r = va_arg (*va, u32 *);
552   u32 tid;
553
554   if (unformat (input, "ip4"))
555     tid = FLOW_CLASSIFY_TABLE_IP4;
556   else if (unformat (input, "ip6"))
557     tid = FLOW_CLASSIFY_TABLE_IP6;
558   else
559     return 0;
560
561   *r = tid;
562   return 1;
563 }
564
565 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
566 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
567 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
568 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
569
570 #if (VPP_API_TEST_BUILTIN==0)
571 uword
572 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
573 {
574   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
575   mfib_itf_attribute_t attr;
576
577   old = *iflags;
578   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
579   {
580     if (unformat (input, mfib_itf_flag_long_names[attr]))
581       *iflags |= (1 << attr);
582   }
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_names[attr]))
586       *iflags |= (1 << attr);
587   }
588
589   return (old == *iflags ? 0 : 1);
590 }
591
592 uword
593 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
594 {
595   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
596   mfib_entry_attribute_t attr;
597
598   old = *eflags;
599   FOR_EACH_MFIB_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_flag_long_names[attr]))
602       *eflags |= (1 << attr);
603   }
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_names[attr]))
607       *eflags |= (1 << attr);
608   }
609
610   return (old == *eflags ? 0 : 1);
611 }
612
613 u8 *
614 format_ip4_address (u8 * s, va_list * args)
615 {
616   u8 *a = va_arg (*args, u8 *);
617   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
618 }
619
620 u8 *
621 format_ip6_address (u8 * s, va_list * args)
622 {
623   ip6_address_t *a = va_arg (*args, ip6_address_t *);
624   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
625
626   i_max_n_zero = ARRAY_LEN (a->as_u16);
627   max_n_zeros = 0;
628   i_first_zero = i_max_n_zero;
629   n_zeros = 0;
630   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
631     {
632       u32 is_zero = a->as_u16[i] == 0;
633       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
634         {
635           i_first_zero = i;
636           n_zeros = 0;
637         }
638       n_zeros += is_zero;
639       if ((!is_zero && n_zeros > max_n_zeros)
640           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
641         {
642           i_max_n_zero = i_first_zero;
643           max_n_zeros = n_zeros;
644           i_first_zero = ARRAY_LEN (a->as_u16);
645           n_zeros = 0;
646         }
647     }
648
649   last_double_colon = 0;
650   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
651     {
652       if (i == i_max_n_zero && max_n_zeros > 1)
653         {
654           s = format (s, "::");
655           i += max_n_zeros - 1;
656           last_double_colon = 1;
657         }
658       else
659         {
660           s = format (s, "%s%x",
661                       (last_double_colon || i == 0) ? "" : ":",
662                       clib_net_to_host_u16 (a->as_u16[i]));
663           last_double_colon = 0;
664         }
665     }
666
667   return s;
668 }
669
670 /* Format an IP46 address. */
671 u8 *
672 format_ip46_address (u8 * s, va_list * args)
673 {
674   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
675   ip46_type_t type = va_arg (*args, ip46_type_t);
676   int is_ip4 = 1;
677
678   switch (type)
679     {
680     case IP46_TYPE_ANY:
681       is_ip4 = ip46_address_is_ip4 (ip46);
682       break;
683     case IP46_TYPE_IP4:
684       is_ip4 = 1;
685       break;
686     case IP46_TYPE_IP6:
687       is_ip4 = 0;
688       break;
689     }
690
691   return is_ip4 ?
692     format (s, "%U", format_ip4_address, &ip46->ip4) :
693     format (s, "%U", format_ip6_address, &ip46->ip6);
694 }
695
696 u8 *
697 format_ethernet_address (u8 * s, va_list * args)
698 {
699   u8 *a = va_arg (*args, u8 *);
700
701   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
702                  a[0], a[1], a[2], a[3], a[4], a[5]);
703 }
704 #endif
705
706 static void
707 increment_v4_address (ip4_address_t * a)
708 {
709   u32 v;
710
711   v = ntohl (a->as_u32) + 1;
712   a->as_u32 = ntohl (v);
713 }
714
715 static void
716 increment_vl_v4_address (vl_api_ip4_address_t * a)
717 {
718   u32 v;
719
720   v = *(u32 *) a;
721   v = ntohl (v);
722   v++;
723   v = ntohl (v);
724   clib_memcpy (a, &v, sizeof (v));
725 }
726
727 static void
728 increment_vl_address (vl_api_address_t * a)
729 {
730   if (ADDRESS_IP4 == a->af)
731     increment_vl_v4_address (&a->un.ip4);
732 }
733
734 static void
735 increment_v6_address (ip6_address_t * a)
736 {
737   u64 v0, v1;
738
739   v0 = clib_net_to_host_u64 (a->as_u64[0]);
740   v1 = clib_net_to_host_u64 (a->as_u64[1]);
741
742   v1 += 1;
743   if (v1 == 0)
744     v0 += 1;
745   a->as_u64[0] = clib_net_to_host_u64 (v0);
746   a->as_u64[1] = clib_net_to_host_u64 (v1);
747 }
748
749 static void
750 increment_mac_address (u8 * mac)
751 {
752   u64 tmp = *((u64 *) mac);
753   tmp = clib_net_to_host_u64 (tmp);
754   tmp += 1 << 16;               /* skip unused (least significant) octets */
755   tmp = clib_host_to_net_u64 (tmp);
756
757   clib_memcpy (mac, &tmp, 6);
758 }
759
760 static void vl_api_create_loopback_reply_t_handler
761   (vl_api_create_loopback_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_reply_t_handler_json
773   (vl_api_create_loopback_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_create_loopback_instance_reply_t_handler
789   (vl_api_create_loopback_instance_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_create_loopback_instance_reply_t_handler_json
801   (vl_api_create_loopback_instance_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_af_packet_create_reply_t_handler
817   (vl_api_af_packet_create_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_af_packet_create_reply_t_handler_json
829   (vl_api_af_packet_create_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_vlan_subif_reply_t_handler
846   (vl_api_create_vlan_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_vlan_subif_reply_t_handler_json
858   (vl_api_create_vlan_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_subif_reply_t_handler
875   (vl_api_create_subif_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->sw_if_index = ntohl (mp->sw_if_index);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_subif_reply_t_handler_json
887   (vl_api_create_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
895
896   vat_json_print (vam->ofp, &node);
897   vat_json_free (&node);
898
899   vam->retval = ntohl (mp->retval);
900   vam->result_ready = 1;
901 }
902
903 static void vl_api_interface_name_renumber_reply_t_handler
904   (vl_api_interface_name_renumber_reply_t * mp)
905 {
906   vat_main_t *vam = &vat_main;
907   i32 retval = ntohl (mp->retval);
908
909   vam->retval = retval;
910   vam->regenerate_interface_table = 1;
911   vam->result_ready = 1;
912 }
913
914 static void vl_api_interface_name_renumber_reply_t_handler_json
915   (vl_api_interface_name_renumber_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   vat_json_node_t node;
919
920   vat_json_init_object (&node);
921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
922
923   vat_json_print (vam->ofp, &node);
924   vat_json_free (&node);
925
926   vam->retval = ntohl (mp->retval);
927   vam->result_ready = 1;
928 }
929
930 /*
931  * Special-case: build the interface table, maintain
932  * the next loopback sw_if_index vbl.
933  */
934 static void vl_api_sw_interface_details_t_handler
935   (vl_api_sw_interface_details_t * mp)
936 {
937   vat_main_t *vam = &vat_main;
938   u8 *s = format (0, "%s%c", mp->interface_name, 0);
939
940   hash_set_mem (vam->sw_if_index_by_interface_name, s,
941                 ntohl (mp->sw_if_index));
942
943   /* In sub interface case, fill the sub interface table entry */
944   if (mp->sw_if_index != mp->sup_sw_if_index)
945     {
946       sw_interface_subif_t *sub = NULL;
947
948       vec_add2 (vam->sw_if_subif_table, sub, 1);
949
950       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
951       strncpy ((char *) sub->interface_name, (char *) s,
952                vec_len (sub->interface_name));
953       sub->sw_if_index = ntohl (mp->sw_if_index);
954       sub->sub_id = ntohl (mp->sub_id);
955
956       sub->sub_dot1ad = mp->sub_dot1ad;
957       sub->sub_number_of_tags = mp->sub_number_of_tags;
958       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
959       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
960       sub->sub_exact_match = mp->sub_exact_match;
961       sub->sub_default = mp->sub_default;
962       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
963       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
964
965       /* vlan tag rewrite */
966       sub->vtr_op = ntohl (mp->vtr_op);
967       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
968       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
969       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
970     }
971 }
972
973 static void vl_api_sw_interface_details_t_handler_json
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   vat_json_node_t *node = NULL;
978
979   if (VAT_JSON_ARRAY != vam->json_tree.type)
980     {
981       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
982       vat_json_init_array (&vam->json_tree);
983     }
984   node = vat_json_array_add (&vam->json_tree);
985
986   vat_json_init_object (node);
987   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
988   vat_json_object_add_uint (node, "sup_sw_if_index",
989                             ntohl (mp->sup_sw_if_index));
990   vat_json_object_add_uint (node, "l2_address_length",
991                             ntohl (mp->l2_address_length));
992   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
993                              sizeof (mp->l2_address));
994   vat_json_object_add_string_copy (node, "interface_name",
995                                    mp->interface_name);
996   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
997   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
998   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
999   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1000   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1001   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1002   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1003   vat_json_object_add_uint (node, "sub_number_of_tags",
1004                             mp->sub_number_of_tags);
1005   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1006                             ntohs (mp->sub_outer_vlan_id));
1007   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1008                             ntohs (mp->sub_inner_vlan_id));
1009   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1010   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1012                             mp->sub_outer_vlan_id_any);
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1014                             mp->sub_inner_vlan_id_any);
1015   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1016   vat_json_object_add_uint (node, "vtr_push_dot1q",
1017                             ntohl (mp->vtr_push_dot1q));
1018   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1019   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1020   if (mp->sub_dot1ah)
1021     {
1022       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1023                                        format (0, "%U",
1024                                                format_ethernet_address,
1025                                                &mp->b_dmac));
1026       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1027                                        format (0, "%U",
1028                                                format_ethernet_address,
1029                                                &mp->b_smac));
1030       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1031       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1032     }
1033 }
1034
1035 #if VPP_API_TEST_BUILTIN == 0
1036 static void vl_api_sw_interface_event_t_handler
1037   (vl_api_sw_interface_event_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   if (vam->interface_event_display)
1041     errmsg ("interface flags: sw_if_index %d %s %s",
1042             ntohl (mp->sw_if_index),
1043             mp->admin_up_down ? "admin-up" : "admin-down",
1044             mp->link_up_down ? "link-up" : "link-down");
1045 }
1046 #endif
1047
1048 static void vl_api_sw_interface_event_t_handler_json
1049   (vl_api_sw_interface_event_t * mp)
1050 {
1051   /* JSON output not supported */
1052 }
1053
1054 static void
1055 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059
1060   vam->retval = retval;
1061   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vam->result_ready = 1;
1063 }
1064
1065 static void
1066 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070   api_main_t *am = &api_main;
1071   void *oldheap;
1072   u8 *reply;
1073
1074   vat_json_init_object (&node);
1075   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1076   vat_json_object_add_uint (&node, "reply_in_shmem",
1077                             ntohl (mp->reply_in_shmem));
1078   /* Toss the shared-memory original... */
1079   pthread_mutex_lock (&am->vlib_rp->mutex);
1080   oldheap = svm_push_data_heap (am->vlib_rp);
1081
1082   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1083   vec_free (reply);
1084
1085   svm_pop_heap (oldheap);
1086   pthread_mutex_unlock (&am->vlib_rp->mutex);
1087
1088   vat_json_print (vam->ofp, &node);
1089   vat_json_free (&node);
1090
1091   vam->retval = ntohl (mp->retval);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   i32 retval = ntohl (mp->retval);
1100   u32 length = vl_api_string_len (&mp->reply);
1101
1102   vec_reset_length (vam->cmd_reply);
1103
1104   vam->retval = retval;
1105   if (retval == 0)
1106     {
1107       vec_validate (vam->cmd_reply, length);
1108       clib_memcpy ((char *) (vam->cmd_reply),
1109                    vl_api_from_api_string (&mp->reply), length);
1110       vam->cmd_reply[length] = 0;
1111     }
1112   vam->result_ready = 1;
1113 }
1114
1115 static void
1116 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1117 {
1118   vat_main_t *vam = &vat_main;
1119   vat_json_node_t node;
1120
1121   vec_reset_length (vam->cmd_reply);
1122
1123   vat_json_init_object (&node);
1124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1125   vat_json_object_add_string_copy (&node, "reply",
1126                                    vl_api_from_api_string (&mp->reply));
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void vl_api_classify_add_del_table_reply_t_handler
1136   (vl_api_classify_add_del_table_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   i32 retval = ntohl (mp->retval);
1140   if (vam->async_mode)
1141     {
1142       vam->async_errors += (retval < 0);
1143     }
1144   else
1145     {
1146       vam->retval = retval;
1147       if (retval == 0 &&
1148           ((mp->new_table_index != 0xFFFFFFFF) ||
1149            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1150            (mp->match_n_vectors != 0xFFFFFFFF)))
1151         /*
1152          * Note: this is just barely thread-safe, depends on
1153          * the main thread spinning waiting for an answer...
1154          */
1155         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1156                 ntohl (mp->new_table_index),
1157                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1158       vam->result_ready = 1;
1159     }
1160 }
1161
1162 static void vl_api_classify_add_del_table_reply_t_handler_json
1163   (vl_api_classify_add_del_table_reply_t * mp)
1164 {
1165   vat_main_t *vam = &vat_main;
1166   vat_json_node_t node;
1167
1168   vat_json_init_object (&node);
1169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1170   vat_json_object_add_uint (&node, "new_table_index",
1171                             ntohl (mp->new_table_index));
1172   vat_json_object_add_uint (&node, "skip_n_vectors",
1173                             ntohl (mp->skip_n_vectors));
1174   vat_json_object_add_uint (&node, "match_n_vectors",
1175                             ntohl (mp->match_n_vectors));
1176
1177   vat_json_print (vam->ofp, &node);
1178   vat_json_free (&node);
1179
1180   vam->retval = ntohl (mp->retval);
1181   vam->result_ready = 1;
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   i32 retval = ntohl (mp->retval);
1189   if (vam->async_mode)
1190     {
1191       vam->async_errors += (retval < 0);
1192     }
1193   else
1194     {
1195       vam->retval = retval;
1196       if (retval == 0)
1197         errmsg ("node index %d", ntohl (mp->node_index));
1198       vam->result_ready = 1;
1199     }
1200 }
1201
1202 static void vl_api_get_node_index_reply_t_handler_json
1203   (vl_api_get_node_index_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   vat_json_node_t node;
1207
1208   vat_json_init_object (&node);
1209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1210   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1211
1212   vat_json_print (vam->ofp, &node);
1213   vat_json_free (&node);
1214
1215   vam->retval = ntohl (mp->retval);
1216   vam->result_ready = 1;
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   i32 retval = ntohl (mp->retval);
1224   if (vam->async_mode)
1225     {
1226       vam->async_errors += (retval < 0);
1227     }
1228   else
1229     {
1230       vam->retval = retval;
1231       if (retval == 0)
1232         errmsg ("next node index %d", ntohl (mp->next_index));
1233       vam->result_ready = 1;
1234     }
1235 }
1236
1237 static void vl_api_get_next_index_reply_t_handler_json
1238   (vl_api_get_next_index_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   vat_json_node_t node;
1242
1243   vat_json_init_object (&node);
1244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1245   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   i32 retval = ntohl (mp->retval);
1259   if (vam->async_mode)
1260     {
1261       vam->async_errors += (retval < 0);
1262     }
1263   else
1264     {
1265       vam->retval = retval;
1266       if (retval == 0)
1267         errmsg ("next index %d", ntohl (mp->next_index));
1268       vam->result_ready = 1;
1269     }
1270 }
1271
1272 static void vl_api_add_node_next_reply_t_handler_json
1273   (vl_api_add_node_next_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   vat_json_node_t node;
1277
1278   vat_json_init_object (&node);
1279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1280   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1281
1282   vat_json_print (vam->ofp, &node);
1283   vat_json_free (&node);
1284
1285   vam->retval = ntohl (mp->retval);
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_show_version_reply_t_handler
1290   (vl_api_show_version_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (retval >= 0)
1296     {
1297       char *s;
1298       char *p = (char *) &mp->program;
1299
1300       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1301       errmsg ("        program: %s\n", s);
1302       free (s);
1303
1304       p +=
1305         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        version: %s\n", s);
1308       free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1313       errmsg ("     build date: %s\n", s);
1314       free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1319       errmsg ("build directory: %s\n", s);
1320       free (s);
1321     }
1322   vam->retval = retval;
1323   vam->result_ready = 1;
1324 }
1325
1326 static void vl_api_show_version_reply_t_handler_json
1327   (vl_api_show_version_reply_t * mp)
1328 {
1329   vat_main_t *vam = &vat_main;
1330   vat_json_node_t node;
1331
1332   vat_json_init_object (&node);
1333   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1334   char *p = (char *) &mp->program;
1335   vat_json_object_add_string_copy (&node, "program",
1336                                    vl_api_from_api_string ((vl_api_string_t *)
1337                                                            p));
1338   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1339   vat_json_object_add_string_copy (&node, "version",
1340                                    vl_api_from_api_string ((vl_api_string_t *)
1341                                                            p));
1342   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1343   vat_json_object_add_string_copy (&node, "build_date",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    vl_api_from_api_string ((vl_api_string_t *)
1349                                                            p));
1350
1351   vat_json_print (vam->ofp, &node);
1352   vat_json_free (&node);
1353
1354   vam->retval = ntohl (mp->retval);
1355   vam->result_ready = 1;
1356 }
1357
1358 static void vl_api_show_threads_reply_t_handler
1359   (vl_api_show_threads_reply_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   i32 retval = ntohl (mp->retval);
1363   int i, count = 0;
1364
1365   if (retval >= 0)
1366     count = ntohl (mp->count);
1367
1368   for (i = 0; i < count; i++)
1369     print (vam->ofp,
1370            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1371            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1372            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1373            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1374            ntohl (mp->thread_data[i].cpu_socket));
1375
1376   vam->retval = retval;
1377   vam->result_ready = 1;
1378 }
1379
1380 static void vl_api_show_threads_reply_t_handler_json
1381   (vl_api_show_threads_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   vat_json_node_t node;
1385   vl_api_thread_data_t *td;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", retval);
1394   vat_json_object_add_uint (&node, "count", count);
1395
1396   for (i = 0; i < count; i++)
1397     {
1398       td = &mp->thread_data[i];
1399       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1400       vat_json_object_add_string_copy (&node, "name", td->name);
1401       vat_json_object_add_string_copy (&node, "type", td->type);
1402       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1403       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1404       vat_json_object_add_int (&node, "core", ntohl (td->id));
1405       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1406     }
1407
1408   vat_json_print (vam->ofp, &node);
1409   vat_json_free (&node);
1410
1411   vam->retval = retval;
1412   vam->result_ready = 1;
1413 }
1414
1415 static int
1416 api_show_threads (vat_main_t * vam)
1417 {
1418   vl_api_show_threads_t *mp;
1419   int ret;
1420
1421   print (vam->ofp,
1422          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1423          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1424
1425   M (SHOW_THREADS, mp);
1426
1427   S (mp);
1428   W (ret);
1429   return ret;
1430 }
1431
1432 static void
1433 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1434 {
1435   u32 sw_if_index = ntohl (mp->sw_if_index);
1436   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1437           mp->mac_ip ? "mac/ip binding" : "address resolution",
1438           ntohl (mp->pid), format_ip4_address, mp->ip,
1439           format_vl_api_mac_address, &mp->mac, sw_if_index);
1440 }
1441
1442 static void
1443 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1444 {
1445   /* JSON output not supported */
1446 }
1447
1448 static void
1449 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1450 {
1451   u32 sw_if_index = ntohl (mp->sw_if_index);
1452   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1453           mp->mac_ip ? "mac/ip binding" : "address resolution",
1454           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1455           format_vl_api_mac_address, mp->mac, sw_if_index);
1456 }
1457
1458 static void
1459 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1460 {
1461   /* JSON output not supported */
1462 }
1463
1464 static void
1465 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1466 {
1467   u32 n_macs = ntohl (mp->n_macs);
1468   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1469           ntohl (mp->pid), mp->client_index, n_macs);
1470   int i;
1471   for (i = 0; i < n_macs; i++)
1472     {
1473       vl_api_mac_entry_t *mac = &mp->mac[i];
1474       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1475               i + 1, ntohl (mac->sw_if_index),
1476               format_ethernet_address, mac->mac_addr, mac->action);
1477       if (i == 1000)
1478         break;
1479     }
1480 }
1481
1482 static void
1483 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1484 {
1485   /* JSON output not supported */
1486 }
1487
1488 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1489 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1490
1491 /*
1492  * Special-case: build the bridge domain table, maintain
1493  * the next bd id vbl.
1494  */
1495 static void vl_api_bridge_domain_details_t_handler
1496   (vl_api_bridge_domain_details_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1500   int i;
1501
1502   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1503          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1504
1505   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1506          ntohl (mp->bd_id), mp->learn, mp->forward,
1507          mp->flood, ntohl (mp->bvi_sw_if_index),
1508          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1509
1510   if (n_sw_ifs)
1511     {
1512       vl_api_bridge_domain_sw_if_t *sw_ifs;
1513       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1514              "Interface Name");
1515
1516       sw_ifs = mp->sw_if_details;
1517       for (i = 0; i < n_sw_ifs; i++)
1518         {
1519           u8 *sw_if_name = 0;
1520           u32 sw_if_index;
1521           hash_pair_t *p;
1522
1523           sw_if_index = ntohl (sw_ifs->sw_if_index);
1524
1525           /* *INDENT-OFF* */
1526           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1527                              ({
1528                                if ((u32) p->value[0] == sw_if_index)
1529                                  {
1530                                    sw_if_name = (u8 *)(p->key);
1531                                    break;
1532                                  }
1533                              }));
1534           /* *INDENT-ON* */
1535           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1536                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1537                  "sw_if_index not found!");
1538
1539           sw_ifs++;
1540         }
1541     }
1542 }
1543
1544 static void vl_api_bridge_domain_details_t_handler_json
1545   (vl_api_bridge_domain_details_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t *node, *array = NULL;
1549   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1550
1551   if (VAT_JSON_ARRAY != vam->json_tree.type)
1552     {
1553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1554       vat_json_init_array (&vam->json_tree);
1555     }
1556   node = vat_json_array_add (&vam->json_tree);
1557
1558   vat_json_init_object (node);
1559   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1560   vat_json_object_add_uint (node, "flood", mp->flood);
1561   vat_json_object_add_uint (node, "forward", mp->forward);
1562   vat_json_object_add_uint (node, "learn", mp->learn);
1563   vat_json_object_add_uint (node, "bvi_sw_if_index",
1564                             ntohl (mp->bvi_sw_if_index));
1565   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1566   array = vat_json_object_add (node, "sw_if");
1567   vat_json_init_array (array);
1568
1569
1570
1571   if (n_sw_ifs)
1572     {
1573       vl_api_bridge_domain_sw_if_t *sw_ifs;
1574       int i;
1575
1576       sw_ifs = mp->sw_if_details;
1577       for (i = 0; i < n_sw_ifs; i++)
1578         {
1579           node = vat_json_array_add (array);
1580           vat_json_init_object (node);
1581           vat_json_object_add_uint (node, "sw_if_index",
1582                                     ntohl (sw_ifs->sw_if_index));
1583           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1584           sw_ifs++;
1585         }
1586     }
1587 }
1588
1589 static void vl_api_control_ping_reply_t_handler
1590   (vl_api_control_ping_reply_t * mp)
1591 {
1592   vat_main_t *vam = &vat_main;
1593   i32 retval = ntohl (mp->retval);
1594   if (vam->async_mode)
1595     {
1596       vam->async_errors += (retval < 0);
1597     }
1598   else
1599     {
1600       vam->retval = retval;
1601       vam->result_ready = 1;
1602     }
1603   if (vam->socket_client_main)
1604     vam->socket_client_main->control_pings_outstanding--;
1605 }
1606
1607 static void vl_api_control_ping_reply_t_handler_json
1608   (vl_api_control_ping_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612
1613   if (VAT_JSON_NONE != vam->json_tree.type)
1614     {
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vat_json_free (&vam->json_tree);
1617       vam->json_tree.type = VAT_JSON_NONE;
1618     }
1619   else
1620     {
1621       /* just print [] */
1622       vat_json_init_array (&vam->json_tree);
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vam->json_tree.type = VAT_JSON_NONE;
1625     }
1626
1627   vam->retval = retval;
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632   vl_api_bridge_domain_set_mac_age_reply_t_handler
1633   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1649   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2_flags_reply_t_handler_json
1681   (vl_api_l2_flags_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1689                             ntohl (mp->resulting_feature_bitmap));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_bridge_flags_reply_t_handler
1699   (vl_api_bridge_flags_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_bridge_flags_reply_t_handler_json
1715   (vl_api_bridge_flags_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1723                             ntohl (mp->resulting_feature_bitmap));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732 static void
1733 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747
1748 }
1749
1750 static void vl_api_tap_create_v2_reply_t_handler_json
1751   (vl_api_tap_create_v2_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765
1766 }
1767
1768 static void
1769 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->result_ready = 1;
1781     }
1782 }
1783
1784 static void vl_api_tap_delete_v2_reply_t_handler_json
1785   (vl_api_tap_delete_v2_reply_t * mp)
1786 {
1787   vat_main_t *vam = &vat_main;
1788   vat_json_node_t node;
1789
1790   vat_json_init_object (&node);
1791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void
1801 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1802                                           mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   i32 retval = ntohl (mp->retval);
1806   if (vam->async_mode)
1807     {
1808       vam->async_errors += (retval < 0);
1809     }
1810   else
1811     {
1812       vam->retval = retval;
1813       vam->sw_if_index = ntohl (mp->sw_if_index);
1814       vam->result_ready = 1;
1815     }
1816 }
1817
1818 static void vl_api_virtio_pci_create_reply_t_handler_json
1819   (vl_api_virtio_pci_create_reply_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   vat_json_node_t node;
1823
1824   vat_json_init_object (&node);
1825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1826   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1827
1828   vat_json_print (vam->ofp, &node);
1829   vat_json_free (&node);
1830
1831   vam->retval = ntohl (mp->retval);
1832   vam->result_ready = 1;
1833
1834 }
1835
1836 static void
1837 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1838                                           mp)
1839 {
1840   vat_main_t *vam = &vat_main;
1841   i32 retval = ntohl (mp->retval);
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->result_ready = 1;
1850     }
1851 }
1852
1853 static void vl_api_virtio_pci_delete_reply_t_handler_json
1854   (vl_api_virtio_pci_delete_reply_t * mp)
1855 {
1856   vat_main_t *vam = &vat_main;
1857   vat_json_node_t node;
1858
1859   vat_json_init_object (&node);
1860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1861
1862   vat_json_print (vam->ofp, &node);
1863   vat_json_free (&node);
1864
1865   vam->retval = ntohl (mp->retval);
1866   vam->result_ready = 1;
1867 }
1868
1869 static void
1870 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1871 {
1872   vat_main_t *vam = &vat_main;
1873   i32 retval = ntohl (mp->retval);
1874
1875   if (vam->async_mode)
1876     {
1877       vam->async_errors += (retval < 0);
1878     }
1879   else
1880     {
1881       vam->retval = retval;
1882       vam->sw_if_index = ntohl (mp->sw_if_index);
1883       vam->result_ready = 1;
1884     }
1885 }
1886
1887 static void vl_api_bond_create_reply_t_handler_json
1888   (vl_api_bond_create_reply_t * mp)
1889 {
1890   vat_main_t *vam = &vat_main;
1891   vat_json_node_t node;
1892
1893   vat_json_init_object (&node);
1894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1895   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_delete_reply_t_handler_json
1922   (vl_api_bond_delete_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1939 {
1940   vat_main_t *vam = &vat_main;
1941   i32 retval = ntohl (mp->retval);
1942
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_bond_enslave_reply_t_handler_json
1955   (vl_api_bond_enslave_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962
1963   vat_json_print (vam->ofp, &node);
1964   vat_json_free (&node);
1965
1966   vam->retval = ntohl (mp->retval);
1967   vam->result_ready = 1;
1968 }
1969
1970 static void
1971 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1972                                           mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976
1977   if (vam->async_mode)
1978     {
1979       vam->async_errors += (retval < 0);
1980     }
1981   else
1982     {
1983       vam->retval = retval;
1984       vam->result_ready = 1;
1985     }
1986 }
1987
1988 static void vl_api_bond_detach_slave_reply_t_handler_json
1989   (vl_api_bond_detach_slave_reply_t * mp)
1990 {
1991   vat_main_t *vam = &vat_main;
1992   vat_json_node_t node;
1993
1994   vat_json_init_object (&node);
1995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1996
1997   vat_json_print (vam->ofp, &node);
1998   vat_json_free (&node);
1999
2000   vam->retval = ntohl (mp->retval);
2001   vam->result_ready = 1;
2002 }
2003
2004 static void vl_api_sw_interface_bond_details_t_handler
2005   (vl_api_sw_interface_bond_details_t * mp)
2006 {
2007   vat_main_t *vam = &vat_main;
2008
2009   print (vam->ofp,
2010          "%-16s %-12d %-12U %-13U %-14u %-14u",
2011          mp->interface_name, ntohl (mp->sw_if_index),
2012          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2013          ntohl (mp->active_slaves), ntohl (mp->slaves));
2014 }
2015
2016 static void vl_api_sw_interface_bond_details_t_handler_json
2017   (vl_api_sw_interface_bond_details_t * mp)
2018 {
2019   vat_main_t *vam = &vat_main;
2020   vat_json_node_t *node = NULL;
2021
2022   if (VAT_JSON_ARRAY != vam->json_tree.type)
2023     {
2024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2025       vat_json_init_array (&vam->json_tree);
2026     }
2027   node = vat_json_array_add (&vam->json_tree);
2028
2029   vat_json_init_object (node);
2030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2031   vat_json_object_add_string_copy (node, "interface_name",
2032                                    mp->interface_name);
2033   vat_json_object_add_uint (node, "mode", mp->mode);
2034   vat_json_object_add_uint (node, "load_balance", mp->lb);
2035   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2036   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2037 }
2038
2039 static int
2040 api_sw_interface_bond_dump (vat_main_t * vam)
2041 {
2042   vl_api_sw_interface_bond_dump_t *mp;
2043   vl_api_control_ping_t *mp_ping;
2044   int ret;
2045
2046   print (vam->ofp,
2047          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2048          "interface name", "sw_if_index", "mode", "load balance",
2049          "active slaves", "slaves");
2050
2051   /* Get list of bond interfaces */
2052   M (SW_INTERFACE_BOND_DUMP, mp);
2053   S (mp);
2054
2055   /* Use a control ping for synchronization */
2056   MPING (CONTROL_PING, mp_ping);
2057   S (mp_ping);
2058
2059   W (ret);
2060   return ret;
2061 }
2062
2063 static void vl_api_sw_interface_slave_details_t_handler
2064   (vl_api_sw_interface_slave_details_t * mp)
2065 {
2066   vat_main_t *vam = &vat_main;
2067
2068   print (vam->ofp,
2069          "%-25s %-12d %-12d %d", mp->interface_name,
2070          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler_json
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077   vat_json_node_t *node = NULL;
2078
2079   if (VAT_JSON_ARRAY != vam->json_tree.type)
2080     {
2081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2082       vat_json_init_array (&vam->json_tree);
2083     }
2084   node = vat_json_array_add (&vam->json_tree);
2085
2086   vat_json_init_object (node);
2087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2088   vat_json_object_add_string_copy (node, "interface_name",
2089                                    mp->interface_name);
2090   vat_json_object_add_uint (node, "passive", mp->is_passive);
2091   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2092 }
2093
2094 static int
2095 api_sw_interface_slave_dump (vat_main_t * vam)
2096 {
2097   unformat_input_t *i = vam->input;
2098   vl_api_sw_interface_slave_dump_t *mp;
2099   vl_api_control_ping_t *mp_ping;
2100   u32 sw_if_index = ~0;
2101   u8 sw_if_index_set = 0;
2102   int ret;
2103
2104   /* Parse args required to build the message */
2105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2106     {
2107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2108         sw_if_index_set = 1;
2109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2110         sw_if_index_set = 1;
2111       else
2112         break;
2113     }
2114
2115   if (sw_if_index_set == 0)
2116     {
2117       errmsg ("missing vpp interface name. ");
2118       return -99;
2119     }
2120
2121   print (vam->ofp,
2122          "\n%-25s %-12s %-12s %s",
2123          "slave interface name", "sw_if_index", "passive", "long_timeout");
2124
2125   /* Get list of bond interfaces */
2126   M (SW_INTERFACE_SLAVE_DUMP, mp);
2127   mp->sw_if_index = ntohl (sw_if_index);
2128   S (mp);
2129
2130   /* Use a control ping for synchronization */
2131   MPING (CONTROL_PING, mp_ping);
2132   S (mp_ping);
2133
2134   W (ret);
2135   return ret;
2136 }
2137
2138 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2139   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2140 {
2141   vat_main_t *vam = &vat_main;
2142   i32 retval = ntohl (mp->retval);
2143   if (vam->async_mode)
2144     {
2145       vam->async_errors += (retval < 0);
2146     }
2147   else
2148     {
2149       vam->retval = retval;
2150       vam->sw_if_index = ntohl (mp->sw_if_index);
2151       vam->result_ready = 1;
2152     }
2153   vam->regenerate_interface_table = 1;
2154 }
2155
2156 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2157   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2158 {
2159   vat_main_t *vam = &vat_main;
2160   vat_json_node_t node;
2161
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2165                             ntohl (mp->sw_if_index));
2166
2167   vat_json_print (vam->ofp, &node);
2168   vat_json_free (&node);
2169
2170   vam->retval = ntohl (mp->retval);
2171   vam->result_ready = 1;
2172 }
2173
2174 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2175   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   i32 retval = ntohl (mp->retval);
2179   if (vam->async_mode)
2180     {
2181       vam->async_errors += (retval < 0);
2182     }
2183   else
2184     {
2185       vam->retval = retval;
2186       vam->sw_if_index = ntohl (mp->sw_if_index);
2187       vam->result_ready = 1;
2188     }
2189 }
2190
2191 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2192   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2193 {
2194   vat_main_t *vam = &vat_main;
2195   vat_json_node_t node;
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2200
2201   vat_json_print (vam->ofp, &node);
2202   vat_json_free (&node);
2203
2204   vam->retval = ntohl (mp->retval);
2205   vam->result_ready = 1;
2206 }
2207
2208 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2209   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   i32 retval = ntohl (mp->retval);
2213   if (vam->async_mode)
2214     {
2215       vam->async_errors += (retval < 0);
2216     }
2217   else
2218     {
2219       vam->retval = retval;
2220       vam->result_ready = 1;
2221     }
2222 }
2223
2224 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2225   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2226 {
2227   vat_main_t *vam = &vat_main;
2228   vat_json_node_t node;
2229
2230   vat_json_init_object (&node);
2231   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2232   vat_json_object_add_uint (&node, "fwd_entry_index",
2233                             clib_net_to_host_u32 (mp->fwd_entry_index));
2234
2235   vat_json_print (vam->ofp, &node);
2236   vat_json_free (&node);
2237
2238   vam->retval = ntohl (mp->retval);
2239   vam->result_ready = 1;
2240 }
2241
2242 u8 *
2243 format_lisp_transport_protocol (u8 * s, va_list * args)
2244 {
2245   u32 proto = va_arg (*args, u32);
2246
2247   switch (proto)
2248     {
2249     case 1:
2250       return format (s, "udp");
2251     case 2:
2252       return format (s, "api");
2253     default:
2254       return 0;
2255     }
2256   return 0;
2257 }
2258
2259 static void vl_api_one_get_transport_protocol_reply_t_handler
2260   (vl_api_one_get_transport_protocol_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   i32 retval = ntohl (mp->retval);
2264   if (vam->async_mode)
2265     {
2266       vam->async_errors += (retval < 0);
2267     }
2268   else
2269     {
2270       u32 proto = mp->protocol;
2271       print (vam->ofp, "Transport protocol: %U",
2272              format_lisp_transport_protocol, proto);
2273       vam->retval = retval;
2274       vam->result_ready = 1;
2275     }
2276 }
2277
2278 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2279   (vl_api_one_get_transport_protocol_reply_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   vat_json_node_t node;
2283   u8 *s;
2284
2285   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2286   vec_add1 (s, 0);
2287
2288   vat_json_init_object (&node);
2289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2290   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2291
2292   vec_free (s);
2293   vat_json_print (vam->ofp, &node);
2294   vat_json_free (&node);
2295
2296   vam->retval = ntohl (mp->retval);
2297   vam->result_ready = 1;
2298 }
2299
2300 static void vl_api_one_add_del_locator_set_reply_t_handler
2301   (vl_api_one_add_del_locator_set_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       vam->retval = retval;
2312       vam->result_ready = 1;
2313     }
2314 }
2315
2316 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2317   (vl_api_one_add_del_locator_set_reply_t * mp)
2318 {
2319   vat_main_t *vam = &vat_main;
2320   vat_json_node_t node;
2321
2322   vat_json_init_object (&node);
2323   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2324   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2325
2326   vat_json_print (vam->ofp, &node);
2327   vat_json_free (&node);
2328
2329   vam->retval = ntohl (mp->retval);
2330   vam->result_ready = 1;
2331 }
2332
2333 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2334   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2335 {
2336   vat_main_t *vam = &vat_main;
2337   i32 retval = ntohl (mp->retval);
2338   if (vam->async_mode)
2339     {
2340       vam->async_errors += (retval < 0);
2341     }
2342   else
2343     {
2344       vam->retval = retval;
2345       vam->sw_if_index = ntohl (mp->sw_if_index);
2346       vam->result_ready = 1;
2347     }
2348   vam->regenerate_interface_table = 1;
2349 }
2350
2351 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2352   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   vat_json_node_t node;
2356
2357   vat_json_init_object (&node);
2358   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2359   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2360
2361   vat_json_print (vam->ofp, &node);
2362   vat_json_free (&node);
2363
2364   vam->retval = ntohl (mp->retval);
2365   vam->result_ready = 1;
2366 }
2367
2368 static void vl_api_vxlan_offload_rx_reply_t_handler
2369   (vl_api_vxlan_offload_rx_reply_t * mp)
2370 {
2371   vat_main_t *vam = &vat_main;
2372   i32 retval = ntohl (mp->retval);
2373   if (vam->async_mode)
2374     {
2375       vam->async_errors += (retval < 0);
2376     }
2377   else
2378     {
2379       vam->retval = retval;
2380       vam->result_ready = 1;
2381     }
2382 }
2383
2384 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2385   (vl_api_vxlan_offload_rx_reply_t * mp)
2386 {
2387   vat_main_t *vam = &vat_main;
2388   vat_json_node_t node;
2389
2390   vat_json_init_object (&node);
2391   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2392
2393   vat_json_print (vam->ofp, &node);
2394   vat_json_free (&node);
2395
2396   vam->retval = ntohl (mp->retval);
2397   vam->result_ready = 1;
2398 }
2399
2400 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2401   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2402 {
2403   vat_main_t *vam = &vat_main;
2404   i32 retval = ntohl (mp->retval);
2405   if (vam->async_mode)
2406     {
2407       vam->async_errors += (retval < 0);
2408     }
2409   else
2410     {
2411       vam->retval = retval;
2412       vam->sw_if_index = ntohl (mp->sw_if_index);
2413       vam->result_ready = 1;
2414     }
2415 }
2416
2417 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2418   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   vat_json_node_t node;
2422
2423   vat_json_init_object (&node);
2424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427   vat_json_print (vam->ofp, &node);
2428   vat_json_free (&node);
2429
2430   vam->retval = ntohl (mp->retval);
2431   vam->result_ready = 1;
2432 }
2433
2434 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2435   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   i32 retval = ntohl (mp->retval);
2439   if (vam->async_mode)
2440     {
2441       vam->async_errors += (retval < 0);
2442     }
2443   else
2444     {
2445       vam->retval = retval;
2446       vam->sw_if_index = ntohl (mp->sw_if_index);
2447       vam->result_ready = 1;
2448     }
2449   vam->regenerate_interface_table = 1;
2450 }
2451
2452 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2453   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2454 {
2455   vat_main_t *vam = &vat_main;
2456   vat_json_node_t node;
2457
2458   vat_json_init_object (&node);
2459   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462   vat_json_print (vam->ofp, &node);
2463   vat_json_free (&node);
2464
2465   vam->retval = ntohl (mp->retval);
2466   vam->result_ready = 1;
2467 }
2468
2469 static void vl_api_gre_tunnel_add_del_reply_t_handler
2470   (vl_api_gre_tunnel_add_del_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   i32 retval = ntohl (mp->retval);
2474   if (vam->async_mode)
2475     {
2476       vam->async_errors += (retval < 0);
2477     }
2478   else
2479     {
2480       vam->retval = retval;
2481       vam->sw_if_index = ntohl (mp->sw_if_index);
2482       vam->result_ready = 1;
2483     }
2484 }
2485
2486 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2487   (vl_api_gre_tunnel_add_del_reply_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t node;
2491
2492   vat_json_init_object (&node);
2493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2495
2496   vat_json_print (vam->ofp, &node);
2497   vat_json_free (&node);
2498
2499   vam->retval = ntohl (mp->retval);
2500   vam->result_ready = 1;
2501 }
2502
2503 static void vl_api_create_vhost_user_if_reply_t_handler
2504   (vl_api_create_vhost_user_if_reply_t * mp)
2505 {
2506   vat_main_t *vam = &vat_main;
2507   i32 retval = ntohl (mp->retval);
2508   if (vam->async_mode)
2509     {
2510       vam->async_errors += (retval < 0);
2511     }
2512   else
2513     {
2514       vam->retval = retval;
2515       vam->sw_if_index = ntohl (mp->sw_if_index);
2516       vam->result_ready = 1;
2517     }
2518   vam->regenerate_interface_table = 1;
2519 }
2520
2521 static void vl_api_create_vhost_user_if_reply_t_handler_json
2522   (vl_api_create_vhost_user_if_reply_t * mp)
2523 {
2524   vat_main_t *vam = &vat_main;
2525   vat_json_node_t node;
2526
2527   vat_json_init_object (&node);
2528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2529   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2530
2531   vat_json_print (vam->ofp, &node);
2532   vat_json_free (&node);
2533
2534   vam->retval = ntohl (mp->retval);
2535   vam->result_ready = 1;
2536 }
2537
2538 static void vl_api_dns_resolve_name_reply_t_handler
2539   (vl_api_dns_resolve_name_reply_t * mp)
2540 {
2541   vat_main_t *vam = &vat_main;
2542   i32 retval = ntohl (mp->retval);
2543   if (vam->async_mode)
2544     {
2545       vam->async_errors += (retval < 0);
2546     }
2547   else
2548     {
2549       vam->retval = retval;
2550       vam->result_ready = 1;
2551
2552       if (retval == 0)
2553         {
2554           if (mp->ip4_set)
2555             clib_warning ("ip4 address %U", format_ip4_address,
2556                           (ip4_address_t *) mp->ip4_address);
2557           if (mp->ip6_set)
2558             clib_warning ("ip6 address %U", format_ip6_address,
2559                           (ip6_address_t *) mp->ip6_address);
2560         }
2561       else
2562         clib_warning ("retval %d", retval);
2563     }
2564 }
2565
2566 static void vl_api_dns_resolve_name_reply_t_handler_json
2567   (vl_api_dns_resolve_name_reply_t * mp)
2568 {
2569   clib_warning ("not implemented");
2570 }
2571
2572 static void vl_api_dns_resolve_ip_reply_t_handler
2573   (vl_api_dns_resolve_ip_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   i32 retval = ntohl (mp->retval);
2577   if (vam->async_mode)
2578     {
2579       vam->async_errors += (retval < 0);
2580     }
2581   else
2582     {
2583       vam->retval = retval;
2584       vam->result_ready = 1;
2585
2586       if (retval == 0)
2587         {
2588           clib_warning ("canonical name %s", mp->name);
2589         }
2590       else
2591         clib_warning ("retval %d", retval);
2592     }
2593 }
2594
2595 static void vl_api_dns_resolve_ip_reply_t_handler_json
2596   (vl_api_dns_resolve_ip_reply_t * mp)
2597 {
2598   clib_warning ("not implemented");
2599 }
2600
2601
2602 static void vl_api_ip_address_details_t_handler
2603   (vl_api_ip_address_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_address_details_t empty_ip_address_details = { {0} };
2607   ip_address_details_t *address = NULL;
2608   ip_details_t *current_ip_details = NULL;
2609   ip_details_t *details = NULL;
2610
2611   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2612
2613   if (!details || vam->current_sw_if_index >= vec_len (details)
2614       || !details[vam->current_sw_if_index].present)
2615     {
2616       errmsg ("ip address details arrived but not stored");
2617       errmsg ("ip_dump should be called first");
2618       return;
2619     }
2620
2621   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2622
2623 #define addresses (current_ip_details->addr)
2624
2625   vec_validate_init_empty (addresses, vec_len (addresses),
2626                            empty_ip_address_details);
2627
2628   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2629
2630   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2631   address->prefix_length = mp->prefix_length;
2632 #undef addresses
2633 }
2634
2635 static void vl_api_ip_address_details_t_handler_json
2636   (vl_api_ip_address_details_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   vat_json_node_t *node = NULL;
2640   struct in6_addr ip6;
2641   struct in_addr ip4;
2642
2643   if (VAT_JSON_ARRAY != vam->json_tree.type)
2644     {
2645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2646       vat_json_init_array (&vam->json_tree);
2647     }
2648   node = vat_json_array_add (&vam->json_tree);
2649
2650   vat_json_init_object (node);
2651   if (vam->is_ipv6)
2652     {
2653       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2654       vat_json_object_add_ip6 (node, "ip", ip6);
2655     }
2656   else
2657     {
2658       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2659       vat_json_object_add_ip4 (node, "ip", ip4);
2660     }
2661   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2662 }
2663
2664 static void
2665 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   static ip_details_t empty_ip_details = { 0 };
2669   ip_details_t *ip = NULL;
2670   u32 sw_if_index = ~0;
2671
2672   sw_if_index = ntohl (mp->sw_if_index);
2673
2674   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2675                            sw_if_index, empty_ip_details);
2676
2677   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2678                          sw_if_index);
2679
2680   ip->present = 1;
2681 }
2682
2683 static void
2684 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2685 {
2686   vat_main_t *vam = &vat_main;
2687
2688   if (VAT_JSON_ARRAY != vam->json_tree.type)
2689     {
2690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2691       vat_json_init_array (&vam->json_tree);
2692     }
2693   vat_json_array_add_uint (&vam->json_tree,
2694                            clib_net_to_host_u32 (mp->sw_if_index));
2695 }
2696
2697 static void
2698 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2699 {
2700   u8 *s, i;
2701
2702   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2703               "host_mac %U router_addr %U",
2704               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2705               mp->lease.hostname,
2706               format_ip4_address, mp->lease.host_address,
2707               format_ethernet_address, mp->lease.host_mac,
2708               format_ip4_address, mp->lease.router_address);
2709
2710   for (i = 0; i < mp->lease.count; i++)
2711     s =
2712       format (s, " domain_server_addr %U", format_ip4_address,
2713               mp->lease.domain_server[i].address);
2714
2715   errmsg ((char *) s);
2716   vec_free (s);
2717 }
2718
2719 static void vl_api_dhcp_compl_event_t_handler_json
2720   (vl_api_dhcp_compl_event_t * mp)
2721 {
2722   /* JSON output not supported */
2723 }
2724
2725 static void vl_api_get_first_msg_id_reply_t_handler
2726   (vl_api_get_first_msg_id_reply_t * mp)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   i32 retval = ntohl (mp->retval);
2730
2731   if (vam->async_mode)
2732     {
2733       vam->async_errors += (retval < 0);
2734     }
2735   else
2736     {
2737       vam->retval = retval;
2738       vam->result_ready = 1;
2739     }
2740   if (retval >= 0)
2741     {
2742       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2743     }
2744 }
2745
2746 static void vl_api_get_first_msg_id_reply_t_handler_json
2747   (vl_api_get_first_msg_id_reply_t * mp)
2748 {
2749   vat_main_t *vam = &vat_main;
2750   vat_json_node_t node;
2751
2752   vat_json_init_object (&node);
2753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2754   vat_json_object_add_uint (&node, "first_msg_id",
2755                             (uint) ntohs (mp->first_msg_id));
2756
2757   vat_json_print (vam->ofp, &node);
2758   vat_json_free (&node);
2759
2760   vam->retval = ntohl (mp->retval);
2761   vam->result_ready = 1;
2762 }
2763
2764 static void vl_api_get_node_graph_reply_t_handler
2765   (vl_api_get_node_graph_reply_t * mp)
2766 {
2767   vat_main_t *vam = &vat_main;
2768   api_main_t *am = &api_main;
2769   i32 retval = ntohl (mp->retval);
2770   u8 *pvt_copy, *reply;
2771   void *oldheap;
2772   vlib_node_t *node;
2773   int i;
2774
2775   if (vam->async_mode)
2776     {
2777       vam->async_errors += (retval < 0);
2778     }
2779   else
2780     {
2781       vam->retval = retval;
2782       vam->result_ready = 1;
2783     }
2784
2785   /* "Should never happen..." */
2786   if (retval != 0)
2787     return;
2788
2789   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2790   pvt_copy = vec_dup (reply);
2791
2792   /* Toss the shared-memory original... */
2793   pthread_mutex_lock (&am->vlib_rp->mutex);
2794   oldheap = svm_push_data_heap (am->vlib_rp);
2795
2796   vec_free (reply);
2797
2798   svm_pop_heap (oldheap);
2799   pthread_mutex_unlock (&am->vlib_rp->mutex);
2800
2801   if (vam->graph_nodes)
2802     {
2803       hash_free (vam->graph_node_index_by_name);
2804
2805       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2806         {
2807           node = vam->graph_nodes[0][i];
2808           vec_free (node->name);
2809           vec_free (node->next_nodes);
2810           vec_free (node);
2811         }
2812       vec_free (vam->graph_nodes[0]);
2813       vec_free (vam->graph_nodes);
2814     }
2815
2816   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2817   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2818   vec_free (pvt_copy);
2819
2820   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2821     {
2822       node = vam->graph_nodes[0][i];
2823       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2824     }
2825 }
2826
2827 static void vl_api_get_node_graph_reply_t_handler_json
2828   (vl_api_get_node_graph_reply_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   api_main_t *am = &api_main;
2832   void *oldheap;
2833   vat_json_node_t node;
2834   u8 *reply;
2835
2836   /* $$$$ make this real? */
2837   vat_json_init_object (&node);
2838   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2839   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2840
2841   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2842
2843   /* Toss the shared-memory original... */
2844   pthread_mutex_lock (&am->vlib_rp->mutex);
2845   oldheap = svm_push_data_heap (am->vlib_rp);
2846
2847   vec_free (reply);
2848
2849   svm_pop_heap (oldheap);
2850   pthread_mutex_unlock (&am->vlib_rp->mutex);
2851
2852   vat_json_print (vam->ofp, &node);
2853   vat_json_free (&node);
2854
2855   vam->retval = ntohl (mp->retval);
2856   vam->result_ready = 1;
2857 }
2858
2859 static void
2860 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   u8 *s = 0;
2864
2865   if (mp->local)
2866     {
2867       s = format (s, "%=16d%=16d%=16d",
2868                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2869     }
2870   else
2871     {
2872       s = format (s, "%=16U%=16d%=16d",
2873                   mp->is_ipv6 ? format_ip6_address :
2874                   format_ip4_address,
2875                   mp->ip_address, mp->priority, mp->weight);
2876     }
2877
2878   print (vam->ofp, "%v", s);
2879   vec_free (s);
2880 }
2881
2882 static void
2883 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886   vat_json_node_t *node = NULL;
2887   struct in6_addr ip6;
2888   struct in_addr ip4;
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896   vat_json_init_object (node);
2897
2898   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2899   vat_json_object_add_uint (node, "priority", mp->priority);
2900   vat_json_object_add_uint (node, "weight", mp->weight);
2901
2902   if (mp->local)
2903     vat_json_object_add_uint (node, "sw_if_index",
2904                               clib_net_to_host_u32 (mp->sw_if_index));
2905   else
2906     {
2907       if (mp->is_ipv6)
2908         {
2909           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2910           vat_json_object_add_ip6 (node, "address", ip6);
2911         }
2912       else
2913         {
2914           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2915           vat_json_object_add_ip4 (node, "address", ip4);
2916         }
2917     }
2918 }
2919
2920 static void
2921 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2922                                           mp)
2923 {
2924   vat_main_t *vam = &vat_main;
2925   u8 *ls_name = 0;
2926
2927   ls_name = format (0, "%s", mp->ls_name);
2928
2929   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2930          ls_name);
2931   vec_free (ls_name);
2932 }
2933
2934 static void
2935   vl_api_one_locator_set_details_t_handler_json
2936   (vl_api_one_locator_set_details_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vat_json_node_t *node = 0;
2940   u8 *ls_name = 0;
2941
2942   ls_name = format (0, "%s", mp->ls_name);
2943   vec_add1 (ls_name, 0);
2944
2945   if (VAT_JSON_ARRAY != vam->json_tree.type)
2946     {
2947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2948       vat_json_init_array (&vam->json_tree);
2949     }
2950   node = vat_json_array_add (&vam->json_tree);
2951
2952   vat_json_init_object (node);
2953   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2954   vat_json_object_add_uint (node, "ls_index",
2955                             clib_net_to_host_u32 (mp->ls_index));
2956   vec_free (ls_name);
2957 }
2958
2959 typedef struct
2960 {
2961   u32 spi;
2962   u8 si;
2963 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2964
2965 uword
2966 unformat_nsh_address (unformat_input_t * input, va_list * args)
2967 {
2968   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2969   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2970 }
2971
2972 u8 *
2973 format_nsh_address_vat (u8 * s, va_list * args)
2974 {
2975   nsh_t *a = va_arg (*args, nsh_t *);
2976   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2977 }
2978
2979 static u8 *
2980 format_lisp_flat_eid (u8 * s, va_list * args)
2981 {
2982   u32 type = va_arg (*args, u32);
2983   u8 *eid = va_arg (*args, u8 *);
2984   u32 eid_len = va_arg (*args, u32);
2985
2986   switch (type)
2987     {
2988     case 0:
2989       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2990     case 1:
2991       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2992     case 2:
2993       return format (s, "%U", format_ethernet_address, eid);
2994     case 3:
2995       return format (s, "%U", format_nsh_address_vat, eid);
2996     }
2997   return 0;
2998 }
2999
3000 static u8 *
3001 format_lisp_eid_vat (u8 * s, va_list * args)
3002 {
3003   u32 type = va_arg (*args, u32);
3004   u8 *eid = va_arg (*args, u8 *);
3005   u32 eid_len = va_arg (*args, u32);
3006   u8 *seid = va_arg (*args, u8 *);
3007   u32 seid_len = va_arg (*args, u32);
3008   u32 is_src_dst = va_arg (*args, u32);
3009
3010   if (is_src_dst)
3011     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3012
3013   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3014
3015   return s;
3016 }
3017
3018 static void
3019 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3020 {
3021   vat_main_t *vam = &vat_main;
3022   u8 *s = 0, *eid = 0;
3023
3024   if (~0 == mp->locator_set_index)
3025     s = format (0, "action: %d", mp->action);
3026   else
3027     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3028
3029   eid = format (0, "%U", format_lisp_eid_vat,
3030                 mp->eid_type,
3031                 mp->eid,
3032                 mp->eid_prefix_len,
3033                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3034   vec_add1 (eid, 0);
3035
3036   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3037          clib_net_to_host_u32 (mp->vni),
3038          eid,
3039          mp->is_local ? "local" : "remote",
3040          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3041          clib_net_to_host_u16 (mp->key_id), mp->key);
3042
3043   vec_free (s);
3044   vec_free (eid);
3045 }
3046
3047 static void
3048 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3049                                              * mp)
3050 {
3051   vat_main_t *vam = &vat_main;
3052   vat_json_node_t *node = 0;
3053   u8 *eid = 0;
3054
3055   if (VAT_JSON_ARRAY != vam->json_tree.type)
3056     {
3057       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3058       vat_json_init_array (&vam->json_tree);
3059     }
3060   node = vat_json_array_add (&vam->json_tree);
3061
3062   vat_json_init_object (node);
3063   if (~0 == mp->locator_set_index)
3064     vat_json_object_add_uint (node, "action", mp->action);
3065   else
3066     vat_json_object_add_uint (node, "locator_set_index",
3067                               clib_net_to_host_u32 (mp->locator_set_index));
3068
3069   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3070   if (mp->eid_type == 3)
3071     {
3072       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3073       vat_json_init_object (nsh_json);
3074       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3075       vat_json_object_add_uint (nsh_json, "spi",
3076                                 clib_net_to_host_u32 (nsh->spi));
3077       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3078     }
3079   else
3080     {
3081       eid = format (0, "%U", format_lisp_eid_vat,
3082                     mp->eid_type,
3083                     mp->eid,
3084                     mp->eid_prefix_len,
3085                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3086       vec_add1 (eid, 0);
3087       vat_json_object_add_string_copy (node, "eid", eid);
3088       vec_free (eid);
3089     }
3090   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3091   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3092   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3093
3094   if (mp->key_id)
3095     {
3096       vat_json_object_add_uint (node, "key_id",
3097                                 clib_net_to_host_u16 (mp->key_id));
3098       vat_json_object_add_string_copy (node, "key", mp->key);
3099     }
3100 }
3101
3102 static void
3103 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3104 {
3105   vat_main_t *vam = &vat_main;
3106   u8 *seid = 0, *deid = 0;
3107   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3108
3109   deid = format (0, "%U", format_lisp_eid_vat,
3110                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3111
3112   seid = format (0, "%U", format_lisp_eid_vat,
3113                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3114
3115   vec_add1 (deid, 0);
3116   vec_add1 (seid, 0);
3117
3118   if (mp->is_ip4)
3119     format_ip_address_fcn = format_ip4_address;
3120   else
3121     format_ip_address_fcn = format_ip6_address;
3122
3123
3124   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3125          clib_net_to_host_u32 (mp->vni),
3126          seid, deid,
3127          format_ip_address_fcn, mp->lloc,
3128          format_ip_address_fcn, mp->rloc,
3129          clib_net_to_host_u32 (mp->pkt_count),
3130          clib_net_to_host_u32 (mp->bytes));
3131
3132   vec_free (deid);
3133   vec_free (seid);
3134 }
3135
3136 static void
3137 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3138 {
3139   struct in6_addr ip6;
3140   struct in_addr ip4;
3141   vat_main_t *vam = &vat_main;
3142   vat_json_node_t *node = 0;
3143   u8 *deid = 0, *seid = 0;
3144
3145   if (VAT_JSON_ARRAY != vam->json_tree.type)
3146     {
3147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3148       vat_json_init_array (&vam->json_tree);
3149     }
3150   node = vat_json_array_add (&vam->json_tree);
3151
3152   vat_json_init_object (node);
3153   deid = format (0, "%U", format_lisp_eid_vat,
3154                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3155
3156   seid = format (0, "%U", format_lisp_eid_vat,
3157                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3158
3159   vec_add1 (deid, 0);
3160   vec_add1 (seid, 0);
3161
3162   vat_json_object_add_string_copy (node, "seid", seid);
3163   vat_json_object_add_string_copy (node, "deid", deid);
3164   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3165
3166   if (mp->is_ip4)
3167     {
3168       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3169       vat_json_object_add_ip4 (node, "lloc", ip4);
3170       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3171       vat_json_object_add_ip4 (node, "rloc", ip4);
3172     }
3173   else
3174     {
3175       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3176       vat_json_object_add_ip6 (node, "lloc", ip6);
3177       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3178       vat_json_object_add_ip6 (node, "rloc", ip6);
3179     }
3180   vat_json_object_add_uint (node, "pkt_count",
3181                             clib_net_to_host_u32 (mp->pkt_count));
3182   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3183
3184   vec_free (deid);
3185   vec_free (seid);
3186 }
3187
3188 static void
3189   vl_api_one_eid_table_map_details_t_handler
3190   (vl_api_one_eid_table_map_details_t * mp)
3191 {
3192   vat_main_t *vam = &vat_main;
3193
3194   u8 *line = format (0, "%=10d%=10d",
3195                      clib_net_to_host_u32 (mp->vni),
3196                      clib_net_to_host_u32 (mp->dp_table));
3197   print (vam->ofp, "%v", line);
3198   vec_free (line);
3199 }
3200
3201 static void
3202   vl_api_one_eid_table_map_details_t_handler_json
3203   (vl_api_one_eid_table_map_details_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   vat_json_node_t *node = NULL;
3207
3208   if (VAT_JSON_ARRAY != vam->json_tree.type)
3209     {
3210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3211       vat_json_init_array (&vam->json_tree);
3212     }
3213   node = vat_json_array_add (&vam->json_tree);
3214   vat_json_init_object (node);
3215   vat_json_object_add_uint (node, "dp_table",
3216                             clib_net_to_host_u32 (mp->dp_table));
3217   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3218 }
3219
3220 static void
3221   vl_api_one_eid_table_vni_details_t_handler
3222   (vl_api_one_eid_table_vni_details_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225
3226   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3227   print (vam->ofp, "%v", line);
3228   vec_free (line);
3229 }
3230
3231 static void
3232   vl_api_one_eid_table_vni_details_t_handler_json
3233   (vl_api_one_eid_table_vni_details_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   vat_json_node_t *node = NULL;
3237
3238   if (VAT_JSON_ARRAY != vam->json_tree.type)
3239     {
3240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3241       vat_json_init_array (&vam->json_tree);
3242     }
3243   node = vat_json_array_add (&vam->json_tree);
3244   vat_json_init_object (node);
3245   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3246 }
3247
3248 static void
3249   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3250   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   int retval = clib_net_to_host_u32 (mp->retval);
3254
3255   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3256   print (vam->ofp, "fallback threshold value: %d", mp->value);
3257
3258   vam->retval = retval;
3259   vam->result_ready = 1;
3260 }
3261
3262 static void
3263   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3264   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3265 {
3266   vat_main_t *vam = &vat_main;
3267   vat_json_node_t _node, *node = &_node;
3268   int retval = clib_net_to_host_u32 (mp->retval);
3269
3270   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3271   vat_json_init_object (node);
3272   vat_json_object_add_uint (node, "value", mp->value);
3273
3274   vat_json_print (vam->ofp, node);
3275   vat_json_free (node);
3276
3277   vam->retval = retval;
3278   vam->result_ready = 1;
3279 }
3280
3281 static void
3282   vl_api_show_one_map_register_state_reply_t_handler
3283   (vl_api_show_one_map_register_state_reply_t * mp)
3284 {
3285   vat_main_t *vam = &vat_main;
3286   int retval = clib_net_to_host_u32 (mp->retval);
3287
3288   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3289
3290   vam->retval = retval;
3291   vam->result_ready = 1;
3292 }
3293
3294 static void
3295   vl_api_show_one_map_register_state_reply_t_handler_json
3296   (vl_api_show_one_map_register_state_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   vat_json_node_t _node, *node = &_node;
3300   int retval = clib_net_to_host_u32 (mp->retval);
3301
3302   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3303
3304   vat_json_init_object (node);
3305   vat_json_object_add_string_copy (node, "state", s);
3306
3307   vat_json_print (vam->ofp, node);
3308   vat_json_free (node);
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312   vec_free (s);
3313 }
3314
3315 static void
3316   vl_api_show_one_rloc_probe_state_reply_t_handler
3317   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   int retval = clib_net_to_host_u32 (mp->retval);
3321
3322   if (retval)
3323     goto end;
3324
3325   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3326 end:
3327   vam->retval = retval;
3328   vam->result_ready = 1;
3329 }
3330
3331 static void
3332   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3333   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3334 {
3335   vat_main_t *vam = &vat_main;
3336   vat_json_node_t _node, *node = &_node;
3337   int retval = clib_net_to_host_u32 (mp->retval);
3338
3339   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3340   vat_json_init_object (node);
3341   vat_json_object_add_string_copy (node, "state", s);
3342
3343   vat_json_print (vam->ofp, node);
3344   vat_json_free (node);
3345
3346   vam->retval = retval;
3347   vam->result_ready = 1;
3348   vec_free (s);
3349 }
3350
3351 static void
3352   vl_api_show_one_stats_enable_disable_reply_t_handler
3353   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3354 {
3355   vat_main_t *vam = &vat_main;
3356   int retval = clib_net_to_host_u32 (mp->retval);
3357
3358   if (retval)
3359     goto end;
3360
3361   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3362 end:
3363   vam->retval = retval;
3364   vam->result_ready = 1;
3365 }
3366
3367 static void
3368   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3369   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372   vat_json_node_t _node, *node = &_node;
3373   int retval = clib_net_to_host_u32 (mp->retval);
3374
3375   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3376   vat_json_init_object (node);
3377   vat_json_object_add_string_copy (node, "state", s);
3378
3379   vat_json_print (vam->ofp, node);
3380   vat_json_free (node);
3381
3382   vam->retval = retval;
3383   vam->result_ready = 1;
3384   vec_free (s);
3385 }
3386
3387 static void
3388 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3389 {
3390   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3391   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3392   e->vni = clib_net_to_host_u32 (e->vni);
3393 }
3394
3395 static void
3396   gpe_fwd_entries_get_reply_t_net_to_host
3397   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3398 {
3399   u32 i;
3400
3401   mp->count = clib_net_to_host_u32 (mp->count);
3402   for (i = 0; i < mp->count; i++)
3403     {
3404       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3405     }
3406 }
3407
3408 static u8 *
3409 format_gpe_encap_mode (u8 * s, va_list * args)
3410 {
3411   u32 mode = va_arg (*args, u32);
3412
3413   switch (mode)
3414     {
3415     case 0:
3416       return format (s, "lisp");
3417     case 1:
3418       return format (s, "vxlan");
3419     }
3420   return 0;
3421 }
3422
3423 static void
3424   vl_api_gpe_get_encap_mode_reply_t_handler
3425   (vl_api_gpe_get_encap_mode_reply_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428
3429   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3430   vam->retval = ntohl (mp->retval);
3431   vam->result_ready = 1;
3432 }
3433
3434 static void
3435   vl_api_gpe_get_encap_mode_reply_t_handler_json
3436   (vl_api_gpe_get_encap_mode_reply_t * mp)
3437 {
3438   vat_main_t *vam = &vat_main;
3439   vat_json_node_t node;
3440
3441   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3442   vec_add1 (encap_mode, 0);
3443
3444   vat_json_init_object (&node);
3445   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3446
3447   vec_free (encap_mode);
3448   vat_json_print (vam->ofp, &node);
3449   vat_json_free (&node);
3450
3451   vam->retval = ntohl (mp->retval);
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_gpe_fwd_entry_path_details_t_handler
3457   (vl_api_gpe_fwd_entry_path_details_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3461
3462   if (mp->lcl_loc.is_ip4)
3463     format_ip_address_fcn = format_ip4_address;
3464   else
3465     format_ip_address_fcn = format_ip6_address;
3466
3467   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3468          format_ip_address_fcn, &mp->lcl_loc,
3469          format_ip_address_fcn, &mp->rmt_loc);
3470 }
3471
3472 static void
3473 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3474 {
3475   struct in6_addr ip6;
3476   struct in_addr ip4;
3477
3478   if (loc->is_ip4)
3479     {
3480       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3481       vat_json_object_add_ip4 (n, "address", ip4);
3482     }
3483   else
3484     {
3485       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3486       vat_json_object_add_ip6 (n, "address", ip6);
3487     }
3488   vat_json_object_add_uint (n, "weight", loc->weight);
3489 }
3490
3491 static void
3492   vl_api_gpe_fwd_entry_path_details_t_handler_json
3493   (vl_api_gpe_fwd_entry_path_details_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   vat_json_node_t *node = NULL;
3497   vat_json_node_t *loc_node;
3498
3499   if (VAT_JSON_ARRAY != vam->json_tree.type)
3500     {
3501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3502       vat_json_init_array (&vam->json_tree);
3503     }
3504   node = vat_json_array_add (&vam->json_tree);
3505   vat_json_init_object (node);
3506
3507   loc_node = vat_json_object_add (node, "local_locator");
3508   vat_json_init_object (loc_node);
3509   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3510
3511   loc_node = vat_json_object_add (node, "remote_locator");
3512   vat_json_init_object (loc_node);
3513   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3514 }
3515
3516 static void
3517   vl_api_gpe_fwd_entries_get_reply_t_handler
3518   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   u32 i;
3522   int retval = clib_net_to_host_u32 (mp->retval);
3523   vl_api_gpe_fwd_entry_t *e;
3524
3525   if (retval)
3526     goto end;
3527
3528   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3529
3530   for (i = 0; i < mp->count; i++)
3531     {
3532       e = &mp->entries[i];
3533       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3534              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3535              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3536     }
3537
3538 end:
3539   vam->retval = retval;
3540   vam->result_ready = 1;
3541 }
3542
3543 static void
3544   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3545   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3546 {
3547   u8 *s = 0;
3548   vat_main_t *vam = &vat_main;
3549   vat_json_node_t *e = 0, root;
3550   u32 i;
3551   int retval = clib_net_to_host_u32 (mp->retval);
3552   vl_api_gpe_fwd_entry_t *fwd;
3553
3554   if (retval)
3555     goto end;
3556
3557   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3558   vat_json_init_array (&root);
3559
3560   for (i = 0; i < mp->count; i++)
3561     {
3562       e = vat_json_array_add (&root);
3563       fwd = &mp->entries[i];
3564
3565       vat_json_init_object (e);
3566       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3567       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3568       vat_json_object_add_int (e, "vni", fwd->vni);
3569       vat_json_object_add_int (e, "action", fwd->action);
3570
3571       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3572                   fwd->leid_prefix_len);
3573       vec_add1 (s, 0);
3574       vat_json_object_add_string_copy (e, "leid", s);
3575       vec_free (s);
3576
3577       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3578                   fwd->reid_prefix_len);
3579       vec_add1 (s, 0);
3580       vat_json_object_add_string_copy (e, "reid", s);
3581       vec_free (s);
3582     }
3583
3584   vat_json_print (vam->ofp, &root);
3585   vat_json_free (&root);
3586
3587 end:
3588   vam->retval = retval;
3589   vam->result_ready = 1;
3590 }
3591
3592 static void
3593   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3594   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3595 {
3596   vat_main_t *vam = &vat_main;
3597   u32 i, n;
3598   int retval = clib_net_to_host_u32 (mp->retval);
3599   vl_api_gpe_native_fwd_rpath_t *r;
3600
3601   if (retval)
3602     goto end;
3603
3604   n = clib_net_to_host_u32 (mp->count);
3605
3606   for (i = 0; i < n; i++)
3607     {
3608       r = &mp->entries[i];
3609       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3610              clib_net_to_host_u32 (r->fib_index),
3611              clib_net_to_host_u32 (r->nh_sw_if_index),
3612              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3613     }
3614
3615 end:
3616   vam->retval = retval;
3617   vam->result_ready = 1;
3618 }
3619
3620 static void
3621   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3622   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3623 {
3624   vat_main_t *vam = &vat_main;
3625   vat_json_node_t root, *e;
3626   u32 i, n;
3627   int retval = clib_net_to_host_u32 (mp->retval);
3628   vl_api_gpe_native_fwd_rpath_t *r;
3629   u8 *s;
3630
3631   if (retval)
3632     goto end;
3633
3634   n = clib_net_to_host_u32 (mp->count);
3635   vat_json_init_array (&root);
3636
3637   for (i = 0; i < n; i++)
3638     {
3639       e = vat_json_array_add (&root);
3640       vat_json_init_object (e);
3641       r = &mp->entries[i];
3642       s =
3643         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3644                 r->nh_addr);
3645       vec_add1 (s, 0);
3646       vat_json_object_add_string_copy (e, "ip4", s);
3647       vec_free (s);
3648
3649       vat_json_object_add_uint (e, "fib_index",
3650                                 clib_net_to_host_u32 (r->fib_index));
3651       vat_json_object_add_uint (e, "nh_sw_if_index",
3652                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3653     }
3654
3655   vat_json_print (vam->ofp, &root);
3656   vat_json_free (&root);
3657
3658 end:
3659   vam->retval = retval;
3660   vam->result_ready = 1;
3661 }
3662
3663 static void
3664   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3665   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3666 {
3667   vat_main_t *vam = &vat_main;
3668   u32 i, n;
3669   int retval = clib_net_to_host_u32 (mp->retval);
3670
3671   if (retval)
3672     goto end;
3673
3674   n = clib_net_to_host_u32 (mp->count);
3675
3676   for (i = 0; i < n; i++)
3677     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3678
3679 end:
3680   vam->retval = retval;
3681   vam->result_ready = 1;
3682 }
3683
3684 static void
3685   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3686   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t root;
3690   u32 i, n;
3691   int retval = clib_net_to_host_u32 (mp->retval);
3692
3693   if (retval)
3694     goto end;
3695
3696   n = clib_net_to_host_u32 (mp->count);
3697   vat_json_init_array (&root);
3698
3699   for (i = 0; i < n; i++)
3700     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3701
3702   vat_json_print (vam->ofp, &root);
3703   vat_json_free (&root);
3704
3705 end:
3706   vam->retval = retval;
3707   vam->result_ready = 1;
3708 }
3709
3710 static void
3711   vl_api_one_ndp_entries_get_reply_t_handler
3712   (vl_api_one_ndp_entries_get_reply_t * mp)
3713 {
3714   vat_main_t *vam = &vat_main;
3715   u32 i, n;
3716   int retval = clib_net_to_host_u32 (mp->retval);
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722
3723   for (i = 0; i < n; i++)
3724     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3725            format_ethernet_address, mp->entries[i].mac);
3726
3727 end:
3728   vam->retval = retval;
3729   vam->result_ready = 1;
3730 }
3731
3732 static void
3733   vl_api_one_ndp_entries_get_reply_t_handler_json
3734   (vl_api_one_ndp_entries_get_reply_t * mp)
3735 {
3736   u8 *s = 0;
3737   vat_main_t *vam = &vat_main;
3738   vat_json_node_t *e = 0, root;
3739   u32 i, n;
3740   int retval = clib_net_to_host_u32 (mp->retval);
3741   vl_api_one_ndp_entry_t *arp_entry;
3742
3743   if (retval)
3744     goto end;
3745
3746   n = clib_net_to_host_u32 (mp->count);
3747   vat_json_init_array (&root);
3748
3749   for (i = 0; i < n; i++)
3750     {
3751       e = vat_json_array_add (&root);
3752       arp_entry = &mp->entries[i];
3753
3754       vat_json_init_object (e);
3755       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3756       vec_add1 (s, 0);
3757
3758       vat_json_object_add_string_copy (e, "mac", s);
3759       vec_free (s);
3760
3761       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3762       vec_add1 (s, 0);
3763       vat_json_object_add_string_copy (e, "ip6", s);
3764       vec_free (s);
3765     }
3766
3767   vat_json_print (vam->ofp, &root);
3768   vat_json_free (&root);
3769
3770 end:
3771   vam->retval = retval;
3772   vam->result_ready = 1;
3773 }
3774
3775 static void
3776   vl_api_one_l2_arp_entries_get_reply_t_handler
3777   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787
3788   for (i = 0; i < n; i++)
3789     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3790            format_ethernet_address, mp->entries[i].mac);
3791
3792 end:
3793   vam->retval = retval;
3794   vam->result_ready = 1;
3795 }
3796
3797 static void
3798   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3799   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3800 {
3801   u8 *s = 0;
3802   vat_main_t *vam = &vat_main;
3803   vat_json_node_t *e = 0, root;
3804   u32 i, n;
3805   int retval = clib_net_to_host_u32 (mp->retval);
3806   vl_api_one_l2_arp_entry_t *arp_entry;
3807
3808   if (retval)
3809     goto end;
3810
3811   n = clib_net_to_host_u32 (mp->count);
3812   vat_json_init_array (&root);
3813
3814   for (i = 0; i < n; i++)
3815     {
3816       e = vat_json_array_add (&root);
3817       arp_entry = &mp->entries[i];
3818
3819       vat_json_init_object (e);
3820       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3821       vec_add1 (s, 0);
3822
3823       vat_json_object_add_string_copy (e, "mac", s);
3824       vec_free (s);
3825
3826       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3827       vec_add1 (s, 0);
3828       vat_json_object_add_string_copy (e, "ip4", s);
3829       vec_free (s);
3830     }
3831
3832   vat_json_print (vam->ofp, &root);
3833   vat_json_free (&root);
3834
3835 end:
3836   vam->retval = retval;
3837   vam->result_ready = 1;
3838 }
3839
3840 static void
3841 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3842 {
3843   vat_main_t *vam = &vat_main;
3844   u32 i, n;
3845   int retval = clib_net_to_host_u32 (mp->retval);
3846
3847   if (retval)
3848     goto end;
3849
3850   n = clib_net_to_host_u32 (mp->count);
3851
3852   for (i = 0; i < n; i++)
3853     {
3854       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3855     }
3856
3857 end:
3858   vam->retval = retval;
3859   vam->result_ready = 1;
3860 }
3861
3862 static void
3863   vl_api_one_ndp_bd_get_reply_t_handler_json
3864   (vl_api_one_ndp_bd_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   vat_json_node_t root;
3868   u32 i, n;
3869   int retval = clib_net_to_host_u32 (mp->retval);
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875   vat_json_init_array (&root);
3876
3877   for (i = 0; i < n; i++)
3878     {
3879       vat_json_array_add_uint (&root,
3880                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3881     }
3882
3883   vat_json_print (vam->ofp, &root);
3884   vat_json_free (&root);
3885
3886 end:
3887   vam->retval = retval;
3888   vam->result_ready = 1;
3889 }
3890
3891 static void
3892   vl_api_one_l2_arp_bd_get_reply_t_handler
3893   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3894 {
3895   vat_main_t *vam = &vat_main;
3896   u32 i, n;
3897   int retval = clib_net_to_host_u32 (mp->retval);
3898
3899   if (retval)
3900     goto end;
3901
3902   n = clib_net_to_host_u32 (mp->count);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3907     }
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3916   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   vat_json_node_t root;
3920   u32 i, n;
3921   int retval = clib_net_to_host_u32 (mp->retval);
3922
3923   if (retval)
3924     goto end;
3925
3926   n = clib_net_to_host_u32 (mp->count);
3927   vat_json_init_array (&root);
3928
3929   for (i = 0; i < n; i++)
3930     {
3931       vat_json_array_add_uint (&root,
3932                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3933     }
3934
3935   vat_json_print (vam->ofp, &root);
3936   vat_json_free (&root);
3937
3938 end:
3939   vam->retval = retval;
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_one_adjacencies_get_reply_t_handler
3945   (vl_api_one_adjacencies_get_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   u32 i, n;
3949   int retval = clib_net_to_host_u32 (mp->retval);
3950   vl_api_one_adjacency_t *a;
3951
3952   if (retval)
3953     goto end;
3954
3955   n = clib_net_to_host_u32 (mp->count);
3956
3957   for (i = 0; i < n; i++)
3958     {
3959       a = &mp->adjacencies[i];
3960       print (vam->ofp, "%U %40U",
3961              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3962              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3963     }
3964
3965 end:
3966   vam->retval = retval;
3967   vam->result_ready = 1;
3968 }
3969
3970 static void
3971   vl_api_one_adjacencies_get_reply_t_handler_json
3972   (vl_api_one_adjacencies_get_reply_t * mp)
3973 {
3974   u8 *s = 0;
3975   vat_main_t *vam = &vat_main;
3976   vat_json_node_t *e = 0, root;
3977   u32 i, n;
3978   int retval = clib_net_to_host_u32 (mp->retval);
3979   vl_api_one_adjacency_t *a;
3980
3981   if (retval)
3982     goto end;
3983
3984   n = clib_net_to_host_u32 (mp->count);
3985   vat_json_init_array (&root);
3986
3987   for (i = 0; i < n; i++)
3988     {
3989       e = vat_json_array_add (&root);
3990       a = &mp->adjacencies[i];
3991
3992       vat_json_init_object (e);
3993       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3994                   a->leid_prefix_len);
3995       vec_add1 (s, 0);
3996       vat_json_object_add_string_copy (e, "leid", s);
3997       vec_free (s);
3998
3999       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4000                   a->reid_prefix_len);
4001       vec_add1 (s, 0);
4002       vat_json_object_add_string_copy (e, "reid", s);
4003       vec_free (s);
4004     }
4005
4006   vat_json_print (vam->ofp, &root);
4007   vat_json_free (&root);
4008
4009 end:
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4016 {
4017   vat_main_t *vam = &vat_main;
4018
4019   print (vam->ofp, "%=20U",
4020          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4021          mp->ip_address);
4022 }
4023
4024 static void
4025   vl_api_one_map_server_details_t_handler_json
4026   (vl_api_one_map_server_details_t * mp)
4027 {
4028   vat_main_t *vam = &vat_main;
4029   vat_json_node_t *node = NULL;
4030   struct in6_addr ip6;
4031   struct in_addr ip4;
4032
4033   if (VAT_JSON_ARRAY != vam->json_tree.type)
4034     {
4035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4036       vat_json_init_array (&vam->json_tree);
4037     }
4038   node = vat_json_array_add (&vam->json_tree);
4039
4040   vat_json_init_object (node);
4041   if (mp->is_ipv6)
4042     {
4043       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4044       vat_json_object_add_ip6 (node, "map-server", ip6);
4045     }
4046   else
4047     {
4048       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4049       vat_json_object_add_ip4 (node, "map-server", ip4);
4050     }
4051 }
4052
4053 static void
4054 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4055                                            * mp)
4056 {
4057   vat_main_t *vam = &vat_main;
4058
4059   print (vam->ofp, "%=20U",
4060          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4061          mp->ip_address);
4062 }
4063
4064 static void
4065   vl_api_one_map_resolver_details_t_handler_json
4066   (vl_api_one_map_resolver_details_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   vat_json_node_t *node = NULL;
4070   struct in6_addr ip6;
4071   struct in_addr ip4;
4072
4073   if (VAT_JSON_ARRAY != vam->json_tree.type)
4074     {
4075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4076       vat_json_init_array (&vam->json_tree);
4077     }
4078   node = vat_json_array_add (&vam->json_tree);
4079
4080   vat_json_init_object (node);
4081   if (mp->is_ipv6)
4082     {
4083       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4084       vat_json_object_add_ip6 (node, "map resolver", ip6);
4085     }
4086   else
4087     {
4088       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4089       vat_json_object_add_ip4 (node, "map resolver", ip4);
4090     }
4091 }
4092
4093 static void
4094 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   i32 retval = ntohl (mp->retval);
4098
4099   if (0 <= retval)
4100     {
4101       print (vam->ofp, "feature: %s\ngpe: %s",
4102              mp->feature_status ? "enabled" : "disabled",
4103              mp->gpe_status ? "enabled" : "disabled");
4104     }
4105
4106   vam->retval = retval;
4107   vam->result_ready = 1;
4108 }
4109
4110 static void
4111   vl_api_show_one_status_reply_t_handler_json
4112   (vl_api_show_one_status_reply_t * mp)
4113 {
4114   vat_main_t *vam = &vat_main;
4115   vat_json_node_t node;
4116   u8 *gpe_status = NULL;
4117   u8 *feature_status = NULL;
4118
4119   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4120   feature_status = format (0, "%s",
4121                            mp->feature_status ? "enabled" : "disabled");
4122   vec_add1 (gpe_status, 0);
4123   vec_add1 (feature_status, 0);
4124
4125   vat_json_init_object (&node);
4126   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4127   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4128
4129   vec_free (gpe_status);
4130   vec_free (feature_status);
4131
4132   vat_json_print (vam->ofp, &node);
4133   vat_json_free (&node);
4134
4135   vam->retval = ntohl (mp->retval);
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4141   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (retval >= 0)
4147     {
4148       print (vam->ofp, "%=20s", mp->locator_set_name);
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4157   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t *node = NULL;
4161
4162   if (VAT_JSON_ARRAY != vam->json_tree.type)
4163     {
4164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4165       vat_json_init_array (&vam->json_tree);
4166     }
4167   node = vat_json_array_add (&vam->json_tree);
4168
4169   vat_json_init_object (node);
4170   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4171
4172   vat_json_print (vam->ofp, node);
4173   vat_json_free (node);
4174
4175   vam->retval = ntohl (mp->retval);
4176   vam->result_ready = 1;
4177 }
4178
4179 static u8 *
4180 format_lisp_map_request_mode (u8 * s, va_list * args)
4181 {
4182   u32 mode = va_arg (*args, u32);
4183
4184   switch (mode)
4185     {
4186     case 0:
4187       return format (0, "dst-only");
4188     case 1:
4189       return format (0, "src-dst");
4190     }
4191   return 0;
4192 }
4193
4194 static void
4195   vl_api_show_one_map_request_mode_reply_t_handler
4196   (vl_api_show_one_map_request_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   i32 retval = ntohl (mp->retval);
4200
4201   if (0 <= retval)
4202     {
4203       u32 mode = mp->mode;
4204       print (vam->ofp, "map_request_mode: %U",
4205              format_lisp_map_request_mode, mode);
4206     }
4207
4208   vam->retval = retval;
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_show_one_map_request_mode_reply_t_handler_json
4214   (vl_api_show_one_map_request_mode_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   vat_json_node_t node;
4218   u8 *s = 0;
4219   u32 mode;
4220
4221   mode = mp->mode;
4222   s = format (0, "%U", format_lisp_map_request_mode, mode);
4223   vec_add1 (s, 0);
4224
4225   vat_json_init_object (&node);
4226   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4227   vat_json_print (vam->ofp, &node);
4228   vat_json_free (&node);
4229
4230   vec_free (s);
4231   vam->retval = ntohl (mp->retval);
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_xtr_mode_reply_t_handler
4237   (vl_api_one_show_xtr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   i32 retval = ntohl (mp->retval);
4241
4242   if (0 <= retval)
4243     {
4244       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4245     }
4246
4247   vam->retval = retval;
4248   vam->result_ready = 1;
4249 }
4250
4251 static void
4252   vl_api_one_show_xtr_mode_reply_t_handler_json
4253   (vl_api_one_show_xtr_mode_reply_t * mp)
4254 {
4255   vat_main_t *vam = &vat_main;
4256   vat_json_node_t node;
4257   u8 *status = 0;
4258
4259   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4260   vec_add1 (status, 0);
4261
4262   vat_json_init_object (&node);
4263   vat_json_object_add_string_copy (&node, "status", status);
4264
4265   vec_free (status);
4266
4267   vat_json_print (vam->ofp, &node);
4268   vat_json_free (&node);
4269
4270   vam->retval = ntohl (mp->retval);
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_pitr_mode_reply_t_handler
4276   (vl_api_one_show_pitr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   i32 retval = ntohl (mp->retval);
4280
4281   if (0 <= retval)
4282     {
4283       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4284     }
4285
4286   vam->retval = retval;
4287   vam->result_ready = 1;
4288 }
4289
4290 static void
4291   vl_api_one_show_pitr_mode_reply_t_handler_json
4292   (vl_api_one_show_pitr_mode_reply_t * mp)
4293 {
4294   vat_main_t *vam = &vat_main;
4295   vat_json_node_t node;
4296   u8 *status = 0;
4297
4298   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4299   vec_add1 (status, 0);
4300
4301   vat_json_init_object (&node);
4302   vat_json_object_add_string_copy (&node, "status", status);
4303
4304   vec_free (status);
4305
4306   vat_json_print (vam->ofp, &node);
4307   vat_json_free (&node);
4308
4309   vam->retval = ntohl (mp->retval);
4310   vam->result_ready = 1;
4311 }
4312
4313 static void
4314   vl_api_one_show_petr_mode_reply_t_handler
4315   (vl_api_one_show_petr_mode_reply_t * mp)
4316 {
4317   vat_main_t *vam = &vat_main;
4318   i32 retval = ntohl (mp->retval);
4319
4320   if (0 <= retval)
4321     {
4322       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4323     }
4324
4325   vam->retval = retval;
4326   vam->result_ready = 1;
4327 }
4328
4329 static void
4330   vl_api_one_show_petr_mode_reply_t_handler_json
4331   (vl_api_one_show_petr_mode_reply_t * mp)
4332 {
4333   vat_main_t *vam = &vat_main;
4334   vat_json_node_t node;
4335   u8 *status = 0;
4336
4337   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4338   vec_add1 (status, 0);
4339
4340   vat_json_init_object (&node);
4341   vat_json_object_add_string_copy (&node, "status", status);
4342
4343   vec_free (status);
4344
4345   vat_json_print (vam->ofp, &node);
4346   vat_json_free (&node);
4347
4348   vam->retval = ntohl (mp->retval);
4349   vam->result_ready = 1;
4350 }
4351
4352 static void
4353   vl_api_show_one_use_petr_reply_t_handler
4354   (vl_api_show_one_use_petr_reply_t * mp)
4355 {
4356   vat_main_t *vam = &vat_main;
4357   i32 retval = ntohl (mp->retval);
4358
4359   if (0 <= retval)
4360     {
4361       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4362       if (mp->status)
4363         {
4364           print (vam->ofp, "Proxy-ETR address; %U",
4365                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4366                  mp->address);
4367         }
4368     }
4369
4370   vam->retval = retval;
4371   vam->result_ready = 1;
4372 }
4373
4374 static void
4375   vl_api_show_one_use_petr_reply_t_handler_json
4376   (vl_api_show_one_use_petr_reply_t * mp)
4377 {
4378   vat_main_t *vam = &vat_main;
4379   vat_json_node_t node;
4380   u8 *status = 0;
4381   struct in_addr ip4;
4382   struct in6_addr ip6;
4383
4384   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4385   vec_add1 (status, 0);
4386
4387   vat_json_init_object (&node);
4388   vat_json_object_add_string_copy (&node, "status", status);
4389   if (mp->status)
4390     {
4391       if (mp->is_ip4)
4392         {
4393           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4394           vat_json_object_add_ip6 (&node, "address", ip6);
4395         }
4396       else
4397         {
4398           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4399           vat_json_object_add_ip4 (&node, "address", ip4);
4400         }
4401     }
4402
4403   vec_free (status);
4404
4405   vat_json_print (vam->ofp, &node);
4406   vat_json_free (&node);
4407
4408   vam->retval = ntohl (mp->retval);
4409   vam->result_ready = 1;
4410 }
4411
4412 static void
4413   vl_api_show_one_nsh_mapping_reply_t_handler
4414   (vl_api_show_one_nsh_mapping_reply_t * mp)
4415 {
4416   vat_main_t *vam = &vat_main;
4417   i32 retval = ntohl (mp->retval);
4418
4419   if (0 <= retval)
4420     {
4421       print (vam->ofp, "%-20s%-16s",
4422              mp->is_set ? "set" : "not-set",
4423              mp->is_set ? (char *) mp->locator_set_name : "");
4424     }
4425
4426   vam->retval = retval;
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_nsh_mapping_reply_t_handler_json
4432   (vl_api_show_one_nsh_mapping_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   vat_json_node_t node;
4436   u8 *status = 0;
4437
4438   status = format (0, "%s", mp->is_set ? "yes" : "no");
4439   vec_add1 (status, 0);
4440
4441   vat_json_init_object (&node);
4442   vat_json_object_add_string_copy (&node, "is_set", status);
4443   if (mp->is_set)
4444     {
4445       vat_json_object_add_string_copy (&node, "locator_set",
4446                                        mp->locator_set_name);
4447     }
4448
4449   vec_free (status);
4450
4451   vat_json_print (vam->ofp, &node);
4452   vat_json_free (&node);
4453
4454   vam->retval = ntohl (mp->retval);
4455   vam->result_ready = 1;
4456 }
4457
4458 static void
4459   vl_api_show_one_map_register_ttl_reply_t_handler
4460   (vl_api_show_one_map_register_ttl_reply_t * mp)
4461 {
4462   vat_main_t *vam = &vat_main;
4463   i32 retval = ntohl (mp->retval);
4464
4465   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4466
4467   if (0 <= retval)
4468     {
4469       print (vam->ofp, "ttl: %u", mp->ttl);
4470     }
4471
4472   vam->retval = retval;
4473   vam->result_ready = 1;
4474 }
4475
4476 static void
4477   vl_api_show_one_map_register_ttl_reply_t_handler_json
4478   (vl_api_show_one_map_register_ttl_reply_t * mp)
4479 {
4480   vat_main_t *vam = &vat_main;
4481   vat_json_node_t node;
4482
4483   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4484   vat_json_init_object (&node);
4485   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4486
4487   vat_json_print (vam->ofp, &node);
4488   vat_json_free (&node);
4489
4490   vam->retval = ntohl (mp->retval);
4491   vam->result_ready = 1;
4492 }
4493
4494 static void
4495 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4496 {
4497   vat_main_t *vam = &vat_main;
4498   i32 retval = ntohl (mp->retval);
4499
4500   if (0 <= retval)
4501     {
4502       print (vam->ofp, "%-20s%-16s",
4503              mp->status ? "enabled" : "disabled",
4504              mp->status ? (char *) mp->locator_set_name : "");
4505     }
4506
4507   vam->retval = retval;
4508   vam->result_ready = 1;
4509 }
4510
4511 static void
4512 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4513 {
4514   vat_main_t *vam = &vat_main;
4515   vat_json_node_t node;
4516   u8 *status = 0;
4517
4518   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4519   vec_add1 (status, 0);
4520
4521   vat_json_init_object (&node);
4522   vat_json_object_add_string_copy (&node, "status", status);
4523   if (mp->status)
4524     {
4525       vat_json_object_add_string_copy (&node, "locator_set",
4526                                        mp->locator_set_name);
4527     }
4528
4529   vec_free (status);
4530
4531   vat_json_print (vam->ofp, &node);
4532   vat_json_free (&node);
4533
4534   vam->retval = ntohl (mp->retval);
4535   vam->result_ready = 1;
4536 }
4537
4538 static u8 *
4539 format_policer_type (u8 * s, va_list * va)
4540 {
4541   u32 i = va_arg (*va, u32);
4542
4543   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4544     s = format (s, "1r2c");
4545   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4546     s = format (s, "1r3c");
4547   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4548     s = format (s, "2r3c-2698");
4549   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4550     s = format (s, "2r3c-4115");
4551   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4552     s = format (s, "2r3c-mef5cf1");
4553   else
4554     s = format (s, "ILLEGAL");
4555   return s;
4556 }
4557
4558 static u8 *
4559 format_policer_rate_type (u8 * s, va_list * va)
4560 {
4561   u32 i = va_arg (*va, u32);
4562
4563   if (i == SSE2_QOS_RATE_KBPS)
4564     s = format (s, "kbps");
4565   else if (i == SSE2_QOS_RATE_PPS)
4566     s = format (s, "pps");
4567   else
4568     s = format (s, "ILLEGAL");
4569   return s;
4570 }
4571
4572 static u8 *
4573 format_policer_round_type (u8 * s, va_list * va)
4574 {
4575   u32 i = va_arg (*va, u32);
4576
4577   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4578     s = format (s, "closest");
4579   else if (i == SSE2_QOS_ROUND_TO_UP)
4580     s = format (s, "up");
4581   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4582     s = format (s, "down");
4583   else
4584     s = format (s, "ILLEGAL");
4585   return s;
4586 }
4587
4588 static u8 *
4589 format_policer_action_type (u8 * s, va_list * va)
4590 {
4591   u32 i = va_arg (*va, u32);
4592
4593   if (i == SSE2_QOS_ACTION_DROP)
4594     s = format (s, "drop");
4595   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4596     s = format (s, "transmit");
4597   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4598     s = format (s, "mark-and-transmit");
4599   else
4600     s = format (s, "ILLEGAL");
4601   return s;
4602 }
4603
4604 static u8 *
4605 format_dscp (u8 * s, va_list * va)
4606 {
4607   u32 i = va_arg (*va, u32);
4608   char *t = 0;
4609
4610   switch (i)
4611     {
4612 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4613       foreach_vnet_dscp
4614 #undef _
4615     default:
4616       return format (s, "ILLEGAL");
4617     }
4618   s = format (s, "%s", t);
4619   return s;
4620 }
4621
4622 static void
4623 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4624 {
4625   vat_main_t *vam = &vat_main;
4626   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4627
4628   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4629     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4630   else
4631     conform_dscp_str = format (0, "");
4632
4633   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4634     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4635   else
4636     exceed_dscp_str = format (0, "");
4637
4638   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4639     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4640   else
4641     violate_dscp_str = format (0, "");
4642
4643   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4644          "rate type %U, round type %U, %s rate, %s color-aware, "
4645          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4646          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4647          "conform action %U%s, exceed action %U%s, violate action %U%s",
4648          mp->name,
4649          format_policer_type, mp->type,
4650          ntohl (mp->cir),
4651          ntohl (mp->eir),
4652          clib_net_to_host_u64 (mp->cb),
4653          clib_net_to_host_u64 (mp->eb),
4654          format_policer_rate_type, mp->rate_type,
4655          format_policer_round_type, mp->round_type,
4656          mp->single_rate ? "single" : "dual",
4657          mp->color_aware ? "is" : "not",
4658          ntohl (mp->cir_tokens_per_period),
4659          ntohl (mp->pir_tokens_per_period),
4660          ntohl (mp->scale),
4661          ntohl (mp->current_limit),
4662          ntohl (mp->current_bucket),
4663          ntohl (mp->extended_limit),
4664          ntohl (mp->extended_bucket),
4665          clib_net_to_host_u64 (mp->last_update_time),
4666          format_policer_action_type, mp->conform_action_type,
4667          conform_dscp_str,
4668          format_policer_action_type, mp->exceed_action_type,
4669          exceed_dscp_str,
4670          format_policer_action_type, mp->violate_action_type,
4671          violate_dscp_str);
4672
4673   vec_free (conform_dscp_str);
4674   vec_free (exceed_dscp_str);
4675   vec_free (violate_dscp_str);
4676 }
4677
4678 static void vl_api_policer_details_t_handler_json
4679   (vl_api_policer_details_t * mp)
4680 {
4681   vat_main_t *vam = &vat_main;
4682   vat_json_node_t *node;
4683   u8 *rate_type_str, *round_type_str, *type_str;
4684   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4685
4686   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4687   round_type_str =
4688     format (0, "%U", format_policer_round_type, mp->round_type);
4689   type_str = format (0, "%U", format_policer_type, mp->type);
4690   conform_action_str = format (0, "%U", format_policer_action_type,
4691                                mp->conform_action_type);
4692   exceed_action_str = format (0, "%U", format_policer_action_type,
4693                               mp->exceed_action_type);
4694   violate_action_str = format (0, "%U", format_policer_action_type,
4695                                mp->violate_action_type);
4696
4697   if (VAT_JSON_ARRAY != vam->json_tree.type)
4698     {
4699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4700       vat_json_init_array (&vam->json_tree);
4701     }
4702   node = vat_json_array_add (&vam->json_tree);
4703
4704   vat_json_init_object (node);
4705   vat_json_object_add_string_copy (node, "name", mp->name);
4706   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4707   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4708   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4709   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4710   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4711   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4712   vat_json_object_add_string_copy (node, "type", type_str);
4713   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4714   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4715   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4716   vat_json_object_add_uint (node, "cir_tokens_per_period",
4717                             ntohl (mp->cir_tokens_per_period));
4718   vat_json_object_add_uint (node, "eir_tokens_per_period",
4719                             ntohl (mp->pir_tokens_per_period));
4720   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4721   vat_json_object_add_uint (node, "current_bucket",
4722                             ntohl (mp->current_bucket));
4723   vat_json_object_add_uint (node, "extended_limit",
4724                             ntohl (mp->extended_limit));
4725   vat_json_object_add_uint (node, "extended_bucket",
4726                             ntohl (mp->extended_bucket));
4727   vat_json_object_add_uint (node, "last_update_time",
4728                             ntohl (mp->last_update_time));
4729   vat_json_object_add_string_copy (node, "conform_action",
4730                                    conform_action_str);
4731   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4732     {
4733       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4734       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4735       vec_free (dscp_str);
4736     }
4737   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4738   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4739     {
4740       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4741       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4742       vec_free (dscp_str);
4743     }
4744   vat_json_object_add_string_copy (node, "violate_action",
4745                                    violate_action_str);
4746   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4747     {
4748       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4749       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4750       vec_free (dscp_str);
4751     }
4752
4753   vec_free (rate_type_str);
4754   vec_free (round_type_str);
4755   vec_free (type_str);
4756   vec_free (conform_action_str);
4757   vec_free (exceed_action_str);
4758   vec_free (violate_action_str);
4759 }
4760
4761 static void
4762 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4763                                            mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766   int i, count = ntohl (mp->count);
4767
4768   if (count > 0)
4769     print (vam->ofp, "classify table ids (%d) : ", count);
4770   for (i = 0; i < count; i++)
4771     {
4772       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4773       print (vam->ofp, (i < count - 1) ? "," : "");
4774     }
4775   vam->retval = ntohl (mp->retval);
4776   vam->result_ready = 1;
4777 }
4778
4779 static void
4780   vl_api_classify_table_ids_reply_t_handler_json
4781   (vl_api_classify_table_ids_reply_t * mp)
4782 {
4783   vat_main_t *vam = &vat_main;
4784   int i, count = ntohl (mp->count);
4785
4786   if (count > 0)
4787     {
4788       vat_json_node_t node;
4789
4790       vat_json_init_object (&node);
4791       for (i = 0; i < count; i++)
4792         {
4793           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4794         }
4795       vat_json_print (vam->ofp, &node);
4796       vat_json_free (&node);
4797     }
4798   vam->retval = ntohl (mp->retval);
4799   vam->result_ready = 1;
4800 }
4801
4802 static void
4803   vl_api_classify_table_by_interface_reply_t_handler
4804   (vl_api_classify_table_by_interface_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   u32 table_id;
4808
4809   table_id = ntohl (mp->l2_table_id);
4810   if (table_id != ~0)
4811     print (vam->ofp, "l2 table id : %d", table_id);
4812   else
4813     print (vam->ofp, "l2 table id : No input ACL tables configured");
4814   table_id = ntohl (mp->ip4_table_id);
4815   if (table_id != ~0)
4816     print (vam->ofp, "ip4 table id : %d", table_id);
4817   else
4818     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4819   table_id = ntohl (mp->ip6_table_id);
4820   if (table_id != ~0)
4821     print (vam->ofp, "ip6 table id : %d", table_id);
4822   else
4823     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4824   vam->retval = ntohl (mp->retval);
4825   vam->result_ready = 1;
4826 }
4827
4828 static void
4829   vl_api_classify_table_by_interface_reply_t_handler_json
4830   (vl_api_classify_table_by_interface_reply_t * mp)
4831 {
4832   vat_main_t *vam = &vat_main;
4833   vat_json_node_t node;
4834
4835   vat_json_init_object (&node);
4836
4837   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4838   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4839   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4840
4841   vat_json_print (vam->ofp, &node);
4842   vat_json_free (&node);
4843
4844   vam->retval = ntohl (mp->retval);
4845   vam->result_ready = 1;
4846 }
4847
4848 static void vl_api_policer_add_del_reply_t_handler
4849   (vl_api_policer_add_del_reply_t * mp)
4850 {
4851   vat_main_t *vam = &vat_main;
4852   i32 retval = ntohl (mp->retval);
4853   if (vam->async_mode)
4854     {
4855       vam->async_errors += (retval < 0);
4856     }
4857   else
4858     {
4859       vam->retval = retval;
4860       vam->result_ready = 1;
4861       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4862         /*
4863          * Note: this is just barely thread-safe, depends on
4864          * the main thread spinning waiting for an answer...
4865          */
4866         errmsg ("policer index %d", ntohl (mp->policer_index));
4867     }
4868 }
4869
4870 static void vl_api_policer_add_del_reply_t_handler_json
4871   (vl_api_policer_add_del_reply_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t node;
4875
4876   vat_json_init_object (&node);
4877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4878   vat_json_object_add_uint (&node, "policer_index",
4879                             ntohl (mp->policer_index));
4880
4881   vat_json_print (vam->ofp, &node);
4882   vat_json_free (&node);
4883
4884   vam->retval = ntohl (mp->retval);
4885   vam->result_ready = 1;
4886 }
4887
4888 /* Format hex dump. */
4889 u8 *
4890 format_hex_bytes (u8 * s, va_list * va)
4891 {
4892   u8 *bytes = va_arg (*va, u8 *);
4893   int n_bytes = va_arg (*va, int);
4894   uword i;
4895
4896   /* Print short or long form depending on byte count. */
4897   uword short_form = n_bytes <= 32;
4898   u32 indent = format_get_indent (s);
4899
4900   if (n_bytes == 0)
4901     return s;
4902
4903   for (i = 0; i < n_bytes; i++)
4904     {
4905       if (!short_form && (i % 32) == 0)
4906         s = format (s, "%08x: ", i);
4907       s = format (s, "%02x", bytes[i]);
4908       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4909         s = format (s, "\n%U", format_white_space, indent);
4910     }
4911
4912   return s;
4913 }
4914
4915 static void
4916 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4917                                             * mp)
4918 {
4919   vat_main_t *vam = &vat_main;
4920   i32 retval = ntohl (mp->retval);
4921   if (retval == 0)
4922     {
4923       print (vam->ofp, "classify table info :");
4924       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4925              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4926              ntohl (mp->miss_next_index));
4927       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4928              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4929              ntohl (mp->match_n_vectors));
4930       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4931              ntohl (mp->mask_length));
4932     }
4933   vam->retval = retval;
4934   vam->result_ready = 1;
4935 }
4936
4937 static void
4938   vl_api_classify_table_info_reply_t_handler_json
4939   (vl_api_classify_table_info_reply_t * mp)
4940 {
4941   vat_main_t *vam = &vat_main;
4942   vat_json_node_t node;
4943
4944   i32 retval = ntohl (mp->retval);
4945   if (retval == 0)
4946     {
4947       vat_json_init_object (&node);
4948
4949       vat_json_object_add_int (&node, "sessions",
4950                                ntohl (mp->active_sessions));
4951       vat_json_object_add_int (&node, "nexttbl",
4952                                ntohl (mp->next_table_index));
4953       vat_json_object_add_int (&node, "nextnode",
4954                                ntohl (mp->miss_next_index));
4955       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4956       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4957       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4958       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4959                       ntohl (mp->mask_length), 0);
4960       vat_json_object_add_string_copy (&node, "mask", s);
4961
4962       vat_json_print (vam->ofp, &node);
4963       vat_json_free (&node);
4964     }
4965   vam->retval = ntohl (mp->retval);
4966   vam->result_ready = 1;
4967 }
4968
4969 static void
4970 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4971                                            mp)
4972 {
4973   vat_main_t *vam = &vat_main;
4974
4975   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4976          ntohl (mp->hit_next_index), ntohl (mp->advance),
4977          ntohl (mp->opaque_index));
4978   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4979          ntohl (mp->match_length));
4980 }
4981
4982 static void
4983   vl_api_classify_session_details_t_handler_json
4984   (vl_api_classify_session_details_t * mp)
4985 {
4986   vat_main_t *vam = &vat_main;
4987   vat_json_node_t *node = NULL;
4988
4989   if (VAT_JSON_ARRAY != vam->json_tree.type)
4990     {
4991       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4992       vat_json_init_array (&vam->json_tree);
4993     }
4994   node = vat_json_array_add (&vam->json_tree);
4995
4996   vat_json_init_object (node);
4997   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4998   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4999   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5000   u8 *s =
5001     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5002             0);
5003   vat_json_object_add_string_copy (node, "match", s);
5004 }
5005
5006 static void vl_api_pg_create_interface_reply_t_handler
5007   (vl_api_pg_create_interface_reply_t * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010
5011   vam->retval = ntohl (mp->retval);
5012   vam->result_ready = 1;
5013 }
5014
5015 static void vl_api_pg_create_interface_reply_t_handler_json
5016   (vl_api_pg_create_interface_reply_t * mp)
5017 {
5018   vat_main_t *vam = &vat_main;
5019   vat_json_node_t node;
5020
5021   i32 retval = ntohl (mp->retval);
5022   if (retval == 0)
5023     {
5024       vat_json_init_object (&node);
5025
5026       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5027
5028       vat_json_print (vam->ofp, &node);
5029       vat_json_free (&node);
5030     }
5031   vam->retval = ntohl (mp->retval);
5032   vam->result_ready = 1;
5033 }
5034
5035 static void vl_api_policer_classify_details_t_handler
5036   (vl_api_policer_classify_details_t * mp)
5037 {
5038   vat_main_t *vam = &vat_main;
5039
5040   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5041          ntohl (mp->table_index));
5042 }
5043
5044 static void vl_api_policer_classify_details_t_handler_json
5045   (vl_api_policer_classify_details_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048   vat_json_node_t *node;
5049
5050   if (VAT_JSON_ARRAY != vam->json_tree.type)
5051     {
5052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5053       vat_json_init_array (&vam->json_tree);
5054     }
5055   node = vat_json_array_add (&vam->json_tree);
5056
5057   vat_json_init_object (node);
5058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5059   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5060 }
5061
5062 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5063   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   i32 retval = ntohl (mp->retval);
5067   if (vam->async_mode)
5068     {
5069       vam->async_errors += (retval < 0);
5070     }
5071   else
5072     {
5073       vam->retval = retval;
5074       vam->sw_if_index = ntohl (mp->sw_if_index);
5075       vam->result_ready = 1;
5076     }
5077   vam->regenerate_interface_table = 1;
5078 }
5079
5080 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5081   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5082 {
5083   vat_main_t *vam = &vat_main;
5084   vat_json_node_t node;
5085
5086   vat_json_init_object (&node);
5087   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5088   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5089
5090   vat_json_print (vam->ofp, &node);
5091   vat_json_free (&node);
5092
5093   vam->retval = ntohl (mp->retval);
5094   vam->result_ready = 1;
5095 }
5096
5097 static void vl_api_flow_classify_details_t_handler
5098   (vl_api_flow_classify_details_t * mp)
5099 {
5100   vat_main_t *vam = &vat_main;
5101
5102   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5103          ntohl (mp->table_index));
5104 }
5105
5106 static void vl_api_flow_classify_details_t_handler_json
5107   (vl_api_flow_classify_details_t * mp)
5108 {
5109   vat_main_t *vam = &vat_main;
5110   vat_json_node_t *node;
5111
5112   if (VAT_JSON_ARRAY != vam->json_tree.type)
5113     {
5114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5115       vat_json_init_array (&vam->json_tree);
5116     }
5117   node = vat_json_array_add (&vam->json_tree);
5118
5119   vat_json_init_object (node);
5120   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5121   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5122 }
5123
5124 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5125 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5126 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5127 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5128 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5129 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5130 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5131 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5132 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5133 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5134
5135 /*
5136  * Generate boilerplate reply handlers, which
5137  * dig the return value out of the xxx_reply_t API message,
5138  * stick it into vam->retval, and set vam->result_ready
5139  *
5140  * Could also do this by pointing N message decode slots at
5141  * a single function, but that could break in subtle ways.
5142  */
5143
5144 #define foreach_standard_reply_retval_handler           \
5145 _(sw_interface_set_flags_reply)                         \
5146 _(sw_interface_add_del_address_reply)                   \
5147 _(sw_interface_set_rx_mode_reply)                       \
5148 _(sw_interface_set_rx_placement_reply)                  \
5149 _(sw_interface_set_table_reply)                         \
5150 _(sw_interface_set_mpls_enable_reply)                   \
5151 _(sw_interface_set_vpath_reply)                         \
5152 _(sw_interface_set_vxlan_bypass_reply)                  \
5153 _(sw_interface_set_geneve_bypass_reply)                 \
5154 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5155 _(sw_interface_set_l2_bridge_reply)                     \
5156 _(bridge_domain_add_del_reply)                          \
5157 _(sw_interface_set_l2_xconnect_reply)                   \
5158 _(l2fib_add_del_reply)                                  \
5159 _(l2fib_flush_int_reply)                                \
5160 _(l2fib_flush_bd_reply)                                 \
5161 _(ip_add_del_route_reply)                               \
5162 _(ip_table_add_del_reply)                               \
5163 _(ip_mroute_add_del_reply)                              \
5164 _(mpls_route_add_del_reply)                             \
5165 _(mpls_table_add_del_reply)                             \
5166 _(mpls_ip_bind_unbind_reply)                            \
5167 _(bier_route_add_del_reply)                             \
5168 _(bier_table_add_del_reply)                             \
5169 _(proxy_arp_add_del_reply)                              \
5170 _(proxy_arp_intfc_enable_disable_reply)                 \
5171 _(sw_interface_set_unnumbered_reply)                    \
5172 _(ip_neighbor_add_del_reply)                            \
5173 _(oam_add_del_reply)                                    \
5174 _(reset_fib_reply)                                      \
5175 _(dhcp_proxy_config_reply)                              \
5176 _(dhcp_proxy_set_vss_reply)                             \
5177 _(dhcp_client_config_reply)                             \
5178 _(set_ip_flow_hash_reply)                               \
5179 _(sw_interface_ip6_enable_disable_reply)                \
5180 _(ip6nd_proxy_add_del_reply)                            \
5181 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5182 _(sw_interface_ip6nd_ra_config_reply)                   \
5183 _(set_arp_neighbor_limit_reply)                         \
5184 _(l2_patch_add_del_reply)                               \
5185 _(sr_mpls_policy_add_reply)                             \
5186 _(sr_mpls_policy_mod_reply)                             \
5187 _(sr_mpls_policy_del_reply)                             \
5188 _(sr_policy_add_reply)                                  \
5189 _(sr_policy_mod_reply)                                  \
5190 _(sr_policy_del_reply)                                  \
5191 _(sr_localsid_add_del_reply)                            \
5192 _(sr_steering_add_del_reply)                            \
5193 _(classify_add_del_session_reply)                       \
5194 _(classify_set_interface_ip_table_reply)                \
5195 _(classify_set_interface_l2_tables_reply)               \
5196 _(l2tpv3_set_tunnel_cookies_reply)                      \
5197 _(l2tpv3_interface_enable_disable_reply)                \
5198 _(l2tpv3_set_lookup_key_reply)                          \
5199 _(l2_fib_clear_table_reply)                             \
5200 _(l2_interface_efp_filter_reply)                        \
5201 _(l2_interface_vlan_tag_rewrite_reply)                  \
5202 _(modify_vhost_user_if_reply)                           \
5203 _(delete_vhost_user_if_reply)                           \
5204 _(ip_probe_neighbor_reply)                              \
5205 _(ip_scan_neighbor_enable_disable_reply)                \
5206 _(want_ip4_arp_events_reply)                            \
5207 _(want_ip6_nd_events_reply)                             \
5208 _(want_l2_macs_events_reply)                            \
5209 _(input_acl_set_interface_reply)                        \
5210 _(ipsec_spd_add_del_reply)                              \
5211 _(ipsec_interface_add_del_spd_reply)                    \
5212 _(ipsec_spd_entry_add_del_reply)                        \
5213 _(ipsec_sad_entry_add_del_reply)                        \
5214 _(ipsec_sa_set_key_reply)                               \
5215 _(ipsec_tunnel_if_add_del_reply)                        \
5216 _(ipsec_tunnel_if_set_key_reply)                        \
5217 _(ipsec_tunnel_if_set_sa_reply)                         \
5218 _(delete_loopback_reply)                                \
5219 _(bd_ip_mac_add_del_reply)                              \
5220 _(bd_ip_mac_flush_reply)                                \
5221 _(want_interface_events_reply)                          \
5222 _(cop_interface_enable_disable_reply)                   \
5223 _(cop_whitelist_enable_disable_reply)                   \
5224 _(sw_interface_clear_stats_reply)                       \
5225 _(ioam_enable_reply)                                    \
5226 _(ioam_disable_reply)                                   \
5227 _(one_add_del_locator_reply)                            \
5228 _(one_add_del_local_eid_reply)                          \
5229 _(one_add_del_remote_mapping_reply)                     \
5230 _(one_add_del_adjacency_reply)                          \
5231 _(one_add_del_map_resolver_reply)                       \
5232 _(one_add_del_map_server_reply)                         \
5233 _(one_enable_disable_reply)                             \
5234 _(one_rloc_probe_enable_disable_reply)                  \
5235 _(one_map_register_enable_disable_reply)                \
5236 _(one_map_register_set_ttl_reply)                       \
5237 _(one_set_transport_protocol_reply)                     \
5238 _(one_map_register_fallback_threshold_reply)            \
5239 _(one_pitr_set_locator_set_reply)                       \
5240 _(one_map_request_mode_reply)                           \
5241 _(one_add_del_map_request_itr_rlocs_reply)              \
5242 _(one_eid_table_add_del_map_reply)                      \
5243 _(one_use_petr_reply)                                   \
5244 _(one_stats_enable_disable_reply)                       \
5245 _(one_add_del_l2_arp_entry_reply)                       \
5246 _(one_add_del_ndp_entry_reply)                          \
5247 _(one_stats_flush_reply)                                \
5248 _(one_enable_disable_xtr_mode_reply)                    \
5249 _(one_enable_disable_pitr_mode_reply)                   \
5250 _(one_enable_disable_petr_mode_reply)                   \
5251 _(gpe_enable_disable_reply)                             \
5252 _(gpe_set_encap_mode_reply)                             \
5253 _(gpe_add_del_iface_reply)                              \
5254 _(gpe_add_del_native_fwd_rpath_reply)                   \
5255 _(af_packet_delete_reply)                               \
5256 _(policer_classify_set_interface_reply)                 \
5257 _(netmap_create_reply)                                  \
5258 _(netmap_delete_reply)                                  \
5259 _(set_ipfix_exporter_reply)                             \
5260 _(set_ipfix_classify_stream_reply)                      \
5261 _(ipfix_classify_table_add_del_reply)                   \
5262 _(flow_classify_set_interface_reply)                    \
5263 _(sw_interface_span_enable_disable_reply)               \
5264 _(pg_capture_reply)                                     \
5265 _(pg_enable_disable_reply)                              \
5266 _(ip_source_and_port_range_check_add_del_reply)         \
5267 _(ip_source_and_port_range_check_interface_add_del_reply)\
5268 _(delete_subif_reply)                                   \
5269 _(l2_interface_pbb_tag_rewrite_reply)                   \
5270 _(set_punt_reply)                                       \
5271 _(feature_enable_disable_reply)                         \
5272 _(sw_interface_tag_add_del_reply)                       \
5273 _(hw_interface_set_mtu_reply)                           \
5274 _(p2p_ethernet_add_reply)                               \
5275 _(p2p_ethernet_del_reply)                               \
5276 _(lldp_config_reply)                                    \
5277 _(sw_interface_set_lldp_reply)                          \
5278 _(tcp_configure_src_addresses_reply)                    \
5279 _(dns_enable_disable_reply)                             \
5280 _(dns_name_server_add_del_reply)                        \
5281 _(session_rule_add_del_reply)                           \
5282 _(ip_container_proxy_add_del_reply)                     \
5283 _(output_acl_set_interface_reply)                       \
5284 _(qos_record_enable_disable_reply)
5285
5286 #define _(n)                                    \
5287     static void vl_api_##n##_t_handler          \
5288     (vl_api_##n##_t * mp)                       \
5289     {                                           \
5290         vat_main_t * vam = &vat_main;           \
5291         i32 retval = ntohl(mp->retval);         \
5292         if (vam->async_mode) {                  \
5293             vam->async_errors += (retval < 0);  \
5294         } else {                                \
5295             vam->retval = retval;               \
5296             vam->result_ready = 1;              \
5297         }                                       \
5298     }
5299 foreach_standard_reply_retval_handler;
5300 #undef _
5301
5302 #define _(n)                                    \
5303     static void vl_api_##n##_t_handler_json     \
5304     (vl_api_##n##_t * mp)                       \
5305     {                                           \
5306         vat_main_t * vam = &vat_main;           \
5307         vat_json_node_t node;                   \
5308         vat_json_init_object(&node);            \
5309         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5310         vat_json_print(vam->ofp, &node);        \
5311         vam->retval = ntohl(mp->retval);        \
5312         vam->result_ready = 1;                  \
5313     }
5314 foreach_standard_reply_retval_handler;
5315 #undef _
5316
5317 /*
5318  * Table of message reply handlers, must include boilerplate handlers
5319  * we just generated
5320  */
5321
5322 #define foreach_vpe_api_reply_msg                                       \
5323 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5324 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5325 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5326 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5327 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5328 _(CLI_REPLY, cli_reply)                                                 \
5329 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5330 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5331   sw_interface_add_del_address_reply)                                   \
5332 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5333 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5334 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5335 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5336 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5337 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5338 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5339 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5340 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5341 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5342   sw_interface_set_l2_xconnect_reply)                                   \
5343 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5344   sw_interface_set_l2_bridge_reply)                                     \
5345 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5346 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5347 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5348 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5349 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5350 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5351 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5352 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5353 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5354 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5355 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5356 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5357 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5358 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5359 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5360 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5361 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5362 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5363 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5364 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5365 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5366 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5367 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5368 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5369 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5370 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5371 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5372 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5373 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5374 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5375   proxy_arp_intfc_enable_disable_reply)                                 \
5376 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5377 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5378   sw_interface_set_unnumbered_reply)                                    \
5379 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5380 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5381 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5382 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5383 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5384 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5385 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5386 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5387 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5388 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5389 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5390   sw_interface_ip6_enable_disable_reply)                                \
5391 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5392 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5393 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5394   sw_interface_ip6nd_ra_prefix_reply)                                   \
5395 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5396   sw_interface_ip6nd_ra_config_reply)                                   \
5397 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5398 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5399 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5400 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5401 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5402 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5403 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5404 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5405 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5406 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5407 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5408 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5409 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5410 classify_set_interface_ip_table_reply)                                  \
5411 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5412   classify_set_interface_l2_tables_reply)                               \
5413 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5414 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5415 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5416 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5417 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5418   l2tpv3_interface_enable_disable_reply)                                \
5419 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5420 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5421 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5422 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5423 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5424 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5425 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5426 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5427 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5428 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5429 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5430 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5431 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5432 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5433 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5434 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5435 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5436 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5437 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5438 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5439 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5440 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5441 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5442 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5443 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5444 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5445 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5446 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5447 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5448 _(L2_MACS_EVENT, l2_macs_event)                                         \
5449 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5450 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5451 _(IP_DETAILS, ip_details)                                               \
5452 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5453 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5454 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5455 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5456 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5457 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5458 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5459 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5460 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5461 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5462 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5463 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5464 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5465 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5466 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5467 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5468 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5469 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5470 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5471 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5472 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5473 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5474 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5475 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5476 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5477 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5478 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5479 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5480 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5481 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5482 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5483   one_map_register_enable_disable_reply)                                \
5484 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5485 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5486 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5487 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5488   one_map_register_fallback_threshold_reply)                            \
5489 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5490   one_rloc_probe_enable_disable_reply)                                  \
5491 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5492 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5493 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5494 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5495 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5496 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5497 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5498 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5499 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5500 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5501 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5502 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5503 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5504 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5505 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5506 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5507   show_one_stats_enable_disable_reply)                                  \
5508 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5509 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5510 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5511 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5512 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5513 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5514 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5515 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5516   one_enable_disable_pitr_mode_reply)                                   \
5517 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5518   one_enable_disable_petr_mode_reply)                                   \
5519 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5520 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5521 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5522 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5523 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5524 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5525 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5526 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5527 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5528 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5529 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5530 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5531   gpe_add_del_native_fwd_rpath_reply)                                   \
5532 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5533   gpe_fwd_entry_path_details)                                           \
5534 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5535 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5536   one_add_del_map_request_itr_rlocs_reply)                              \
5537 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5538   one_get_map_request_itr_rlocs_reply)                                  \
5539 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5540 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5541 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5542 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5543 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5544 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5545   show_one_map_register_state_reply)                                    \
5546 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5547 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5548   show_one_map_register_fallback_threshold_reply)                       \
5549 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5550 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5551 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5552 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5553 _(POLICER_DETAILS, policer_details)                                     \
5554 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5555 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5556 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5557 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5558 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5559 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5560 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5561 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5562 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5563 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5564 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5565 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5566 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5567 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5568 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5569 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5570 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5571 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5572 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5573 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5574 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5575 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5576 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5577 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5578 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5579  ip_source_and_port_range_check_add_del_reply)                          \
5580 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5581  ip_source_and_port_range_check_interface_add_del_reply)                \
5582 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5583 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5584 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5585 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5586 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5587 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5588 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5589 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5590 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5591 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5592 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5593 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5594 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5595 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5596 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5597 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5598 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5599 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5600 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5601 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5602 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5603 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5604 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5605 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5606 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5607 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5608 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5609 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5610
5611 #define foreach_standalone_reply_msg                                    \
5612 _(SW_INTERFACE_EVENT, sw_interface_event)
5613
5614 typedef struct
5615 {
5616   u8 *name;
5617   u32 value;
5618 } name_sort_t;
5619
5620 #define STR_VTR_OP_CASE(op)     \
5621     case L2_VTR_ ## op:         \
5622         return "" # op;
5623
5624 static const char *
5625 str_vtr_op (u32 vtr_op)
5626 {
5627   switch (vtr_op)
5628     {
5629       STR_VTR_OP_CASE (DISABLED);
5630       STR_VTR_OP_CASE (PUSH_1);
5631       STR_VTR_OP_CASE (PUSH_2);
5632       STR_VTR_OP_CASE (POP_1);
5633       STR_VTR_OP_CASE (POP_2);
5634       STR_VTR_OP_CASE (TRANSLATE_1_1);
5635       STR_VTR_OP_CASE (TRANSLATE_1_2);
5636       STR_VTR_OP_CASE (TRANSLATE_2_1);
5637       STR_VTR_OP_CASE (TRANSLATE_2_2);
5638     }
5639
5640   return "UNKNOWN";
5641 }
5642
5643 static int
5644 dump_sub_interface_table (vat_main_t * vam)
5645 {
5646   const sw_interface_subif_t *sub = NULL;
5647
5648   if (vam->json_output)
5649     {
5650       clib_warning
5651         ("JSON output supported only for VPE API calls and dump_stats_table");
5652       return -99;
5653     }
5654
5655   print (vam->ofp,
5656          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5657          "Interface", "sw_if_index",
5658          "sub id", "dot1ad", "tags", "outer id",
5659          "inner id", "exact", "default", "outer any", "inner any");
5660
5661   vec_foreach (sub, vam->sw_if_subif_table)
5662   {
5663     print (vam->ofp,
5664            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5665            sub->interface_name,
5666            sub->sw_if_index,
5667            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5668            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5669            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5670            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5671     if (sub->vtr_op != L2_VTR_DISABLED)
5672       {
5673         print (vam->ofp,
5674                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5675                "tag1: %d tag2: %d ]",
5676                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5677                sub->vtr_tag1, sub->vtr_tag2);
5678       }
5679   }
5680
5681   return 0;
5682 }
5683
5684 static int
5685 name_sort_cmp (void *a1, void *a2)
5686 {
5687   name_sort_t *n1 = a1;
5688   name_sort_t *n2 = a2;
5689
5690   return strcmp ((char *) n1->name, (char *) n2->name);
5691 }
5692
5693 static int
5694 dump_interface_table (vat_main_t * vam)
5695 {
5696   hash_pair_t *p;
5697   name_sort_t *nses = 0, *ns;
5698
5699   if (vam->json_output)
5700     {
5701       clib_warning
5702         ("JSON output supported only for VPE API calls and dump_stats_table");
5703       return -99;
5704     }
5705
5706   /* *INDENT-OFF* */
5707   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5708   ({
5709     vec_add2 (nses, ns, 1);
5710     ns->name = (u8 *)(p->key);
5711     ns->value = (u32) p->value[0];
5712   }));
5713   /* *INDENT-ON* */
5714
5715   vec_sort_with_function (nses, name_sort_cmp);
5716
5717   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5718   vec_foreach (ns, nses)
5719   {
5720     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5721   }
5722   vec_free (nses);
5723   return 0;
5724 }
5725
5726 static int
5727 dump_ip_table (vat_main_t * vam, int is_ipv6)
5728 {
5729   const ip_details_t *det = NULL;
5730   const ip_address_details_t *address = NULL;
5731   u32 i = ~0;
5732
5733   print (vam->ofp, "%-12s", "sw_if_index");
5734
5735   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5736   {
5737     i++;
5738     if (!det->present)
5739       {
5740         continue;
5741       }
5742     print (vam->ofp, "%-12d", i);
5743     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5744     if (!det->addr)
5745       {
5746         continue;
5747       }
5748     vec_foreach (address, det->addr)
5749     {
5750       print (vam->ofp,
5751              "            %-30U%-13d",
5752              is_ipv6 ? format_ip6_address : format_ip4_address,
5753              address->ip, address->prefix_length);
5754     }
5755   }
5756
5757   return 0;
5758 }
5759
5760 static int
5761 dump_ipv4_table (vat_main_t * vam)
5762 {
5763   if (vam->json_output)
5764     {
5765       clib_warning
5766         ("JSON output supported only for VPE API calls and dump_stats_table");
5767       return -99;
5768     }
5769
5770   return dump_ip_table (vam, 0);
5771 }
5772
5773 static int
5774 dump_ipv6_table (vat_main_t * vam)
5775 {
5776   if (vam->json_output)
5777     {
5778       clib_warning
5779         ("JSON output supported only for VPE API calls and dump_stats_table");
5780       return -99;
5781     }
5782
5783   return dump_ip_table (vam, 1);
5784 }
5785
5786 /*
5787  * Pass CLI buffers directly in the CLI_INBAND API message,
5788  * instead of an additional shared memory area.
5789  */
5790 static int
5791 exec_inband (vat_main_t * vam)
5792 {
5793   vl_api_cli_inband_t *mp;
5794   unformat_input_t *i = vam->input;
5795   int ret;
5796
5797   if (vec_len (i->buffer) == 0)
5798     return -1;
5799
5800   if (vam->exec_mode == 0 && unformat (i, "mode"))
5801     {
5802       vam->exec_mode = 1;
5803       return 0;
5804     }
5805   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5806     {
5807       vam->exec_mode = 0;
5808       return 0;
5809     }
5810
5811   /*
5812    * In order for the CLI command to work, it
5813    * must be a vector ending in \n, not a C-string ending
5814    * in \n\0.
5815    */
5816   u32 len = vec_len (vam->input->buffer);
5817   M2 (CLI_INBAND, mp, len);
5818   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5819
5820   S (mp);
5821   W (ret);
5822   /* json responses may or may not include a useful reply... */
5823   if (vec_len (vam->cmd_reply))
5824     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5825   return ret;
5826 }
5827
5828 int
5829 exec (vat_main_t * vam)
5830 {
5831   return exec_inband (vam);
5832 }
5833
5834 static int
5835 api_create_loopback (vat_main_t * vam)
5836 {
5837   unformat_input_t *i = vam->input;
5838   vl_api_create_loopback_t *mp;
5839   vl_api_create_loopback_instance_t *mp_lbi;
5840   u8 mac_address[6];
5841   u8 mac_set = 0;
5842   u8 is_specified = 0;
5843   u32 user_instance = 0;
5844   int ret;
5845
5846   clib_memset (mac_address, 0, sizeof (mac_address));
5847
5848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5849     {
5850       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5851         mac_set = 1;
5852       if (unformat (i, "instance %d", &user_instance))
5853         is_specified = 1;
5854       else
5855         break;
5856     }
5857
5858   if (is_specified)
5859     {
5860       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5861       mp_lbi->is_specified = is_specified;
5862       if (is_specified)
5863         mp_lbi->user_instance = htonl (user_instance);
5864       if (mac_set)
5865         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5866       S (mp_lbi);
5867     }
5868   else
5869     {
5870       /* Construct the API message */
5871       M (CREATE_LOOPBACK, mp);
5872       if (mac_set)
5873         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5874       S (mp);
5875     }
5876
5877   W (ret);
5878   return ret;
5879 }
5880
5881 static int
5882 api_delete_loopback (vat_main_t * vam)
5883 {
5884   unformat_input_t *i = vam->input;
5885   vl_api_delete_loopback_t *mp;
5886   u32 sw_if_index = ~0;
5887   int ret;
5888
5889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5890     {
5891       if (unformat (i, "sw_if_index %d", &sw_if_index))
5892         ;
5893       else
5894         break;
5895     }
5896
5897   if (sw_if_index == ~0)
5898     {
5899       errmsg ("missing sw_if_index");
5900       return -99;
5901     }
5902
5903   /* Construct the API message */
5904   M (DELETE_LOOPBACK, mp);
5905   mp->sw_if_index = ntohl (sw_if_index);
5906
5907   S (mp);
5908   W (ret);
5909   return ret;
5910 }
5911
5912 static int
5913 api_want_interface_events (vat_main_t * vam)
5914 {
5915   unformat_input_t *i = vam->input;
5916   vl_api_want_interface_events_t *mp;
5917   int enable = -1;
5918   int ret;
5919
5920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5921     {
5922       if (unformat (i, "enable"))
5923         enable = 1;
5924       else if (unformat (i, "disable"))
5925         enable = 0;
5926       else
5927         break;
5928     }
5929
5930   if (enable == -1)
5931     {
5932       errmsg ("missing enable|disable");
5933       return -99;
5934     }
5935
5936   M (WANT_INTERFACE_EVENTS, mp);
5937   mp->enable_disable = enable;
5938
5939   vam->interface_event_display = enable;
5940
5941   S (mp);
5942   W (ret);
5943   return ret;
5944 }
5945
5946
5947 /* Note: non-static, called once to set up the initial intfc table */
5948 int
5949 api_sw_interface_dump (vat_main_t * vam)
5950 {
5951   vl_api_sw_interface_dump_t *mp;
5952   vl_api_control_ping_t *mp_ping;
5953   hash_pair_t *p;
5954   name_sort_t *nses = 0, *ns;
5955   sw_interface_subif_t *sub = NULL;
5956   int ret;
5957
5958   /* Toss the old name table */
5959   /* *INDENT-OFF* */
5960   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5961   ({
5962     vec_add2 (nses, ns, 1);
5963     ns->name = (u8 *)(p->key);
5964     ns->value = (u32) p->value[0];
5965   }));
5966   /* *INDENT-ON* */
5967
5968   hash_free (vam->sw_if_index_by_interface_name);
5969
5970   vec_foreach (ns, nses) vec_free (ns->name);
5971
5972   vec_free (nses);
5973
5974   vec_foreach (sub, vam->sw_if_subif_table)
5975   {
5976     vec_free (sub->interface_name);
5977   }
5978   vec_free (vam->sw_if_subif_table);
5979
5980   /* recreate the interface name hash table */
5981   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5982
5983   /*
5984    * Ask for all interface names. Otherwise, the epic catalog of
5985    * name filters becomes ridiculously long, and vat ends up needing
5986    * to be taught about new interface types.
5987    */
5988   M (SW_INTERFACE_DUMP, mp);
5989   S (mp);
5990
5991   /* Use a control ping for synchronization */
5992   MPING (CONTROL_PING, mp_ping);
5993   S (mp_ping);
5994
5995   W (ret);
5996   return ret;
5997 }
5998
5999 static int
6000 api_sw_interface_set_flags (vat_main_t * vam)
6001 {
6002   unformat_input_t *i = vam->input;
6003   vl_api_sw_interface_set_flags_t *mp;
6004   u32 sw_if_index;
6005   u8 sw_if_index_set = 0;
6006   u8 admin_up = 0;
6007   int ret;
6008
6009   /* Parse args required to build the message */
6010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6011     {
6012       if (unformat (i, "admin-up"))
6013         admin_up = 1;
6014       else if (unformat (i, "admin-down"))
6015         admin_up = 0;
6016       else
6017         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6018         sw_if_index_set = 1;
6019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6020         sw_if_index_set = 1;
6021       else
6022         break;
6023     }
6024
6025   if (sw_if_index_set == 0)
6026     {
6027       errmsg ("missing interface name or sw_if_index");
6028       return -99;
6029     }
6030
6031   /* Construct the API message */
6032   M (SW_INTERFACE_SET_FLAGS, mp);
6033   mp->sw_if_index = ntohl (sw_if_index);
6034   mp->admin_up_down = admin_up;
6035
6036   /* send it... */
6037   S (mp);
6038
6039   /* Wait for a reply, return the good/bad news... */
6040   W (ret);
6041   return ret;
6042 }
6043
6044 static int
6045 api_sw_interface_set_rx_mode (vat_main_t * vam)
6046 {
6047   unformat_input_t *i = vam->input;
6048   vl_api_sw_interface_set_rx_mode_t *mp;
6049   u32 sw_if_index;
6050   u8 sw_if_index_set = 0;
6051   int ret;
6052   u8 queue_id_valid = 0;
6053   u32 queue_id;
6054   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6055
6056   /* Parse args required to build the message */
6057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6058     {
6059       if (unformat (i, "queue %d", &queue_id))
6060         queue_id_valid = 1;
6061       else if (unformat (i, "polling"))
6062         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6063       else if (unformat (i, "interrupt"))
6064         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6065       else if (unformat (i, "adaptive"))
6066         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6067       else
6068         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6069         sw_if_index_set = 1;
6070       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6071         sw_if_index_set = 1;
6072       else
6073         break;
6074     }
6075
6076   if (sw_if_index_set == 0)
6077     {
6078       errmsg ("missing interface name or sw_if_index");
6079       return -99;
6080     }
6081   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6082     {
6083       errmsg ("missing rx-mode");
6084       return -99;
6085     }
6086
6087   /* Construct the API message */
6088   M (SW_INTERFACE_SET_RX_MODE, mp);
6089   mp->sw_if_index = ntohl (sw_if_index);
6090   mp->mode = mode;
6091   mp->queue_id_valid = queue_id_valid;
6092   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6093
6094   /* send it... */
6095   S (mp);
6096
6097   /* Wait for a reply, return the good/bad news... */
6098   W (ret);
6099   return ret;
6100 }
6101
6102 static int
6103 api_sw_interface_set_rx_placement (vat_main_t * vam)
6104 {
6105   unformat_input_t *i = vam->input;
6106   vl_api_sw_interface_set_rx_placement_t *mp;
6107   u32 sw_if_index;
6108   u8 sw_if_index_set = 0;
6109   int ret;
6110   u8 is_main = 0;
6111   u32 queue_id, thread_index;
6112
6113   /* Parse args required to build the message */
6114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6115     {
6116       if (unformat (i, "queue %d", &queue_id))
6117         ;
6118       else if (unformat (i, "main"))
6119         is_main = 1;
6120       else if (unformat (i, "worker %d", &thread_index))
6121         ;
6122       else
6123         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6124         sw_if_index_set = 1;
6125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6126         sw_if_index_set = 1;
6127       else
6128         break;
6129     }
6130
6131   if (sw_if_index_set == 0)
6132     {
6133       errmsg ("missing interface name or sw_if_index");
6134       return -99;
6135     }
6136
6137   if (is_main)
6138     thread_index = 0;
6139   /* Construct the API message */
6140   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6141   mp->sw_if_index = ntohl (sw_if_index);
6142   mp->worker_id = ntohl (thread_index);
6143   mp->queue_id = ntohl (queue_id);
6144   mp->is_main = is_main;
6145
6146   /* send it... */
6147   S (mp);
6148   /* Wait for a reply, return the good/bad news... */
6149   W (ret);
6150   return ret;
6151 }
6152
6153 static void vl_api_sw_interface_rx_placement_details_t_handler
6154   (vl_api_sw_interface_rx_placement_details_t * mp)
6155 {
6156   vat_main_t *vam = &vat_main;
6157   u32 worker_id = ntohl (mp->worker_id);
6158
6159   print (vam->ofp,
6160          "\n%-11d %-11s %-6d %-5d %-9s",
6161          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6162          worker_id, ntohl (mp->queue_id),
6163          (mp->mode ==
6164           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6165 }
6166
6167 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6168   (vl_api_sw_interface_rx_placement_details_t * mp)
6169 {
6170   vat_main_t *vam = &vat_main;
6171   vat_json_node_t *node = NULL;
6172
6173   if (VAT_JSON_ARRAY != vam->json_tree.type)
6174     {
6175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6176       vat_json_init_array (&vam->json_tree);
6177     }
6178   node = vat_json_array_add (&vam->json_tree);
6179
6180   vat_json_init_object (node);
6181   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6182   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6183   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6184   vat_json_object_add_uint (node, "mode", mp->mode);
6185 }
6186
6187 static int
6188 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6189 {
6190   unformat_input_t *i = vam->input;
6191   vl_api_sw_interface_rx_placement_dump_t *mp;
6192   vl_api_control_ping_t *mp_ping;
6193   int ret;
6194   u32 sw_if_index;
6195   u8 sw_if_index_set = 0;
6196
6197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6198     {
6199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6200         sw_if_index_set++;
6201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6202         sw_if_index_set++;
6203       else
6204         break;
6205     }
6206
6207   print (vam->ofp,
6208          "\n%-11s %-11s %-6s %-5s %-4s",
6209          "sw_if_index", "main/worker", "thread", "queue", "mode");
6210
6211   /* Dump Interface rx placement */
6212   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6213
6214   if (sw_if_index_set)
6215     mp->sw_if_index = htonl (sw_if_index);
6216   else
6217     mp->sw_if_index = ~0;
6218
6219   S (mp);
6220
6221   /* Use a control ping for synchronization */
6222   MPING (CONTROL_PING, mp_ping);
6223   S (mp_ping);
6224
6225   W (ret);
6226   return ret;
6227 }
6228
6229 static int
6230 api_sw_interface_clear_stats (vat_main_t * vam)
6231 {
6232   unformat_input_t *i = vam->input;
6233   vl_api_sw_interface_clear_stats_t *mp;
6234   u32 sw_if_index;
6235   u8 sw_if_index_set = 0;
6236   int ret;
6237
6238   /* Parse args required to build the message */
6239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6240     {
6241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6242         sw_if_index_set = 1;
6243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6244         sw_if_index_set = 1;
6245       else
6246         break;
6247     }
6248
6249   /* Construct the API message */
6250   M (SW_INTERFACE_CLEAR_STATS, mp);
6251
6252   if (sw_if_index_set == 1)
6253     mp->sw_if_index = ntohl (sw_if_index);
6254   else
6255     mp->sw_if_index = ~0;
6256
6257   /* send it... */
6258   S (mp);
6259
6260   /* Wait for a reply, return the good/bad news... */
6261   W (ret);
6262   return ret;
6263 }
6264
6265 static int
6266 api_sw_interface_add_del_address (vat_main_t * vam)
6267 {
6268   unformat_input_t *i = vam->input;
6269   vl_api_sw_interface_add_del_address_t *mp;
6270   u32 sw_if_index;
6271   u8 sw_if_index_set = 0;
6272   u8 is_add = 1, del_all = 0;
6273   u32 address_length = 0;
6274   u8 v4_address_set = 0;
6275   u8 v6_address_set = 0;
6276   ip4_address_t v4address;
6277   ip6_address_t v6address;
6278   int ret;
6279
6280   /* Parse args required to build the message */
6281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6282     {
6283       if (unformat (i, "del-all"))
6284         del_all = 1;
6285       else if (unformat (i, "del"))
6286         is_add = 0;
6287       else
6288         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6291         sw_if_index_set = 1;
6292       else if (unformat (i, "%U/%d",
6293                          unformat_ip4_address, &v4address, &address_length))
6294         v4_address_set = 1;
6295       else if (unformat (i, "%U/%d",
6296                          unformat_ip6_address, &v6address, &address_length))
6297         v6_address_set = 1;
6298       else
6299         break;
6300     }
6301
6302   if (sw_if_index_set == 0)
6303     {
6304       errmsg ("missing interface name or sw_if_index");
6305       return -99;
6306     }
6307   if (v4_address_set && v6_address_set)
6308     {
6309       errmsg ("both v4 and v6 addresses set");
6310       return -99;
6311     }
6312   if (!v4_address_set && !v6_address_set && !del_all)
6313     {
6314       errmsg ("no addresses set");
6315       return -99;
6316     }
6317
6318   /* Construct the API message */
6319   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6320
6321   mp->sw_if_index = ntohl (sw_if_index);
6322   mp->is_add = is_add;
6323   mp->del_all = del_all;
6324   if (v6_address_set)
6325     {
6326       mp->is_ipv6 = 1;
6327       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6328     }
6329   else
6330     {
6331       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6332     }
6333   mp->address_length = address_length;
6334
6335   /* send it... */
6336   S (mp);
6337
6338   /* Wait for a reply, return good/bad news  */
6339   W (ret);
6340   return ret;
6341 }
6342
6343 static int
6344 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6345 {
6346   unformat_input_t *i = vam->input;
6347   vl_api_sw_interface_set_mpls_enable_t *mp;
6348   u32 sw_if_index;
6349   u8 sw_if_index_set = 0;
6350   u8 enable = 1;
6351   int ret;
6352
6353   /* Parse args required to build the message */
6354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6355     {
6356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6357         sw_if_index_set = 1;
6358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6359         sw_if_index_set = 1;
6360       else if (unformat (i, "disable"))
6361         enable = 0;
6362       else if (unformat (i, "dis"))
6363         enable = 0;
6364       else
6365         break;
6366     }
6367
6368   if (sw_if_index_set == 0)
6369     {
6370       errmsg ("missing interface name or sw_if_index");
6371       return -99;
6372     }
6373
6374   /* Construct the API message */
6375   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6376
6377   mp->sw_if_index = ntohl (sw_if_index);
6378   mp->enable = enable;
6379
6380   /* send it... */
6381   S (mp);
6382
6383   /* Wait for a reply... */
6384   W (ret);
6385   return ret;
6386 }
6387
6388 static int
6389 api_sw_interface_set_table (vat_main_t * vam)
6390 {
6391   unformat_input_t *i = vam->input;
6392   vl_api_sw_interface_set_table_t *mp;
6393   u32 sw_if_index, vrf_id = 0;
6394   u8 sw_if_index_set = 0;
6395   u8 is_ipv6 = 0;
6396   int ret;
6397
6398   /* Parse args required to build the message */
6399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6400     {
6401       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6402         sw_if_index_set = 1;
6403       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6404         sw_if_index_set = 1;
6405       else if (unformat (i, "vrf %d", &vrf_id))
6406         ;
6407       else if (unformat (i, "ipv6"))
6408         is_ipv6 = 1;
6409       else
6410         break;
6411     }
6412
6413   if (sw_if_index_set == 0)
6414     {
6415       errmsg ("missing interface name or sw_if_index");
6416       return -99;
6417     }
6418
6419   /* Construct the API message */
6420   M (SW_INTERFACE_SET_TABLE, mp);
6421
6422   mp->sw_if_index = ntohl (sw_if_index);
6423   mp->is_ipv6 = is_ipv6;
6424   mp->vrf_id = ntohl (vrf_id);
6425
6426   /* send it... */
6427   S (mp);
6428
6429   /* Wait for a reply... */
6430   W (ret);
6431   return ret;
6432 }
6433
6434 static void vl_api_sw_interface_get_table_reply_t_handler
6435   (vl_api_sw_interface_get_table_reply_t * mp)
6436 {
6437   vat_main_t *vam = &vat_main;
6438
6439   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6440
6441   vam->retval = ntohl (mp->retval);
6442   vam->result_ready = 1;
6443
6444 }
6445
6446 static void vl_api_sw_interface_get_table_reply_t_handler_json
6447   (vl_api_sw_interface_get_table_reply_t * mp)
6448 {
6449   vat_main_t *vam = &vat_main;
6450   vat_json_node_t node;
6451
6452   vat_json_init_object (&node);
6453   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6454   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6455
6456   vat_json_print (vam->ofp, &node);
6457   vat_json_free (&node);
6458
6459   vam->retval = ntohl (mp->retval);
6460   vam->result_ready = 1;
6461 }
6462
6463 static int
6464 api_sw_interface_get_table (vat_main_t * vam)
6465 {
6466   unformat_input_t *i = vam->input;
6467   vl_api_sw_interface_get_table_t *mp;
6468   u32 sw_if_index;
6469   u8 sw_if_index_set = 0;
6470   u8 is_ipv6 = 0;
6471   int ret;
6472
6473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6474     {
6475       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6476         sw_if_index_set = 1;
6477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6478         sw_if_index_set = 1;
6479       else if (unformat (i, "ipv6"))
6480         is_ipv6 = 1;
6481       else
6482         break;
6483     }
6484
6485   if (sw_if_index_set == 0)
6486     {
6487       errmsg ("missing interface name or sw_if_index");
6488       return -99;
6489     }
6490
6491   M (SW_INTERFACE_GET_TABLE, mp);
6492   mp->sw_if_index = htonl (sw_if_index);
6493   mp->is_ipv6 = is_ipv6;
6494
6495   S (mp);
6496   W (ret);
6497   return ret;
6498 }
6499
6500 static int
6501 api_sw_interface_set_vpath (vat_main_t * vam)
6502 {
6503   unformat_input_t *i = vam->input;
6504   vl_api_sw_interface_set_vpath_t *mp;
6505   u32 sw_if_index = 0;
6506   u8 sw_if_index_set = 0;
6507   u8 is_enable = 0;
6508   int ret;
6509
6510   /* Parse args required to build the message */
6511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6512     {
6513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6514         sw_if_index_set = 1;
6515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "enable"))
6518         is_enable = 1;
6519       else if (unformat (i, "disable"))
6520         is_enable = 0;
6521       else
6522         break;
6523     }
6524
6525   if (sw_if_index_set == 0)
6526     {
6527       errmsg ("missing interface name or sw_if_index");
6528       return -99;
6529     }
6530
6531   /* Construct the API message */
6532   M (SW_INTERFACE_SET_VPATH, mp);
6533
6534   mp->sw_if_index = ntohl (sw_if_index);
6535   mp->enable = is_enable;
6536
6537   /* send it... */
6538   S (mp);
6539
6540   /* Wait for a reply... */
6541   W (ret);
6542   return ret;
6543 }
6544
6545 static int
6546 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6550   u32 sw_if_index = 0;
6551   u8 sw_if_index_set = 0;
6552   u8 is_enable = 1;
6553   u8 is_ipv6 = 0;
6554   int ret;
6555
6556   /* Parse args required to build the message */
6557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6558     {
6559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6560         sw_if_index_set = 1;
6561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6562         sw_if_index_set = 1;
6563       else if (unformat (i, "enable"))
6564         is_enable = 1;
6565       else if (unformat (i, "disable"))
6566         is_enable = 0;
6567       else if (unformat (i, "ip4"))
6568         is_ipv6 = 0;
6569       else if (unformat (i, "ip6"))
6570         is_ipv6 = 1;
6571       else
6572         break;
6573     }
6574
6575   if (sw_if_index_set == 0)
6576     {
6577       errmsg ("missing interface name or sw_if_index");
6578       return -99;
6579     }
6580
6581   /* Construct the API message */
6582   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6583
6584   mp->sw_if_index = ntohl (sw_if_index);
6585   mp->enable = is_enable;
6586   mp->is_ipv6 = is_ipv6;
6587
6588   /* send it... */
6589   S (mp);
6590
6591   /* Wait for a reply... */
6592   W (ret);
6593   return ret;
6594 }
6595
6596 static int
6597 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6598 {
6599   unformat_input_t *i = vam->input;
6600   vl_api_sw_interface_set_geneve_bypass_t *mp;
6601   u32 sw_if_index = 0;
6602   u8 sw_if_index_set = 0;
6603   u8 is_enable = 1;
6604   u8 is_ipv6 = 0;
6605   int ret;
6606
6607   /* Parse args required to build the message */
6608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6609     {
6610       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6611         sw_if_index_set = 1;
6612       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6613         sw_if_index_set = 1;
6614       else if (unformat (i, "enable"))
6615         is_enable = 1;
6616       else if (unformat (i, "disable"))
6617         is_enable = 0;
6618       else if (unformat (i, "ip4"))
6619         is_ipv6 = 0;
6620       else if (unformat (i, "ip6"))
6621         is_ipv6 = 1;
6622       else
6623         break;
6624     }
6625
6626   if (sw_if_index_set == 0)
6627     {
6628       errmsg ("missing interface name or sw_if_index");
6629       return -99;
6630     }
6631
6632   /* Construct the API message */
6633   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6634
6635   mp->sw_if_index = ntohl (sw_if_index);
6636   mp->enable = is_enable;
6637   mp->is_ipv6 = is_ipv6;
6638
6639   /* send it... */
6640   S (mp);
6641
6642   /* Wait for a reply... */
6643   W (ret);
6644   return ret;
6645 }
6646
6647 static int
6648 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6649 {
6650   unformat_input_t *i = vam->input;
6651   vl_api_sw_interface_set_l2_xconnect_t *mp;
6652   u32 rx_sw_if_index;
6653   u8 rx_sw_if_index_set = 0;
6654   u32 tx_sw_if_index;
6655   u8 tx_sw_if_index_set = 0;
6656   u8 enable = 1;
6657   int ret;
6658
6659   /* Parse args required to build the message */
6660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6661     {
6662       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6663         rx_sw_if_index_set = 1;
6664       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6665         tx_sw_if_index_set = 1;
6666       else if (unformat (i, "rx"))
6667         {
6668           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6669             {
6670               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6671                             &rx_sw_if_index))
6672                 rx_sw_if_index_set = 1;
6673             }
6674           else
6675             break;
6676         }
6677       else if (unformat (i, "tx"))
6678         {
6679           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6680             {
6681               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6682                             &tx_sw_if_index))
6683                 tx_sw_if_index_set = 1;
6684             }
6685           else
6686             break;
6687         }
6688       else if (unformat (i, "enable"))
6689         enable = 1;
6690       else if (unformat (i, "disable"))
6691         enable = 0;
6692       else
6693         break;
6694     }
6695
6696   if (rx_sw_if_index_set == 0)
6697     {
6698       errmsg ("missing rx interface name or rx_sw_if_index");
6699       return -99;
6700     }
6701
6702   if (enable && (tx_sw_if_index_set == 0))
6703     {
6704       errmsg ("missing tx interface name or tx_sw_if_index");
6705       return -99;
6706     }
6707
6708   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6709
6710   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6711   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6712   mp->enable = enable;
6713
6714   S (mp);
6715   W (ret);
6716   return ret;
6717 }
6718
6719 static int
6720 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6721 {
6722   unformat_input_t *i = vam->input;
6723   vl_api_sw_interface_set_l2_bridge_t *mp;
6724   vl_api_l2_port_type_t port_type;
6725   u32 rx_sw_if_index;
6726   u8 rx_sw_if_index_set = 0;
6727   u32 bd_id;
6728   u8 bd_id_set = 0;
6729   u32 shg = 0;
6730   u8 enable = 1;
6731   int ret;
6732
6733   port_type = L2_API_PORT_TYPE_NORMAL;
6734
6735   /* Parse args required to build the message */
6736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6737     {
6738       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6739         rx_sw_if_index_set = 1;
6740       else if (unformat (i, "bd_id %d", &bd_id))
6741         bd_id_set = 1;
6742       else
6743         if (unformat
6744             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6745         rx_sw_if_index_set = 1;
6746       else if (unformat (i, "shg %d", &shg))
6747         ;
6748       else if (unformat (i, "bvi"))
6749         port_type = L2_API_PORT_TYPE_BVI;
6750       else if (unformat (i, "uu-fwd"))
6751         port_type = L2_API_PORT_TYPE_UU_FWD;
6752       else if (unformat (i, "enable"))
6753         enable = 1;
6754       else if (unformat (i, "disable"))
6755         enable = 0;
6756       else
6757         break;
6758     }
6759
6760   if (rx_sw_if_index_set == 0)
6761     {
6762       errmsg ("missing rx interface name or sw_if_index");
6763       return -99;
6764     }
6765
6766   if (enable && (bd_id_set == 0))
6767     {
6768       errmsg ("missing bridge domain");
6769       return -99;
6770     }
6771
6772   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6773
6774   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6775   mp->bd_id = ntohl (bd_id);
6776   mp->shg = (u8) shg;
6777   mp->port_type = ntohl (port_type);
6778   mp->enable = enable;
6779
6780   S (mp);
6781   W (ret);
6782   return ret;
6783 }
6784
6785 static int
6786 api_bridge_domain_dump (vat_main_t * vam)
6787 {
6788   unformat_input_t *i = vam->input;
6789   vl_api_bridge_domain_dump_t *mp;
6790   vl_api_control_ping_t *mp_ping;
6791   u32 bd_id = ~0;
6792   int ret;
6793
6794   /* Parse args required to build the message */
6795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6796     {
6797       if (unformat (i, "bd_id %d", &bd_id))
6798         ;
6799       else
6800         break;
6801     }
6802
6803   M (BRIDGE_DOMAIN_DUMP, mp);
6804   mp->bd_id = ntohl (bd_id);
6805   S (mp);
6806
6807   /* Use a control ping for synchronization */
6808   MPING (CONTROL_PING, mp_ping);
6809   S (mp_ping);
6810
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_bridge_domain_add_del (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_bridge_domain_add_del_t *mp;
6820   u32 bd_id = ~0;
6821   u8 is_add = 1;
6822   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6823   u8 *bd_tag = NULL;
6824   u32 mac_age = 0;
6825   int ret;
6826
6827   /* Parse args required to build the message */
6828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6829     {
6830       if (unformat (i, "bd_id %d", &bd_id))
6831         ;
6832       else if (unformat (i, "flood %d", &flood))
6833         ;
6834       else if (unformat (i, "uu-flood %d", &uu_flood))
6835         ;
6836       else if (unformat (i, "forward %d", &forward))
6837         ;
6838       else if (unformat (i, "learn %d", &learn))
6839         ;
6840       else if (unformat (i, "arp-term %d", &arp_term))
6841         ;
6842       else if (unformat (i, "mac-age %d", &mac_age))
6843         ;
6844       else if (unformat (i, "bd-tag %s", &bd_tag))
6845         ;
6846       else if (unformat (i, "del"))
6847         {
6848           is_add = 0;
6849           flood = uu_flood = forward = learn = 0;
6850         }
6851       else
6852         break;
6853     }
6854
6855   if (bd_id == ~0)
6856     {
6857       errmsg ("missing bridge domain");
6858       ret = -99;
6859       goto done;
6860     }
6861
6862   if (mac_age > 255)
6863     {
6864       errmsg ("mac age must be less than 256 ");
6865       ret = -99;
6866       goto done;
6867     }
6868
6869   if ((bd_tag) && (vec_len (bd_tag) > 63))
6870     {
6871       errmsg ("bd-tag cannot be longer than 63");
6872       ret = -99;
6873       goto done;
6874     }
6875
6876   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6877
6878   mp->bd_id = ntohl (bd_id);
6879   mp->flood = flood;
6880   mp->uu_flood = uu_flood;
6881   mp->forward = forward;
6882   mp->learn = learn;
6883   mp->arp_term = arp_term;
6884   mp->is_add = is_add;
6885   mp->mac_age = (u8) mac_age;
6886   if (bd_tag)
6887     {
6888       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6889       mp->bd_tag[vec_len (bd_tag)] = 0;
6890     }
6891   S (mp);
6892   W (ret);
6893
6894 done:
6895   vec_free (bd_tag);
6896   return ret;
6897 }
6898
6899 static int
6900 api_l2fib_flush_bd (vat_main_t * vam)
6901 {
6902   unformat_input_t *i = vam->input;
6903   vl_api_l2fib_flush_bd_t *mp;
6904   u32 bd_id = ~0;
6905   int ret;
6906
6907   /* Parse args required to build the message */
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "bd_id %d", &bd_id));
6911       else
6912         break;
6913     }
6914
6915   if (bd_id == ~0)
6916     {
6917       errmsg ("missing bridge domain");
6918       return -99;
6919     }
6920
6921   M (L2FIB_FLUSH_BD, mp);
6922
6923   mp->bd_id = htonl (bd_id);
6924
6925   S (mp);
6926   W (ret);
6927   return ret;
6928 }
6929
6930 static int
6931 api_l2fib_flush_int (vat_main_t * vam)
6932 {
6933   unformat_input_t *i = vam->input;
6934   vl_api_l2fib_flush_int_t *mp;
6935   u32 sw_if_index = ~0;
6936   int ret;
6937
6938   /* Parse args required to build the message */
6939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6940     {
6941       if (unformat (i, "sw_if_index %d", &sw_if_index));
6942       else
6943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6944       else
6945         break;
6946     }
6947
6948   if (sw_if_index == ~0)
6949     {
6950       errmsg ("missing interface name or sw_if_index");
6951       return -99;
6952     }
6953
6954   M (L2FIB_FLUSH_INT, mp);
6955
6956   mp->sw_if_index = ntohl (sw_if_index);
6957
6958   S (mp);
6959   W (ret);
6960   return ret;
6961 }
6962
6963 static int
6964 api_l2fib_add_del (vat_main_t * vam)
6965 {
6966   unformat_input_t *i = vam->input;
6967   vl_api_l2fib_add_del_t *mp;
6968   f64 timeout;
6969   u8 mac[6] = { 0 };
6970   u8 mac_set = 0;
6971   u32 bd_id;
6972   u8 bd_id_set = 0;
6973   u32 sw_if_index = 0;
6974   u8 sw_if_index_set = 0;
6975   u8 is_add = 1;
6976   u8 static_mac = 0;
6977   u8 filter_mac = 0;
6978   u8 bvi_mac = 0;
6979   int count = 1;
6980   f64 before = 0;
6981   int j;
6982
6983   /* Parse args required to build the message */
6984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6985     {
6986       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6987         mac_set = 1;
6988       else if (unformat (i, "bd_id %d", &bd_id))
6989         bd_id_set = 1;
6990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6991         sw_if_index_set = 1;
6992       else if (unformat (i, "sw_if"))
6993         {
6994           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995             {
6996               if (unformat
6997                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6998                 sw_if_index_set = 1;
6999             }
7000           else
7001             break;
7002         }
7003       else if (unformat (i, "static"))
7004         static_mac = 1;
7005       else if (unformat (i, "filter"))
7006         {
7007           filter_mac = 1;
7008           static_mac = 1;
7009         }
7010       else if (unformat (i, "bvi"))
7011         {
7012           bvi_mac = 1;
7013           static_mac = 1;
7014         }
7015       else if (unformat (i, "del"))
7016         is_add = 0;
7017       else if (unformat (i, "count %d", &count))
7018         ;
7019       else
7020         break;
7021     }
7022
7023   if (mac_set == 0)
7024     {
7025       errmsg ("missing mac address");
7026       return -99;
7027     }
7028
7029   if (bd_id_set == 0)
7030     {
7031       errmsg ("missing bridge domain");
7032       return -99;
7033     }
7034
7035   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7036     {
7037       errmsg ("missing interface name or sw_if_index");
7038       return -99;
7039     }
7040
7041   if (count > 1)
7042     {
7043       /* Turn on async mode */
7044       vam->async_mode = 1;
7045       vam->async_errors = 0;
7046       before = vat_time_now (vam);
7047     }
7048
7049   for (j = 0; j < count; j++)
7050     {
7051       M (L2FIB_ADD_DEL, mp);
7052
7053       clib_memcpy (mp->mac, mac, 6);
7054       mp->bd_id = ntohl (bd_id);
7055       mp->is_add = is_add;
7056       mp->sw_if_index = ntohl (sw_if_index);
7057
7058       if (is_add)
7059         {
7060           mp->static_mac = static_mac;
7061           mp->filter_mac = filter_mac;
7062           mp->bvi_mac = bvi_mac;
7063         }
7064       increment_mac_address (mac);
7065       /* send it... */
7066       S (mp);
7067     }
7068
7069   if (count > 1)
7070     {
7071       vl_api_control_ping_t *mp_ping;
7072       f64 after;
7073
7074       /* Shut off async mode */
7075       vam->async_mode = 0;
7076
7077       MPING (CONTROL_PING, mp_ping);
7078       S (mp_ping);
7079
7080       timeout = vat_time_now (vam) + 1.0;
7081       while (vat_time_now (vam) < timeout)
7082         if (vam->result_ready == 1)
7083           goto out;
7084       vam->retval = -99;
7085
7086     out:
7087       if (vam->retval == -99)
7088         errmsg ("timeout");
7089
7090       if (vam->async_errors > 0)
7091         {
7092           errmsg ("%d asynchronous errors", vam->async_errors);
7093           vam->retval = -98;
7094         }
7095       vam->async_errors = 0;
7096       after = vat_time_now (vam);
7097
7098       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7099              count, after - before, count / (after - before));
7100     }
7101   else
7102     {
7103       int ret;
7104
7105       /* Wait for a reply... */
7106       W (ret);
7107       return ret;
7108     }
7109   /* Return the good/bad news */
7110   return (vam->retval);
7111 }
7112
7113 static int
7114 api_bridge_domain_set_mac_age (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_bridge_domain_set_mac_age_t *mp;
7118   u32 bd_id = ~0;
7119   u32 mac_age = 0;
7120   int ret;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "bd_id %d", &bd_id));
7126       else if (unformat (i, "mac-age %d", &mac_age));
7127       else
7128         break;
7129     }
7130
7131   if (bd_id == ~0)
7132     {
7133       errmsg ("missing bridge domain");
7134       return -99;
7135     }
7136
7137   if (mac_age > 255)
7138     {
7139       errmsg ("mac age must be less than 256 ");
7140       return -99;
7141     }
7142
7143   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7144
7145   mp->bd_id = htonl (bd_id);
7146   mp->mac_age = (u8) mac_age;
7147
7148   S (mp);
7149   W (ret);
7150   return ret;
7151 }
7152
7153 static int
7154 api_l2_flags (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_l2_flags_t *mp;
7158   u32 sw_if_index;
7159   u32 flags = 0;
7160   u8 sw_if_index_set = 0;
7161   u8 is_set = 0;
7162   int ret;
7163
7164   /* Parse args required to build the message */
7165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7166     {
7167       if (unformat (i, "sw_if_index %d", &sw_if_index))
7168         sw_if_index_set = 1;
7169       else if (unformat (i, "sw_if"))
7170         {
7171           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7172             {
7173               if (unformat
7174                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7175                 sw_if_index_set = 1;
7176             }
7177           else
7178             break;
7179         }
7180       else if (unformat (i, "learn"))
7181         flags |= L2_LEARN;
7182       else if (unformat (i, "forward"))
7183         flags |= L2_FWD;
7184       else if (unformat (i, "flood"))
7185         flags |= L2_FLOOD;
7186       else if (unformat (i, "uu-flood"))
7187         flags |= L2_UU_FLOOD;
7188       else if (unformat (i, "arp-term"))
7189         flags |= L2_ARP_TERM;
7190       else if (unformat (i, "off"))
7191         is_set = 0;
7192       else if (unformat (i, "disable"))
7193         is_set = 0;
7194       else
7195         break;
7196     }
7197
7198   if (sw_if_index_set == 0)
7199     {
7200       errmsg ("missing interface name or sw_if_index");
7201       return -99;
7202     }
7203
7204   M (L2_FLAGS, mp);
7205
7206   mp->sw_if_index = ntohl (sw_if_index);
7207   mp->feature_bitmap = ntohl (flags);
7208   mp->is_set = is_set;
7209
7210   S (mp);
7211   W (ret);
7212   return ret;
7213 }
7214
7215 static int
7216 api_bridge_flags (vat_main_t * vam)
7217 {
7218   unformat_input_t *i = vam->input;
7219   vl_api_bridge_flags_t *mp;
7220   u32 bd_id;
7221   u8 bd_id_set = 0;
7222   u8 is_set = 1;
7223   bd_flags_t flags = 0;
7224   int ret;
7225
7226   /* Parse args required to build the message */
7227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228     {
7229       if (unformat (i, "bd_id %d", &bd_id))
7230         bd_id_set = 1;
7231       else if (unformat (i, "learn"))
7232         flags |= BRIDGE_API_FLAG_LEARN;
7233       else if (unformat (i, "forward"))
7234         flags |= BRIDGE_API_FLAG_FWD;
7235       else if (unformat (i, "flood"))
7236         flags |= BRIDGE_API_FLAG_FLOOD;
7237       else if (unformat (i, "uu-flood"))
7238         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7239       else if (unformat (i, "arp-term"))
7240         flags |= BRIDGE_API_FLAG_ARP_TERM;
7241       else if (unformat (i, "off"))
7242         is_set = 0;
7243       else if (unformat (i, "disable"))
7244         is_set = 0;
7245       else
7246         break;
7247     }
7248
7249   if (bd_id_set == 0)
7250     {
7251       errmsg ("missing bridge domain");
7252       return -99;
7253     }
7254
7255   M (BRIDGE_FLAGS, mp);
7256
7257   mp->bd_id = ntohl (bd_id);
7258   mp->flags = ntohl (flags);
7259   mp->is_set = is_set;
7260
7261   S (mp);
7262   W (ret);
7263   return ret;
7264 }
7265
7266 static int
7267 api_bd_ip_mac_add_del (vat_main_t * vam)
7268 {
7269   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7270   vl_api_mac_address_t mac = { 0 };
7271   unformat_input_t *i = vam->input;
7272   vl_api_bd_ip_mac_add_del_t *mp;
7273   ip46_type_t type;
7274   u32 bd_id;
7275   u8 is_ipv6 = 0;
7276   u8 is_add = 1;
7277   u8 bd_id_set = 0;
7278   u8 ip_set = 0;
7279   u8 mac_set = 0;
7280   u8 macaddr[6];
7281   int ret;
7282
7283
7284   /* Parse args required to build the message */
7285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7286     {
7287       if (unformat (i, "bd_id %d", &bd_id))
7288         {
7289           bd_id_set++;
7290         }
7291       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7292         {
7293           ip_set++;
7294         }
7295       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7296         {
7297           mac_set++;
7298         }
7299       else if (unformat (i, "del"))
7300         is_add = 0;
7301       else
7302         break;
7303     }
7304
7305   if (bd_id_set == 0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310   else if (ip_set == 0)
7311     {
7312       errmsg ("missing IP address");
7313       return -99;
7314     }
7315   else if (mac_set == 0)
7316     {
7317       errmsg ("missing MAC address");
7318       return -99;
7319     }
7320
7321   M (BD_IP_MAC_ADD_DEL, mp);
7322
7323   mp->bd_id = ntohl (bd_id);
7324   mp->is_add = is_add;
7325
7326   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7327   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7328
7329   S (mp);
7330   W (ret);
7331   return ret;
7332 }
7333
7334 static int
7335 api_bd_ip_mac_flush (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_bd_ip_mac_flush_t *mp;
7339   u32 bd_id;
7340   u8 bd_id_set = 0;
7341   int ret;
7342
7343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7344     {
7345       if (unformat (i, "bd_id %d", &bd_id))
7346         {
7347           bd_id_set++;
7348         }
7349       else
7350         break;
7351     }
7352
7353   if (bd_id_set == 0)
7354     {
7355       errmsg ("missing bridge domain");
7356       return -99;
7357     }
7358
7359   M (BD_IP_MAC_FLUSH, mp);
7360
7361   mp->bd_id = ntohl (bd_id);
7362
7363   S (mp);
7364   W (ret);
7365   return ret;
7366 }
7367
7368 static void vl_api_bd_ip_mac_details_t_handler
7369   (vl_api_bd_ip_mac_details_t * mp)
7370 {
7371   vat_main_t *vam = &vat_main;
7372   u8 *ip = 0;
7373
7374   if (!mp->is_ipv6)
7375     ip =
7376       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7377   else
7378     ip =
7379       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7380
7381   print (vam->ofp,
7382          "\n%-5d %-7s %-20U %-30s",
7383          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7384          format_ethernet_address, mp->mac_address, ip);
7385
7386   vec_free (ip);
7387 }
7388
7389 static void vl_api_bd_ip_mac_details_t_handler_json
7390   (vl_api_bd_ip_mac_details_t * mp)
7391 {
7392   vat_main_t *vam = &vat_main;
7393   vat_json_node_t *node = NULL;
7394
7395   if (VAT_JSON_ARRAY != vam->json_tree.type)
7396     {
7397       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7398       vat_json_init_array (&vam->json_tree);
7399     }
7400   node = vat_json_array_add (&vam->json_tree);
7401
7402   vat_json_init_object (node);
7403   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7404   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7405   vat_json_object_add_string_copy (node, "mac_address",
7406                                    format (0, "%U", format_ethernet_address,
7407                                            &mp->mac_address));
7408   u8 *ip = 0;
7409
7410   if (!mp->is_ipv6)
7411     ip =
7412       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7413   else
7414     ip =
7415       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7416   vat_json_object_add_string_copy (node, "ip_address", ip);
7417   vec_free (ip);
7418 }
7419
7420 static int
7421 api_bd_ip_mac_dump (vat_main_t * vam)
7422 {
7423   unformat_input_t *i = vam->input;
7424   vl_api_bd_ip_mac_dump_t *mp;
7425   vl_api_control_ping_t *mp_ping;
7426   int ret;
7427   u32 bd_id;
7428   u8 bd_id_set = 0;
7429
7430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7431     {
7432       if (unformat (i, "bd_id %d", &bd_id))
7433         {
7434           bd_id_set++;
7435         }
7436       else
7437         break;
7438     }
7439
7440   print (vam->ofp,
7441          "\n%-5s %-7s %-20s %-30s",
7442          "bd_id", "is_ipv6", "mac_address", "ip_address");
7443
7444   /* Dump Bridge Domain Ip to Mac entries */
7445   M (BD_IP_MAC_DUMP, mp);
7446
7447   if (bd_id_set)
7448     mp->bd_id = htonl (bd_id);
7449   else
7450     mp->bd_id = ~0;
7451
7452   S (mp);
7453
7454   /* Use a control ping for synchronization */
7455   MPING (CONTROL_PING, mp_ping);
7456   S (mp_ping);
7457
7458   W (ret);
7459   return ret;
7460 }
7461
7462 static int
7463 api_tap_create_v2 (vat_main_t * vam)
7464 {
7465   unformat_input_t *i = vam->input;
7466   vl_api_tap_create_v2_t *mp;
7467   u8 mac_address[6];
7468   u8 random_mac = 1;
7469   u32 id = ~0;
7470   u8 *host_if_name = 0;
7471   u8 *host_ns = 0;
7472   u8 host_mac_addr[6];
7473   u8 host_mac_addr_set = 0;
7474   u8 *host_bridge = 0;
7475   ip4_address_t host_ip4_addr;
7476   ip4_address_t host_ip4_gw;
7477   u8 host_ip4_gw_set = 0;
7478   u32 host_ip4_prefix_len = 0;
7479   ip6_address_t host_ip6_addr;
7480   ip6_address_t host_ip6_gw;
7481   u8 host_ip6_gw_set = 0;
7482   u32 host_ip6_prefix_len = 0;
7483   int ret;
7484   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7485
7486   clib_memset (mac_address, 0, sizeof (mac_address));
7487
7488   /* Parse args required to build the message */
7489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7490     {
7491       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7492         {
7493           random_mac = 0;
7494         }
7495       else if (unformat (i, "id %u", &id))
7496         ;
7497       else if (unformat (i, "host-if-name %s", &host_if_name))
7498         ;
7499       else if (unformat (i, "host-ns %s", &host_ns))
7500         ;
7501       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7502                          host_mac_addr))
7503         host_mac_addr_set = 1;
7504       else if (unformat (i, "host-bridge %s", &host_bridge))
7505         ;
7506       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7507                          &host_ip4_addr, &host_ip4_prefix_len))
7508         ;
7509       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7510                          &host_ip6_addr, &host_ip6_prefix_len))
7511         ;
7512       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7513                          &host_ip4_gw))
7514         host_ip4_gw_set = 1;
7515       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7516                          &host_ip6_gw))
7517         host_ip6_gw_set = 1;
7518       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7519         ;
7520       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7521         ;
7522       else
7523         break;
7524     }
7525
7526   if (vec_len (host_if_name) > 63)
7527     {
7528       errmsg ("tap name too long. ");
7529       return -99;
7530     }
7531   if (vec_len (host_ns) > 63)
7532     {
7533       errmsg ("host name space too long. ");
7534       return -99;
7535     }
7536   if (vec_len (host_bridge) > 63)
7537     {
7538       errmsg ("host bridge name too long. ");
7539       return -99;
7540     }
7541   if (host_ip4_prefix_len > 32)
7542     {
7543       errmsg ("host ip4 prefix length not valid. ");
7544       return -99;
7545     }
7546   if (host_ip6_prefix_len > 128)
7547     {
7548       errmsg ("host ip6 prefix length not valid. ");
7549       return -99;
7550     }
7551   if (!is_pow2 (rx_ring_sz))
7552     {
7553       errmsg ("rx ring size must be power of 2. ");
7554       return -99;
7555     }
7556   if (rx_ring_sz > 32768)
7557     {
7558       errmsg ("rx ring size must be 32768 or lower. ");
7559       return -99;
7560     }
7561   if (!is_pow2 (tx_ring_sz))
7562     {
7563       errmsg ("tx ring size must be power of 2. ");
7564       return -99;
7565     }
7566   if (tx_ring_sz > 32768)
7567     {
7568       errmsg ("tx ring size must be 32768 or lower. ");
7569       return -99;
7570     }
7571
7572   /* Construct the API message */
7573   M (TAP_CREATE_V2, mp);
7574
7575   mp->use_random_mac = random_mac;
7576
7577   mp->id = ntohl (id);
7578   mp->host_namespace_set = host_ns != 0;
7579   mp->host_bridge_set = host_bridge != 0;
7580   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7581   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7582   mp->rx_ring_sz = ntohs (rx_ring_sz);
7583   mp->tx_ring_sz = ntohs (tx_ring_sz);
7584
7585   if (random_mac == 0)
7586     clib_memcpy (mp->mac_address, mac_address, 6);
7587   if (host_mac_addr_set)
7588     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7589   if (host_if_name)
7590     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7591   if (host_ns)
7592     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7593   if (host_bridge)
7594     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7595   if (host_ip4_prefix_len)
7596     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7597   if (host_ip6_prefix_len)
7598     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7599   if (host_ip4_gw_set)
7600     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7601   if (host_ip6_gw_set)
7602     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7603
7604   vec_free (host_ns);
7605   vec_free (host_if_name);
7606   vec_free (host_bridge);
7607
7608   /* send it... */
7609   S (mp);
7610
7611   /* Wait for a reply... */
7612   W (ret);
7613   return ret;
7614 }
7615
7616 static int
7617 api_tap_delete_v2 (vat_main_t * vam)
7618 {
7619   unformat_input_t *i = vam->input;
7620   vl_api_tap_delete_v2_t *mp;
7621   u32 sw_if_index = ~0;
7622   u8 sw_if_index_set = 0;
7623   int ret;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7629         sw_if_index_set = 1;
7630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7631         sw_if_index_set = 1;
7632       else
7633         break;
7634     }
7635
7636   if (sw_if_index_set == 0)
7637     {
7638       errmsg ("missing vpp interface name. ");
7639       return -99;
7640     }
7641
7642   /* Construct the API message */
7643   M (TAP_DELETE_V2, mp);
7644
7645   mp->sw_if_index = ntohl (sw_if_index);
7646
7647   /* send it... */
7648   S (mp);
7649
7650   /* Wait for a reply... */
7651   W (ret);
7652   return ret;
7653 }
7654
7655 uword
7656 unformat_pci_addr (unformat_input_t * input, va_list * args)
7657 {
7658   struct pci_addr_t
7659   {
7660     u16 domain;
7661     u8 bus;
7662     u8 slot:5;
7663     u8 function:3;
7664   } *addr;
7665   addr = va_arg (*args, struct pci_addr_t *);
7666   u32 x[4];
7667
7668   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7669     return 0;
7670
7671   addr->domain = x[0];
7672   addr->bus = x[1];
7673   addr->slot = x[2];
7674   addr->function = x[3];
7675
7676   return 1;
7677 }
7678
7679 static int
7680 api_virtio_pci_create (vat_main_t * vam)
7681 {
7682   unformat_input_t *i = vam->input;
7683   vl_api_virtio_pci_create_t *mp;
7684   u8 mac_address[6];
7685   u8 random_mac = 1;
7686   u32 pci_addr = 0;
7687   u64 features = (u64) ~ (0ULL);
7688   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7689   int ret;
7690
7691   clib_memset (mac_address, 0, sizeof (mac_address));
7692
7693   /* Parse args required to build the message */
7694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7695     {
7696       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7697         {
7698           random_mac = 0;
7699         }
7700       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7701         ;
7702       else if (unformat (i, "features 0x%llx", &features))
7703         ;
7704       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7705         ;
7706       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7707         ;
7708       else
7709         break;
7710     }
7711
7712   if (pci_addr == 0)
7713     {
7714       errmsg ("pci address must be non zero. ");
7715       return -99;
7716     }
7717   if (!is_pow2 (rx_ring_sz))
7718     {
7719       errmsg ("rx ring size must be power of 2. ");
7720       return -99;
7721     }
7722   if (rx_ring_sz > 32768)
7723     {
7724       errmsg ("rx ring size must be 32768 or lower. ");
7725       return -99;
7726     }
7727   if (!is_pow2 (tx_ring_sz))
7728     {
7729       errmsg ("tx ring size must be power of 2. ");
7730       return -99;
7731     }
7732   if (tx_ring_sz > 32768)
7733     {
7734       errmsg ("tx ring size must be 32768 or lower. ");
7735       return -99;
7736     }
7737
7738   /* Construct the API message */
7739   M (VIRTIO_PCI_CREATE, mp);
7740
7741   mp->use_random_mac = random_mac;
7742
7743   mp->pci_addr = htonl (pci_addr);
7744   mp->features = clib_host_to_net_u64 (features);
7745
7746   if (random_mac == 0)
7747     clib_memcpy (mp->mac_address, mac_address, 6);
7748
7749   /* send it... */
7750   S (mp);
7751
7752   /* Wait for a reply... */
7753   W (ret);
7754   return ret;
7755 }
7756
7757 static int
7758 api_virtio_pci_delete (vat_main_t * vam)
7759 {
7760   unformat_input_t *i = vam->input;
7761   vl_api_virtio_pci_delete_t *mp;
7762   u32 sw_if_index = ~0;
7763   u8 sw_if_index_set = 0;
7764   int ret;
7765
7766   /* Parse args required to build the message */
7767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7768     {
7769       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7770         sw_if_index_set = 1;
7771       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7772         sw_if_index_set = 1;
7773       else
7774         break;
7775     }
7776
7777   if (sw_if_index_set == 0)
7778     {
7779       errmsg ("missing vpp interface name. ");
7780       return -99;
7781     }
7782
7783   /* Construct the API message */
7784   M (VIRTIO_PCI_DELETE, mp);
7785
7786   mp->sw_if_index = htonl (sw_if_index);
7787
7788   /* send it... */
7789   S (mp);
7790
7791   /* Wait for a reply... */
7792   W (ret);
7793   return ret;
7794 }
7795
7796 static int
7797 api_bond_create (vat_main_t * vam)
7798 {
7799   unformat_input_t *i = vam->input;
7800   vl_api_bond_create_t *mp;
7801   u8 mac_address[6];
7802   u8 custom_mac = 0;
7803   int ret;
7804   u8 mode;
7805   u8 lb;
7806   u8 mode_is_set = 0;
7807   u32 id = ~0;
7808
7809   clib_memset (mac_address, 0, sizeof (mac_address));
7810   lb = BOND_LB_L2;
7811
7812   /* Parse args required to build the message */
7813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7814     {
7815       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7816         mode_is_set = 1;
7817       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7818                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7819         ;
7820       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7821                          mac_address))
7822         custom_mac = 1;
7823       else if (unformat (i, "id %u", &id))
7824         ;
7825       else
7826         break;
7827     }
7828
7829   if (mode_is_set == 0)
7830     {
7831       errmsg ("Missing bond mode. ");
7832       return -99;
7833     }
7834
7835   /* Construct the API message */
7836   M (BOND_CREATE, mp);
7837
7838   mp->use_custom_mac = custom_mac;
7839
7840   mp->mode = mode;
7841   mp->lb = lb;
7842   mp->id = htonl (id);
7843
7844   if (custom_mac)
7845     clib_memcpy (mp->mac_address, mac_address, 6);
7846
7847   /* send it... */
7848   S (mp);
7849
7850   /* Wait for a reply... */
7851   W (ret);
7852   return ret;
7853 }
7854
7855 static int
7856 api_bond_delete (vat_main_t * vam)
7857 {
7858   unformat_input_t *i = vam->input;
7859   vl_api_bond_delete_t *mp;
7860   u32 sw_if_index = ~0;
7861   u8 sw_if_index_set = 0;
7862   int ret;
7863
7864   /* Parse args required to build the message */
7865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7866     {
7867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7868         sw_if_index_set = 1;
7869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7870         sw_if_index_set = 1;
7871       else
7872         break;
7873     }
7874
7875   if (sw_if_index_set == 0)
7876     {
7877       errmsg ("missing vpp interface name. ");
7878       return -99;
7879     }
7880
7881   /* Construct the API message */
7882   M (BOND_DELETE, mp);
7883
7884   mp->sw_if_index = ntohl (sw_if_index);
7885
7886   /* send it... */
7887   S (mp);
7888
7889   /* Wait for a reply... */
7890   W (ret);
7891   return ret;
7892 }
7893
7894 static int
7895 api_bond_enslave (vat_main_t * vam)
7896 {
7897   unformat_input_t *i = vam->input;
7898   vl_api_bond_enslave_t *mp;
7899   u32 bond_sw_if_index;
7900   int ret;
7901   u8 is_passive;
7902   u8 is_long_timeout;
7903   u32 bond_sw_if_index_is_set = 0;
7904   u32 sw_if_index;
7905   u8 sw_if_index_is_set = 0;
7906
7907   /* Parse args required to build the message */
7908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7909     {
7910       if (unformat (i, "sw_if_index %d", &sw_if_index))
7911         sw_if_index_is_set = 1;
7912       else if (unformat (i, "bond %u", &bond_sw_if_index))
7913         bond_sw_if_index_is_set = 1;
7914       else if (unformat (i, "passive %d", &is_passive))
7915         ;
7916       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7917         ;
7918       else
7919         break;
7920     }
7921
7922   if (bond_sw_if_index_is_set == 0)
7923     {
7924       errmsg ("Missing bond sw_if_index. ");
7925       return -99;
7926     }
7927   if (sw_if_index_is_set == 0)
7928     {
7929       errmsg ("Missing slave sw_if_index. ");
7930       return -99;
7931     }
7932
7933   /* Construct the API message */
7934   M (BOND_ENSLAVE, mp);
7935
7936   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7937   mp->sw_if_index = ntohl (sw_if_index);
7938   mp->is_long_timeout = is_long_timeout;
7939   mp->is_passive = is_passive;
7940
7941   /* send it... */
7942   S (mp);
7943
7944   /* Wait for a reply... */
7945   W (ret);
7946   return ret;
7947 }
7948
7949 static int
7950 api_bond_detach_slave (vat_main_t * vam)
7951 {
7952   unformat_input_t *i = vam->input;
7953   vl_api_bond_detach_slave_t *mp;
7954   u32 sw_if_index = ~0;
7955   u8 sw_if_index_set = 0;
7956   int ret;
7957
7958   /* Parse args required to build the message */
7959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7962         sw_if_index_set = 1;
7963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7964         sw_if_index_set = 1;
7965       else
7966         break;
7967     }
7968
7969   if (sw_if_index_set == 0)
7970     {
7971       errmsg ("missing vpp interface name. ");
7972       return -99;
7973     }
7974
7975   /* Construct the API message */
7976   M (BOND_DETACH_SLAVE, mp);
7977
7978   mp->sw_if_index = ntohl (sw_if_index);
7979
7980   /* send it... */
7981   S (mp);
7982
7983   /* Wait for a reply... */
7984   W (ret);
7985   return ret;
7986 }
7987
7988 static int
7989 api_ip_table_add_del (vat_main_t * vam)
7990 {
7991   unformat_input_t *i = vam->input;
7992   vl_api_ip_table_add_del_t *mp;
7993   u32 table_id = ~0;
7994   u8 is_ipv6 = 0;
7995   u8 is_add = 1;
7996   int ret = 0;
7997
7998   /* Parse args required to build the message */
7999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8000     {
8001       if (unformat (i, "ipv6"))
8002         is_ipv6 = 1;
8003       else if (unformat (i, "del"))
8004         is_add = 0;
8005       else if (unformat (i, "add"))
8006         is_add = 1;
8007       else if (unformat (i, "table %d", &table_id))
8008         ;
8009       else
8010         {
8011           clib_warning ("parse error '%U'", format_unformat_error, i);
8012           return -99;
8013         }
8014     }
8015
8016   if (~0 == table_id)
8017     {
8018       errmsg ("missing table-ID");
8019       return -99;
8020     }
8021
8022   /* Construct the API message */
8023   M (IP_TABLE_ADD_DEL, mp);
8024
8025   mp->table_id = ntohl (table_id);
8026   mp->is_ipv6 = is_ipv6;
8027   mp->is_add = is_add;
8028
8029   /* send it... */
8030   S (mp);
8031
8032   /* Wait for a reply... */
8033   W (ret);
8034
8035   return ret;
8036 }
8037
8038 static int
8039 api_ip_add_del_route (vat_main_t * vam)
8040 {
8041   unformat_input_t *i = vam->input;
8042   vl_api_ip_add_del_route_t *mp;
8043   u32 sw_if_index = ~0, vrf_id = 0;
8044   u8 is_ipv6 = 0;
8045   u8 is_local = 0, is_drop = 0;
8046   u8 is_unreach = 0, is_prohibit = 0;
8047   u8 is_add = 1;
8048   u32 next_hop_weight = 1;
8049   u8 is_multipath = 0;
8050   u8 address_set = 0;
8051   u8 address_length_set = 0;
8052   u32 next_hop_table_id = 0;
8053   u32 resolve_attempts = 0;
8054   u32 dst_address_length = 0;
8055   u8 next_hop_set = 0;
8056   ip4_address_t v4_dst_address, v4_next_hop_address;
8057   ip6_address_t v6_dst_address, v6_next_hop_address;
8058   int count = 1;
8059   int j;
8060   f64 before = 0;
8061   u32 random_add_del = 0;
8062   u32 *random_vector = 0;
8063   uword *random_hash;
8064   u32 random_seed = 0xdeaddabe;
8065   u32 classify_table_index = ~0;
8066   u8 is_classify = 0;
8067   u8 resolve_host = 0, resolve_attached = 0;
8068   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8069   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8070   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8071
8072   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8073   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8074   /* Parse args required to build the message */
8075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8076     {
8077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8078         ;
8079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8080         ;
8081       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8082         {
8083           address_set = 1;
8084           is_ipv6 = 0;
8085         }
8086       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8087         {
8088           address_set = 1;
8089           is_ipv6 = 1;
8090         }
8091       else if (unformat (i, "/%d", &dst_address_length))
8092         {
8093           address_length_set = 1;
8094         }
8095
8096       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8097                                          &v4_next_hop_address))
8098         {
8099           next_hop_set = 1;
8100         }
8101       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8102                                          &v6_next_hop_address))
8103         {
8104           next_hop_set = 1;
8105         }
8106       else
8107         if (unformat
8108             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8109         {
8110           next_hop_set = 1;
8111         }
8112       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8113         {
8114           next_hop_set = 1;
8115         }
8116       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8117         ;
8118       else if (unformat (i, "weight %d", &next_hop_weight))
8119         ;
8120       else if (unformat (i, "drop"))
8121         {
8122           is_drop = 1;
8123         }
8124       else if (unformat (i, "null-send-unreach"))
8125         {
8126           is_unreach = 1;
8127         }
8128       else if (unformat (i, "null-send-prohibit"))
8129         {
8130           is_prohibit = 1;
8131         }
8132       else if (unformat (i, "local"))
8133         {
8134           is_local = 1;
8135         }
8136       else if (unformat (i, "classify %d", &classify_table_index))
8137         {
8138           is_classify = 1;
8139         }
8140       else if (unformat (i, "del"))
8141         is_add = 0;
8142       else if (unformat (i, "add"))
8143         is_add = 1;
8144       else if (unformat (i, "resolve-via-host"))
8145         resolve_host = 1;
8146       else if (unformat (i, "resolve-via-attached"))
8147         resolve_attached = 1;
8148       else if (unformat (i, "multipath"))
8149         is_multipath = 1;
8150       else if (unformat (i, "vrf %d", &vrf_id))
8151         ;
8152       else if (unformat (i, "count %d", &count))
8153         ;
8154       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8155         ;
8156       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8157         ;
8158       else if (unformat (i, "out-label %d", &next_hop_out_label))
8159         {
8160           vl_api_fib_mpls_label_t fib_label = {
8161             .label = ntohl (next_hop_out_label),
8162             .ttl = 64,
8163             .exp = 0,
8164           };
8165           vec_add1 (next_hop_out_label_stack, fib_label);
8166         }
8167       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8168         ;
8169       else if (unformat (i, "random"))
8170         random_add_del = 1;
8171       else if (unformat (i, "seed %d", &random_seed))
8172         ;
8173       else
8174         {
8175           clib_warning ("parse error '%U'", format_unformat_error, i);
8176           return -99;
8177         }
8178     }
8179
8180   if (!next_hop_set && !is_drop && !is_local &&
8181       !is_classify && !is_unreach && !is_prohibit &&
8182       MPLS_LABEL_INVALID == next_hop_via_label)
8183     {
8184       errmsg
8185         ("next hop / local / drop / unreach / prohibit / classify not set");
8186       return -99;
8187     }
8188
8189   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8190     {
8191       errmsg ("next hop and next-hop via label set");
8192       return -99;
8193     }
8194   if (address_set == 0)
8195     {
8196       errmsg ("missing addresses");
8197       return -99;
8198     }
8199
8200   if (address_length_set == 0)
8201     {
8202       errmsg ("missing address length");
8203       return -99;
8204     }
8205
8206   /* Generate a pile of unique, random routes */
8207   if (random_add_del)
8208     {
8209       u32 this_random_address;
8210       random_hash = hash_create (count, sizeof (uword));
8211
8212       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8213       for (j = 0; j <= count; j++)
8214         {
8215           do
8216             {
8217               this_random_address = random_u32 (&random_seed);
8218               this_random_address =
8219                 clib_host_to_net_u32 (this_random_address);
8220             }
8221           while (hash_get (random_hash, this_random_address));
8222           vec_add1 (random_vector, this_random_address);
8223           hash_set (random_hash, this_random_address, 1);
8224         }
8225       hash_free (random_hash);
8226       v4_dst_address.as_u32 = random_vector[0];
8227     }
8228
8229   if (count > 1)
8230     {
8231       /* Turn on async mode */
8232       vam->async_mode = 1;
8233       vam->async_errors = 0;
8234       before = vat_time_now (vam);
8235     }
8236
8237   for (j = 0; j < count; j++)
8238     {
8239       /* Construct the API message */
8240       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8241           vec_len (next_hop_out_label_stack));
8242
8243       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8244       mp->table_id = ntohl (vrf_id);
8245
8246       mp->is_add = is_add;
8247       mp->is_drop = is_drop;
8248       mp->is_unreach = is_unreach;
8249       mp->is_prohibit = is_prohibit;
8250       mp->is_ipv6 = is_ipv6;
8251       mp->is_local = is_local;
8252       mp->is_classify = is_classify;
8253       mp->is_multipath = is_multipath;
8254       mp->is_resolve_host = resolve_host;
8255       mp->is_resolve_attached = resolve_attached;
8256       mp->next_hop_weight = next_hop_weight;
8257       mp->next_hop_preference = 0;
8258       mp->dst_address_length = dst_address_length;
8259       mp->next_hop_table_id = ntohl (next_hop_table_id);
8260       mp->classify_table_index = ntohl (classify_table_index);
8261       mp->next_hop_via_label = ntohl (next_hop_via_label);
8262       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8263       if (0 != mp->next_hop_n_out_labels)
8264         {
8265           memcpy (mp->next_hop_out_label_stack,
8266                   next_hop_out_label_stack,
8267                   (vec_len (next_hop_out_label_stack) *
8268                    sizeof (vl_api_fib_mpls_label_t)));
8269           vec_free (next_hop_out_label_stack);
8270         }
8271
8272       if (is_ipv6)
8273         {
8274           clib_memcpy (mp->dst_address, &v6_dst_address,
8275                        sizeof (v6_dst_address));
8276           if (next_hop_set)
8277             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8278                          sizeof (v6_next_hop_address));
8279           increment_v6_address (&v6_dst_address);
8280         }
8281       else
8282         {
8283           clib_memcpy (mp->dst_address, &v4_dst_address,
8284                        sizeof (v4_dst_address));
8285           if (next_hop_set)
8286             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8287                          sizeof (v4_next_hop_address));
8288           if (random_add_del)
8289             v4_dst_address.as_u32 = random_vector[j + 1];
8290           else
8291             increment_v4_address (&v4_dst_address);
8292         }
8293       /* send it... */
8294       S (mp);
8295       /* If we receive SIGTERM, stop now... */
8296       if (vam->do_exit)
8297         break;
8298     }
8299
8300   /* When testing multiple add/del ops, use a control-ping to sync */
8301   if (count > 1)
8302     {
8303       vl_api_control_ping_t *mp_ping;
8304       f64 after;
8305       f64 timeout;
8306
8307       /* Shut off async mode */
8308       vam->async_mode = 0;
8309
8310       MPING (CONTROL_PING, mp_ping);
8311       S (mp_ping);
8312
8313       timeout = vat_time_now (vam) + 1.0;
8314       while (vat_time_now (vam) < timeout)
8315         if (vam->result_ready == 1)
8316           goto out;
8317       vam->retval = -99;
8318
8319     out:
8320       if (vam->retval == -99)
8321         errmsg ("timeout");
8322
8323       if (vam->async_errors > 0)
8324         {
8325           errmsg ("%d asynchronous errors", vam->async_errors);
8326           vam->retval = -98;
8327         }
8328       vam->async_errors = 0;
8329       after = vat_time_now (vam);
8330
8331       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8332       if (j > 0)
8333         count = j;
8334
8335       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8336              count, after - before, count / (after - before));
8337     }
8338   else
8339     {
8340       int ret;
8341
8342       /* Wait for a reply... */
8343       W (ret);
8344       return ret;
8345     }
8346
8347   /* Return the good/bad news */
8348   return (vam->retval);
8349 }
8350
8351 static int
8352 api_ip_mroute_add_del (vat_main_t * vam)
8353 {
8354   unformat_input_t *i = vam->input;
8355   vl_api_ip_mroute_add_del_t *mp;
8356   u32 sw_if_index = ~0, vrf_id = 0;
8357   u8 is_ipv6 = 0;
8358   u8 is_local = 0;
8359   u8 is_add = 1;
8360   u8 address_set = 0;
8361   u32 grp_address_length = 0;
8362   ip4_address_t v4_grp_address, v4_src_address;
8363   ip6_address_t v6_grp_address, v6_src_address;
8364   mfib_itf_flags_t iflags = 0;
8365   mfib_entry_flags_t eflags = 0;
8366   int ret;
8367
8368   /* Parse args required to build the message */
8369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8370     {
8371       if (unformat (i, "sw_if_index %d", &sw_if_index))
8372         ;
8373       else if (unformat (i, "%U %U",
8374                          unformat_ip4_address, &v4_src_address,
8375                          unformat_ip4_address, &v4_grp_address))
8376         {
8377           grp_address_length = 64;
8378           address_set = 1;
8379           is_ipv6 = 0;
8380         }
8381       else if (unformat (i, "%U %U",
8382                          unformat_ip6_address, &v6_src_address,
8383                          unformat_ip6_address, &v6_grp_address))
8384         {
8385           grp_address_length = 256;
8386           address_set = 1;
8387           is_ipv6 = 1;
8388         }
8389       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8390         {
8391           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8392           grp_address_length = 32;
8393           address_set = 1;
8394           is_ipv6 = 0;
8395         }
8396       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8397         {
8398           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8399           grp_address_length = 128;
8400           address_set = 1;
8401           is_ipv6 = 1;
8402         }
8403       else if (unformat (i, "/%d", &grp_address_length))
8404         ;
8405       else if (unformat (i, "local"))
8406         {
8407           is_local = 1;
8408         }
8409       else if (unformat (i, "del"))
8410         is_add = 0;
8411       else if (unformat (i, "add"))
8412         is_add = 1;
8413       else if (unformat (i, "vrf %d", &vrf_id))
8414         ;
8415       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8416         ;
8417       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8418         ;
8419       else
8420         {
8421           clib_warning ("parse error '%U'", format_unformat_error, i);
8422           return -99;
8423         }
8424     }
8425
8426   if (address_set == 0)
8427     {
8428       errmsg ("missing addresses\n");
8429       return -99;
8430     }
8431
8432   /* Construct the API message */
8433   M (IP_MROUTE_ADD_DEL, mp);
8434
8435   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8436   mp->table_id = ntohl (vrf_id);
8437
8438   mp->is_add = is_add;
8439   mp->is_ipv6 = is_ipv6;
8440   mp->is_local = is_local;
8441   mp->itf_flags = ntohl (iflags);
8442   mp->entry_flags = ntohl (eflags);
8443   mp->grp_address_length = grp_address_length;
8444   mp->grp_address_length = ntohs (mp->grp_address_length);
8445
8446   if (is_ipv6)
8447     {
8448       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8449       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8450     }
8451   else
8452     {
8453       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8454       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8455
8456     }
8457
8458   /* send it... */
8459   S (mp);
8460   /* Wait for a reply... */
8461   W (ret);
8462   return ret;
8463 }
8464
8465 static int
8466 api_mpls_table_add_del (vat_main_t * vam)
8467 {
8468   unformat_input_t *i = vam->input;
8469   vl_api_mpls_table_add_del_t *mp;
8470   u32 table_id = ~0;
8471   u8 is_add = 1;
8472   int ret = 0;
8473
8474   /* Parse args required to build the message */
8475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8476     {
8477       if (unformat (i, "table %d", &table_id))
8478         ;
8479       else if (unformat (i, "del"))
8480         is_add = 0;
8481       else if (unformat (i, "add"))
8482         is_add = 1;
8483       else
8484         {
8485           clib_warning ("parse error '%U'", format_unformat_error, i);
8486           return -99;
8487         }
8488     }
8489
8490   if (~0 == table_id)
8491     {
8492       errmsg ("missing table-ID");
8493       return -99;
8494     }
8495
8496   /* Construct the API message */
8497   M (MPLS_TABLE_ADD_DEL, mp);
8498
8499   mp->mt_table_id = ntohl (table_id);
8500   mp->mt_is_add = is_add;
8501
8502   /* send it... */
8503   S (mp);
8504
8505   /* Wait for a reply... */
8506   W (ret);
8507
8508   return ret;
8509 }
8510
8511 static int
8512 api_mpls_route_add_del (vat_main_t * vam)
8513 {
8514   unformat_input_t *i = vam->input;
8515   vl_api_mpls_route_add_del_t *mp;
8516   u32 sw_if_index = ~0, table_id = 0;
8517   u8 is_add = 1;
8518   u32 next_hop_weight = 1;
8519   u8 is_multipath = 0;
8520   u32 next_hop_table_id = 0;
8521   u8 next_hop_set = 0;
8522   ip4_address_t v4_next_hop_address = {
8523     .as_u32 = 0,
8524   };
8525   ip6_address_t v6_next_hop_address = { {0} };
8526   int count = 1;
8527   int j;
8528   f64 before = 0;
8529   u32 classify_table_index = ~0;
8530   u8 is_classify = 0;
8531   u8 resolve_host = 0, resolve_attached = 0;
8532   u8 is_interface_rx = 0;
8533   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8534   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8535   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8536   mpls_label_t local_label = MPLS_LABEL_INVALID;
8537   u8 is_eos = 0;
8538   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8539
8540   /* Parse args required to build the message */
8541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8542     {
8543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8544         ;
8545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8546         ;
8547       else if (unformat (i, "%d", &local_label))
8548         ;
8549       else if (unformat (i, "eos"))
8550         is_eos = 1;
8551       else if (unformat (i, "non-eos"))
8552         is_eos = 0;
8553       else if (unformat (i, "via %U", unformat_ip4_address,
8554                          &v4_next_hop_address))
8555         {
8556           next_hop_set = 1;
8557           next_hop_proto = DPO_PROTO_IP4;
8558         }
8559       else if (unformat (i, "via %U", unformat_ip6_address,
8560                          &v6_next_hop_address))
8561         {
8562           next_hop_set = 1;
8563           next_hop_proto = DPO_PROTO_IP6;
8564         }
8565       else if (unformat (i, "weight %d", &next_hop_weight))
8566         ;
8567       else if (unformat (i, "classify %d", &classify_table_index))
8568         {
8569           is_classify = 1;
8570         }
8571       else if (unformat (i, "del"))
8572         is_add = 0;
8573       else if (unformat (i, "add"))
8574         is_add = 1;
8575       else if (unformat (i, "resolve-via-host"))
8576         resolve_host = 1;
8577       else if (unformat (i, "resolve-via-attached"))
8578         resolve_attached = 1;
8579       else if (unformat (i, "multipath"))
8580         is_multipath = 1;
8581       else if (unformat (i, "count %d", &count))
8582         ;
8583       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8584         {
8585           next_hop_set = 1;
8586           next_hop_proto = DPO_PROTO_IP4;
8587         }
8588       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8589         {
8590           next_hop_set = 1;
8591           next_hop_proto = DPO_PROTO_IP6;
8592         }
8593       else
8594         if (unformat
8595             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8596              &sw_if_index))
8597         {
8598           next_hop_set = 1;
8599           next_hop_proto = DPO_PROTO_ETHERNET;
8600           is_interface_rx = 1;
8601         }
8602       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8603         {
8604           next_hop_set = 1;
8605           next_hop_proto = DPO_PROTO_ETHERNET;
8606           is_interface_rx = 1;
8607         }
8608       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8609         next_hop_set = 1;
8610       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8611         next_hop_set = 1;
8612       else if (unformat (i, "out-label %d", &next_hop_out_label))
8613         {
8614           vl_api_fib_mpls_label_t fib_label = {
8615             .label = ntohl (next_hop_out_label),
8616             .ttl = 64,
8617             .exp = 0,
8618           };
8619           vec_add1 (next_hop_out_label_stack, fib_label);
8620         }
8621       else
8622         {
8623           clib_warning ("parse error '%U'", format_unformat_error, i);
8624           return -99;
8625         }
8626     }
8627
8628   if (!next_hop_set && !is_classify)
8629     {
8630       errmsg ("next hop / classify not set");
8631       return -99;
8632     }
8633
8634   if (MPLS_LABEL_INVALID == local_label)
8635     {
8636       errmsg ("missing label");
8637       return -99;
8638     }
8639
8640   if (count > 1)
8641     {
8642       /* Turn on async mode */
8643       vam->async_mode = 1;
8644       vam->async_errors = 0;
8645       before = vat_time_now (vam);
8646     }
8647
8648   for (j = 0; j < count; j++)
8649     {
8650       /* Construct the API message */
8651       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8652           vec_len (next_hop_out_label_stack));
8653
8654       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8655       mp->mr_table_id = ntohl (table_id);
8656
8657       mp->mr_is_add = is_add;
8658       mp->mr_next_hop_proto = next_hop_proto;
8659       mp->mr_is_classify = is_classify;
8660       mp->mr_is_multipath = is_multipath;
8661       mp->mr_is_resolve_host = resolve_host;
8662       mp->mr_is_resolve_attached = resolve_attached;
8663       mp->mr_is_interface_rx = is_interface_rx;
8664       mp->mr_next_hop_weight = next_hop_weight;
8665       mp->mr_next_hop_preference = 0;
8666       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8667       mp->mr_classify_table_index = ntohl (classify_table_index);
8668       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8669       mp->mr_label = ntohl (local_label);
8670       mp->mr_eos = is_eos;
8671
8672       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8673       if (0 != mp->mr_next_hop_n_out_labels)
8674         {
8675           memcpy (mp->mr_next_hop_out_label_stack,
8676                   next_hop_out_label_stack,
8677                   vec_len (next_hop_out_label_stack) *
8678                   sizeof (vl_api_fib_mpls_label_t));
8679           vec_free (next_hop_out_label_stack);
8680         }
8681
8682       if (next_hop_set)
8683         {
8684           if (DPO_PROTO_IP4 == next_hop_proto)
8685             {
8686               clib_memcpy (mp->mr_next_hop,
8687                            &v4_next_hop_address,
8688                            sizeof (v4_next_hop_address));
8689             }
8690           else if (DPO_PROTO_IP6 == next_hop_proto)
8691
8692             {
8693               clib_memcpy (mp->mr_next_hop,
8694                            &v6_next_hop_address,
8695                            sizeof (v6_next_hop_address));
8696             }
8697         }
8698       local_label++;
8699
8700       /* send it... */
8701       S (mp);
8702       /* If we receive SIGTERM, stop now... */
8703       if (vam->do_exit)
8704         break;
8705     }
8706
8707   /* When testing multiple add/del ops, use a control-ping to sync */
8708   if (count > 1)
8709     {
8710       vl_api_control_ping_t *mp_ping;
8711       f64 after;
8712       f64 timeout;
8713
8714       /* Shut off async mode */
8715       vam->async_mode = 0;
8716
8717       MPING (CONTROL_PING, mp_ping);
8718       S (mp_ping);
8719
8720       timeout = vat_time_now (vam) + 1.0;
8721       while (vat_time_now (vam) < timeout)
8722         if (vam->result_ready == 1)
8723           goto out;
8724       vam->retval = -99;
8725
8726     out:
8727       if (vam->retval == -99)
8728         errmsg ("timeout");
8729
8730       if (vam->async_errors > 0)
8731         {
8732           errmsg ("%d asynchronous errors", vam->async_errors);
8733           vam->retval = -98;
8734         }
8735       vam->async_errors = 0;
8736       after = vat_time_now (vam);
8737
8738       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8739       if (j > 0)
8740         count = j;
8741
8742       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8743              count, after - before, count / (after - before));
8744     }
8745   else
8746     {
8747       int ret;
8748
8749       /* Wait for a reply... */
8750       W (ret);
8751       return ret;
8752     }
8753
8754   /* Return the good/bad news */
8755   return (vam->retval);
8756 }
8757
8758 static int
8759 api_mpls_ip_bind_unbind (vat_main_t * vam)
8760 {
8761   unformat_input_t *i = vam->input;
8762   vl_api_mpls_ip_bind_unbind_t *mp;
8763   u32 ip_table_id = 0;
8764   u8 is_bind = 1;
8765   u8 is_ip4 = 1;
8766   ip4_address_t v4_address;
8767   ip6_address_t v6_address;
8768   u32 address_length;
8769   u8 address_set = 0;
8770   mpls_label_t local_label = MPLS_LABEL_INVALID;
8771   int ret;
8772
8773   /* Parse args required to build the message */
8774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8775     {
8776       if (unformat (i, "%U/%d", unformat_ip4_address,
8777                     &v4_address, &address_length))
8778         {
8779           is_ip4 = 1;
8780           address_set = 1;
8781         }
8782       else if (unformat (i, "%U/%d", unformat_ip6_address,
8783                          &v6_address, &address_length))
8784         {
8785           is_ip4 = 0;
8786           address_set = 1;
8787         }
8788       else if (unformat (i, "%d", &local_label))
8789         ;
8790       else if (unformat (i, "table-id %d", &ip_table_id))
8791         ;
8792       else if (unformat (i, "unbind"))
8793         is_bind = 0;
8794       else if (unformat (i, "bind"))
8795         is_bind = 1;
8796       else
8797         {
8798           clib_warning ("parse error '%U'", format_unformat_error, i);
8799           return -99;
8800         }
8801     }
8802
8803   if (!address_set)
8804     {
8805       errmsg ("IP address not set");
8806       return -99;
8807     }
8808
8809   if (MPLS_LABEL_INVALID == local_label)
8810     {
8811       errmsg ("missing label");
8812       return -99;
8813     }
8814
8815   /* Construct the API message */
8816   M (MPLS_IP_BIND_UNBIND, mp);
8817
8818   mp->mb_is_bind = is_bind;
8819   mp->mb_is_ip4 = is_ip4;
8820   mp->mb_ip_table_id = ntohl (ip_table_id);
8821   mp->mb_mpls_table_id = 0;
8822   mp->mb_label = ntohl (local_label);
8823   mp->mb_address_length = address_length;
8824
8825   if (is_ip4)
8826     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8827   else
8828     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8829
8830   /* send it... */
8831   S (mp);
8832
8833   /* Wait for a reply... */
8834   W (ret);
8835   return ret;
8836 }
8837
8838 static int
8839 api_sr_mpls_policy_add (vat_main_t * vam)
8840 {
8841   unformat_input_t *i = vam->input;
8842   vl_api_sr_mpls_policy_add_t *mp;
8843   u32 bsid = 0;
8844   u32 weight = 1;
8845   u8 type = 0;
8846   u8 n_segments = 0;
8847   u32 sid;
8848   u32 *segments = NULL;
8849   int ret;
8850
8851   /* Parse args required to build the message */
8852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8853     {
8854       if (unformat (i, "bsid %d", &bsid))
8855         ;
8856       else if (unformat (i, "weight %d", &weight))
8857         ;
8858       else if (unformat (i, "spray"))
8859         type = 1;
8860       else if (unformat (i, "next %d", &sid))
8861         {
8862           n_segments += 1;
8863           vec_add1 (segments, htonl (sid));
8864         }
8865       else
8866         {
8867           clib_warning ("parse error '%U'", format_unformat_error, i);
8868           return -99;
8869         }
8870     }
8871
8872   if (bsid == 0)
8873     {
8874       errmsg ("bsid not set");
8875       return -99;
8876     }
8877
8878   if (n_segments == 0)
8879     {
8880       errmsg ("no sid in segment stack");
8881       return -99;
8882     }
8883
8884   /* Construct the API message */
8885   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8886
8887   mp->bsid = htonl (bsid);
8888   mp->weight = htonl (weight);
8889   mp->type = type;
8890   mp->n_segments = n_segments;
8891   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8892   vec_free (segments);
8893
8894   /* send it... */
8895   S (mp);
8896
8897   /* Wait for a reply... */
8898   W (ret);
8899   return ret;
8900 }
8901
8902 static int
8903 api_sr_mpls_policy_del (vat_main_t * vam)
8904 {
8905   unformat_input_t *i = vam->input;
8906   vl_api_sr_mpls_policy_del_t *mp;
8907   u32 bsid = 0;
8908   int ret;
8909
8910   /* Parse args required to build the message */
8911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8912     {
8913       if (unformat (i, "bsid %d", &bsid))
8914         ;
8915       else
8916         {
8917           clib_warning ("parse error '%U'", format_unformat_error, i);
8918           return -99;
8919         }
8920     }
8921
8922   if (bsid == 0)
8923     {
8924       errmsg ("bsid not set");
8925       return -99;
8926     }
8927
8928   /* Construct the API message */
8929   M (SR_MPLS_POLICY_DEL, mp);
8930
8931   mp->bsid = htonl (bsid);
8932
8933   /* send it... */
8934   S (mp);
8935
8936   /* Wait for a reply... */
8937   W (ret);
8938   return ret;
8939 }
8940
8941 static int
8942 api_bier_table_add_del (vat_main_t * vam)
8943 {
8944   unformat_input_t *i = vam->input;
8945   vl_api_bier_table_add_del_t *mp;
8946   u8 is_add = 1;
8947   u32 set = 0, sub_domain = 0, hdr_len = 3;
8948   mpls_label_t local_label = MPLS_LABEL_INVALID;
8949   int ret;
8950
8951   /* Parse args required to build the message */
8952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (unformat (i, "sub-domain %d", &sub_domain))
8955         ;
8956       else if (unformat (i, "set %d", &set))
8957         ;
8958       else if (unformat (i, "label %d", &local_label))
8959         ;
8960       else if (unformat (i, "hdr-len %d", &hdr_len))
8961         ;
8962       else if (unformat (i, "add"))
8963         is_add = 1;
8964       else if (unformat (i, "del"))
8965         is_add = 0;
8966       else
8967         {
8968           clib_warning ("parse error '%U'", format_unformat_error, i);
8969           return -99;
8970         }
8971     }
8972
8973   if (MPLS_LABEL_INVALID == local_label)
8974     {
8975       errmsg ("missing label\n");
8976       return -99;
8977     }
8978
8979   /* Construct the API message */
8980   M (BIER_TABLE_ADD_DEL, mp);
8981
8982   mp->bt_is_add = is_add;
8983   mp->bt_label = ntohl (local_label);
8984   mp->bt_tbl_id.bt_set = set;
8985   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8986   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8987
8988   /* send it... */
8989   S (mp);
8990
8991   /* Wait for a reply... */
8992   W (ret);
8993
8994   return (ret);
8995 }
8996
8997 static int
8998 api_bier_route_add_del (vat_main_t * vam)
8999 {
9000   unformat_input_t *i = vam->input;
9001   vl_api_bier_route_add_del_t *mp;
9002   u8 is_add = 1;
9003   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9004   ip4_address_t v4_next_hop_address;
9005   ip6_address_t v6_next_hop_address;
9006   u8 next_hop_set = 0;
9007   u8 next_hop_proto_is_ip4 = 1;
9008   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9009   int ret;
9010
9011   /* Parse args required to build the message */
9012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9015         {
9016           next_hop_proto_is_ip4 = 1;
9017           next_hop_set = 1;
9018         }
9019       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9020         {
9021           next_hop_proto_is_ip4 = 0;
9022           next_hop_set = 1;
9023         }
9024       if (unformat (i, "sub-domain %d", &sub_domain))
9025         ;
9026       else if (unformat (i, "set %d", &set))
9027         ;
9028       else if (unformat (i, "hdr-len %d", &hdr_len))
9029         ;
9030       else if (unformat (i, "bp %d", &bp))
9031         ;
9032       else if (unformat (i, "add"))
9033         is_add = 1;
9034       else if (unformat (i, "del"))
9035         is_add = 0;
9036       else if (unformat (i, "out-label %d", &next_hop_out_label))
9037         ;
9038       else
9039         {
9040           clib_warning ("parse error '%U'", format_unformat_error, i);
9041           return -99;
9042         }
9043     }
9044
9045   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9046     {
9047       errmsg ("next hop / label set\n");
9048       return -99;
9049     }
9050   if (0 == bp)
9051     {
9052       errmsg ("bit=position not set\n");
9053       return -99;
9054     }
9055
9056   /* Construct the API message */
9057   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9058
9059   mp->br_is_add = is_add;
9060   mp->br_tbl_id.bt_set = set;
9061   mp->br_tbl_id.bt_sub_domain = sub_domain;
9062   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9063   mp->br_bp = ntohs (bp);
9064   mp->br_n_paths = 1;
9065   mp->br_paths[0].n_labels = 1;
9066   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9067   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9068
9069   if (next_hop_proto_is_ip4)
9070     {
9071       clib_memcpy (mp->br_paths[0].next_hop,
9072                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9073     }
9074   else
9075     {
9076       clib_memcpy (mp->br_paths[0].next_hop,
9077                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9078     }
9079
9080   /* send it... */
9081   S (mp);
9082
9083   /* Wait for a reply... */
9084   W (ret);
9085
9086   return (ret);
9087 }
9088
9089 static int
9090 api_proxy_arp_add_del (vat_main_t * vam)
9091 {
9092   unformat_input_t *i = vam->input;
9093   vl_api_proxy_arp_add_del_t *mp;
9094   u32 vrf_id = 0;
9095   u8 is_add = 1;
9096   vl_api_ip4_address_t lo, hi;
9097   u8 range_set = 0;
9098   int ret;
9099
9100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9101     {
9102       if (unformat (i, "vrf %d", &vrf_id))
9103         ;
9104       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9105                          unformat_vl_api_ip4_address, &hi))
9106         range_set = 1;
9107       else if (unformat (i, "del"))
9108         is_add = 0;
9109       else
9110         {
9111           clib_warning ("parse error '%U'", format_unformat_error, i);
9112           return -99;
9113         }
9114     }
9115
9116   if (range_set == 0)
9117     {
9118       errmsg ("address range not set");
9119       return -99;
9120     }
9121
9122   M (PROXY_ARP_ADD_DEL, mp);
9123
9124   mp->proxy.table_id = ntohl (vrf_id);
9125   mp->is_add = is_add;
9126   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9127   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9128
9129   S (mp);
9130   W (ret);
9131   return ret;
9132 }
9133
9134 static int
9135 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9136 {
9137   unformat_input_t *i = vam->input;
9138   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9139   u32 sw_if_index;
9140   u8 enable = 1;
9141   u8 sw_if_index_set = 0;
9142   int ret;
9143
9144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9147         sw_if_index_set = 1;
9148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9149         sw_if_index_set = 1;
9150       else if (unformat (i, "enable"))
9151         enable = 1;
9152       else if (unformat (i, "disable"))
9153         enable = 0;
9154       else
9155         {
9156           clib_warning ("parse error '%U'", format_unformat_error, i);
9157           return -99;
9158         }
9159     }
9160
9161   if (sw_if_index_set == 0)
9162     {
9163       errmsg ("missing interface name or sw_if_index");
9164       return -99;
9165     }
9166
9167   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9168
9169   mp->sw_if_index = ntohl (sw_if_index);
9170   mp->enable_disable = enable;
9171
9172   S (mp);
9173   W (ret);
9174   return ret;
9175 }
9176
9177 static int
9178 api_mpls_tunnel_add_del (vat_main_t * vam)
9179 {
9180   unformat_input_t *i = vam->input;
9181   vl_api_mpls_tunnel_add_del_t *mp;
9182
9183   u8 is_add = 1;
9184   u8 l2_only = 0;
9185   u32 sw_if_index = ~0;
9186   u32 next_hop_sw_if_index = ~0;
9187   u32 next_hop_proto_is_ip4 = 1;
9188
9189   u32 next_hop_table_id = 0;
9190   ip4_address_t v4_next_hop_address = {
9191     .as_u32 = 0,
9192   };
9193   ip6_address_t v6_next_hop_address = { {0} };
9194   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9195   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9196   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9197   int ret;
9198
9199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9200     {
9201       if (unformat (i, "add"))
9202         is_add = 1;
9203       else
9204         if (unformat
9205             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9206         is_add = 0;
9207       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9208         is_add = 0;
9209       else if (unformat (i, "via %U",
9210                          unformat_ip4_address, &v4_next_hop_address))
9211         {
9212           next_hop_proto_is_ip4 = 1;
9213         }
9214       else if (unformat (i, "via %U",
9215                          unformat_ip6_address, &v6_next_hop_address))
9216         {
9217           next_hop_proto_is_ip4 = 0;
9218         }
9219       else if (unformat (i, "via-label %d", &next_hop_via_label))
9220         ;
9221       else
9222         if (unformat
9223             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9224         ;
9225       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9226         ;
9227       else if (unformat (i, "l2-only"))
9228         l2_only = 1;
9229       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9230         ;
9231       else if (unformat (i, "out-label %d", &next_hop_out_label))
9232         {
9233           vl_api_fib_mpls_label_t fib_label = {
9234             .label = ntohl (next_hop_out_label),
9235             .ttl = 64,
9236             .exp = 0,
9237           };
9238           vec_add1 (next_hop_out_label_stack, fib_label);
9239         }
9240       else
9241         {
9242           clib_warning ("parse error '%U'", format_unformat_error, i);
9243           return -99;
9244         }
9245     }
9246
9247   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9248       vec_len (next_hop_out_label_stack));
9249
9250   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9251   mp->mt_sw_if_index = ntohl (sw_if_index);
9252   mp->mt_is_add = is_add;
9253   mp->mt_l2_only = l2_only;
9254   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9255   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9256   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9257   mp->mt_next_hop_weight = 1;
9258   mp->mt_next_hop_preference = 0;
9259
9260   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9261
9262   if (0 != mp->mt_next_hop_n_out_labels)
9263     {
9264       clib_memcpy (mp->mt_next_hop_out_label_stack,
9265                    next_hop_out_label_stack,
9266                    (vec_len (next_hop_out_label_stack) *
9267                     sizeof (vl_api_fib_mpls_label_t)));
9268       vec_free (next_hop_out_label_stack);
9269     }
9270
9271   if (next_hop_proto_is_ip4)
9272     {
9273       clib_memcpy (mp->mt_next_hop,
9274                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9275     }
9276   else
9277     {
9278       clib_memcpy (mp->mt_next_hop,
9279                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9280     }
9281
9282   S (mp);
9283   W (ret);
9284   return ret;
9285 }
9286
9287 static int
9288 api_sw_interface_set_unnumbered (vat_main_t * vam)
9289 {
9290   unformat_input_t *i = vam->input;
9291   vl_api_sw_interface_set_unnumbered_t *mp;
9292   u32 sw_if_index;
9293   u32 unnum_sw_index = ~0;
9294   u8 is_add = 1;
9295   u8 sw_if_index_set = 0;
9296   int ret;
9297
9298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9301         sw_if_index_set = 1;
9302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9303         sw_if_index_set = 1;
9304       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9305         ;
9306       else if (unformat (i, "del"))
9307         is_add = 0;
9308       else
9309         {
9310           clib_warning ("parse error '%U'", format_unformat_error, i);
9311           return -99;
9312         }
9313     }
9314
9315   if (sw_if_index_set == 0)
9316     {
9317       errmsg ("missing interface name or sw_if_index");
9318       return -99;
9319     }
9320
9321   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9322
9323   mp->sw_if_index = ntohl (sw_if_index);
9324   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9325   mp->is_add = is_add;
9326
9327   S (mp);
9328   W (ret);
9329   return ret;
9330 }
9331
9332 static int
9333 api_ip_neighbor_add_del (vat_main_t * vam)
9334 {
9335   vl_api_mac_address_t mac_address;
9336   unformat_input_t *i = vam->input;
9337   vl_api_ip_neighbor_add_del_t *mp;
9338   vl_api_address_t ip_address;
9339   u32 sw_if_index;
9340   u8 sw_if_index_set = 0;
9341   u8 is_add = 1;
9342   u8 mac_set = 0;
9343   u8 address_set = 0;
9344   int ret;
9345   ip_neighbor_flags_t flags;
9346
9347   flags = IP_NEIGHBOR_FLAG_NONE;
9348   clib_memset (&ip_address, 0, sizeof (ip_address));
9349   clib_memset (&mac_address, 0, sizeof (mac_address));
9350   /* Parse args required to build the message */
9351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9352     {
9353       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9354         {
9355           mac_set = 1;
9356         }
9357       else if (unformat (i, "del"))
9358         is_add = 0;
9359       else
9360         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9361         sw_if_index_set = 1;
9362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9363         sw_if_index_set = 1;
9364       else if (unformat (i, "static"))
9365         flags |= IP_NEIGHBOR_FLAG_STATIC;
9366       else if (unformat (i, "no-fib-entry"))
9367         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9368       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9369         address_set = 1;
9370       else
9371         {
9372           clib_warning ("parse error '%U'", format_unformat_error, i);
9373           return -99;
9374         }
9375     }
9376
9377   if (sw_if_index_set == 0)
9378     {
9379       errmsg ("missing interface name or sw_if_index");
9380       return -99;
9381     }
9382   if (!address_set)
9383     {
9384       errmsg ("no address set");
9385       return -99;
9386     }
9387
9388   /* Construct the API message */
9389   M (IP_NEIGHBOR_ADD_DEL, mp);
9390
9391   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9392   mp->is_add = is_add;
9393   mp->neighbor.flags = htonl (flags);
9394   if (mac_set)
9395     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9396                  sizeof (mac_address));
9397   if (address_set)
9398     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9399
9400   /* send it... */
9401   S (mp);
9402
9403   /* Wait for a reply, return good/bad news  */
9404   W (ret);
9405   return ret;
9406 }
9407
9408 static int
9409 api_create_vlan_subif (vat_main_t * vam)
9410 {
9411   unformat_input_t *i = vam->input;
9412   vl_api_create_vlan_subif_t *mp;
9413   u32 sw_if_index;
9414   u8 sw_if_index_set = 0;
9415   u32 vlan_id;
9416   u8 vlan_id_set = 0;
9417   int ret;
9418
9419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9420     {
9421       if (unformat (i, "sw_if_index %d", &sw_if_index))
9422         sw_if_index_set = 1;
9423       else
9424         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9425         sw_if_index_set = 1;
9426       else if (unformat (i, "vlan %d", &vlan_id))
9427         vlan_id_set = 1;
9428       else
9429         {
9430           clib_warning ("parse error '%U'", format_unformat_error, i);
9431           return -99;
9432         }
9433     }
9434
9435   if (sw_if_index_set == 0)
9436     {
9437       errmsg ("missing interface name or sw_if_index");
9438       return -99;
9439     }
9440
9441   if (vlan_id_set == 0)
9442     {
9443       errmsg ("missing vlan_id");
9444       return -99;
9445     }
9446   M (CREATE_VLAN_SUBIF, mp);
9447
9448   mp->sw_if_index = ntohl (sw_if_index);
9449   mp->vlan_id = ntohl (vlan_id);
9450
9451   S (mp);
9452   W (ret);
9453   return ret;
9454 }
9455
9456 #define foreach_create_subif_bit                \
9457 _(no_tags)                                      \
9458 _(one_tag)                                      \
9459 _(two_tags)                                     \
9460 _(dot1ad)                                       \
9461 _(exact_match)                                  \
9462 _(default_sub)                                  \
9463 _(outer_vlan_id_any)                            \
9464 _(inner_vlan_id_any)
9465
9466 static int
9467 api_create_subif (vat_main_t * vam)
9468 {
9469   unformat_input_t *i = vam->input;
9470   vl_api_create_subif_t *mp;
9471   u32 sw_if_index;
9472   u8 sw_if_index_set = 0;
9473   u32 sub_id;
9474   u8 sub_id_set = 0;
9475   u32 no_tags = 0;
9476   u32 one_tag = 0;
9477   u32 two_tags = 0;
9478   u32 dot1ad = 0;
9479   u32 exact_match = 0;
9480   u32 default_sub = 0;
9481   u32 outer_vlan_id_any = 0;
9482   u32 inner_vlan_id_any = 0;
9483   u32 tmp;
9484   u16 outer_vlan_id = 0;
9485   u16 inner_vlan_id = 0;
9486   int ret;
9487
9488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9489     {
9490       if (unformat (i, "sw_if_index %d", &sw_if_index))
9491         sw_if_index_set = 1;
9492       else
9493         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9494         sw_if_index_set = 1;
9495       else if (unformat (i, "sub_id %d", &sub_id))
9496         sub_id_set = 1;
9497       else if (unformat (i, "outer_vlan_id %d", &tmp))
9498         outer_vlan_id = tmp;
9499       else if (unformat (i, "inner_vlan_id %d", &tmp))
9500         inner_vlan_id = tmp;
9501
9502 #define _(a) else if (unformat (i, #a)) a = 1 ;
9503       foreach_create_subif_bit
9504 #undef _
9505         else
9506         {
9507           clib_warning ("parse error '%U'", format_unformat_error, i);
9508           return -99;
9509         }
9510     }
9511
9512   if (sw_if_index_set == 0)
9513     {
9514       errmsg ("missing interface name or sw_if_index");
9515       return -99;
9516     }
9517
9518   if (sub_id_set == 0)
9519     {
9520       errmsg ("missing sub_id");
9521       return -99;
9522     }
9523   M (CREATE_SUBIF, mp);
9524
9525   mp->sw_if_index = ntohl (sw_if_index);
9526   mp->sub_id = ntohl (sub_id);
9527
9528 #define _(a) mp->a = a;
9529   foreach_create_subif_bit;
9530 #undef _
9531
9532   mp->outer_vlan_id = ntohs (outer_vlan_id);
9533   mp->inner_vlan_id = ntohs (inner_vlan_id);
9534
9535   S (mp);
9536   W (ret);
9537   return ret;
9538 }
9539
9540 static int
9541 api_oam_add_del (vat_main_t * vam)
9542 {
9543   unformat_input_t *i = vam->input;
9544   vl_api_oam_add_del_t *mp;
9545   u32 vrf_id = 0;
9546   u8 is_add = 1;
9547   ip4_address_t src, dst;
9548   u8 src_set = 0;
9549   u8 dst_set = 0;
9550   int ret;
9551
9552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9553     {
9554       if (unformat (i, "vrf %d", &vrf_id))
9555         ;
9556       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9557         src_set = 1;
9558       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9559         dst_set = 1;
9560       else if (unformat (i, "del"))
9561         is_add = 0;
9562       else
9563         {
9564           clib_warning ("parse error '%U'", format_unformat_error, i);
9565           return -99;
9566         }
9567     }
9568
9569   if (src_set == 0)
9570     {
9571       errmsg ("missing src addr");
9572       return -99;
9573     }
9574
9575   if (dst_set == 0)
9576     {
9577       errmsg ("missing dst addr");
9578       return -99;
9579     }
9580
9581   M (OAM_ADD_DEL, mp);
9582
9583   mp->vrf_id = ntohl (vrf_id);
9584   mp->is_add = is_add;
9585   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9586   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9587
9588   S (mp);
9589   W (ret);
9590   return ret;
9591 }
9592
9593 static int
9594 api_reset_fib (vat_main_t * vam)
9595 {
9596   unformat_input_t *i = vam->input;
9597   vl_api_reset_fib_t *mp;
9598   u32 vrf_id = 0;
9599   u8 is_ipv6 = 0;
9600   u8 vrf_id_set = 0;
9601
9602   int ret;
9603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9604     {
9605       if (unformat (i, "vrf %d", &vrf_id))
9606         vrf_id_set = 1;
9607       else if (unformat (i, "ipv6"))
9608         is_ipv6 = 1;
9609       else
9610         {
9611           clib_warning ("parse error '%U'", format_unformat_error, i);
9612           return -99;
9613         }
9614     }
9615
9616   if (vrf_id_set == 0)
9617     {
9618       errmsg ("missing vrf id");
9619       return -99;
9620     }
9621
9622   M (RESET_FIB, mp);
9623
9624   mp->vrf_id = ntohl (vrf_id);
9625   mp->is_ipv6 = is_ipv6;
9626
9627   S (mp);
9628   W (ret);
9629   return ret;
9630 }
9631
9632 static int
9633 api_dhcp_proxy_config (vat_main_t * vam)
9634 {
9635   unformat_input_t *i = vam->input;
9636   vl_api_dhcp_proxy_config_t *mp;
9637   u32 rx_vrf_id = 0;
9638   u32 server_vrf_id = 0;
9639   u8 is_add = 1;
9640   u8 v4_address_set = 0;
9641   u8 v6_address_set = 0;
9642   ip4_address_t v4address;
9643   ip6_address_t v6address;
9644   u8 v4_src_address_set = 0;
9645   u8 v6_src_address_set = 0;
9646   ip4_address_t v4srcaddress;
9647   ip6_address_t v6srcaddress;
9648   int ret;
9649
9650   /* Parse args required to build the message */
9651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9652     {
9653       if (unformat (i, "del"))
9654         is_add = 0;
9655       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9656         ;
9657       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9658         ;
9659       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9660         v4_address_set = 1;
9661       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9662         v6_address_set = 1;
9663       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9664         v4_src_address_set = 1;
9665       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9666         v6_src_address_set = 1;
9667       else
9668         break;
9669     }
9670
9671   if (v4_address_set && v6_address_set)
9672     {
9673       errmsg ("both v4 and v6 server addresses set");
9674       return -99;
9675     }
9676   if (!v4_address_set && !v6_address_set)
9677     {
9678       errmsg ("no server addresses set");
9679       return -99;
9680     }
9681
9682   if (v4_src_address_set && v6_src_address_set)
9683     {
9684       errmsg ("both v4 and v6  src addresses set");
9685       return -99;
9686     }
9687   if (!v4_src_address_set && !v6_src_address_set)
9688     {
9689       errmsg ("no src addresses set");
9690       return -99;
9691     }
9692
9693   if (!(v4_src_address_set && v4_address_set) &&
9694       !(v6_src_address_set && v6_address_set))
9695     {
9696       errmsg ("no matching server and src addresses set");
9697       return -99;
9698     }
9699
9700   /* Construct the API message */
9701   M (DHCP_PROXY_CONFIG, mp);
9702
9703   mp->is_add = is_add;
9704   mp->rx_vrf_id = ntohl (rx_vrf_id);
9705   mp->server_vrf_id = ntohl (server_vrf_id);
9706   if (v6_address_set)
9707     {
9708       mp->is_ipv6 = 1;
9709       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9710       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9711     }
9712   else
9713     {
9714       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9715       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9716     }
9717
9718   /* send it... */
9719   S (mp);
9720
9721   /* Wait for a reply, return good/bad news  */
9722   W (ret);
9723   return ret;
9724 }
9725
9726 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9727 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9728
9729 static void
9730 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9731 {
9732   vat_main_t *vam = &vat_main;
9733   u32 i, count = mp->count;
9734   vl_api_dhcp_server_t *s;
9735
9736   if (mp->is_ipv6)
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_ip6_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   else
9745     print (vam->ofp,
9746            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9747            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9748            ntohl (mp->rx_vrf_id),
9749            format_ip4_address, mp->dhcp_src_address,
9750            mp->vss_type, mp->vss_vpn_ascii_id,
9751            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9752
9753   for (i = 0; i < count; i++)
9754     {
9755       s = &mp->servers[i];
9756
9757       if (mp->is_ipv6)
9758         print (vam->ofp,
9759                " Server Table-ID %d, Server Address %U",
9760                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9761       else
9762         print (vam->ofp,
9763                " Server Table-ID %d, Server Address %U",
9764                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9765     }
9766 }
9767
9768 static void vl_api_dhcp_proxy_details_t_handler_json
9769   (vl_api_dhcp_proxy_details_t * mp)
9770 {
9771   vat_main_t *vam = &vat_main;
9772   vat_json_node_t *node = NULL;
9773   u32 i, count = mp->count;
9774   struct in_addr ip4;
9775   struct in6_addr ip6;
9776   vl_api_dhcp_server_t *s;
9777
9778   if (VAT_JSON_ARRAY != vam->json_tree.type)
9779     {
9780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9781       vat_json_init_array (&vam->json_tree);
9782     }
9783   node = vat_json_array_add (&vam->json_tree);
9784
9785   vat_json_init_object (node);
9786   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9787   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9788                              sizeof (mp->vss_type));
9789   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9790                                    mp->vss_vpn_ascii_id);
9791   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9792   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9793
9794   if (mp->is_ipv6)
9795     {
9796       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9797       vat_json_object_add_ip6 (node, "src_address", ip6);
9798     }
9799   else
9800     {
9801       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9802       vat_json_object_add_ip4 (node, "src_address", ip4);
9803     }
9804
9805   for (i = 0; i < count; i++)
9806     {
9807       s = &mp->servers[i];
9808
9809       vat_json_object_add_uint (node, "server-table-id",
9810                                 ntohl (s->server_vrf_id));
9811
9812       if (mp->is_ipv6)
9813         {
9814           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9815           vat_json_object_add_ip4 (node, "src_address", ip4);
9816         }
9817       else
9818         {
9819           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9820           vat_json_object_add_ip6 (node, "server_address", ip6);
9821         }
9822     }
9823 }
9824
9825 static int
9826 api_dhcp_proxy_dump (vat_main_t * vam)
9827 {
9828   unformat_input_t *i = vam->input;
9829   vl_api_control_ping_t *mp_ping;
9830   vl_api_dhcp_proxy_dump_t *mp;
9831   u8 is_ipv6 = 0;
9832   int ret;
9833
9834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9835     {
9836       if (unformat (i, "ipv6"))
9837         is_ipv6 = 1;
9838       else
9839         {
9840           clib_warning ("parse error '%U'", format_unformat_error, i);
9841           return -99;
9842         }
9843     }
9844
9845   M (DHCP_PROXY_DUMP, mp);
9846
9847   mp->is_ip6 = is_ipv6;
9848   S (mp);
9849
9850   /* Use a control ping for synchronization */
9851   MPING (CONTROL_PING, mp_ping);
9852   S (mp_ping);
9853
9854   W (ret);
9855   return ret;
9856 }
9857
9858 static int
9859 api_dhcp_proxy_set_vss (vat_main_t * vam)
9860 {
9861   unformat_input_t *i = vam->input;
9862   vl_api_dhcp_proxy_set_vss_t *mp;
9863   u8 is_ipv6 = 0;
9864   u8 is_add = 1;
9865   u32 tbl_id = ~0;
9866   u8 vss_type = VSS_TYPE_DEFAULT;
9867   u8 *vpn_ascii_id = 0;
9868   u32 oui = 0;
9869   u32 fib_id = 0;
9870   int ret;
9871
9872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9873     {
9874       if (unformat (i, "tbl_id %d", &tbl_id))
9875         ;
9876       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9877         vss_type = VSS_TYPE_ASCII;
9878       else if (unformat (i, "fib_id %d", &fib_id))
9879         vss_type = VSS_TYPE_VPN_ID;
9880       else if (unformat (i, "oui %d", &oui))
9881         vss_type = VSS_TYPE_VPN_ID;
9882       else if (unformat (i, "ipv6"))
9883         is_ipv6 = 1;
9884       else if (unformat (i, "del"))
9885         is_add = 0;
9886       else
9887         break;
9888     }
9889
9890   if (tbl_id == ~0)
9891     {
9892       errmsg ("missing tbl_id ");
9893       vec_free (vpn_ascii_id);
9894       return -99;
9895     }
9896
9897   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9898     {
9899       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9900       vec_free (vpn_ascii_id);
9901       return -99;
9902     }
9903
9904   M (DHCP_PROXY_SET_VSS, mp);
9905   mp->tbl_id = ntohl (tbl_id);
9906   mp->vss_type = vss_type;
9907   if (vpn_ascii_id)
9908     {
9909       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9910       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9911     }
9912   mp->vpn_index = ntohl (fib_id);
9913   mp->oui = ntohl (oui);
9914   mp->is_ipv6 = is_ipv6;
9915   mp->is_add = is_add;
9916
9917   S (mp);
9918   W (ret);
9919
9920   vec_free (vpn_ascii_id);
9921   return ret;
9922 }
9923
9924 static int
9925 api_dhcp_client_config (vat_main_t * vam)
9926 {
9927   unformat_input_t *i = vam->input;
9928   vl_api_dhcp_client_config_t *mp;
9929   u32 sw_if_index;
9930   u8 sw_if_index_set = 0;
9931   u8 is_add = 1;
9932   u8 *hostname = 0;
9933   u8 disable_event = 0;
9934   int ret;
9935
9936   /* Parse args required to build the message */
9937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9938     {
9939       if (unformat (i, "del"))
9940         is_add = 0;
9941       else
9942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9943         sw_if_index_set = 1;
9944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9945         sw_if_index_set = 1;
9946       else if (unformat (i, "hostname %s", &hostname))
9947         ;
9948       else if (unformat (i, "disable_event"))
9949         disable_event = 1;
9950       else
9951         break;
9952     }
9953
9954   if (sw_if_index_set == 0)
9955     {
9956       errmsg ("missing interface name or sw_if_index");
9957       return -99;
9958     }
9959
9960   if (vec_len (hostname) > 63)
9961     {
9962       errmsg ("hostname too long");
9963     }
9964   vec_add1 (hostname, 0);
9965
9966   /* Construct the API message */
9967   M (DHCP_CLIENT_CONFIG, mp);
9968
9969   mp->is_add = is_add;
9970   mp->client.sw_if_index = htonl (sw_if_index);
9971   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9972   vec_free (hostname);
9973   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9974   mp->client.pid = htonl (getpid ());
9975
9976   /* send it... */
9977   S (mp);
9978
9979   /* Wait for a reply, return good/bad news  */
9980   W (ret);
9981   return ret;
9982 }
9983
9984 static int
9985 api_set_ip_flow_hash (vat_main_t * vam)
9986 {
9987   unformat_input_t *i = vam->input;
9988   vl_api_set_ip_flow_hash_t *mp;
9989   u32 vrf_id = 0;
9990   u8 is_ipv6 = 0;
9991   u8 vrf_id_set = 0;
9992   u8 src = 0;
9993   u8 dst = 0;
9994   u8 sport = 0;
9995   u8 dport = 0;
9996   u8 proto = 0;
9997   u8 reverse = 0;
9998   int ret;
9999
10000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10001     {
10002       if (unformat (i, "vrf %d", &vrf_id))
10003         vrf_id_set = 1;
10004       else if (unformat (i, "ipv6"))
10005         is_ipv6 = 1;
10006       else if (unformat (i, "src"))
10007         src = 1;
10008       else if (unformat (i, "dst"))
10009         dst = 1;
10010       else if (unformat (i, "sport"))
10011         sport = 1;
10012       else if (unformat (i, "dport"))
10013         dport = 1;
10014       else if (unformat (i, "proto"))
10015         proto = 1;
10016       else if (unformat (i, "reverse"))
10017         reverse = 1;
10018
10019       else
10020         {
10021           clib_warning ("parse error '%U'", format_unformat_error, i);
10022           return -99;
10023         }
10024     }
10025
10026   if (vrf_id_set == 0)
10027     {
10028       errmsg ("missing vrf id");
10029       return -99;
10030     }
10031
10032   M (SET_IP_FLOW_HASH, mp);
10033   mp->src = src;
10034   mp->dst = dst;
10035   mp->sport = sport;
10036   mp->dport = dport;
10037   mp->proto = proto;
10038   mp->reverse = reverse;
10039   mp->vrf_id = ntohl (vrf_id);
10040   mp->is_ipv6 = is_ipv6;
10041
10042   S (mp);
10043   W (ret);
10044   return ret;
10045 }
10046
10047 static int
10048 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10049 {
10050   unformat_input_t *i = vam->input;
10051   vl_api_sw_interface_ip6_enable_disable_t *mp;
10052   u32 sw_if_index;
10053   u8 sw_if_index_set = 0;
10054   u8 enable = 0;
10055   int ret;
10056
10057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10058     {
10059       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10060         sw_if_index_set = 1;
10061       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10062         sw_if_index_set = 1;
10063       else if (unformat (i, "enable"))
10064         enable = 1;
10065       else if (unformat (i, "disable"))
10066         enable = 0;
10067       else
10068         {
10069           clib_warning ("parse error '%U'", format_unformat_error, i);
10070           return -99;
10071         }
10072     }
10073
10074   if (sw_if_index_set == 0)
10075     {
10076       errmsg ("missing interface name or sw_if_index");
10077       return -99;
10078     }
10079
10080   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10081
10082   mp->sw_if_index = ntohl (sw_if_index);
10083   mp->enable = enable;
10084
10085   S (mp);
10086   W (ret);
10087   return ret;
10088 }
10089
10090 static int
10091 api_ip6nd_proxy_add_del (vat_main_t * vam)
10092 {
10093   unformat_input_t *i = vam->input;
10094   vl_api_ip6nd_proxy_add_del_t *mp;
10095   u32 sw_if_index = ~0;
10096   u8 v6_address_set = 0;
10097   vl_api_ip6_address_t v6address;
10098   u8 is_del = 0;
10099   int ret;
10100
10101   /* Parse args required to build the message */
10102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10103     {
10104       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10105         ;
10106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10107         ;
10108       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10109         v6_address_set = 1;
10110       if (unformat (i, "del"))
10111         is_del = 1;
10112       else
10113         {
10114           clib_warning ("parse error '%U'", format_unformat_error, i);
10115           return -99;
10116         }
10117     }
10118
10119   if (sw_if_index == ~0)
10120     {
10121       errmsg ("missing interface name or sw_if_index");
10122       return -99;
10123     }
10124   if (!v6_address_set)
10125     {
10126       errmsg ("no address set");
10127       return -99;
10128     }
10129
10130   /* Construct the API message */
10131   M (IP6ND_PROXY_ADD_DEL, mp);
10132
10133   mp->is_del = is_del;
10134   mp->sw_if_index = ntohl (sw_if_index);
10135   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10136
10137   /* send it... */
10138   S (mp);
10139
10140   /* Wait for a reply, return good/bad news  */
10141   W (ret);
10142   return ret;
10143 }
10144
10145 static int
10146 api_ip6nd_proxy_dump (vat_main_t * vam)
10147 {
10148   vl_api_ip6nd_proxy_dump_t *mp;
10149   vl_api_control_ping_t *mp_ping;
10150   int ret;
10151
10152   M (IP6ND_PROXY_DUMP, mp);
10153
10154   S (mp);
10155
10156   /* Use a control ping for synchronization */
10157   MPING (CONTROL_PING, mp_ping);
10158   S (mp_ping);
10159
10160   W (ret);
10161   return ret;
10162 }
10163
10164 static void vl_api_ip6nd_proxy_details_t_handler
10165   (vl_api_ip6nd_proxy_details_t * mp)
10166 {
10167   vat_main_t *vam = &vat_main;
10168
10169   print (vam->ofp, "host %U sw_if_index %d",
10170          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10171 }
10172
10173 static void vl_api_ip6nd_proxy_details_t_handler_json
10174   (vl_api_ip6nd_proxy_details_t * mp)
10175 {
10176   vat_main_t *vam = &vat_main;
10177   struct in6_addr ip6;
10178   vat_json_node_t *node = NULL;
10179
10180   if (VAT_JSON_ARRAY != vam->json_tree.type)
10181     {
10182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10183       vat_json_init_array (&vam->json_tree);
10184     }
10185   node = vat_json_array_add (&vam->json_tree);
10186
10187   vat_json_init_object (node);
10188   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10189
10190   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10191   vat_json_object_add_ip6 (node, "host", ip6);
10192 }
10193
10194 static int
10195 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10196 {
10197   unformat_input_t *i = vam->input;
10198   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10199   u32 sw_if_index;
10200   u8 sw_if_index_set = 0;
10201   u32 address_length = 0;
10202   u8 v6_address_set = 0;
10203   vl_api_prefix_t pfx;
10204   u8 use_default = 0;
10205   u8 no_advertise = 0;
10206   u8 off_link = 0;
10207   u8 no_autoconfig = 0;
10208   u8 no_onlink = 0;
10209   u8 is_no = 0;
10210   u32 val_lifetime = 0;
10211   u32 pref_lifetime = 0;
10212   int ret;
10213
10214   /* Parse args required to build the message */
10215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10216     {
10217       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10218         sw_if_index_set = 1;
10219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10220         sw_if_index_set = 1;
10221       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10222         v6_address_set = 1;
10223       else if (unformat (i, "val_life %d", &val_lifetime))
10224         ;
10225       else if (unformat (i, "pref_life %d", &pref_lifetime))
10226         ;
10227       else if (unformat (i, "def"))
10228         use_default = 1;
10229       else if (unformat (i, "noadv"))
10230         no_advertise = 1;
10231       else if (unformat (i, "offl"))
10232         off_link = 1;
10233       else if (unformat (i, "noauto"))
10234         no_autoconfig = 1;
10235       else if (unformat (i, "nolink"))
10236         no_onlink = 1;
10237       else if (unformat (i, "isno"))
10238         is_no = 1;
10239       else
10240         {
10241           clib_warning ("parse error '%U'", format_unformat_error, i);
10242           return -99;
10243         }
10244     }
10245
10246   if (sw_if_index_set == 0)
10247     {
10248       errmsg ("missing interface name or sw_if_index");
10249       return -99;
10250     }
10251   if (!v6_address_set)
10252     {
10253       errmsg ("no address set");
10254       return -99;
10255     }
10256
10257   /* Construct the API message */
10258   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10259
10260   mp->sw_if_index = ntohl (sw_if_index);
10261   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10262   mp->use_default = use_default;
10263   mp->no_advertise = no_advertise;
10264   mp->off_link = off_link;
10265   mp->no_autoconfig = no_autoconfig;
10266   mp->no_onlink = no_onlink;
10267   mp->is_no = is_no;
10268   mp->val_lifetime = ntohl (val_lifetime);
10269   mp->pref_lifetime = ntohl (pref_lifetime);
10270
10271   /* send it... */
10272   S (mp);
10273
10274   /* Wait for a reply, return good/bad news  */
10275   W (ret);
10276   return ret;
10277 }
10278
10279 static int
10280 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10281 {
10282   unformat_input_t *i = vam->input;
10283   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10284   u32 sw_if_index;
10285   u8 sw_if_index_set = 0;
10286   u8 suppress = 0;
10287   u8 managed = 0;
10288   u8 other = 0;
10289   u8 ll_option = 0;
10290   u8 send_unicast = 0;
10291   u8 cease = 0;
10292   u8 is_no = 0;
10293   u8 default_router = 0;
10294   u32 max_interval = 0;
10295   u32 min_interval = 0;
10296   u32 lifetime = 0;
10297   u32 initial_count = 0;
10298   u32 initial_interval = 0;
10299   int ret;
10300
10301
10302   /* Parse args required to build the message */
10303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10304     {
10305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10306         sw_if_index_set = 1;
10307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10308         sw_if_index_set = 1;
10309       else if (unformat (i, "maxint %d", &max_interval))
10310         ;
10311       else if (unformat (i, "minint %d", &min_interval))
10312         ;
10313       else if (unformat (i, "life %d", &lifetime))
10314         ;
10315       else if (unformat (i, "count %d", &initial_count))
10316         ;
10317       else if (unformat (i, "interval %d", &initial_interval))
10318         ;
10319       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10320         suppress = 1;
10321       else if (unformat (i, "managed"))
10322         managed = 1;
10323       else if (unformat (i, "other"))
10324         other = 1;
10325       else if (unformat (i, "ll"))
10326         ll_option = 1;
10327       else if (unformat (i, "send"))
10328         send_unicast = 1;
10329       else if (unformat (i, "cease"))
10330         cease = 1;
10331       else if (unformat (i, "isno"))
10332         is_no = 1;
10333       else if (unformat (i, "def"))
10334         default_router = 1;
10335       else
10336         {
10337           clib_warning ("parse error '%U'", format_unformat_error, i);
10338           return -99;
10339         }
10340     }
10341
10342   if (sw_if_index_set == 0)
10343     {
10344       errmsg ("missing interface name or sw_if_index");
10345       return -99;
10346     }
10347
10348   /* Construct the API message */
10349   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10350
10351   mp->sw_if_index = ntohl (sw_if_index);
10352   mp->max_interval = ntohl (max_interval);
10353   mp->min_interval = ntohl (min_interval);
10354   mp->lifetime = ntohl (lifetime);
10355   mp->initial_count = ntohl (initial_count);
10356   mp->initial_interval = ntohl (initial_interval);
10357   mp->suppress = suppress;
10358   mp->managed = managed;
10359   mp->other = other;
10360   mp->ll_option = ll_option;
10361   mp->send_unicast = send_unicast;
10362   mp->cease = cease;
10363   mp->is_no = is_no;
10364   mp->default_router = default_router;
10365
10366   /* send it... */
10367   S (mp);
10368
10369   /* Wait for a reply, return good/bad news  */
10370   W (ret);
10371   return ret;
10372 }
10373
10374 static int
10375 api_set_arp_neighbor_limit (vat_main_t * vam)
10376 {
10377   unformat_input_t *i = vam->input;
10378   vl_api_set_arp_neighbor_limit_t *mp;
10379   u32 arp_nbr_limit;
10380   u8 limit_set = 0;
10381   u8 is_ipv6 = 0;
10382   int ret;
10383
10384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10385     {
10386       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10387         limit_set = 1;
10388       else if (unformat (i, "ipv6"))
10389         is_ipv6 = 1;
10390       else
10391         {
10392           clib_warning ("parse error '%U'", format_unformat_error, i);
10393           return -99;
10394         }
10395     }
10396
10397   if (limit_set == 0)
10398     {
10399       errmsg ("missing limit value");
10400       return -99;
10401     }
10402
10403   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10404
10405   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10406   mp->is_ipv6 = is_ipv6;
10407
10408   S (mp);
10409   W (ret);
10410   return ret;
10411 }
10412
10413 static int
10414 api_l2_patch_add_del (vat_main_t * vam)
10415 {
10416   unformat_input_t *i = vam->input;
10417   vl_api_l2_patch_add_del_t *mp;
10418   u32 rx_sw_if_index;
10419   u8 rx_sw_if_index_set = 0;
10420   u32 tx_sw_if_index;
10421   u8 tx_sw_if_index_set = 0;
10422   u8 is_add = 1;
10423   int ret;
10424
10425   /* Parse args required to build the message */
10426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10427     {
10428       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10429         rx_sw_if_index_set = 1;
10430       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10431         tx_sw_if_index_set = 1;
10432       else if (unformat (i, "rx"))
10433         {
10434           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10435             {
10436               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10437                             &rx_sw_if_index))
10438                 rx_sw_if_index_set = 1;
10439             }
10440           else
10441             break;
10442         }
10443       else if (unformat (i, "tx"))
10444         {
10445           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10446             {
10447               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10448                             &tx_sw_if_index))
10449                 tx_sw_if_index_set = 1;
10450             }
10451           else
10452             break;
10453         }
10454       else if (unformat (i, "del"))
10455         is_add = 0;
10456       else
10457         break;
10458     }
10459
10460   if (rx_sw_if_index_set == 0)
10461     {
10462       errmsg ("missing rx interface name or rx_sw_if_index");
10463       return -99;
10464     }
10465
10466   if (tx_sw_if_index_set == 0)
10467     {
10468       errmsg ("missing tx interface name or tx_sw_if_index");
10469       return -99;
10470     }
10471
10472   M (L2_PATCH_ADD_DEL, mp);
10473
10474   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10475   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10476   mp->is_add = is_add;
10477
10478   S (mp);
10479   W (ret);
10480   return ret;
10481 }
10482
10483 u8 is_del;
10484 u8 localsid_addr[16];
10485 u8 end_psp;
10486 u8 behavior;
10487 u32 sw_if_index;
10488 u32 vlan_index;
10489 u32 fib_table;
10490 u8 nh_addr[16];
10491
10492 static int
10493 api_sr_localsid_add_del (vat_main_t * vam)
10494 {
10495   unformat_input_t *i = vam->input;
10496   vl_api_sr_localsid_add_del_t *mp;
10497
10498   u8 is_del;
10499   ip6_address_t localsid;
10500   u8 end_psp = 0;
10501   u8 behavior = ~0;
10502   u32 sw_if_index;
10503   u32 fib_table = ~(u32) 0;
10504   ip6_address_t nh_addr6;
10505   ip4_address_t nh_addr4;
10506   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10507   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10508
10509   bool nexthop_set = 0;
10510
10511   int ret;
10512
10513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10514     {
10515       if (unformat (i, "del"))
10516         is_del = 1;
10517       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10518       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10519         nexthop_set = 1;
10520       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10521         nexthop_set = 1;
10522       else if (unformat (i, "behavior %u", &behavior));
10523       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10524       else if (unformat (i, "fib-table %u", &fib_table));
10525       else if (unformat (i, "end.psp %u", &behavior));
10526       else
10527         break;
10528     }
10529
10530   M (SR_LOCALSID_ADD_DEL, mp);
10531
10532   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10533   if (nexthop_set)
10534     {
10535       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10536       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10537     }
10538   mp->behavior = behavior;
10539   mp->sw_if_index = ntohl (sw_if_index);
10540   mp->fib_table = ntohl (fib_table);
10541   mp->end_psp = end_psp;
10542   mp->is_del = is_del;
10543
10544   S (mp);
10545   W (ret);
10546   return ret;
10547 }
10548
10549 static int
10550 api_ioam_enable (vat_main_t * vam)
10551 {
10552   unformat_input_t *input = vam->input;
10553   vl_api_ioam_enable_t *mp;
10554   u32 id = 0;
10555   int has_trace_option = 0;
10556   int has_pot_option = 0;
10557   int has_seqno_option = 0;
10558   int has_analyse_option = 0;
10559   int ret;
10560
10561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10562     {
10563       if (unformat (input, "trace"))
10564         has_trace_option = 1;
10565       else if (unformat (input, "pot"))
10566         has_pot_option = 1;
10567       else if (unformat (input, "seqno"))
10568         has_seqno_option = 1;
10569       else if (unformat (input, "analyse"))
10570         has_analyse_option = 1;
10571       else
10572         break;
10573     }
10574   M (IOAM_ENABLE, mp);
10575   mp->id = htons (id);
10576   mp->seqno = has_seqno_option;
10577   mp->analyse = has_analyse_option;
10578   mp->pot_enable = has_pot_option;
10579   mp->trace_enable = has_trace_option;
10580
10581   S (mp);
10582   W (ret);
10583   return ret;
10584 }
10585
10586
10587 static int
10588 api_ioam_disable (vat_main_t * vam)
10589 {
10590   vl_api_ioam_disable_t *mp;
10591   int ret;
10592
10593   M (IOAM_DISABLE, mp);
10594   S (mp);
10595   W (ret);
10596   return ret;
10597 }
10598
10599 #define foreach_tcp_proto_field                 \
10600 _(src_port)                                     \
10601 _(dst_port)
10602
10603 #define foreach_udp_proto_field                 \
10604 _(src_port)                                     \
10605 _(dst_port)
10606
10607 #define foreach_ip4_proto_field                 \
10608 _(src_address)                                  \
10609 _(dst_address)                                  \
10610 _(tos)                                          \
10611 _(length)                                       \
10612 _(fragment_id)                                  \
10613 _(ttl)                                          \
10614 _(protocol)                                     \
10615 _(checksum)
10616
10617 typedef struct
10618 {
10619   u16 src_port, dst_port;
10620 } tcpudp_header_t;
10621
10622 #if VPP_API_TEST_BUILTIN == 0
10623 uword
10624 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10625 {
10626   u8 **maskp = va_arg (*args, u8 **);
10627   u8 *mask = 0;
10628   u8 found_something = 0;
10629   tcp_header_t *tcp;
10630
10631 #define _(a) u8 a=0;
10632   foreach_tcp_proto_field;
10633 #undef _
10634
10635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (0);
10638 #define _(a) else if (unformat (input, #a)) a=1;
10639       foreach_tcp_proto_field
10640 #undef _
10641         else
10642         break;
10643     }
10644
10645 #define _(a) found_something += a;
10646   foreach_tcp_proto_field;
10647 #undef _
10648
10649   if (found_something == 0)
10650     return 0;
10651
10652   vec_validate (mask, sizeof (*tcp) - 1);
10653
10654   tcp = (tcp_header_t *) mask;
10655
10656 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10657   foreach_tcp_proto_field;
10658 #undef _
10659
10660   *maskp = mask;
10661   return 1;
10662 }
10663
10664 uword
10665 unformat_udp_mask (unformat_input_t * input, va_list * args)
10666 {
10667   u8 **maskp = va_arg (*args, u8 **);
10668   u8 *mask = 0;
10669   u8 found_something = 0;
10670   udp_header_t *udp;
10671
10672 #define _(a) u8 a=0;
10673   foreach_udp_proto_field;
10674 #undef _
10675
10676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10677     {
10678       if (0);
10679 #define _(a) else if (unformat (input, #a)) a=1;
10680       foreach_udp_proto_field
10681 #undef _
10682         else
10683         break;
10684     }
10685
10686 #define _(a) found_something += a;
10687   foreach_udp_proto_field;
10688 #undef _
10689
10690   if (found_something == 0)
10691     return 0;
10692
10693   vec_validate (mask, sizeof (*udp) - 1);
10694
10695   udp = (udp_header_t *) mask;
10696
10697 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10698   foreach_udp_proto_field;
10699 #undef _
10700
10701   *maskp = mask;
10702   return 1;
10703 }
10704
10705 uword
10706 unformat_l4_mask (unformat_input_t * input, va_list * args)
10707 {
10708   u8 **maskp = va_arg (*args, u8 **);
10709   u16 src_port = 0, dst_port = 0;
10710   tcpudp_header_t *tcpudp;
10711
10712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10713     {
10714       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10715         return 1;
10716       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10717         return 1;
10718       else if (unformat (input, "src_port"))
10719         src_port = 0xFFFF;
10720       else if (unformat (input, "dst_port"))
10721         dst_port = 0xFFFF;
10722       else
10723         return 0;
10724     }
10725
10726   if (!src_port && !dst_port)
10727     return 0;
10728
10729   u8 *mask = 0;
10730   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10731
10732   tcpudp = (tcpudp_header_t *) mask;
10733   tcpudp->src_port = src_port;
10734   tcpudp->dst_port = dst_port;
10735
10736   *maskp = mask;
10737
10738   return 1;
10739 }
10740
10741 uword
10742 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10743 {
10744   u8 **maskp = va_arg (*args, u8 **);
10745   u8 *mask = 0;
10746   u8 found_something = 0;
10747   ip4_header_t *ip;
10748
10749 #define _(a) u8 a=0;
10750   foreach_ip4_proto_field;
10751 #undef _
10752   u8 version = 0;
10753   u8 hdr_length = 0;
10754
10755
10756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10757     {
10758       if (unformat (input, "version"))
10759         version = 1;
10760       else if (unformat (input, "hdr_length"))
10761         hdr_length = 1;
10762       else if (unformat (input, "src"))
10763         src_address = 1;
10764       else if (unformat (input, "dst"))
10765         dst_address = 1;
10766       else if (unformat (input, "proto"))
10767         protocol = 1;
10768
10769 #define _(a) else if (unformat (input, #a)) a=1;
10770       foreach_ip4_proto_field
10771 #undef _
10772         else
10773         break;
10774     }
10775
10776 #define _(a) found_something += a;
10777   foreach_ip4_proto_field;
10778 #undef _
10779
10780   if (found_something == 0)
10781     return 0;
10782
10783   vec_validate (mask, sizeof (*ip) - 1);
10784
10785   ip = (ip4_header_t *) mask;
10786
10787 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10788   foreach_ip4_proto_field;
10789 #undef _
10790
10791   ip->ip_version_and_header_length = 0;
10792
10793   if (version)
10794     ip->ip_version_and_header_length |= 0xF0;
10795
10796   if (hdr_length)
10797     ip->ip_version_and_header_length |= 0x0F;
10798
10799   *maskp = mask;
10800   return 1;
10801 }
10802
10803 #define foreach_ip6_proto_field                 \
10804 _(src_address)                                  \
10805 _(dst_address)                                  \
10806 _(payload_length)                               \
10807 _(hop_limit)                                    \
10808 _(protocol)
10809
10810 uword
10811 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10812 {
10813   u8 **maskp = va_arg (*args, u8 **);
10814   u8 *mask = 0;
10815   u8 found_something = 0;
10816   ip6_header_t *ip;
10817   u32 ip_version_traffic_class_and_flow_label;
10818
10819 #define _(a) u8 a=0;
10820   foreach_ip6_proto_field;
10821 #undef _
10822   u8 version = 0;
10823   u8 traffic_class = 0;
10824   u8 flow_label = 0;
10825
10826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10827     {
10828       if (unformat (input, "version"))
10829         version = 1;
10830       else if (unformat (input, "traffic-class"))
10831         traffic_class = 1;
10832       else if (unformat (input, "flow-label"))
10833         flow_label = 1;
10834       else if (unformat (input, "src"))
10835         src_address = 1;
10836       else if (unformat (input, "dst"))
10837         dst_address = 1;
10838       else if (unformat (input, "proto"))
10839         protocol = 1;
10840
10841 #define _(a) else if (unformat (input, #a)) a=1;
10842       foreach_ip6_proto_field
10843 #undef _
10844         else
10845         break;
10846     }
10847
10848 #define _(a) found_something += a;
10849   foreach_ip6_proto_field;
10850 #undef _
10851
10852   if (found_something == 0)
10853     return 0;
10854
10855   vec_validate (mask, sizeof (*ip) - 1);
10856
10857   ip = (ip6_header_t *) mask;
10858
10859 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10860   foreach_ip6_proto_field;
10861 #undef _
10862
10863   ip_version_traffic_class_and_flow_label = 0;
10864
10865   if (version)
10866     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10867
10868   if (traffic_class)
10869     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10870
10871   if (flow_label)
10872     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10873
10874   ip->ip_version_traffic_class_and_flow_label =
10875     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10876
10877   *maskp = mask;
10878   return 1;
10879 }
10880
10881 uword
10882 unformat_l3_mask (unformat_input_t * input, va_list * args)
10883 {
10884   u8 **maskp = va_arg (*args, u8 **);
10885
10886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10889         return 1;
10890       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10891         return 1;
10892       else
10893         break;
10894     }
10895   return 0;
10896 }
10897
10898 uword
10899 unformat_l2_mask (unformat_input_t * input, va_list * args)
10900 {
10901   u8 **maskp = va_arg (*args, u8 **);
10902   u8 *mask = 0;
10903   u8 src = 0;
10904   u8 dst = 0;
10905   u8 proto = 0;
10906   u8 tag1 = 0;
10907   u8 tag2 = 0;
10908   u8 ignore_tag1 = 0;
10909   u8 ignore_tag2 = 0;
10910   u8 cos1 = 0;
10911   u8 cos2 = 0;
10912   u8 dot1q = 0;
10913   u8 dot1ad = 0;
10914   int len = 14;
10915
10916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10917     {
10918       if (unformat (input, "src"))
10919         src = 1;
10920       else if (unformat (input, "dst"))
10921         dst = 1;
10922       else if (unformat (input, "proto"))
10923         proto = 1;
10924       else if (unformat (input, "tag1"))
10925         tag1 = 1;
10926       else if (unformat (input, "tag2"))
10927         tag2 = 1;
10928       else if (unformat (input, "ignore-tag1"))
10929         ignore_tag1 = 1;
10930       else if (unformat (input, "ignore-tag2"))
10931         ignore_tag2 = 1;
10932       else if (unformat (input, "cos1"))
10933         cos1 = 1;
10934       else if (unformat (input, "cos2"))
10935         cos2 = 1;
10936       else if (unformat (input, "dot1q"))
10937         dot1q = 1;
10938       else if (unformat (input, "dot1ad"))
10939         dot1ad = 1;
10940       else
10941         break;
10942     }
10943   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10944        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10945     return 0;
10946
10947   if (tag1 || ignore_tag1 || cos1 || dot1q)
10948     len = 18;
10949   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10950     len = 22;
10951
10952   vec_validate (mask, len - 1);
10953
10954   if (dst)
10955     clib_memset (mask, 0xff, 6);
10956
10957   if (src)
10958     clib_memset (mask + 6, 0xff, 6);
10959
10960   if (tag2 || dot1ad)
10961     {
10962       /* inner vlan tag */
10963       if (tag2)
10964         {
10965           mask[19] = 0xff;
10966           mask[18] = 0x0f;
10967         }
10968       if (cos2)
10969         mask[18] |= 0xe0;
10970       if (proto)
10971         mask[21] = mask[20] = 0xff;
10972       if (tag1)
10973         {
10974           mask[15] = 0xff;
10975           mask[14] = 0x0f;
10976         }
10977       if (cos1)
10978         mask[14] |= 0xe0;
10979       *maskp = mask;
10980       return 1;
10981     }
10982   if (tag1 | dot1q)
10983     {
10984       if (tag1)
10985         {
10986           mask[15] = 0xff;
10987           mask[14] = 0x0f;
10988         }
10989       if (cos1)
10990         mask[14] |= 0xe0;
10991       if (proto)
10992         mask[16] = mask[17] = 0xff;
10993
10994       *maskp = mask;
10995       return 1;
10996     }
10997   if (cos2)
10998     mask[18] |= 0xe0;
10999   if (cos1)
11000     mask[14] |= 0xe0;
11001   if (proto)
11002     mask[12] = mask[13] = 0xff;
11003
11004   *maskp = mask;
11005   return 1;
11006 }
11007
11008 uword
11009 unformat_classify_mask (unformat_input_t * input, va_list * args)
11010 {
11011   u8 **maskp = va_arg (*args, u8 **);
11012   u32 *skipp = va_arg (*args, u32 *);
11013   u32 *matchp = va_arg (*args, u32 *);
11014   u32 match;
11015   u8 *mask = 0;
11016   u8 *l2 = 0;
11017   u8 *l3 = 0;
11018   u8 *l4 = 0;
11019   int i;
11020
11021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11022     {
11023       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11024         ;
11025       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11026         ;
11027       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11028         ;
11029       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11030         ;
11031       else
11032         break;
11033     }
11034
11035   if (l4 && !l3)
11036     {
11037       vec_free (mask);
11038       vec_free (l2);
11039       vec_free (l4);
11040       return 0;
11041     }
11042
11043   if (mask || l2 || l3 || l4)
11044     {
11045       if (l2 || l3 || l4)
11046         {
11047           /* "With a free Ethernet header in every package" */
11048           if (l2 == 0)
11049             vec_validate (l2, 13);
11050           mask = l2;
11051           if (vec_len (l3))
11052             {
11053               vec_append (mask, l3);
11054               vec_free (l3);
11055             }
11056           if (vec_len (l4))
11057             {
11058               vec_append (mask, l4);
11059               vec_free (l4);
11060             }
11061         }
11062
11063       /* Scan forward looking for the first significant mask octet */
11064       for (i = 0; i < vec_len (mask); i++)
11065         if (mask[i])
11066           break;
11067
11068       /* compute (skip, match) params */
11069       *skipp = i / sizeof (u32x4);
11070       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11071
11072       /* Pad mask to an even multiple of the vector size */
11073       while (vec_len (mask) % sizeof (u32x4))
11074         vec_add1 (mask, 0);
11075
11076       match = vec_len (mask) / sizeof (u32x4);
11077
11078       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11079         {
11080           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11081           if (*tmp || *(tmp + 1))
11082             break;
11083           match--;
11084         }
11085       if (match == 0)
11086         clib_warning ("BUG: match 0");
11087
11088       _vec_len (mask) = match * sizeof (u32x4);
11089
11090       *matchp = match;
11091       *maskp = mask;
11092
11093       return 1;
11094     }
11095
11096   return 0;
11097 }
11098 #endif /* VPP_API_TEST_BUILTIN */
11099
11100 #define foreach_l2_next                         \
11101 _(drop, DROP)                                   \
11102 _(ethernet, ETHERNET_INPUT)                     \
11103 _(ip4, IP4_INPUT)                               \
11104 _(ip6, IP6_INPUT)
11105
11106 uword
11107 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11108 {
11109   u32 *miss_next_indexp = va_arg (*args, u32 *);
11110   u32 next_index = 0;
11111   u32 tmp;
11112
11113 #define _(n,N) \
11114   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11115   foreach_l2_next;
11116 #undef _
11117
11118   if (unformat (input, "%d", &tmp))
11119     {
11120       next_index = tmp;
11121       goto out;
11122     }
11123
11124   return 0;
11125
11126 out:
11127   *miss_next_indexp = next_index;
11128   return 1;
11129 }
11130
11131 #define foreach_ip_next                         \
11132 _(drop, DROP)                                   \
11133 _(local, LOCAL)                                 \
11134 _(rewrite, REWRITE)
11135
11136 uword
11137 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11138 {
11139   u32 *miss_next_indexp = va_arg (*args, u32 *);
11140   u32 next_index = 0;
11141   u32 tmp;
11142
11143 #define _(n,N) \
11144   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11145   foreach_ip_next;
11146 #undef _
11147
11148   if (unformat (input, "%d", &tmp))
11149     {
11150       next_index = tmp;
11151       goto out;
11152     }
11153
11154   return 0;
11155
11156 out:
11157   *miss_next_indexp = next_index;
11158   return 1;
11159 }
11160
11161 #define foreach_acl_next                        \
11162 _(deny, DENY)
11163
11164 uword
11165 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11166 {
11167   u32 *miss_next_indexp = va_arg (*args, u32 *);
11168   u32 next_index = 0;
11169   u32 tmp;
11170
11171 #define _(n,N) \
11172   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11173   foreach_acl_next;
11174 #undef _
11175
11176   if (unformat (input, "permit"))
11177     {
11178       next_index = ~0;
11179       goto out;
11180     }
11181   else if (unformat (input, "%d", &tmp))
11182     {
11183       next_index = tmp;
11184       goto out;
11185     }
11186
11187   return 0;
11188
11189 out:
11190   *miss_next_indexp = next_index;
11191   return 1;
11192 }
11193
11194 uword
11195 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11196 {
11197   u32 *r = va_arg (*args, u32 *);
11198
11199   if (unformat (input, "conform-color"))
11200     *r = POLICE_CONFORM;
11201   else if (unformat (input, "exceed-color"))
11202     *r = POLICE_EXCEED;
11203   else
11204     return 0;
11205
11206   return 1;
11207 }
11208
11209 static int
11210 api_classify_add_del_table (vat_main_t * vam)
11211 {
11212   unformat_input_t *i = vam->input;
11213   vl_api_classify_add_del_table_t *mp;
11214
11215   u32 nbuckets = 2;
11216   u32 skip = ~0;
11217   u32 match = ~0;
11218   int is_add = 1;
11219   int del_chain = 0;
11220   u32 table_index = ~0;
11221   u32 next_table_index = ~0;
11222   u32 miss_next_index = ~0;
11223   u32 memory_size = 32 << 20;
11224   u8 *mask = 0;
11225   u32 current_data_flag = 0;
11226   int current_data_offset = 0;
11227   int ret;
11228
11229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11230     {
11231       if (unformat (i, "del"))
11232         is_add = 0;
11233       else if (unformat (i, "del-chain"))
11234         {
11235           is_add = 0;
11236           del_chain = 1;
11237         }
11238       else if (unformat (i, "buckets %d", &nbuckets))
11239         ;
11240       else if (unformat (i, "memory_size %d", &memory_size))
11241         ;
11242       else if (unformat (i, "skip %d", &skip))
11243         ;
11244       else if (unformat (i, "match %d", &match))
11245         ;
11246       else if (unformat (i, "table %d", &table_index))
11247         ;
11248       else if (unformat (i, "mask %U", unformat_classify_mask,
11249                          &mask, &skip, &match))
11250         ;
11251       else if (unformat (i, "next-table %d", &next_table_index))
11252         ;
11253       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11254                          &miss_next_index))
11255         ;
11256       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11257                          &miss_next_index))
11258         ;
11259       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11260                          &miss_next_index))
11261         ;
11262       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11263         ;
11264       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11265         ;
11266       else
11267         break;
11268     }
11269
11270   if (is_add && mask == 0)
11271     {
11272       errmsg ("Mask required");
11273       return -99;
11274     }
11275
11276   if (is_add && skip == ~0)
11277     {
11278       errmsg ("skip count required");
11279       return -99;
11280     }
11281
11282   if (is_add && match == ~0)
11283     {
11284       errmsg ("match count required");
11285       return -99;
11286     }
11287
11288   if (!is_add && table_index == ~0)
11289     {
11290       errmsg ("table index required for delete");
11291       return -99;
11292     }
11293
11294   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11295
11296   mp->is_add = is_add;
11297   mp->del_chain = del_chain;
11298   mp->table_index = ntohl (table_index);
11299   mp->nbuckets = ntohl (nbuckets);
11300   mp->memory_size = ntohl (memory_size);
11301   mp->skip_n_vectors = ntohl (skip);
11302   mp->match_n_vectors = ntohl (match);
11303   mp->next_table_index = ntohl (next_table_index);
11304   mp->miss_next_index = ntohl (miss_next_index);
11305   mp->current_data_flag = ntohl (current_data_flag);
11306   mp->current_data_offset = ntohl (current_data_offset);
11307   mp->mask_len = ntohl (vec_len (mask));
11308   clib_memcpy (mp->mask, mask, vec_len (mask));
11309
11310   vec_free (mask);
11311
11312   S (mp);
11313   W (ret);
11314   return ret;
11315 }
11316
11317 #if VPP_API_TEST_BUILTIN == 0
11318 uword
11319 unformat_l4_match (unformat_input_t * input, va_list * args)
11320 {
11321   u8 **matchp = va_arg (*args, u8 **);
11322
11323   u8 *proto_header = 0;
11324   int src_port = 0;
11325   int dst_port = 0;
11326
11327   tcpudp_header_t h;
11328
11329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11330     {
11331       if (unformat (input, "src_port %d", &src_port))
11332         ;
11333       else if (unformat (input, "dst_port %d", &dst_port))
11334         ;
11335       else
11336         return 0;
11337     }
11338
11339   h.src_port = clib_host_to_net_u16 (src_port);
11340   h.dst_port = clib_host_to_net_u16 (dst_port);
11341   vec_validate (proto_header, sizeof (h) - 1);
11342   memcpy (proto_header, &h, sizeof (h));
11343
11344   *matchp = proto_header;
11345
11346   return 1;
11347 }
11348
11349 uword
11350 unformat_ip4_match (unformat_input_t * input, va_list * args)
11351 {
11352   u8 **matchp = va_arg (*args, u8 **);
11353   u8 *match = 0;
11354   ip4_header_t *ip;
11355   int version = 0;
11356   u32 version_val;
11357   int hdr_length = 0;
11358   u32 hdr_length_val;
11359   int src = 0, dst = 0;
11360   ip4_address_t src_val, dst_val;
11361   int proto = 0;
11362   u32 proto_val;
11363   int tos = 0;
11364   u32 tos_val;
11365   int length = 0;
11366   u32 length_val;
11367   int fragment_id = 0;
11368   u32 fragment_id_val;
11369   int ttl = 0;
11370   int ttl_val;
11371   int checksum = 0;
11372   u32 checksum_val;
11373
11374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11375     {
11376       if (unformat (input, "version %d", &version_val))
11377         version = 1;
11378       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11379         hdr_length = 1;
11380       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11381         src = 1;
11382       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11383         dst = 1;
11384       else if (unformat (input, "proto %d", &proto_val))
11385         proto = 1;
11386       else if (unformat (input, "tos %d", &tos_val))
11387         tos = 1;
11388       else if (unformat (input, "length %d", &length_val))
11389         length = 1;
11390       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11391         fragment_id = 1;
11392       else if (unformat (input, "ttl %d", &ttl_val))
11393         ttl = 1;
11394       else if (unformat (input, "checksum %d", &checksum_val))
11395         checksum = 1;
11396       else
11397         break;
11398     }
11399
11400   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11401       + ttl + checksum == 0)
11402     return 0;
11403
11404   /*
11405    * Aligned because we use the real comparison functions
11406    */
11407   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11408
11409   ip = (ip4_header_t *) match;
11410
11411   /* These are realistically matched in practice */
11412   if (src)
11413     ip->src_address.as_u32 = src_val.as_u32;
11414
11415   if (dst)
11416     ip->dst_address.as_u32 = dst_val.as_u32;
11417
11418   if (proto)
11419     ip->protocol = proto_val;
11420
11421
11422   /* These are not, but they're included for completeness */
11423   if (version)
11424     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11425
11426   if (hdr_length)
11427     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11428
11429   if (tos)
11430     ip->tos = tos_val;
11431
11432   if (length)
11433     ip->length = clib_host_to_net_u16 (length_val);
11434
11435   if (ttl)
11436     ip->ttl = ttl_val;
11437
11438   if (checksum)
11439     ip->checksum = clib_host_to_net_u16 (checksum_val);
11440
11441   *matchp = match;
11442   return 1;
11443 }
11444
11445 uword
11446 unformat_ip6_match (unformat_input_t * input, va_list * args)
11447 {
11448   u8 **matchp = va_arg (*args, u8 **);
11449   u8 *match = 0;
11450   ip6_header_t *ip;
11451   int version = 0;
11452   u32 version_val;
11453   u8 traffic_class = 0;
11454   u32 traffic_class_val = 0;
11455   u8 flow_label = 0;
11456   u8 flow_label_val;
11457   int src = 0, dst = 0;
11458   ip6_address_t src_val, dst_val;
11459   int proto = 0;
11460   u32 proto_val;
11461   int payload_length = 0;
11462   u32 payload_length_val;
11463   int hop_limit = 0;
11464   int hop_limit_val;
11465   u32 ip_version_traffic_class_and_flow_label;
11466
11467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11468     {
11469       if (unformat (input, "version %d", &version_val))
11470         version = 1;
11471       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11472         traffic_class = 1;
11473       else if (unformat (input, "flow_label %d", &flow_label_val))
11474         flow_label = 1;
11475       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11476         src = 1;
11477       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11478         dst = 1;
11479       else if (unformat (input, "proto %d", &proto_val))
11480         proto = 1;
11481       else if (unformat (input, "payload_length %d", &payload_length_val))
11482         payload_length = 1;
11483       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11484         hop_limit = 1;
11485       else
11486         break;
11487     }
11488
11489   if (version + traffic_class + flow_label + src + dst + proto +
11490       payload_length + hop_limit == 0)
11491     return 0;
11492
11493   /*
11494    * Aligned because we use the real comparison functions
11495    */
11496   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11497
11498   ip = (ip6_header_t *) match;
11499
11500   if (src)
11501     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11502
11503   if (dst)
11504     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11505
11506   if (proto)
11507     ip->protocol = proto_val;
11508
11509   ip_version_traffic_class_and_flow_label = 0;
11510
11511   if (version)
11512     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11513
11514   if (traffic_class)
11515     ip_version_traffic_class_and_flow_label |=
11516       (traffic_class_val & 0xFF) << 20;
11517
11518   if (flow_label)
11519     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11520
11521   ip->ip_version_traffic_class_and_flow_label =
11522     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11523
11524   if (payload_length)
11525     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11526
11527   if (hop_limit)
11528     ip->hop_limit = hop_limit_val;
11529
11530   *matchp = match;
11531   return 1;
11532 }
11533
11534 uword
11535 unformat_l3_match (unformat_input_t * input, va_list * args)
11536 {
11537   u8 **matchp = va_arg (*args, u8 **);
11538
11539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11540     {
11541       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11542         return 1;
11543       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11544         return 1;
11545       else
11546         break;
11547     }
11548   return 0;
11549 }
11550
11551 uword
11552 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11553 {
11554   u8 *tagp = va_arg (*args, u8 *);
11555   u32 tag;
11556
11557   if (unformat (input, "%d", &tag))
11558     {
11559       tagp[0] = (tag >> 8) & 0x0F;
11560       tagp[1] = tag & 0xFF;
11561       return 1;
11562     }
11563
11564   return 0;
11565 }
11566
11567 uword
11568 unformat_l2_match (unformat_input_t * input, va_list * args)
11569 {
11570   u8 **matchp = va_arg (*args, u8 **);
11571   u8 *match = 0;
11572   u8 src = 0;
11573   u8 src_val[6];
11574   u8 dst = 0;
11575   u8 dst_val[6];
11576   u8 proto = 0;
11577   u16 proto_val;
11578   u8 tag1 = 0;
11579   u8 tag1_val[2];
11580   u8 tag2 = 0;
11581   u8 tag2_val[2];
11582   int len = 14;
11583   u8 ignore_tag1 = 0;
11584   u8 ignore_tag2 = 0;
11585   u8 cos1 = 0;
11586   u8 cos2 = 0;
11587   u32 cos1_val = 0;
11588   u32 cos2_val = 0;
11589
11590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11591     {
11592       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11593         src = 1;
11594       else
11595         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11596         dst = 1;
11597       else if (unformat (input, "proto %U",
11598                          unformat_ethernet_type_host_byte_order, &proto_val))
11599         proto = 1;
11600       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11601         tag1 = 1;
11602       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11603         tag2 = 1;
11604       else if (unformat (input, "ignore-tag1"))
11605         ignore_tag1 = 1;
11606       else if (unformat (input, "ignore-tag2"))
11607         ignore_tag2 = 1;
11608       else if (unformat (input, "cos1 %d", &cos1_val))
11609         cos1 = 1;
11610       else if (unformat (input, "cos2 %d", &cos2_val))
11611         cos2 = 1;
11612       else
11613         break;
11614     }
11615   if ((src + dst + proto + tag1 + tag2 +
11616        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11617     return 0;
11618
11619   if (tag1 || ignore_tag1 || cos1)
11620     len = 18;
11621   if (tag2 || ignore_tag2 || cos2)
11622     len = 22;
11623
11624   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11625
11626   if (dst)
11627     clib_memcpy (match, dst_val, 6);
11628
11629   if (src)
11630     clib_memcpy (match + 6, src_val, 6);
11631
11632   if (tag2)
11633     {
11634       /* inner vlan tag */
11635       match[19] = tag2_val[1];
11636       match[18] = tag2_val[0];
11637       if (cos2)
11638         match[18] |= (cos2_val & 0x7) << 5;
11639       if (proto)
11640         {
11641           match[21] = proto_val & 0xff;
11642           match[20] = proto_val >> 8;
11643         }
11644       if (tag1)
11645         {
11646           match[15] = tag1_val[1];
11647           match[14] = tag1_val[0];
11648         }
11649       if (cos1)
11650         match[14] |= (cos1_val & 0x7) << 5;
11651       *matchp = match;
11652       return 1;
11653     }
11654   if (tag1)
11655     {
11656       match[15] = tag1_val[1];
11657       match[14] = tag1_val[0];
11658       if (proto)
11659         {
11660           match[17] = proto_val & 0xff;
11661           match[16] = proto_val >> 8;
11662         }
11663       if (cos1)
11664         match[14] |= (cos1_val & 0x7) << 5;
11665
11666       *matchp = match;
11667       return 1;
11668     }
11669   if (cos2)
11670     match[18] |= (cos2_val & 0x7) << 5;
11671   if (cos1)
11672     match[14] |= (cos1_val & 0x7) << 5;
11673   if (proto)
11674     {
11675       match[13] = proto_val & 0xff;
11676       match[12] = proto_val >> 8;
11677     }
11678
11679   *matchp = match;
11680   return 1;
11681 }
11682
11683 uword
11684 unformat_qos_source (unformat_input_t * input, va_list * args)
11685 {
11686   int *qs = va_arg (*args, int *);
11687
11688   if (unformat (input, "ip"))
11689     *qs = QOS_SOURCE_IP;
11690   else if (unformat (input, "mpls"))
11691     *qs = QOS_SOURCE_MPLS;
11692   else if (unformat (input, "ext"))
11693     *qs = QOS_SOURCE_EXT;
11694   else if (unformat (input, "vlan"))
11695     *qs = QOS_SOURCE_VLAN;
11696   else
11697     return 0;
11698
11699   return 1;
11700 }
11701 #endif
11702
11703 uword
11704 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11705 {
11706   u8 **matchp = va_arg (*args, u8 **);
11707   u32 skip_n_vectors = va_arg (*args, u32);
11708   u32 match_n_vectors = va_arg (*args, u32);
11709
11710   u8 *match = 0;
11711   u8 *l2 = 0;
11712   u8 *l3 = 0;
11713   u8 *l4 = 0;
11714
11715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11716     {
11717       if (unformat (input, "hex %U", unformat_hex_string, &match))
11718         ;
11719       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11720         ;
11721       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11722         ;
11723       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11724         ;
11725       else
11726         break;
11727     }
11728
11729   if (l4 && !l3)
11730     {
11731       vec_free (match);
11732       vec_free (l2);
11733       vec_free (l4);
11734       return 0;
11735     }
11736
11737   if (match || l2 || l3 || l4)
11738     {
11739       if (l2 || l3 || l4)
11740         {
11741           /* "Win a free Ethernet header in every packet" */
11742           if (l2 == 0)
11743             vec_validate_aligned (l2, 13, sizeof (u32x4));
11744           match = l2;
11745           if (vec_len (l3))
11746             {
11747               vec_append_aligned (match, l3, sizeof (u32x4));
11748               vec_free (l3);
11749             }
11750           if (vec_len (l4))
11751             {
11752               vec_append_aligned (match, l4, sizeof (u32x4));
11753               vec_free (l4);
11754             }
11755         }
11756
11757       /* Make sure the vector is big enough even if key is all 0's */
11758       vec_validate_aligned
11759         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11760          sizeof (u32x4));
11761
11762       /* Set size, include skipped vectors */
11763       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11764
11765       *matchp = match;
11766
11767       return 1;
11768     }
11769
11770   return 0;
11771 }
11772
11773 static int
11774 api_classify_add_del_session (vat_main_t * vam)
11775 {
11776   unformat_input_t *i = vam->input;
11777   vl_api_classify_add_del_session_t *mp;
11778   int is_add = 1;
11779   u32 table_index = ~0;
11780   u32 hit_next_index = ~0;
11781   u32 opaque_index = ~0;
11782   u8 *match = 0;
11783   i32 advance = 0;
11784   u32 skip_n_vectors = 0;
11785   u32 match_n_vectors = 0;
11786   u32 action = 0;
11787   u32 metadata = 0;
11788   int ret;
11789
11790   /*
11791    * Warning: you have to supply skip_n and match_n
11792    * because the API client cant simply look at the classify
11793    * table object.
11794    */
11795
11796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11797     {
11798       if (unformat (i, "del"))
11799         is_add = 0;
11800       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11801                          &hit_next_index))
11802         ;
11803       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11804                          &hit_next_index))
11805         ;
11806       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11807                          &hit_next_index))
11808         ;
11809       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11810         ;
11811       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11812         ;
11813       else if (unformat (i, "opaque-index %d", &opaque_index))
11814         ;
11815       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11816         ;
11817       else if (unformat (i, "match_n %d", &match_n_vectors))
11818         ;
11819       else if (unformat (i, "match %U", api_unformat_classify_match,
11820                          &match, skip_n_vectors, match_n_vectors))
11821         ;
11822       else if (unformat (i, "advance %d", &advance))
11823         ;
11824       else if (unformat (i, "table-index %d", &table_index))
11825         ;
11826       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11827         action = 1;
11828       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11829         action = 2;
11830       else if (unformat (i, "action %d", &action))
11831         ;
11832       else if (unformat (i, "metadata %d", &metadata))
11833         ;
11834       else
11835         break;
11836     }
11837
11838   if (table_index == ~0)
11839     {
11840       errmsg ("Table index required");
11841       return -99;
11842     }
11843
11844   if (is_add && match == 0)
11845     {
11846       errmsg ("Match value required");
11847       return -99;
11848     }
11849
11850   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11851
11852   mp->is_add = is_add;
11853   mp->table_index = ntohl (table_index);
11854   mp->hit_next_index = ntohl (hit_next_index);
11855   mp->opaque_index = ntohl (opaque_index);
11856   mp->advance = ntohl (advance);
11857   mp->action = action;
11858   mp->metadata = ntohl (metadata);
11859   mp->match_len = ntohl (vec_len (match));
11860   clib_memcpy (mp->match, match, vec_len (match));
11861   vec_free (match);
11862
11863   S (mp);
11864   W (ret);
11865   return ret;
11866 }
11867
11868 static int
11869 api_classify_set_interface_ip_table (vat_main_t * vam)
11870 {
11871   unformat_input_t *i = vam->input;
11872   vl_api_classify_set_interface_ip_table_t *mp;
11873   u32 sw_if_index;
11874   int sw_if_index_set;
11875   u32 table_index = ~0;
11876   u8 is_ipv6 = 0;
11877   int ret;
11878
11879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11880     {
11881       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11882         sw_if_index_set = 1;
11883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11884         sw_if_index_set = 1;
11885       else if (unformat (i, "table %d", &table_index))
11886         ;
11887       else
11888         {
11889           clib_warning ("parse error '%U'", format_unformat_error, i);
11890           return -99;
11891         }
11892     }
11893
11894   if (sw_if_index_set == 0)
11895     {
11896       errmsg ("missing interface name or sw_if_index");
11897       return -99;
11898     }
11899
11900
11901   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11902
11903   mp->sw_if_index = ntohl (sw_if_index);
11904   mp->table_index = ntohl (table_index);
11905   mp->is_ipv6 = is_ipv6;
11906
11907   S (mp);
11908   W (ret);
11909   return ret;
11910 }
11911
11912 static int
11913 api_classify_set_interface_l2_tables (vat_main_t * vam)
11914 {
11915   unformat_input_t *i = vam->input;
11916   vl_api_classify_set_interface_l2_tables_t *mp;
11917   u32 sw_if_index;
11918   int sw_if_index_set;
11919   u32 ip4_table_index = ~0;
11920   u32 ip6_table_index = ~0;
11921   u32 other_table_index = ~0;
11922   u32 is_input = 1;
11923   int ret;
11924
11925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11926     {
11927       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11928         sw_if_index_set = 1;
11929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11930         sw_if_index_set = 1;
11931       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11932         ;
11933       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11934         ;
11935       else if (unformat (i, "other-table %d", &other_table_index))
11936         ;
11937       else if (unformat (i, "is-input %d", &is_input))
11938         ;
11939       else
11940         {
11941           clib_warning ("parse error '%U'", format_unformat_error, i);
11942           return -99;
11943         }
11944     }
11945
11946   if (sw_if_index_set == 0)
11947     {
11948       errmsg ("missing interface name or sw_if_index");
11949       return -99;
11950     }
11951
11952
11953   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11954
11955   mp->sw_if_index = ntohl (sw_if_index);
11956   mp->ip4_table_index = ntohl (ip4_table_index);
11957   mp->ip6_table_index = ntohl (ip6_table_index);
11958   mp->other_table_index = ntohl (other_table_index);
11959   mp->is_input = (u8) is_input;
11960
11961   S (mp);
11962   W (ret);
11963   return ret;
11964 }
11965
11966 static int
11967 api_set_ipfix_exporter (vat_main_t * vam)
11968 {
11969   unformat_input_t *i = vam->input;
11970   vl_api_set_ipfix_exporter_t *mp;
11971   ip4_address_t collector_address;
11972   u8 collector_address_set = 0;
11973   u32 collector_port = ~0;
11974   ip4_address_t src_address;
11975   u8 src_address_set = 0;
11976   u32 vrf_id = ~0;
11977   u32 path_mtu = ~0;
11978   u32 template_interval = ~0;
11979   u8 udp_checksum = 0;
11980   int ret;
11981
11982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11983     {
11984       if (unformat (i, "collector_address %U", unformat_ip4_address,
11985                     &collector_address))
11986         collector_address_set = 1;
11987       else if (unformat (i, "collector_port %d", &collector_port))
11988         ;
11989       else if (unformat (i, "src_address %U", unformat_ip4_address,
11990                          &src_address))
11991         src_address_set = 1;
11992       else if (unformat (i, "vrf_id %d", &vrf_id))
11993         ;
11994       else if (unformat (i, "path_mtu %d", &path_mtu))
11995         ;
11996       else if (unformat (i, "template_interval %d", &template_interval))
11997         ;
11998       else if (unformat (i, "udp_checksum"))
11999         udp_checksum = 1;
12000       else
12001         break;
12002     }
12003
12004   if (collector_address_set == 0)
12005     {
12006       errmsg ("collector_address required");
12007       return -99;
12008     }
12009
12010   if (src_address_set == 0)
12011     {
12012       errmsg ("src_address required");
12013       return -99;
12014     }
12015
12016   M (SET_IPFIX_EXPORTER, mp);
12017
12018   memcpy (mp->collector_address, collector_address.data,
12019           sizeof (collector_address.data));
12020   mp->collector_port = htons ((u16) collector_port);
12021   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12022   mp->vrf_id = htonl (vrf_id);
12023   mp->path_mtu = htonl (path_mtu);
12024   mp->template_interval = htonl (template_interval);
12025   mp->udp_checksum = udp_checksum;
12026
12027   S (mp);
12028   W (ret);
12029   return ret;
12030 }
12031
12032 static int
12033 api_set_ipfix_classify_stream (vat_main_t * vam)
12034 {
12035   unformat_input_t *i = vam->input;
12036   vl_api_set_ipfix_classify_stream_t *mp;
12037   u32 domain_id = 0;
12038   u32 src_port = UDP_DST_PORT_ipfix;
12039   int ret;
12040
12041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12042     {
12043       if (unformat (i, "domain %d", &domain_id))
12044         ;
12045       else if (unformat (i, "src_port %d", &src_port))
12046         ;
12047       else
12048         {
12049           errmsg ("unknown input `%U'", format_unformat_error, i);
12050           return -99;
12051         }
12052     }
12053
12054   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12055
12056   mp->domain_id = htonl (domain_id);
12057   mp->src_port = htons ((u16) src_port);
12058
12059   S (mp);
12060   W (ret);
12061   return ret;
12062 }
12063
12064 static int
12065 api_ipfix_classify_table_add_del (vat_main_t * vam)
12066 {
12067   unformat_input_t *i = vam->input;
12068   vl_api_ipfix_classify_table_add_del_t *mp;
12069   int is_add = -1;
12070   u32 classify_table_index = ~0;
12071   u8 ip_version = 0;
12072   u8 transport_protocol = 255;
12073   int ret;
12074
12075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12076     {
12077       if (unformat (i, "add"))
12078         is_add = 1;
12079       else if (unformat (i, "del"))
12080         is_add = 0;
12081       else if (unformat (i, "table %d", &classify_table_index))
12082         ;
12083       else if (unformat (i, "ip4"))
12084         ip_version = 4;
12085       else if (unformat (i, "ip6"))
12086         ip_version = 6;
12087       else if (unformat (i, "tcp"))
12088         transport_protocol = 6;
12089       else if (unformat (i, "udp"))
12090         transport_protocol = 17;
12091       else
12092         {
12093           errmsg ("unknown input `%U'", format_unformat_error, i);
12094           return -99;
12095         }
12096     }
12097
12098   if (is_add == -1)
12099     {
12100       errmsg ("expecting: add|del");
12101       return -99;
12102     }
12103   if (classify_table_index == ~0)
12104     {
12105       errmsg ("classifier table not specified");
12106       return -99;
12107     }
12108   if (ip_version == 0)
12109     {
12110       errmsg ("IP version not specified");
12111       return -99;
12112     }
12113
12114   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12115
12116   mp->is_add = is_add;
12117   mp->table_id = htonl (classify_table_index);
12118   mp->ip_version = ip_version;
12119   mp->transport_protocol = transport_protocol;
12120
12121   S (mp);
12122   W (ret);
12123   return ret;
12124 }
12125
12126 static int
12127 api_get_node_index (vat_main_t * vam)
12128 {
12129   unformat_input_t *i = vam->input;
12130   vl_api_get_node_index_t *mp;
12131   u8 *name = 0;
12132   int ret;
12133
12134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12135     {
12136       if (unformat (i, "node %s", &name))
12137         ;
12138       else
12139         break;
12140     }
12141   if (name == 0)
12142     {
12143       errmsg ("node name required");
12144       return -99;
12145     }
12146   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12147     {
12148       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12149       return -99;
12150     }
12151
12152   M (GET_NODE_INDEX, mp);
12153   clib_memcpy (mp->node_name, name, vec_len (name));
12154   vec_free (name);
12155
12156   S (mp);
12157   W (ret);
12158   return ret;
12159 }
12160
12161 static int
12162 api_get_next_index (vat_main_t * vam)
12163 {
12164   unformat_input_t *i = vam->input;
12165   vl_api_get_next_index_t *mp;
12166   u8 *node_name = 0, *next_node_name = 0;
12167   int ret;
12168
12169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12170     {
12171       if (unformat (i, "node-name %s", &node_name))
12172         ;
12173       else if (unformat (i, "next-node-name %s", &next_node_name))
12174         break;
12175     }
12176
12177   if (node_name == 0)
12178     {
12179       errmsg ("node name required");
12180       return -99;
12181     }
12182   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12183     {
12184       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12185       return -99;
12186     }
12187
12188   if (next_node_name == 0)
12189     {
12190       errmsg ("next node name required");
12191       return -99;
12192     }
12193   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12194     {
12195       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12196       return -99;
12197     }
12198
12199   M (GET_NEXT_INDEX, mp);
12200   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12201   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12202   vec_free (node_name);
12203   vec_free (next_node_name);
12204
12205   S (mp);
12206   W (ret);
12207   return ret;
12208 }
12209
12210 static int
12211 api_add_node_next (vat_main_t * vam)
12212 {
12213   unformat_input_t *i = vam->input;
12214   vl_api_add_node_next_t *mp;
12215   u8 *name = 0;
12216   u8 *next = 0;
12217   int ret;
12218
12219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12220     {
12221       if (unformat (i, "node %s", &name))
12222         ;
12223       else if (unformat (i, "next %s", &next))
12224         ;
12225       else
12226         break;
12227     }
12228   if (name == 0)
12229     {
12230       errmsg ("node name required");
12231       return -99;
12232     }
12233   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12234     {
12235       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12236       return -99;
12237     }
12238   if (next == 0)
12239     {
12240       errmsg ("next node required");
12241       return -99;
12242     }
12243   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12244     {
12245       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12246       return -99;
12247     }
12248
12249   M (ADD_NODE_NEXT, mp);
12250   clib_memcpy (mp->node_name, name, vec_len (name));
12251   clib_memcpy (mp->next_name, next, vec_len (next));
12252   vec_free (name);
12253   vec_free (next);
12254
12255   S (mp);
12256   W (ret);
12257   return ret;
12258 }
12259
12260 static int
12261 api_l2tpv3_create_tunnel (vat_main_t * vam)
12262 {
12263   unformat_input_t *i = vam->input;
12264   ip6_address_t client_address, our_address;
12265   int client_address_set = 0;
12266   int our_address_set = 0;
12267   u32 local_session_id = 0;
12268   u32 remote_session_id = 0;
12269   u64 local_cookie = 0;
12270   u64 remote_cookie = 0;
12271   u8 l2_sublayer_present = 0;
12272   vl_api_l2tpv3_create_tunnel_t *mp;
12273   int ret;
12274
12275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12276     {
12277       if (unformat (i, "client_address %U", unformat_ip6_address,
12278                     &client_address))
12279         client_address_set = 1;
12280       else if (unformat (i, "our_address %U", unformat_ip6_address,
12281                          &our_address))
12282         our_address_set = 1;
12283       else if (unformat (i, "local_session_id %d", &local_session_id))
12284         ;
12285       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12286         ;
12287       else if (unformat (i, "local_cookie %lld", &local_cookie))
12288         ;
12289       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12290         ;
12291       else if (unformat (i, "l2-sublayer-present"))
12292         l2_sublayer_present = 1;
12293       else
12294         break;
12295     }
12296
12297   if (client_address_set == 0)
12298     {
12299       errmsg ("client_address required");
12300       return -99;
12301     }
12302
12303   if (our_address_set == 0)
12304     {
12305       errmsg ("our_address required");
12306       return -99;
12307     }
12308
12309   M (L2TPV3_CREATE_TUNNEL, mp);
12310
12311   clib_memcpy (mp->client_address, client_address.as_u8,
12312                sizeof (mp->client_address));
12313
12314   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12315
12316   mp->local_session_id = ntohl (local_session_id);
12317   mp->remote_session_id = ntohl (remote_session_id);
12318   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12319   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12320   mp->l2_sublayer_present = l2_sublayer_present;
12321   mp->is_ipv6 = 1;
12322
12323   S (mp);
12324   W (ret);
12325   return ret;
12326 }
12327
12328 static int
12329 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12330 {
12331   unformat_input_t *i = vam->input;
12332   u32 sw_if_index;
12333   u8 sw_if_index_set = 0;
12334   u64 new_local_cookie = 0;
12335   u64 new_remote_cookie = 0;
12336   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12337   int ret;
12338
12339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12340     {
12341       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12342         sw_if_index_set = 1;
12343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12344         sw_if_index_set = 1;
12345       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12346         ;
12347       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12348         ;
12349       else
12350         break;
12351     }
12352
12353   if (sw_if_index_set == 0)
12354     {
12355       errmsg ("missing interface name or sw_if_index");
12356       return -99;
12357     }
12358
12359   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12360
12361   mp->sw_if_index = ntohl (sw_if_index);
12362   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12363   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12364
12365   S (mp);
12366   W (ret);
12367   return ret;
12368 }
12369
12370 static int
12371 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12372 {
12373   unformat_input_t *i = vam->input;
12374   vl_api_l2tpv3_interface_enable_disable_t *mp;
12375   u32 sw_if_index;
12376   u8 sw_if_index_set = 0;
12377   u8 enable_disable = 1;
12378   int ret;
12379
12380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12381     {
12382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12383         sw_if_index_set = 1;
12384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12385         sw_if_index_set = 1;
12386       else if (unformat (i, "enable"))
12387         enable_disable = 1;
12388       else if (unformat (i, "disable"))
12389         enable_disable = 0;
12390       else
12391         break;
12392     }
12393
12394   if (sw_if_index_set == 0)
12395     {
12396       errmsg ("missing interface name or sw_if_index");
12397       return -99;
12398     }
12399
12400   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12401
12402   mp->sw_if_index = ntohl (sw_if_index);
12403   mp->enable_disable = enable_disable;
12404
12405   S (mp);
12406   W (ret);
12407   return ret;
12408 }
12409
12410 static int
12411 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12412 {
12413   unformat_input_t *i = vam->input;
12414   vl_api_l2tpv3_set_lookup_key_t *mp;
12415   u8 key = ~0;
12416   int ret;
12417
12418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12419     {
12420       if (unformat (i, "lookup_v6_src"))
12421         key = L2T_LOOKUP_SRC_ADDRESS;
12422       else if (unformat (i, "lookup_v6_dst"))
12423         key = L2T_LOOKUP_DST_ADDRESS;
12424       else if (unformat (i, "lookup_session_id"))
12425         key = L2T_LOOKUP_SESSION_ID;
12426       else
12427         break;
12428     }
12429
12430   if (key == (u8) ~ 0)
12431     {
12432       errmsg ("l2tp session lookup key unset");
12433       return -99;
12434     }
12435
12436   M (L2TPV3_SET_LOOKUP_KEY, mp);
12437
12438   mp->key = key;
12439
12440   S (mp);
12441   W (ret);
12442   return ret;
12443 }
12444
12445 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12446   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12447 {
12448   vat_main_t *vam = &vat_main;
12449
12450   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12451          format_ip6_address, mp->our_address,
12452          format_ip6_address, mp->client_address,
12453          clib_net_to_host_u32 (mp->sw_if_index));
12454
12455   print (vam->ofp,
12456          "   local cookies %016llx %016llx remote cookie %016llx",
12457          clib_net_to_host_u64 (mp->local_cookie[0]),
12458          clib_net_to_host_u64 (mp->local_cookie[1]),
12459          clib_net_to_host_u64 (mp->remote_cookie));
12460
12461   print (vam->ofp, "   local session-id %d remote session-id %d",
12462          clib_net_to_host_u32 (mp->local_session_id),
12463          clib_net_to_host_u32 (mp->remote_session_id));
12464
12465   print (vam->ofp, "   l2 specific sublayer %s\n",
12466          mp->l2_sublayer_present ? "preset" : "absent");
12467
12468 }
12469
12470 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12471   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12472 {
12473   vat_main_t *vam = &vat_main;
12474   vat_json_node_t *node = NULL;
12475   struct in6_addr addr;
12476
12477   if (VAT_JSON_ARRAY != vam->json_tree.type)
12478     {
12479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12480       vat_json_init_array (&vam->json_tree);
12481     }
12482   node = vat_json_array_add (&vam->json_tree);
12483
12484   vat_json_init_object (node);
12485
12486   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12487   vat_json_object_add_ip6 (node, "our_address", addr);
12488   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12489   vat_json_object_add_ip6 (node, "client_address", addr);
12490
12491   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12492   vat_json_init_array (lc);
12493   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12494   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12495   vat_json_object_add_uint (node, "remote_cookie",
12496                             clib_net_to_host_u64 (mp->remote_cookie));
12497
12498   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12499   vat_json_object_add_uint (node, "local_session_id",
12500                             clib_net_to_host_u32 (mp->local_session_id));
12501   vat_json_object_add_uint (node, "remote_session_id",
12502                             clib_net_to_host_u32 (mp->remote_session_id));
12503   vat_json_object_add_string_copy (node, "l2_sublayer",
12504                                    mp->l2_sublayer_present ? (u8 *) "present"
12505                                    : (u8 *) "absent");
12506 }
12507
12508 static int
12509 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12510 {
12511   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12512   vl_api_control_ping_t *mp_ping;
12513   int ret;
12514
12515   /* Get list of l2tpv3-tunnel interfaces */
12516   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12517   S (mp);
12518
12519   /* Use a control ping for synchronization */
12520   MPING (CONTROL_PING, mp_ping);
12521   S (mp_ping);
12522
12523   W (ret);
12524   return ret;
12525 }
12526
12527
12528 static void vl_api_sw_interface_tap_v2_details_t_handler
12529   (vl_api_sw_interface_tap_v2_details_t * mp)
12530 {
12531   vat_main_t *vam = &vat_main;
12532
12533   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12534                     mp->host_ip4_prefix_len);
12535   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12536                     mp->host_ip6_prefix_len);
12537
12538   print (vam->ofp,
12539          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12540          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12541          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12542          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12543          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12544
12545   vec_free (ip4);
12546   vec_free (ip6);
12547 }
12548
12549 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12550   (vl_api_sw_interface_tap_v2_details_t * mp)
12551 {
12552   vat_main_t *vam = &vat_main;
12553   vat_json_node_t *node = NULL;
12554
12555   if (VAT_JSON_ARRAY != vam->json_tree.type)
12556     {
12557       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12558       vat_json_init_array (&vam->json_tree);
12559     }
12560   node = vat_json_array_add (&vam->json_tree);
12561
12562   vat_json_init_object (node);
12563   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12564   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12565   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12566   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12567   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12568   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12569   vat_json_object_add_string_copy (node, "host_mac_addr",
12570                                    format (0, "%U", format_ethernet_address,
12571                                            &mp->host_mac_addr));
12572   vat_json_object_add_string_copy (node, "host_namespace",
12573                                    mp->host_namespace);
12574   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12575   vat_json_object_add_string_copy (node, "host_ip4_addr",
12576                                    format (0, "%U/%d", format_ip4_address,
12577                                            mp->host_ip4_addr,
12578                                            mp->host_ip4_prefix_len));
12579   vat_json_object_add_string_copy (node, "host_ip6_addr",
12580                                    format (0, "%U/%d", format_ip6_address,
12581                                            mp->host_ip6_addr,
12582                                            mp->host_ip6_prefix_len));
12583
12584 }
12585
12586 static int
12587 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12588 {
12589   vl_api_sw_interface_tap_v2_dump_t *mp;
12590   vl_api_control_ping_t *mp_ping;
12591   int ret;
12592
12593   print (vam->ofp,
12594          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12595          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12596          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12597          "host_ip6_addr");
12598
12599   /* Get list of tap interfaces */
12600   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12601   S (mp);
12602
12603   /* Use a control ping for synchronization */
12604   MPING (CONTROL_PING, mp_ping);
12605   S (mp_ping);
12606
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static void vl_api_sw_interface_virtio_pci_details_t_handler
12612   (vl_api_sw_interface_virtio_pci_details_t * mp)
12613 {
12614   vat_main_t *vam = &vat_main;
12615
12616   typedef union
12617   {
12618     struct
12619     {
12620       u16 domain;
12621       u8 bus;
12622       u8 slot:5;
12623       u8 function:3;
12624     };
12625     u32 as_u32;
12626   } pci_addr_t;
12627   pci_addr_t addr;
12628   addr.as_u32 = ntohl (mp->pci_addr);
12629   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12630                          addr.slot, addr.function);
12631
12632   print (vam->ofp,
12633          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12634          pci_addr, ntohl (mp->sw_if_index),
12635          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12636          format_ethernet_address, mp->mac_addr,
12637          clib_net_to_host_u64 (mp->features));
12638   vec_free (pci_addr);
12639 }
12640
12641 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12642   (vl_api_sw_interface_virtio_pci_details_t * mp)
12643 {
12644   vat_main_t *vam = &vat_main;
12645   vat_json_node_t *node = NULL;
12646
12647   if (VAT_JSON_ARRAY != vam->json_tree.type)
12648     {
12649       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12650       vat_json_init_array (&vam->json_tree);
12651     }
12652   node = vat_json_array_add (&vam->json_tree);
12653
12654   vat_json_init_object (node);
12655   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12656   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12657   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12658   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12659   vat_json_object_add_uint (node, "features",
12660                             clib_net_to_host_u64 (mp->features));
12661   vat_json_object_add_string_copy (node, "mac_addr",
12662                                    format (0, "%U", format_ethernet_address,
12663                                            &mp->mac_addr));
12664 }
12665
12666 static int
12667 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12668 {
12669   vl_api_sw_interface_virtio_pci_dump_t *mp;
12670   vl_api_control_ping_t *mp_ping;
12671   int ret;
12672
12673   print (vam->ofp,
12674          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12675          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12676          "mac_addr", "features");
12677
12678   /* Get list of tap interfaces */
12679   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12680   S (mp);
12681
12682   /* Use a control ping for synchronization */
12683   MPING (CONTROL_PING, mp_ping);
12684   S (mp_ping);
12685
12686   W (ret);
12687   return ret;
12688 }
12689
12690 static int
12691 api_vxlan_offload_rx (vat_main_t * vam)
12692 {
12693   unformat_input_t *line_input = vam->input;
12694   vl_api_vxlan_offload_rx_t *mp;
12695   u32 hw_if_index = ~0, rx_if_index = ~0;
12696   u8 is_add = 1;
12697   int ret;
12698
12699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12700     {
12701       if (unformat (line_input, "del"))
12702         is_add = 0;
12703       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12704                          &hw_if_index))
12705         ;
12706       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12707         ;
12708       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12709                          &rx_if_index))
12710         ;
12711       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12712         ;
12713       else
12714         {
12715           errmsg ("parse error '%U'", format_unformat_error, line_input);
12716           return -99;
12717         }
12718     }
12719
12720   if (hw_if_index == ~0)
12721     {
12722       errmsg ("no hw interface");
12723       return -99;
12724     }
12725
12726   if (rx_if_index == ~0)
12727     {
12728       errmsg ("no rx tunnel");
12729       return -99;
12730     }
12731
12732   M (VXLAN_OFFLOAD_RX, mp);
12733
12734   mp->hw_if_index = ntohl (hw_if_index);
12735   mp->sw_if_index = ntohl (rx_if_index);
12736   mp->enable = is_add;
12737
12738   S (mp);
12739   W (ret);
12740   return ret;
12741 }
12742
12743 static uword unformat_vxlan_decap_next
12744   (unformat_input_t * input, va_list * args)
12745 {
12746   u32 *result = va_arg (*args, u32 *);
12747   u32 tmp;
12748
12749   if (unformat (input, "l2"))
12750     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12751   else if (unformat (input, "%d", &tmp))
12752     *result = tmp;
12753   else
12754     return 0;
12755   return 1;
12756 }
12757
12758 static int
12759 api_vxlan_add_del_tunnel (vat_main_t * vam)
12760 {
12761   unformat_input_t *line_input = vam->input;
12762   vl_api_vxlan_add_del_tunnel_t *mp;
12763   ip46_address_t src, dst;
12764   u8 is_add = 1;
12765   u8 ipv4_set = 0, ipv6_set = 0;
12766   u8 src_set = 0;
12767   u8 dst_set = 0;
12768   u8 grp_set = 0;
12769   u32 instance = ~0;
12770   u32 mcast_sw_if_index = ~0;
12771   u32 encap_vrf_id = 0;
12772   u32 decap_next_index = ~0;
12773   u32 vni = 0;
12774   int ret;
12775
12776   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12777   clib_memset (&src, 0, sizeof src);
12778   clib_memset (&dst, 0, sizeof dst);
12779
12780   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12781     {
12782       if (unformat (line_input, "del"))
12783         is_add = 0;
12784       else if (unformat (line_input, "instance %d", &instance))
12785         ;
12786       else
12787         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12788         {
12789           ipv4_set = 1;
12790           src_set = 1;
12791         }
12792       else
12793         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12794         {
12795           ipv4_set = 1;
12796           dst_set = 1;
12797         }
12798       else
12799         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12800         {
12801           ipv6_set = 1;
12802           src_set = 1;
12803         }
12804       else
12805         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12806         {
12807           ipv6_set = 1;
12808           dst_set = 1;
12809         }
12810       else if (unformat (line_input, "group %U %U",
12811                          unformat_ip4_address, &dst.ip4,
12812                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12813         {
12814           grp_set = dst_set = 1;
12815           ipv4_set = 1;
12816         }
12817       else if (unformat (line_input, "group %U",
12818                          unformat_ip4_address, &dst.ip4))
12819         {
12820           grp_set = dst_set = 1;
12821           ipv4_set = 1;
12822         }
12823       else if (unformat (line_input, "group %U %U",
12824                          unformat_ip6_address, &dst.ip6,
12825                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12826         {
12827           grp_set = dst_set = 1;
12828           ipv6_set = 1;
12829         }
12830       else if (unformat (line_input, "group %U",
12831                          unformat_ip6_address, &dst.ip6))
12832         {
12833           grp_set = dst_set = 1;
12834           ipv6_set = 1;
12835         }
12836       else
12837         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12838         ;
12839       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12840         ;
12841       else if (unformat (line_input, "decap-next %U",
12842                          unformat_vxlan_decap_next, &decap_next_index))
12843         ;
12844       else if (unformat (line_input, "vni %d", &vni))
12845         ;
12846       else
12847         {
12848           errmsg ("parse error '%U'", format_unformat_error, line_input);
12849           return -99;
12850         }
12851     }
12852
12853   if (src_set == 0)
12854     {
12855       errmsg ("tunnel src address not specified");
12856       return -99;
12857     }
12858   if (dst_set == 0)
12859     {
12860       errmsg ("tunnel dst address not specified");
12861       return -99;
12862     }
12863
12864   if (grp_set && !ip46_address_is_multicast (&dst))
12865     {
12866       errmsg ("tunnel group address not multicast");
12867       return -99;
12868     }
12869   if (grp_set && mcast_sw_if_index == ~0)
12870     {
12871       errmsg ("tunnel nonexistent multicast device");
12872       return -99;
12873     }
12874   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12875     {
12876       errmsg ("tunnel dst address must be unicast");
12877       return -99;
12878     }
12879
12880
12881   if (ipv4_set && ipv6_set)
12882     {
12883       errmsg ("both IPv4 and IPv6 addresses specified");
12884       return -99;
12885     }
12886
12887   if ((vni == 0) || (vni >> 24))
12888     {
12889       errmsg ("vni not specified or out of range");
12890       return -99;
12891     }
12892
12893   M (VXLAN_ADD_DEL_TUNNEL, mp);
12894
12895   if (ipv6_set)
12896     {
12897       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12898       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12899     }
12900   else
12901     {
12902       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12903       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12904     }
12905
12906   mp->instance = htonl (instance);
12907   mp->encap_vrf_id = ntohl (encap_vrf_id);
12908   mp->decap_next_index = ntohl (decap_next_index);
12909   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12910   mp->vni = ntohl (vni);
12911   mp->is_add = is_add;
12912   mp->is_ipv6 = ipv6_set;
12913
12914   S (mp);
12915   W (ret);
12916   return ret;
12917 }
12918
12919 static void vl_api_vxlan_tunnel_details_t_handler
12920   (vl_api_vxlan_tunnel_details_t * mp)
12921 {
12922   vat_main_t *vam = &vat_main;
12923   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12924   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12925
12926   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12927          ntohl (mp->sw_if_index),
12928          ntohl (mp->instance),
12929          format_ip46_address, &src, IP46_TYPE_ANY,
12930          format_ip46_address, &dst, IP46_TYPE_ANY,
12931          ntohl (mp->encap_vrf_id),
12932          ntohl (mp->decap_next_index), ntohl (mp->vni),
12933          ntohl (mp->mcast_sw_if_index));
12934 }
12935
12936 static void vl_api_vxlan_tunnel_details_t_handler_json
12937   (vl_api_vxlan_tunnel_details_t * mp)
12938 {
12939   vat_main_t *vam = &vat_main;
12940   vat_json_node_t *node = NULL;
12941
12942   if (VAT_JSON_ARRAY != vam->json_tree.type)
12943     {
12944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12945       vat_json_init_array (&vam->json_tree);
12946     }
12947   node = vat_json_array_add (&vam->json_tree);
12948
12949   vat_json_init_object (node);
12950   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12951
12952   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12953
12954   if (mp->is_ipv6)
12955     {
12956       struct in6_addr ip6;
12957
12958       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12959       vat_json_object_add_ip6 (node, "src_address", ip6);
12960       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12961       vat_json_object_add_ip6 (node, "dst_address", ip6);
12962     }
12963   else
12964     {
12965       struct in_addr ip4;
12966
12967       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12968       vat_json_object_add_ip4 (node, "src_address", ip4);
12969       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12970       vat_json_object_add_ip4 (node, "dst_address", ip4);
12971     }
12972   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12973   vat_json_object_add_uint (node, "decap_next_index",
12974                             ntohl (mp->decap_next_index));
12975   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12976   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12977   vat_json_object_add_uint (node, "mcast_sw_if_index",
12978                             ntohl (mp->mcast_sw_if_index));
12979 }
12980
12981 static int
12982 api_vxlan_tunnel_dump (vat_main_t * vam)
12983 {
12984   unformat_input_t *i = vam->input;
12985   vl_api_vxlan_tunnel_dump_t *mp;
12986   vl_api_control_ping_t *mp_ping;
12987   u32 sw_if_index;
12988   u8 sw_if_index_set = 0;
12989   int ret;
12990
12991   /* Parse args required to build the message */
12992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12993     {
12994       if (unformat (i, "sw_if_index %d", &sw_if_index))
12995         sw_if_index_set = 1;
12996       else
12997         break;
12998     }
12999
13000   if (sw_if_index_set == 0)
13001     {
13002       sw_if_index = ~0;
13003     }
13004
13005   if (!vam->json_output)
13006     {
13007       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13008              "sw_if_index", "instance", "src_address", "dst_address",
13009              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13010     }
13011
13012   /* Get list of vxlan-tunnel interfaces */
13013   M (VXLAN_TUNNEL_DUMP, mp);
13014
13015   mp->sw_if_index = htonl (sw_if_index);
13016
13017   S (mp);
13018
13019   /* Use a control ping for synchronization */
13020   MPING (CONTROL_PING, mp_ping);
13021   S (mp_ping);
13022
13023   W (ret);
13024   return ret;
13025 }
13026
13027 static uword unformat_geneve_decap_next
13028   (unformat_input_t * input, va_list * args)
13029 {
13030   u32 *result = va_arg (*args, u32 *);
13031   u32 tmp;
13032
13033   if (unformat (input, "l2"))
13034     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13035   else if (unformat (input, "%d", &tmp))
13036     *result = tmp;
13037   else
13038     return 0;
13039   return 1;
13040 }
13041
13042 static int
13043 api_geneve_add_del_tunnel (vat_main_t * vam)
13044 {
13045   unformat_input_t *line_input = vam->input;
13046   vl_api_geneve_add_del_tunnel_t *mp;
13047   ip46_address_t src, dst;
13048   u8 is_add = 1;
13049   u8 ipv4_set = 0, ipv6_set = 0;
13050   u8 src_set = 0;
13051   u8 dst_set = 0;
13052   u8 grp_set = 0;
13053   u32 mcast_sw_if_index = ~0;
13054   u32 encap_vrf_id = 0;
13055   u32 decap_next_index = ~0;
13056   u32 vni = 0;
13057   int ret;
13058
13059   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13060   clib_memset (&src, 0, sizeof src);
13061   clib_memset (&dst, 0, sizeof dst);
13062
13063   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13064     {
13065       if (unformat (line_input, "del"))
13066         is_add = 0;
13067       else
13068         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13069         {
13070           ipv4_set = 1;
13071           src_set = 1;
13072         }
13073       else
13074         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13075         {
13076           ipv4_set = 1;
13077           dst_set = 1;
13078         }
13079       else
13080         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13081         {
13082           ipv6_set = 1;
13083           src_set = 1;
13084         }
13085       else
13086         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13087         {
13088           ipv6_set = 1;
13089           dst_set = 1;
13090         }
13091       else if (unformat (line_input, "group %U %U",
13092                          unformat_ip4_address, &dst.ip4,
13093                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13094         {
13095           grp_set = dst_set = 1;
13096           ipv4_set = 1;
13097         }
13098       else if (unformat (line_input, "group %U",
13099                          unformat_ip4_address, &dst.ip4))
13100         {
13101           grp_set = dst_set = 1;
13102           ipv4_set = 1;
13103         }
13104       else if (unformat (line_input, "group %U %U",
13105                          unformat_ip6_address, &dst.ip6,
13106                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13107         {
13108           grp_set = dst_set = 1;
13109           ipv6_set = 1;
13110         }
13111       else if (unformat (line_input, "group %U",
13112                          unformat_ip6_address, &dst.ip6))
13113         {
13114           grp_set = dst_set = 1;
13115           ipv6_set = 1;
13116         }
13117       else
13118         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13119         ;
13120       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13121         ;
13122       else if (unformat (line_input, "decap-next %U",
13123                          unformat_geneve_decap_next, &decap_next_index))
13124         ;
13125       else if (unformat (line_input, "vni %d", &vni))
13126         ;
13127       else
13128         {
13129           errmsg ("parse error '%U'", format_unformat_error, line_input);
13130           return -99;
13131         }
13132     }
13133
13134   if (src_set == 0)
13135     {
13136       errmsg ("tunnel src address not specified");
13137       return -99;
13138     }
13139   if (dst_set == 0)
13140     {
13141       errmsg ("tunnel dst address not specified");
13142       return -99;
13143     }
13144
13145   if (grp_set && !ip46_address_is_multicast (&dst))
13146     {
13147       errmsg ("tunnel group address not multicast");
13148       return -99;
13149     }
13150   if (grp_set && mcast_sw_if_index == ~0)
13151     {
13152       errmsg ("tunnel nonexistent multicast device");
13153       return -99;
13154     }
13155   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13156     {
13157       errmsg ("tunnel dst address must be unicast");
13158       return -99;
13159     }
13160
13161
13162   if (ipv4_set && ipv6_set)
13163     {
13164       errmsg ("both IPv4 and IPv6 addresses specified");
13165       return -99;
13166     }
13167
13168   if ((vni == 0) || (vni >> 24))
13169     {
13170       errmsg ("vni not specified or out of range");
13171       return -99;
13172     }
13173
13174   M (GENEVE_ADD_DEL_TUNNEL, mp);
13175
13176   if (ipv6_set)
13177     {
13178       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13179       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13180     }
13181   else
13182     {
13183       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13184       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13185     }
13186   mp->encap_vrf_id = ntohl (encap_vrf_id);
13187   mp->decap_next_index = ntohl (decap_next_index);
13188   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13189   mp->vni = ntohl (vni);
13190   mp->is_add = is_add;
13191   mp->is_ipv6 = ipv6_set;
13192
13193   S (mp);
13194   W (ret);
13195   return ret;
13196 }
13197
13198 static void vl_api_geneve_tunnel_details_t_handler
13199   (vl_api_geneve_tunnel_details_t * mp)
13200 {
13201   vat_main_t *vam = &vat_main;
13202   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13203   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13204
13205   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13206          ntohl (mp->sw_if_index),
13207          format_ip46_address, &src, IP46_TYPE_ANY,
13208          format_ip46_address, &dst, IP46_TYPE_ANY,
13209          ntohl (mp->encap_vrf_id),
13210          ntohl (mp->decap_next_index), ntohl (mp->vni),
13211          ntohl (mp->mcast_sw_if_index));
13212 }
13213
13214 static void vl_api_geneve_tunnel_details_t_handler_json
13215   (vl_api_geneve_tunnel_details_t * mp)
13216 {
13217   vat_main_t *vam = &vat_main;
13218   vat_json_node_t *node = NULL;
13219
13220   if (VAT_JSON_ARRAY != vam->json_tree.type)
13221     {
13222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13223       vat_json_init_array (&vam->json_tree);
13224     }
13225   node = vat_json_array_add (&vam->json_tree);
13226
13227   vat_json_init_object (node);
13228   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13229   if (mp->is_ipv6)
13230     {
13231       struct in6_addr ip6;
13232
13233       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13234       vat_json_object_add_ip6 (node, "src_address", ip6);
13235       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13236       vat_json_object_add_ip6 (node, "dst_address", ip6);
13237     }
13238   else
13239     {
13240       struct in_addr ip4;
13241
13242       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13243       vat_json_object_add_ip4 (node, "src_address", ip4);
13244       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13245       vat_json_object_add_ip4 (node, "dst_address", ip4);
13246     }
13247   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13248   vat_json_object_add_uint (node, "decap_next_index",
13249                             ntohl (mp->decap_next_index));
13250   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13251   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13252   vat_json_object_add_uint (node, "mcast_sw_if_index",
13253                             ntohl (mp->mcast_sw_if_index));
13254 }
13255
13256 static int
13257 api_geneve_tunnel_dump (vat_main_t * vam)
13258 {
13259   unformat_input_t *i = vam->input;
13260   vl_api_geneve_tunnel_dump_t *mp;
13261   vl_api_control_ping_t *mp_ping;
13262   u32 sw_if_index;
13263   u8 sw_if_index_set = 0;
13264   int ret;
13265
13266   /* Parse args required to build the message */
13267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13268     {
13269       if (unformat (i, "sw_if_index %d", &sw_if_index))
13270         sw_if_index_set = 1;
13271       else
13272         break;
13273     }
13274
13275   if (sw_if_index_set == 0)
13276     {
13277       sw_if_index = ~0;
13278     }
13279
13280   if (!vam->json_output)
13281     {
13282       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13283              "sw_if_index", "local_address", "remote_address",
13284              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13285     }
13286
13287   /* Get list of geneve-tunnel interfaces */
13288   M (GENEVE_TUNNEL_DUMP, mp);
13289
13290   mp->sw_if_index = htonl (sw_if_index);
13291
13292   S (mp);
13293
13294   /* Use a control ping for synchronization */
13295   M (CONTROL_PING, mp_ping);
13296   S (mp_ping);
13297
13298   W (ret);
13299   return ret;
13300 }
13301
13302 static int
13303 api_gre_tunnel_add_del (vat_main_t * vam)
13304 {
13305   unformat_input_t *line_input = vam->input;
13306   vl_api_address_t src = { }, dst =
13307   {
13308   };
13309   vl_api_gre_tunnel_add_del_t *mp;
13310   vl_api_gre_tunnel_type_t t_type;
13311   u8 is_add = 1;
13312   u8 ipv4_set = 0;
13313   u8 ipv6_set = 0;
13314   u8 src_set = 0;
13315   u8 dst_set = 0;
13316   u32 outer_fib_id = 0;
13317   u32 session_id = 0;
13318   u32 instance = ~0;
13319   int ret;
13320
13321   t_type = GRE_API_TUNNEL_TYPE_L3;
13322
13323   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13324     {
13325       if (unformat (line_input, "del"))
13326         is_add = 0;
13327       else if (unformat (line_input, "instance %d", &instance))
13328         ;
13329       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13330         {
13331           src_set = 1;
13332         }
13333       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13334         {
13335           dst_set = 1;
13336         }
13337       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13338         ;
13339       else if (unformat (line_input, "teb"))
13340         t_type = GRE_API_TUNNEL_TYPE_TEB;
13341       else if (unformat (line_input, "erspan %d", &session_id))
13342         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13343       else
13344         {
13345           errmsg ("parse error '%U'", format_unformat_error, line_input);
13346           return -99;
13347         }
13348     }
13349
13350   if (src_set == 0)
13351     {
13352       errmsg ("tunnel src address not specified");
13353       return -99;
13354     }
13355   if (dst_set == 0)
13356     {
13357       errmsg ("tunnel dst address not specified");
13358       return -99;
13359     }
13360
13361   M (GRE_TUNNEL_ADD_DEL, mp);
13362
13363   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13364   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13365
13366   mp->tunnel.instance = htonl (instance);
13367   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13368   mp->is_add = is_add;
13369   mp->tunnel.session_id = htons ((u16) session_id);
13370   mp->tunnel.type = htonl (t_type);
13371
13372   S (mp);
13373   W (ret);
13374   return ret;
13375 }
13376
13377 static void vl_api_gre_tunnel_details_t_handler
13378   (vl_api_gre_tunnel_details_t * mp)
13379 {
13380   vat_main_t *vam = &vat_main;
13381
13382   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13383          ntohl (mp->tunnel.sw_if_index),
13384          ntohl (mp->tunnel.instance),
13385          format_vl_api_address, &mp->tunnel.src,
13386          format_vl_api_address, &mp->tunnel.dst,
13387          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13388          ntohl (mp->tunnel.session_id));
13389 }
13390
13391 static void
13392 vat_json_object_add_address (vat_json_node_t * node,
13393                              const char *str, const vl_api_address_t * addr)
13394 {
13395   if (ADDRESS_IP6 == addr->af)
13396     {
13397       struct in6_addr ip6;
13398
13399       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13400       vat_json_object_add_ip6 (node, str, ip6);
13401     }
13402   else
13403     {
13404       struct in_addr ip4;
13405
13406       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13407       vat_json_object_add_ip4 (node, str, ip4);
13408     }
13409 }
13410
13411 static void vl_api_gre_tunnel_details_t_handler_json
13412   (vl_api_gre_tunnel_details_t * mp)
13413 {
13414   vat_main_t *vam = &vat_main;
13415   vat_json_node_t *node = NULL;
13416   struct in_addr ip4;
13417   struct in6_addr ip6;
13418
13419   if (VAT_JSON_ARRAY != vam->json_tree.type)
13420     {
13421       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13422       vat_json_init_array (&vam->json_tree);
13423     }
13424   node = vat_json_array_add (&vam->json_tree);
13425
13426   vat_json_init_object (node);
13427   vat_json_object_add_uint (node, "sw_if_index",
13428                             ntohl (mp->tunnel.sw_if_index));
13429   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13430
13431   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13432   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13433   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13434   vat_json_object_add_uint (node, "outer_fib_id",
13435                             ntohl (mp->tunnel.outer_fib_id));
13436   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13437 }
13438
13439 static int
13440 api_gre_tunnel_dump (vat_main_t * vam)
13441 {
13442   unformat_input_t *i = vam->input;
13443   vl_api_gre_tunnel_dump_t *mp;
13444   vl_api_control_ping_t *mp_ping;
13445   u32 sw_if_index;
13446   u8 sw_if_index_set = 0;
13447   int ret;
13448
13449   /* Parse args required to build the message */
13450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13451     {
13452       if (unformat (i, "sw_if_index %d", &sw_if_index))
13453         sw_if_index_set = 1;
13454       else
13455         break;
13456     }
13457
13458   if (sw_if_index_set == 0)
13459     {
13460       sw_if_index = ~0;
13461     }
13462
13463   if (!vam->json_output)
13464     {
13465       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13466              "sw_if_index", "instance", "src_address", "dst_address",
13467              "tunnel_type", "outer_fib_id", "session_id");
13468     }
13469
13470   /* Get list of gre-tunnel interfaces */
13471   M (GRE_TUNNEL_DUMP, mp);
13472
13473   mp->sw_if_index = htonl (sw_if_index);
13474
13475   S (mp);
13476
13477   /* Use a control ping for synchronization */
13478   MPING (CONTROL_PING, mp_ping);
13479   S (mp_ping);
13480
13481   W (ret);
13482   return ret;
13483 }
13484
13485 static int
13486 api_l2_fib_clear_table (vat_main_t * vam)
13487 {
13488 //  unformat_input_t * i = vam->input;
13489   vl_api_l2_fib_clear_table_t *mp;
13490   int ret;
13491
13492   M (L2_FIB_CLEAR_TABLE, mp);
13493
13494   S (mp);
13495   W (ret);
13496   return ret;
13497 }
13498
13499 static int
13500 api_l2_interface_efp_filter (vat_main_t * vam)
13501 {
13502   unformat_input_t *i = vam->input;
13503   vl_api_l2_interface_efp_filter_t *mp;
13504   u32 sw_if_index;
13505   u8 enable = 1;
13506   u8 sw_if_index_set = 0;
13507   int ret;
13508
13509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13510     {
13511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13512         sw_if_index_set = 1;
13513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13514         sw_if_index_set = 1;
13515       else if (unformat (i, "enable"))
13516         enable = 1;
13517       else if (unformat (i, "disable"))
13518         enable = 0;
13519       else
13520         {
13521           clib_warning ("parse error '%U'", format_unformat_error, i);
13522           return -99;
13523         }
13524     }
13525
13526   if (sw_if_index_set == 0)
13527     {
13528       errmsg ("missing sw_if_index");
13529       return -99;
13530     }
13531
13532   M (L2_INTERFACE_EFP_FILTER, mp);
13533
13534   mp->sw_if_index = ntohl (sw_if_index);
13535   mp->enable_disable = enable;
13536
13537   S (mp);
13538   W (ret);
13539   return ret;
13540 }
13541
13542 #define foreach_vtr_op                          \
13543 _("disable",  L2_VTR_DISABLED)                  \
13544 _("push-1",  L2_VTR_PUSH_1)                     \
13545 _("push-2",  L2_VTR_PUSH_2)                     \
13546 _("pop-1",  L2_VTR_POP_1)                       \
13547 _("pop-2",  L2_VTR_POP_2)                       \
13548 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13549 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13550 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13551 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13552
13553 static int
13554 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13555 {
13556   unformat_input_t *i = vam->input;
13557   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13558   u32 sw_if_index;
13559   u8 sw_if_index_set = 0;
13560   u8 vtr_op_set = 0;
13561   u32 vtr_op = 0;
13562   u32 push_dot1q = 1;
13563   u32 tag1 = ~0;
13564   u32 tag2 = ~0;
13565   int ret;
13566
13567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13568     {
13569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13570         sw_if_index_set = 1;
13571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13572         sw_if_index_set = 1;
13573       else if (unformat (i, "vtr_op %d", &vtr_op))
13574         vtr_op_set = 1;
13575 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13576       foreach_vtr_op
13577 #undef _
13578         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13579         ;
13580       else if (unformat (i, "tag1 %d", &tag1))
13581         ;
13582       else if (unformat (i, "tag2 %d", &tag2))
13583         ;
13584       else
13585         {
13586           clib_warning ("parse error '%U'", format_unformat_error, i);
13587           return -99;
13588         }
13589     }
13590
13591   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13592     {
13593       errmsg ("missing vtr operation or sw_if_index");
13594       return -99;
13595     }
13596
13597   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13598   mp->sw_if_index = ntohl (sw_if_index);
13599   mp->vtr_op = ntohl (vtr_op);
13600   mp->push_dot1q = ntohl (push_dot1q);
13601   mp->tag1 = ntohl (tag1);
13602   mp->tag2 = ntohl (tag2);
13603
13604   S (mp);
13605   W (ret);
13606   return ret;
13607 }
13608
13609 static int
13610 api_create_vhost_user_if (vat_main_t * vam)
13611 {
13612   unformat_input_t *i = vam->input;
13613   vl_api_create_vhost_user_if_t *mp;
13614   u8 *file_name;
13615   u8 is_server = 0;
13616   u8 file_name_set = 0;
13617   u32 custom_dev_instance = ~0;
13618   u8 hwaddr[6];
13619   u8 use_custom_mac = 0;
13620   u8 disable_mrg_rxbuf = 0;
13621   u8 disable_indirect_desc = 0;
13622   u8 *tag = 0;
13623   int ret;
13624
13625   /* Shut up coverity */
13626   clib_memset (hwaddr, 0, sizeof (hwaddr));
13627
13628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13629     {
13630       if (unformat (i, "socket %s", &file_name))
13631         {
13632           file_name_set = 1;
13633         }
13634       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13635         ;
13636       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13637         use_custom_mac = 1;
13638       else if (unformat (i, "server"))
13639         is_server = 1;
13640       else if (unformat (i, "disable_mrg_rxbuf"))
13641         disable_mrg_rxbuf = 1;
13642       else if (unformat (i, "disable_indirect_desc"))
13643         disable_indirect_desc = 1;
13644       else if (unformat (i, "tag %s", &tag))
13645         ;
13646       else
13647         break;
13648     }
13649
13650   if (file_name_set == 0)
13651     {
13652       errmsg ("missing socket file name");
13653       return -99;
13654     }
13655
13656   if (vec_len (file_name) > 255)
13657     {
13658       errmsg ("socket file name too long");
13659       return -99;
13660     }
13661   vec_add1 (file_name, 0);
13662
13663   M (CREATE_VHOST_USER_IF, mp);
13664
13665   mp->is_server = is_server;
13666   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13667   mp->disable_indirect_desc = disable_indirect_desc;
13668   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13669   vec_free (file_name);
13670   if (custom_dev_instance != ~0)
13671     {
13672       mp->renumber = 1;
13673       mp->custom_dev_instance = ntohl (custom_dev_instance);
13674     }
13675
13676   mp->use_custom_mac = use_custom_mac;
13677   clib_memcpy (mp->mac_address, hwaddr, 6);
13678   if (tag)
13679     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13680   vec_free (tag);
13681
13682   S (mp);
13683   W (ret);
13684   return ret;
13685 }
13686
13687 static int
13688 api_modify_vhost_user_if (vat_main_t * vam)
13689 {
13690   unformat_input_t *i = vam->input;
13691   vl_api_modify_vhost_user_if_t *mp;
13692   u8 *file_name;
13693   u8 is_server = 0;
13694   u8 file_name_set = 0;
13695   u32 custom_dev_instance = ~0;
13696   u8 sw_if_index_set = 0;
13697   u32 sw_if_index = (u32) ~ 0;
13698   int ret;
13699
13700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13701     {
13702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13703         sw_if_index_set = 1;
13704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13705         sw_if_index_set = 1;
13706       else if (unformat (i, "socket %s", &file_name))
13707         {
13708           file_name_set = 1;
13709         }
13710       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13711         ;
13712       else if (unformat (i, "server"))
13713         is_server = 1;
13714       else
13715         break;
13716     }
13717
13718   if (sw_if_index_set == 0)
13719     {
13720       errmsg ("missing sw_if_index or interface name");
13721       return -99;
13722     }
13723
13724   if (file_name_set == 0)
13725     {
13726       errmsg ("missing socket file name");
13727       return -99;
13728     }
13729
13730   if (vec_len (file_name) > 255)
13731     {
13732       errmsg ("socket file name too long");
13733       return -99;
13734     }
13735   vec_add1 (file_name, 0);
13736
13737   M (MODIFY_VHOST_USER_IF, mp);
13738
13739   mp->sw_if_index = ntohl (sw_if_index);
13740   mp->is_server = is_server;
13741   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13742   vec_free (file_name);
13743   if (custom_dev_instance != ~0)
13744     {
13745       mp->renumber = 1;
13746       mp->custom_dev_instance = ntohl (custom_dev_instance);
13747     }
13748
13749   S (mp);
13750   W (ret);
13751   return ret;
13752 }
13753
13754 static int
13755 api_delete_vhost_user_if (vat_main_t * vam)
13756 {
13757   unformat_input_t *i = vam->input;
13758   vl_api_delete_vhost_user_if_t *mp;
13759   u32 sw_if_index = ~0;
13760   u8 sw_if_index_set = 0;
13761   int ret;
13762
13763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13764     {
13765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13766         sw_if_index_set = 1;
13767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13768         sw_if_index_set = 1;
13769       else
13770         break;
13771     }
13772
13773   if (sw_if_index_set == 0)
13774     {
13775       errmsg ("missing sw_if_index or interface name");
13776       return -99;
13777     }
13778
13779
13780   M (DELETE_VHOST_USER_IF, mp);
13781
13782   mp->sw_if_index = ntohl (sw_if_index);
13783
13784   S (mp);
13785   W (ret);
13786   return ret;
13787 }
13788
13789 static void vl_api_sw_interface_vhost_user_details_t_handler
13790   (vl_api_sw_interface_vhost_user_details_t * mp)
13791 {
13792   vat_main_t *vam = &vat_main;
13793
13794   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13795          (char *) mp->interface_name,
13796          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13797          clib_net_to_host_u64 (mp->features), mp->is_server,
13798          ntohl (mp->num_regions), (char *) mp->sock_filename);
13799   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13800 }
13801
13802 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13803   (vl_api_sw_interface_vhost_user_details_t * mp)
13804 {
13805   vat_main_t *vam = &vat_main;
13806   vat_json_node_t *node = NULL;
13807
13808   if (VAT_JSON_ARRAY != vam->json_tree.type)
13809     {
13810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13811       vat_json_init_array (&vam->json_tree);
13812     }
13813   node = vat_json_array_add (&vam->json_tree);
13814
13815   vat_json_init_object (node);
13816   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13817   vat_json_object_add_string_copy (node, "interface_name",
13818                                    mp->interface_name);
13819   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13820                             ntohl (mp->virtio_net_hdr_sz));
13821   vat_json_object_add_uint (node, "features",
13822                             clib_net_to_host_u64 (mp->features));
13823   vat_json_object_add_uint (node, "is_server", mp->is_server);
13824   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13825   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13826   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13827 }
13828
13829 static int
13830 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13831 {
13832   vl_api_sw_interface_vhost_user_dump_t *mp;
13833   vl_api_control_ping_t *mp_ping;
13834   int ret;
13835   print (vam->ofp,
13836          "Interface name            idx hdr_sz features server regions filename");
13837
13838   /* Get list of vhost-user interfaces */
13839   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13840   S (mp);
13841
13842   /* Use a control ping for synchronization */
13843   MPING (CONTROL_PING, mp_ping);
13844   S (mp_ping);
13845
13846   W (ret);
13847   return ret;
13848 }
13849
13850 static int
13851 api_show_version (vat_main_t * vam)
13852 {
13853   vl_api_show_version_t *mp;
13854   int ret;
13855
13856   M (SHOW_VERSION, mp);
13857
13858   S (mp);
13859   W (ret);
13860   return ret;
13861 }
13862
13863
13864 static int
13865 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13866 {
13867   unformat_input_t *line_input = vam->input;
13868   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13869   ip4_address_t local4, remote4;
13870   ip6_address_t local6, remote6;
13871   u8 is_add = 1;
13872   u8 ipv4_set = 0, ipv6_set = 0;
13873   u8 local_set = 0;
13874   u8 remote_set = 0;
13875   u8 grp_set = 0;
13876   u32 mcast_sw_if_index = ~0;
13877   u32 encap_vrf_id = 0;
13878   u32 decap_vrf_id = 0;
13879   u8 protocol = ~0;
13880   u32 vni;
13881   u8 vni_set = 0;
13882   int ret;
13883
13884   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13885   clib_memset (&local4, 0, sizeof local4);
13886   clib_memset (&remote4, 0, sizeof remote4);
13887   clib_memset (&local6, 0, sizeof local6);
13888   clib_memset (&remote6, 0, sizeof remote6);
13889
13890   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13891     {
13892       if (unformat (line_input, "del"))
13893         is_add = 0;
13894       else if (unformat (line_input, "local %U",
13895                          unformat_ip4_address, &local4))
13896         {
13897           local_set = 1;
13898           ipv4_set = 1;
13899         }
13900       else if (unformat (line_input, "remote %U",
13901                          unformat_ip4_address, &remote4))
13902         {
13903           remote_set = 1;
13904           ipv4_set = 1;
13905         }
13906       else if (unformat (line_input, "local %U",
13907                          unformat_ip6_address, &local6))
13908         {
13909           local_set = 1;
13910           ipv6_set = 1;
13911         }
13912       else if (unformat (line_input, "remote %U",
13913                          unformat_ip6_address, &remote6))
13914         {
13915           remote_set = 1;
13916           ipv6_set = 1;
13917         }
13918       else if (unformat (line_input, "group %U %U",
13919                          unformat_ip4_address, &remote4,
13920                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13921         {
13922           grp_set = remote_set = 1;
13923           ipv4_set = 1;
13924         }
13925       else if (unformat (line_input, "group %U",
13926                          unformat_ip4_address, &remote4))
13927         {
13928           grp_set = remote_set = 1;
13929           ipv4_set = 1;
13930         }
13931       else if (unformat (line_input, "group %U %U",
13932                          unformat_ip6_address, &remote6,
13933                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13934         {
13935           grp_set = remote_set = 1;
13936           ipv6_set = 1;
13937         }
13938       else if (unformat (line_input, "group %U",
13939                          unformat_ip6_address, &remote6))
13940         {
13941           grp_set = remote_set = 1;
13942           ipv6_set = 1;
13943         }
13944       else
13945         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13946         ;
13947       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13948         ;
13949       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13950         ;
13951       else if (unformat (line_input, "vni %d", &vni))
13952         vni_set = 1;
13953       else if (unformat (line_input, "next-ip4"))
13954         protocol = 1;
13955       else if (unformat (line_input, "next-ip6"))
13956         protocol = 2;
13957       else if (unformat (line_input, "next-ethernet"))
13958         protocol = 3;
13959       else if (unformat (line_input, "next-nsh"))
13960         protocol = 4;
13961       else
13962         {
13963           errmsg ("parse error '%U'", format_unformat_error, line_input);
13964           return -99;
13965         }
13966     }
13967
13968   if (local_set == 0)
13969     {
13970       errmsg ("tunnel local address not specified");
13971       return -99;
13972     }
13973   if (remote_set == 0)
13974     {
13975       errmsg ("tunnel remote address not specified");
13976       return -99;
13977     }
13978   if (grp_set && mcast_sw_if_index == ~0)
13979     {
13980       errmsg ("tunnel nonexistent multicast device");
13981       return -99;
13982     }
13983   if (ipv4_set && ipv6_set)
13984     {
13985       errmsg ("both IPv4 and IPv6 addresses specified");
13986       return -99;
13987     }
13988
13989   if (vni_set == 0)
13990     {
13991       errmsg ("vni not specified");
13992       return -99;
13993     }
13994
13995   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13996
13997
13998   if (ipv6_set)
13999     {
14000       clib_memcpy (&mp->local, &local6, sizeof (local6));
14001       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14002     }
14003   else
14004     {
14005       clib_memcpy (&mp->local, &local4, sizeof (local4));
14006       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14007     }
14008
14009   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14010   mp->encap_vrf_id = ntohl (encap_vrf_id);
14011   mp->decap_vrf_id = ntohl (decap_vrf_id);
14012   mp->protocol = protocol;
14013   mp->vni = ntohl (vni);
14014   mp->is_add = is_add;
14015   mp->is_ipv6 = ipv6_set;
14016
14017   S (mp);
14018   W (ret);
14019   return ret;
14020 }
14021
14022 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14023   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14024 {
14025   vat_main_t *vam = &vat_main;
14026   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14027   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14028
14029   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14030          ntohl (mp->sw_if_index),
14031          format_ip46_address, &local, IP46_TYPE_ANY,
14032          format_ip46_address, &remote, IP46_TYPE_ANY,
14033          ntohl (mp->vni), mp->protocol,
14034          ntohl (mp->mcast_sw_if_index),
14035          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14036 }
14037
14038
14039 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14040   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14041 {
14042   vat_main_t *vam = &vat_main;
14043   vat_json_node_t *node = NULL;
14044   struct in_addr ip4;
14045   struct in6_addr ip6;
14046
14047   if (VAT_JSON_ARRAY != vam->json_tree.type)
14048     {
14049       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14050       vat_json_init_array (&vam->json_tree);
14051     }
14052   node = vat_json_array_add (&vam->json_tree);
14053
14054   vat_json_init_object (node);
14055   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14056   if (mp->is_ipv6)
14057     {
14058       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14059       vat_json_object_add_ip6 (node, "local", ip6);
14060       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14061       vat_json_object_add_ip6 (node, "remote", ip6);
14062     }
14063   else
14064     {
14065       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14066       vat_json_object_add_ip4 (node, "local", ip4);
14067       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14068       vat_json_object_add_ip4 (node, "remote", ip4);
14069     }
14070   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14071   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14072   vat_json_object_add_uint (node, "mcast_sw_if_index",
14073                             ntohl (mp->mcast_sw_if_index));
14074   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14075   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14076   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14077 }
14078
14079 static int
14080 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14081 {
14082   unformat_input_t *i = vam->input;
14083   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14084   vl_api_control_ping_t *mp_ping;
14085   u32 sw_if_index;
14086   u8 sw_if_index_set = 0;
14087   int ret;
14088
14089   /* Parse args required to build the message */
14090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14091     {
14092       if (unformat (i, "sw_if_index %d", &sw_if_index))
14093         sw_if_index_set = 1;
14094       else
14095         break;
14096     }
14097
14098   if (sw_if_index_set == 0)
14099     {
14100       sw_if_index = ~0;
14101     }
14102
14103   if (!vam->json_output)
14104     {
14105       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14106              "sw_if_index", "local", "remote", "vni",
14107              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14108     }
14109
14110   /* Get list of vxlan-tunnel interfaces */
14111   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14112
14113   mp->sw_if_index = htonl (sw_if_index);
14114
14115   S (mp);
14116
14117   /* Use a control ping for synchronization */
14118   MPING (CONTROL_PING, mp_ping);
14119   S (mp_ping);
14120
14121   W (ret);
14122   return ret;
14123 }
14124
14125 static void vl_api_l2_fib_table_details_t_handler
14126   (vl_api_l2_fib_table_details_t * mp)
14127 {
14128   vat_main_t *vam = &vat_main;
14129
14130   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14131          "       %d       %d     %d",
14132          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14133          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14134          mp->bvi_mac);
14135 }
14136
14137 static void vl_api_l2_fib_table_details_t_handler_json
14138   (vl_api_l2_fib_table_details_t * mp)
14139 {
14140   vat_main_t *vam = &vat_main;
14141   vat_json_node_t *node = NULL;
14142
14143   if (VAT_JSON_ARRAY != vam->json_tree.type)
14144     {
14145       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14146       vat_json_init_array (&vam->json_tree);
14147     }
14148   node = vat_json_array_add (&vam->json_tree);
14149
14150   vat_json_init_object (node);
14151   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14152   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14153   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14154   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14155   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14156   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14157 }
14158
14159 static int
14160 api_l2_fib_table_dump (vat_main_t * vam)
14161 {
14162   unformat_input_t *i = vam->input;
14163   vl_api_l2_fib_table_dump_t *mp;
14164   vl_api_control_ping_t *mp_ping;
14165   u32 bd_id;
14166   u8 bd_id_set = 0;
14167   int ret;
14168
14169   /* Parse args required to build the message */
14170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (i, "bd_id %d", &bd_id))
14173         bd_id_set = 1;
14174       else
14175         break;
14176     }
14177
14178   if (bd_id_set == 0)
14179     {
14180       errmsg ("missing bridge domain");
14181       return -99;
14182     }
14183
14184   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14185
14186   /* Get list of l2 fib entries */
14187   M (L2_FIB_TABLE_DUMP, mp);
14188
14189   mp->bd_id = ntohl (bd_id);
14190   S (mp);
14191
14192   /* Use a control ping for synchronization */
14193   MPING (CONTROL_PING, mp_ping);
14194   S (mp_ping);
14195
14196   W (ret);
14197   return ret;
14198 }
14199
14200
14201 static int
14202 api_interface_name_renumber (vat_main_t * vam)
14203 {
14204   unformat_input_t *line_input = vam->input;
14205   vl_api_interface_name_renumber_t *mp;
14206   u32 sw_if_index = ~0;
14207   u32 new_show_dev_instance = ~0;
14208   int ret;
14209
14210   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14211     {
14212       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14213                     &sw_if_index))
14214         ;
14215       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14216         ;
14217       else if (unformat (line_input, "new_show_dev_instance %d",
14218                          &new_show_dev_instance))
14219         ;
14220       else
14221         break;
14222     }
14223
14224   if (sw_if_index == ~0)
14225     {
14226       errmsg ("missing interface name or sw_if_index");
14227       return -99;
14228     }
14229
14230   if (new_show_dev_instance == ~0)
14231     {
14232       errmsg ("missing new_show_dev_instance");
14233       return -99;
14234     }
14235
14236   M (INTERFACE_NAME_RENUMBER, mp);
14237
14238   mp->sw_if_index = ntohl (sw_if_index);
14239   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14240
14241   S (mp);
14242   W (ret);
14243   return ret;
14244 }
14245
14246 static int
14247 api_ip_probe_neighbor (vat_main_t * vam)
14248 {
14249   unformat_input_t *i = vam->input;
14250   vl_api_ip_probe_neighbor_t *mp;
14251   vl_api_address_t dst_adr;
14252   u8 int_set = 0;
14253   u8 adr_set = 0;
14254   u32 sw_if_index;
14255   int ret;
14256
14257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14258     {
14259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14260         int_set = 1;
14261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14262         int_set = 1;
14263       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14264         adr_set = 1;
14265       else
14266         break;
14267     }
14268
14269   if (int_set == 0)
14270     {
14271       errmsg ("missing interface");
14272       return -99;
14273     }
14274
14275   if (adr_set == 0)
14276     {
14277       errmsg ("missing addresses");
14278       return -99;
14279     }
14280
14281   M (IP_PROBE_NEIGHBOR, mp);
14282
14283   mp->sw_if_index = ntohl (sw_if_index);
14284   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14285
14286   S (mp);
14287   W (ret);
14288   return ret;
14289 }
14290
14291 static int
14292 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14293 {
14294   unformat_input_t *i = vam->input;
14295   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14296   u8 mode = IP_SCAN_V46_NEIGHBORS;
14297   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14298   int ret;
14299
14300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14301     {
14302       if (unformat (i, "ip4"))
14303         mode = IP_SCAN_V4_NEIGHBORS;
14304       else if (unformat (i, "ip6"))
14305         mode = IP_SCAN_V6_NEIGHBORS;
14306       if (unformat (i, "both"))
14307         mode = IP_SCAN_V46_NEIGHBORS;
14308       else if (unformat (i, "disable"))
14309         mode = IP_SCAN_DISABLED;
14310       else if (unformat (i, "interval %d", &interval))
14311         ;
14312       else if (unformat (i, "max-time %d", &time))
14313         ;
14314       else if (unformat (i, "max-update %d", &update))
14315         ;
14316       else if (unformat (i, "delay %d", &delay))
14317         ;
14318       else if (unformat (i, "stale %d", &stale))
14319         ;
14320       else
14321         break;
14322     }
14323
14324   if (interval > 255)
14325     {
14326       errmsg ("interval cannot exceed 255 minutes.");
14327       return -99;
14328     }
14329   if (time > 255)
14330     {
14331       errmsg ("max-time cannot exceed 255 usec.");
14332       return -99;
14333     }
14334   if (update > 255)
14335     {
14336       errmsg ("max-update cannot exceed 255.");
14337       return -99;
14338     }
14339   if (delay > 255)
14340     {
14341       errmsg ("delay cannot exceed 255 msec.");
14342       return -99;
14343     }
14344   if (stale > 255)
14345     {
14346       errmsg ("stale cannot exceed 255 minutes.");
14347       return -99;
14348     }
14349
14350   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14351   mp->mode = mode;
14352   mp->scan_interval = interval;
14353   mp->max_proc_time = time;
14354   mp->max_update = update;
14355   mp->scan_int_delay = delay;
14356   mp->stale_threshold = stale;
14357
14358   S (mp);
14359   W (ret);
14360   return ret;
14361 }
14362
14363 static int
14364 api_want_ip4_arp_events (vat_main_t * vam)
14365 {
14366   unformat_input_t *line_input = vam->input;
14367   vl_api_want_ip4_arp_events_t *mp;
14368   ip4_address_t address;
14369   int address_set = 0;
14370   u32 enable_disable = 1;
14371   int ret;
14372
14373   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14374     {
14375       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14376         address_set = 1;
14377       else if (unformat (line_input, "del"))
14378         enable_disable = 0;
14379       else
14380         break;
14381     }
14382
14383   if (address_set == 0)
14384     {
14385       errmsg ("missing addresses");
14386       return -99;
14387     }
14388
14389   M (WANT_IP4_ARP_EVENTS, mp);
14390   mp->enable_disable = enable_disable;
14391   mp->pid = htonl (getpid ());
14392   clib_memcpy (mp->ip, &address, sizeof (address));
14393
14394   S (mp);
14395   W (ret);
14396   return ret;
14397 }
14398
14399 static int
14400 api_want_ip6_nd_events (vat_main_t * vam)
14401 {
14402   unformat_input_t *line_input = vam->input;
14403   vl_api_want_ip6_nd_events_t *mp;
14404   vl_api_ip6_address_t address;
14405   int address_set = 0;
14406   u32 enable_disable = 1;
14407   int ret;
14408
14409   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14410     {
14411       if (unformat
14412           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14413         address_set = 1;
14414       else if (unformat (line_input, "del"))
14415         enable_disable = 0;
14416       else
14417         break;
14418     }
14419
14420   if (address_set == 0)
14421     {
14422       errmsg ("missing addresses");
14423       return -99;
14424     }
14425
14426   M (WANT_IP6_ND_EVENTS, mp);
14427   mp->enable_disable = enable_disable;
14428   mp->pid = htonl (getpid ());
14429   clib_memcpy (&mp->ip, &address, sizeof (address));
14430
14431   S (mp);
14432   W (ret);
14433   return ret;
14434 }
14435
14436 static int
14437 api_want_l2_macs_events (vat_main_t * vam)
14438 {
14439   unformat_input_t *line_input = vam->input;
14440   vl_api_want_l2_macs_events_t *mp;
14441   u8 enable_disable = 1;
14442   u32 scan_delay = 0;
14443   u32 max_macs_in_event = 0;
14444   u32 learn_limit = 0;
14445   int ret;
14446
14447   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14448     {
14449       if (unformat (line_input, "learn-limit %d", &learn_limit))
14450         ;
14451       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14452         ;
14453       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14454         ;
14455       else if (unformat (line_input, "disable"))
14456         enable_disable = 0;
14457       else
14458         break;
14459     }
14460
14461   M (WANT_L2_MACS_EVENTS, mp);
14462   mp->enable_disable = enable_disable;
14463   mp->pid = htonl (getpid ());
14464   mp->learn_limit = htonl (learn_limit);
14465   mp->scan_delay = (u8) scan_delay;
14466   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14467   S (mp);
14468   W (ret);
14469   return ret;
14470 }
14471
14472 static int
14473 api_input_acl_set_interface (vat_main_t * vam)
14474 {
14475   unformat_input_t *i = vam->input;
14476   vl_api_input_acl_set_interface_t *mp;
14477   u32 sw_if_index;
14478   int sw_if_index_set;
14479   u32 ip4_table_index = ~0;
14480   u32 ip6_table_index = ~0;
14481   u32 l2_table_index = ~0;
14482   u8 is_add = 1;
14483   int ret;
14484
14485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14486     {
14487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14488         sw_if_index_set = 1;
14489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14490         sw_if_index_set = 1;
14491       else if (unformat (i, "del"))
14492         is_add = 0;
14493       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14494         ;
14495       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14496         ;
14497       else if (unformat (i, "l2-table %d", &l2_table_index))
14498         ;
14499       else
14500         {
14501           clib_warning ("parse error '%U'", format_unformat_error, i);
14502           return -99;
14503         }
14504     }
14505
14506   if (sw_if_index_set == 0)
14507     {
14508       errmsg ("missing interface name or sw_if_index");
14509       return -99;
14510     }
14511
14512   M (INPUT_ACL_SET_INTERFACE, mp);
14513
14514   mp->sw_if_index = ntohl (sw_if_index);
14515   mp->ip4_table_index = ntohl (ip4_table_index);
14516   mp->ip6_table_index = ntohl (ip6_table_index);
14517   mp->l2_table_index = ntohl (l2_table_index);
14518   mp->is_add = is_add;
14519
14520   S (mp);
14521   W (ret);
14522   return ret;
14523 }
14524
14525 static int
14526 api_output_acl_set_interface (vat_main_t * vam)
14527 {
14528   unformat_input_t *i = vam->input;
14529   vl_api_output_acl_set_interface_t *mp;
14530   u32 sw_if_index;
14531   int sw_if_index_set;
14532   u32 ip4_table_index = ~0;
14533   u32 ip6_table_index = ~0;
14534   u32 l2_table_index = ~0;
14535   u8 is_add = 1;
14536   int ret;
14537
14538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14539     {
14540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14541         sw_if_index_set = 1;
14542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14543         sw_if_index_set = 1;
14544       else if (unformat (i, "del"))
14545         is_add = 0;
14546       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14547         ;
14548       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14549         ;
14550       else if (unformat (i, "l2-table %d", &l2_table_index))
14551         ;
14552       else
14553         {
14554           clib_warning ("parse error '%U'", format_unformat_error, i);
14555           return -99;
14556         }
14557     }
14558
14559   if (sw_if_index_set == 0)
14560     {
14561       errmsg ("missing interface name or sw_if_index");
14562       return -99;
14563     }
14564
14565   M (OUTPUT_ACL_SET_INTERFACE, mp);
14566
14567   mp->sw_if_index = ntohl (sw_if_index);
14568   mp->ip4_table_index = ntohl (ip4_table_index);
14569   mp->ip6_table_index = ntohl (ip6_table_index);
14570   mp->l2_table_index = ntohl (l2_table_index);
14571   mp->is_add = is_add;
14572
14573   S (mp);
14574   W (ret);
14575   return ret;
14576 }
14577
14578 static int
14579 api_ip_address_dump (vat_main_t * vam)
14580 {
14581   unformat_input_t *i = vam->input;
14582   vl_api_ip_address_dump_t *mp;
14583   vl_api_control_ping_t *mp_ping;
14584   u32 sw_if_index = ~0;
14585   u8 sw_if_index_set = 0;
14586   u8 ipv4_set = 0;
14587   u8 ipv6_set = 0;
14588   int ret;
14589
14590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (i, "sw_if_index %d", &sw_if_index))
14593         sw_if_index_set = 1;
14594       else
14595         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14596         sw_if_index_set = 1;
14597       else if (unformat (i, "ipv4"))
14598         ipv4_set = 1;
14599       else if (unformat (i, "ipv6"))
14600         ipv6_set = 1;
14601       else
14602         break;
14603     }
14604
14605   if (ipv4_set && ipv6_set)
14606     {
14607       errmsg ("ipv4 and ipv6 flags cannot be both set");
14608       return -99;
14609     }
14610
14611   if ((!ipv4_set) && (!ipv6_set))
14612     {
14613       errmsg ("no ipv4 nor ipv6 flag set");
14614       return -99;
14615     }
14616
14617   if (sw_if_index_set == 0)
14618     {
14619       errmsg ("missing interface name or sw_if_index");
14620       return -99;
14621     }
14622
14623   vam->current_sw_if_index = sw_if_index;
14624   vam->is_ipv6 = ipv6_set;
14625
14626   M (IP_ADDRESS_DUMP, mp);
14627   mp->sw_if_index = ntohl (sw_if_index);
14628   mp->is_ipv6 = ipv6_set;
14629   S (mp);
14630
14631   /* Use a control ping for synchronization */
14632   MPING (CONTROL_PING, mp_ping);
14633   S (mp_ping);
14634
14635   W (ret);
14636   return ret;
14637 }
14638
14639 static int
14640 api_ip_dump (vat_main_t * vam)
14641 {
14642   vl_api_ip_dump_t *mp;
14643   vl_api_control_ping_t *mp_ping;
14644   unformat_input_t *in = vam->input;
14645   int ipv4_set = 0;
14646   int ipv6_set = 0;
14647   int is_ipv6;
14648   int i;
14649   int ret;
14650
14651   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (in, "ipv4"))
14654         ipv4_set = 1;
14655       else if (unformat (in, "ipv6"))
14656         ipv6_set = 1;
14657       else
14658         break;
14659     }
14660
14661   if (ipv4_set && ipv6_set)
14662     {
14663       errmsg ("ipv4 and ipv6 flags cannot be both set");
14664       return -99;
14665     }
14666
14667   if ((!ipv4_set) && (!ipv6_set))
14668     {
14669       errmsg ("no ipv4 nor ipv6 flag set");
14670       return -99;
14671     }
14672
14673   is_ipv6 = ipv6_set;
14674   vam->is_ipv6 = is_ipv6;
14675
14676   /* free old data */
14677   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14678     {
14679       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14680     }
14681   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14682
14683   M (IP_DUMP, mp);
14684   mp->is_ipv6 = ipv6_set;
14685   S (mp);
14686
14687   /* Use a control ping for synchronization */
14688   MPING (CONTROL_PING, mp_ping);
14689   S (mp_ping);
14690
14691   W (ret);
14692   return ret;
14693 }
14694
14695 static int
14696 api_ipsec_spd_add_del (vat_main_t * vam)
14697 {
14698   unformat_input_t *i = vam->input;
14699   vl_api_ipsec_spd_add_del_t *mp;
14700   u32 spd_id = ~0;
14701   u8 is_add = 1;
14702   int ret;
14703
14704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14705     {
14706       if (unformat (i, "spd_id %d", &spd_id))
14707         ;
14708       else if (unformat (i, "del"))
14709         is_add = 0;
14710       else
14711         {
14712           clib_warning ("parse error '%U'", format_unformat_error, i);
14713           return -99;
14714         }
14715     }
14716   if (spd_id == ~0)
14717     {
14718       errmsg ("spd_id must be set");
14719       return -99;
14720     }
14721
14722   M (IPSEC_SPD_ADD_DEL, mp);
14723
14724   mp->spd_id = ntohl (spd_id);
14725   mp->is_add = is_add;
14726
14727   S (mp);
14728   W (ret);
14729   return ret;
14730 }
14731
14732 static int
14733 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14734 {
14735   unformat_input_t *i = vam->input;
14736   vl_api_ipsec_interface_add_del_spd_t *mp;
14737   u32 sw_if_index;
14738   u8 sw_if_index_set = 0;
14739   u32 spd_id = (u32) ~ 0;
14740   u8 is_add = 1;
14741   int ret;
14742
14743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14744     {
14745       if (unformat (i, "del"))
14746         is_add = 0;
14747       else if (unformat (i, "spd_id %d", &spd_id))
14748         ;
14749       else
14750         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14751         sw_if_index_set = 1;
14752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14753         sw_if_index_set = 1;
14754       else
14755         {
14756           clib_warning ("parse error '%U'", format_unformat_error, i);
14757           return -99;
14758         }
14759
14760     }
14761
14762   if (spd_id == (u32) ~ 0)
14763     {
14764       errmsg ("spd_id must be set");
14765       return -99;
14766     }
14767
14768   if (sw_if_index_set == 0)
14769     {
14770       errmsg ("missing interface name or sw_if_index");
14771       return -99;
14772     }
14773
14774   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14775
14776   mp->spd_id = ntohl (spd_id);
14777   mp->sw_if_index = ntohl (sw_if_index);
14778   mp->is_add = is_add;
14779
14780   S (mp);
14781   W (ret);
14782   return ret;
14783 }
14784
14785 static int
14786 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14787 {
14788   unformat_input_t *i = vam->input;
14789   vl_api_ipsec_spd_entry_add_del_t *mp;
14790   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14791   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14792   i32 priority = 0;
14793   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14794   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14795   vl_api_address_t laddr_start = { }, laddr_stop =
14796   {
14797   }, raddr_start =
14798   {
14799   }, raddr_stop =
14800   {
14801   };
14802   int ret;
14803
14804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14805     {
14806       if (unformat (i, "del"))
14807         is_add = 0;
14808       if (unformat (i, "outbound"))
14809         is_outbound = 1;
14810       if (unformat (i, "inbound"))
14811         is_outbound = 0;
14812       else if (unformat (i, "spd_id %d", &spd_id))
14813         ;
14814       else if (unformat (i, "sa_id %d", &sa_id))
14815         ;
14816       else if (unformat (i, "priority %d", &priority))
14817         ;
14818       else if (unformat (i, "protocol %d", &protocol))
14819         ;
14820       else if (unformat (i, "lport_start %d", &lport_start))
14821         ;
14822       else if (unformat (i, "lport_stop %d", &lport_stop))
14823         ;
14824       else if (unformat (i, "rport_start %d", &rport_start))
14825         ;
14826       else if (unformat (i, "rport_stop %d", &rport_stop))
14827         ;
14828       else if (unformat (i, "laddr_start %U",
14829                          unformat_vl_api_address, &laddr_start))
14830         is_ip_any = 0;
14831       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14832                          &laddr_stop))
14833         is_ip_any = 0;
14834       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14835                          &raddr_start))
14836         is_ip_any = 0;
14837       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14838                          &raddr_stop))
14839         is_ip_any = 0;
14840       else
14841         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14842         {
14843           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14844             {
14845               clib_warning ("unsupported action: 'resolve'");
14846               return -99;
14847             }
14848         }
14849       else
14850         {
14851           clib_warning ("parse error '%U'", format_unformat_error, i);
14852           return -99;
14853         }
14854
14855     }
14856
14857   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14858
14859   mp->is_add = is_add;
14860
14861   mp->entry.spd_id = ntohl (spd_id);
14862   mp->entry.priority = ntohl (priority);
14863   mp->entry.is_outbound = is_outbound;
14864
14865   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14866                sizeof (vl_api_address_t));
14867   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14868                sizeof (vl_api_address_t));
14869   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14870                sizeof (vl_api_address_t));
14871   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14872                sizeof (vl_api_address_t));
14873
14874   mp->entry.protocol = (u8) protocol;
14875   mp->entry.local_port_start = ntohs ((u16) lport_start);
14876   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14877   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14878   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14879   mp->entry.policy = (u8) policy;
14880   mp->entry.sa_id = ntohl (sa_id);
14881
14882   S (mp);
14883   W (ret);
14884   return ret;
14885 }
14886
14887 static int
14888 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14889 {
14890   unformat_input_t *i = vam->input;
14891   vl_api_ipsec_sad_entry_add_del_t *mp;
14892   u32 sad_id = 0, spi = 0;
14893   u8 *ck = 0, *ik = 0;
14894   u8 is_add = 1;
14895
14896   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14897   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14898   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14899   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14900   vl_api_address_t tun_src, tun_dst;
14901   int ret;
14902
14903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (i, "del"))
14906         is_add = 0;
14907       else if (unformat (i, "sad_id %d", &sad_id))
14908         ;
14909       else if (unformat (i, "spi %d", &spi))
14910         ;
14911       else if (unformat (i, "esp"))
14912         protocol = IPSEC_API_PROTO_ESP;
14913       else
14914         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14915         {
14916           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14917           if (ADDRESS_IP6 == tun_src.af)
14918             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14919         }
14920       else
14921         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14922         {
14923           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14924           if (ADDRESS_IP6 == tun_src.af)
14925             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14926         }
14927       else
14928         if (unformat (i, "crypto_alg %U",
14929                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14930         ;
14931       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14932         ;
14933       else if (unformat (i, "integ_alg %U",
14934                          unformat_ipsec_api_integ_alg, &integ_alg))
14935         ;
14936       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14937         ;
14938       else
14939         {
14940           clib_warning ("parse error '%U'", format_unformat_error, i);
14941           return -99;
14942         }
14943
14944     }
14945
14946   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14947
14948   mp->is_add = is_add;
14949   mp->entry.sad_id = ntohl (sad_id);
14950   mp->entry.protocol = protocol;
14951   mp->entry.spi = ntohl (spi);
14952   mp->entry.flags = flags;
14953
14954   mp->entry.crypto_algorithm = crypto_alg;
14955   mp->entry.integrity_algorithm = integ_alg;
14956   mp->entry.crypto_key.length = vec_len (ck);
14957   mp->entry.integrity_key.length = vec_len (ik);
14958
14959   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14960     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14961
14962   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14963     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14964
14965   if (ck)
14966     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14967   if (ik)
14968     clib_memcpy (mp->entry.integrity_key.data, ik,
14969                  mp->entry.integrity_key.length);
14970
14971   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14972     {
14973       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14974                    sizeof (mp->entry.tunnel_src));
14975       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14976                    sizeof (mp->entry.tunnel_dst));
14977     }
14978
14979   S (mp);
14980   W (ret);
14981   return ret;
14982 }
14983
14984 static int
14985 api_ipsec_sa_set_key (vat_main_t * vam)
14986 {
14987   unformat_input_t *i = vam->input;
14988   vl_api_ipsec_sa_set_key_t *mp;
14989   u32 sa_id;
14990   u8 *ck = 0, *ik = 0;
14991   int ret;
14992
14993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14994     {
14995       if (unformat (i, "sa_id %d", &sa_id))
14996         ;
14997       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14998         ;
14999       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15000         ;
15001       else
15002         {
15003           clib_warning ("parse error '%U'", format_unformat_error, i);
15004           return -99;
15005         }
15006     }
15007
15008   M (IPSEC_SA_SET_KEY, mp);
15009
15010   mp->sa_id = ntohl (sa_id);
15011   mp->crypto_key.length = vec_len (ck);
15012   mp->integrity_key.length = vec_len (ik);
15013
15014   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
15015     mp->crypto_key.length = sizeof (mp->crypto_key.data);
15016
15017   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
15018     mp->integrity_key.length = sizeof (mp->integrity_key.data);
15019
15020   if (ck)
15021     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
15022   if (ik)
15023     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
15024
15025   S (mp);
15026   W (ret);
15027   return ret;
15028 }
15029
15030 static int
15031 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15032 {
15033   unformat_input_t *i = vam->input;
15034   vl_api_ipsec_tunnel_if_add_del_t *mp;
15035   u32 local_spi = 0, remote_spi = 0;
15036   u32 crypto_alg = 0, integ_alg = 0;
15037   u8 *lck = NULL, *rck = NULL;
15038   u8 *lik = NULL, *rik = NULL;
15039   vl_api_address_t local_ip = { 0 };
15040   vl_api_address_t remote_ip = { 0 };
15041   f64 before = 0;
15042   u8 is_add = 1;
15043   u8 esn = 0;
15044   u8 anti_replay = 0;
15045   u8 renumber = 0;
15046   u32 instance = ~0;
15047   u32 count = 1, jj;
15048   int ret;
15049
15050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15051     {
15052       if (unformat (i, "del"))
15053         is_add = 0;
15054       else if (unformat (i, "esn"))
15055         esn = 1;
15056       else if (unformat (i, "anti-replay"))
15057         anti_replay = 1;
15058       else if (unformat (i, "count %d", &count))
15059         ;
15060       else if (unformat (i, "local_spi %d", &local_spi))
15061         ;
15062       else if (unformat (i, "remote_spi %d", &remote_spi))
15063         ;
15064       else
15065         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
15066         ;
15067       else
15068         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
15069         ;
15070       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15071         ;
15072       else
15073         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15074         ;
15075       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15076         ;
15077       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15078         ;
15079       else
15080         if (unformat
15081             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15082         {
15083           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15084             {
15085               errmsg ("unsupported crypto-alg: '%U'\n",
15086                       format_ipsec_crypto_alg, crypto_alg);
15087               return -99;
15088             }
15089         }
15090       else
15091         if (unformat
15092             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15093         {
15094           if (integ_alg >= IPSEC_INTEG_N_ALG)
15095             {
15096               errmsg ("unsupported integ-alg: '%U'\n",
15097                       format_ipsec_integ_alg, integ_alg);
15098               return -99;
15099             }
15100         }
15101       else if (unformat (i, "instance %u", &instance))
15102         renumber = 1;
15103       else
15104         {
15105           errmsg ("parse error '%U'\n", format_unformat_error, i);
15106           return -99;
15107         }
15108     }
15109
15110   if (count > 1)
15111     {
15112       /* Turn on async mode */
15113       vam->async_mode = 1;
15114       vam->async_errors = 0;
15115       before = vat_time_now (vam);
15116     }
15117
15118   for (jj = 0; jj < count; jj++)
15119     {
15120       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15121
15122       mp->is_add = is_add;
15123       mp->esn = esn;
15124       mp->anti_replay = anti_replay;
15125
15126       if (jj > 0)
15127         increment_vl_address (&remote_ip);
15128
15129       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15130       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15131
15132       mp->local_spi = htonl (local_spi + jj);
15133       mp->remote_spi = htonl (remote_spi + jj);
15134       mp->crypto_alg = (u8) crypto_alg;
15135
15136       mp->local_crypto_key_len = 0;
15137       if (lck)
15138         {
15139           mp->local_crypto_key_len = vec_len (lck);
15140           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15141             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15142           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15143         }
15144
15145       mp->remote_crypto_key_len = 0;
15146       if (rck)
15147         {
15148           mp->remote_crypto_key_len = vec_len (rck);
15149           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15150             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15151           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15152         }
15153
15154       mp->integ_alg = (u8) integ_alg;
15155
15156       mp->local_integ_key_len = 0;
15157       if (lik)
15158         {
15159           mp->local_integ_key_len = vec_len (lik);
15160           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15161             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15162           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15163         }
15164
15165       mp->remote_integ_key_len = 0;
15166       if (rik)
15167         {
15168           mp->remote_integ_key_len = vec_len (rik);
15169           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15170             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15171           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15172         }
15173
15174       if (renumber)
15175         {
15176           mp->renumber = renumber;
15177           mp->show_instance = ntohl (instance);
15178         }
15179       S (mp);
15180     }
15181
15182   /* When testing multiple add/del ops, use a control-ping to sync */
15183   if (count > 1)
15184     {
15185       vl_api_control_ping_t *mp_ping;
15186       f64 after;
15187       f64 timeout;
15188
15189       /* Shut off async mode */
15190       vam->async_mode = 0;
15191
15192       MPING (CONTROL_PING, mp_ping);
15193       S (mp_ping);
15194
15195       timeout = vat_time_now (vam) + 1.0;
15196       while (vat_time_now (vam) < timeout)
15197         if (vam->result_ready == 1)
15198           goto out;
15199       vam->retval = -99;
15200
15201     out:
15202       if (vam->retval == -99)
15203         errmsg ("timeout");
15204
15205       if (vam->async_errors > 0)
15206         {
15207           errmsg ("%d asynchronous errors", vam->async_errors);
15208           vam->retval = -98;
15209         }
15210       vam->async_errors = 0;
15211       after = vat_time_now (vam);
15212
15213       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15214       if (jj > 0)
15215         count = jj;
15216
15217       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15218              count, after - before, count / (after - before));
15219     }
15220   else
15221     {
15222       /* Wait for a reply... */
15223       W (ret);
15224       return ret;
15225     }
15226
15227   return ret;
15228 }
15229
15230 static void
15231 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15232 {
15233   vat_main_t *vam = &vat_main;
15234
15235   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15236          "crypto_key %U integ_alg %u integ_key %U flags %x "
15237          "tunnel_src_addr %U tunnel_dst_addr %U "
15238          "salt %u seq_outbound %lu last_seq_inbound %lu "
15239          "replay_window %lu\n",
15240          ntohl (mp->entry.sad_id),
15241          ntohl (mp->sw_if_index),
15242          ntohl (mp->entry.spi),
15243          ntohl (mp->entry.protocol),
15244          ntohl (mp->entry.crypto_algorithm),
15245          format_hex_bytes, mp->entry.crypto_key.data,
15246          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15247          format_hex_bytes, mp->entry.integrity_key.data,
15248          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15249          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15250          &mp->entry.tunnel_dst, ntohl (mp->salt),
15251          clib_net_to_host_u64 (mp->seq_outbound),
15252          clib_net_to_host_u64 (mp->last_seq_inbound),
15253          clib_net_to_host_u64 (mp->replay_window));
15254 }
15255
15256 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15257 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15258
15259 static void vl_api_ipsec_sa_details_t_handler_json
15260   (vl_api_ipsec_sa_details_t * mp)
15261 {
15262   vat_main_t *vam = &vat_main;
15263   vat_json_node_t *node = NULL;
15264   vl_api_ipsec_sad_flags_t flags;
15265
15266   if (VAT_JSON_ARRAY != vam->json_tree.type)
15267     {
15268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15269       vat_json_init_array (&vam->json_tree);
15270     }
15271   node = vat_json_array_add (&vam->json_tree);
15272
15273   vat_json_init_object (node);
15274   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15275   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15276   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15277   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15278   vat_json_object_add_uint (node, "crypto_alg",
15279                             ntohl (mp->entry.crypto_algorithm));
15280   vat_json_object_add_uint (node, "integ_alg",
15281                             ntohl (mp->entry.integrity_algorithm));
15282   flags = ntohl (mp->entry.flags);
15283   vat_json_object_add_uint (node, "use_esn",
15284                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15285   vat_json_object_add_uint (node, "use_anti_replay",
15286                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15287   vat_json_object_add_uint (node, "is_tunnel",
15288                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15289   vat_json_object_add_uint (node, "is_tunnel_ip6",
15290                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15291   vat_json_object_add_uint (node, "udp_encap",
15292                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15293   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15294                              mp->entry.crypto_key.length);
15295   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15296                              mp->entry.integrity_key.length);
15297   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15298   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15299   vat_json_object_add_uint (node, "replay_window",
15300                             clib_net_to_host_u64 (mp->replay_window));
15301 }
15302
15303 static int
15304 api_ipsec_sa_dump (vat_main_t * vam)
15305 {
15306   unformat_input_t *i = vam->input;
15307   vl_api_ipsec_sa_dump_t *mp;
15308   vl_api_control_ping_t *mp_ping;
15309   u32 sa_id = ~0;
15310   int ret;
15311
15312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15313     {
15314       if (unformat (i, "sa_id %d", &sa_id))
15315         ;
15316       else
15317         {
15318           clib_warning ("parse error '%U'", format_unformat_error, i);
15319           return -99;
15320         }
15321     }
15322
15323   M (IPSEC_SA_DUMP, mp);
15324
15325   mp->sa_id = ntohl (sa_id);
15326
15327   S (mp);
15328
15329   /* Use a control ping for synchronization */
15330   M (CONTROL_PING, mp_ping);
15331   S (mp_ping);
15332
15333   W (ret);
15334   return ret;
15335 }
15336
15337 static int
15338 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15339 {
15340   unformat_input_t *i = vam->input;
15341   vl_api_ipsec_tunnel_if_set_key_t *mp;
15342   u32 sw_if_index = ~0;
15343   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15344   u8 *key = 0;
15345   u32 alg = ~0;
15346   int ret;
15347
15348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15349     {
15350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15351         ;
15352       else
15353         if (unformat
15354             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15355         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15356       else
15357         if (unformat
15358             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15359         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15360       else
15361         if (unformat
15362             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15363         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15364       else
15365         if (unformat
15366             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15367         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15368       else if (unformat (i, "%U", unformat_hex_string, &key))
15369         ;
15370       else
15371         {
15372           clib_warning ("parse error '%U'", format_unformat_error, i);
15373           return -99;
15374         }
15375     }
15376
15377   if (sw_if_index == ~0)
15378     {
15379       errmsg ("interface must be specified");
15380       return -99;
15381     }
15382
15383   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15384     {
15385       errmsg ("key type must be specified");
15386       return -99;
15387     }
15388
15389   if (alg == ~0)
15390     {
15391       errmsg ("algorithm must be specified");
15392       return -99;
15393     }
15394
15395   if (vec_len (key) == 0)
15396     {
15397       errmsg ("key must be specified");
15398       return -99;
15399     }
15400
15401   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15402
15403   mp->sw_if_index = htonl (sw_if_index);
15404   mp->alg = alg;
15405   mp->key_type = key_type;
15406   mp->key_len = vec_len (key);
15407   clib_memcpy (mp->key, key, vec_len (key));
15408
15409   S (mp);
15410   W (ret);
15411
15412   return ret;
15413 }
15414
15415 static int
15416 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15417 {
15418   unformat_input_t *i = vam->input;
15419   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15420   u32 sw_if_index = ~0;
15421   u32 sa_id = ~0;
15422   u8 is_outbound = (u8) ~ 0;
15423   int ret;
15424
15425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15426     {
15427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15428         ;
15429       else if (unformat (i, "sa_id %d", &sa_id))
15430         ;
15431       else if (unformat (i, "outbound"))
15432         is_outbound = 1;
15433       else if (unformat (i, "inbound"))
15434         is_outbound = 0;
15435       else
15436         {
15437           clib_warning ("parse error '%U'", format_unformat_error, i);
15438           return -99;
15439         }
15440     }
15441
15442   if (sw_if_index == ~0)
15443     {
15444       errmsg ("interface must be specified");
15445       return -99;
15446     }
15447
15448   if (sa_id == ~0)
15449     {
15450       errmsg ("SA ID must be specified");
15451       return -99;
15452     }
15453
15454   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15455
15456   mp->sw_if_index = htonl (sw_if_index);
15457   mp->sa_id = htonl (sa_id);
15458   mp->is_outbound = is_outbound;
15459
15460   S (mp);
15461   W (ret);
15462
15463   return ret;
15464 }
15465
15466 static int
15467 api_get_first_msg_id (vat_main_t * vam)
15468 {
15469   vl_api_get_first_msg_id_t *mp;
15470   unformat_input_t *i = vam->input;
15471   u8 *name;
15472   u8 name_set = 0;
15473   int ret;
15474
15475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15476     {
15477       if (unformat (i, "client %s", &name))
15478         name_set = 1;
15479       else
15480         break;
15481     }
15482
15483   if (name_set == 0)
15484     {
15485       errmsg ("missing client name");
15486       return -99;
15487     }
15488   vec_add1 (name, 0);
15489
15490   if (vec_len (name) > 63)
15491     {
15492       errmsg ("client name too long");
15493       return -99;
15494     }
15495
15496   M (GET_FIRST_MSG_ID, mp);
15497   clib_memcpy (mp->name, name, vec_len (name));
15498   S (mp);
15499   W (ret);
15500   return ret;
15501 }
15502
15503 static int
15504 api_cop_interface_enable_disable (vat_main_t * vam)
15505 {
15506   unformat_input_t *line_input = vam->input;
15507   vl_api_cop_interface_enable_disable_t *mp;
15508   u32 sw_if_index = ~0;
15509   u8 enable_disable = 1;
15510   int ret;
15511
15512   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15513     {
15514       if (unformat (line_input, "disable"))
15515         enable_disable = 0;
15516       if (unformat (line_input, "enable"))
15517         enable_disable = 1;
15518       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15519                          vam, &sw_if_index))
15520         ;
15521       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15522         ;
15523       else
15524         break;
15525     }
15526
15527   if (sw_if_index == ~0)
15528     {
15529       errmsg ("missing interface name or sw_if_index");
15530       return -99;
15531     }
15532
15533   /* Construct the API message */
15534   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15535   mp->sw_if_index = ntohl (sw_if_index);
15536   mp->enable_disable = enable_disable;
15537
15538   /* send it... */
15539   S (mp);
15540   /* Wait for the reply */
15541   W (ret);
15542   return ret;
15543 }
15544
15545 static int
15546 api_cop_whitelist_enable_disable (vat_main_t * vam)
15547 {
15548   unformat_input_t *line_input = vam->input;
15549   vl_api_cop_whitelist_enable_disable_t *mp;
15550   u32 sw_if_index = ~0;
15551   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15552   u32 fib_id = 0;
15553   int ret;
15554
15555   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15556     {
15557       if (unformat (line_input, "ip4"))
15558         ip4 = 1;
15559       else if (unformat (line_input, "ip6"))
15560         ip6 = 1;
15561       else if (unformat (line_input, "default"))
15562         default_cop = 1;
15563       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15564                          vam, &sw_if_index))
15565         ;
15566       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15567         ;
15568       else if (unformat (line_input, "fib-id %d", &fib_id))
15569         ;
15570       else
15571         break;
15572     }
15573
15574   if (sw_if_index == ~0)
15575     {
15576       errmsg ("missing interface name or sw_if_index");
15577       return -99;
15578     }
15579
15580   /* Construct the API message */
15581   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15582   mp->sw_if_index = ntohl (sw_if_index);
15583   mp->fib_id = ntohl (fib_id);
15584   mp->ip4 = ip4;
15585   mp->ip6 = ip6;
15586   mp->default_cop = default_cop;
15587
15588   /* send it... */
15589   S (mp);
15590   /* Wait for the reply */
15591   W (ret);
15592   return ret;
15593 }
15594
15595 static int
15596 api_get_node_graph (vat_main_t * vam)
15597 {
15598   vl_api_get_node_graph_t *mp;
15599   int ret;
15600
15601   M (GET_NODE_GRAPH, mp);
15602
15603   /* send it... */
15604   S (mp);
15605   /* Wait for the reply */
15606   W (ret);
15607   return ret;
15608 }
15609
15610 /* *INDENT-OFF* */
15611 /** Used for parsing LISP eids */
15612 typedef CLIB_PACKED(struct{
15613   u8 addr[16];   /**< eid address */
15614   u32 len;       /**< prefix length if IP */
15615   u8 type;      /**< type of eid */
15616 }) lisp_eid_vat_t;
15617 /* *INDENT-ON* */
15618
15619 static uword
15620 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15621 {
15622   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15623
15624   clib_memset (a, 0, sizeof (a[0]));
15625
15626   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15627     {
15628       a->type = 0;              /* ipv4 type */
15629     }
15630   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15631     {
15632       a->type = 1;              /* ipv6 type */
15633     }
15634   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15635     {
15636       a->type = 2;              /* mac type */
15637     }
15638   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15639     {
15640       a->type = 3;              /* NSH type */
15641       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15642       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15643     }
15644   else
15645     {
15646       return 0;
15647     }
15648
15649   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15650     {
15651       return 0;
15652     }
15653
15654   return 1;
15655 }
15656
15657 static int
15658 lisp_eid_size_vat (u8 type)
15659 {
15660   switch (type)
15661     {
15662     case 0:
15663       return 4;
15664     case 1:
15665       return 16;
15666     case 2:
15667       return 6;
15668     case 3:
15669       return 5;
15670     }
15671   return 0;
15672 }
15673
15674 static void
15675 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15676 {
15677   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15678 }
15679
15680 static int
15681 api_one_add_del_locator_set (vat_main_t * vam)
15682 {
15683   unformat_input_t *input = vam->input;
15684   vl_api_one_add_del_locator_set_t *mp;
15685   u8 is_add = 1;
15686   u8 *locator_set_name = NULL;
15687   u8 locator_set_name_set = 0;
15688   vl_api_local_locator_t locator, *locators = 0;
15689   u32 sw_if_index, priority, weight;
15690   u32 data_len = 0;
15691
15692   int ret;
15693   /* Parse args required to build the message */
15694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15695     {
15696       if (unformat (input, "del"))
15697         {
15698           is_add = 0;
15699         }
15700       else if (unformat (input, "locator-set %s", &locator_set_name))
15701         {
15702           locator_set_name_set = 1;
15703         }
15704       else if (unformat (input, "sw_if_index %u p %u w %u",
15705                          &sw_if_index, &priority, &weight))
15706         {
15707           locator.sw_if_index = htonl (sw_if_index);
15708           locator.priority = priority;
15709           locator.weight = weight;
15710           vec_add1 (locators, locator);
15711         }
15712       else
15713         if (unformat
15714             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15715              &sw_if_index, &priority, &weight))
15716         {
15717           locator.sw_if_index = htonl (sw_if_index);
15718           locator.priority = priority;
15719           locator.weight = weight;
15720           vec_add1 (locators, locator);
15721         }
15722       else
15723         break;
15724     }
15725
15726   if (locator_set_name_set == 0)
15727     {
15728       errmsg ("missing locator-set name");
15729       vec_free (locators);
15730       return -99;
15731     }
15732
15733   if (vec_len (locator_set_name) > 64)
15734     {
15735       errmsg ("locator-set name too long");
15736       vec_free (locator_set_name);
15737       vec_free (locators);
15738       return -99;
15739     }
15740   vec_add1 (locator_set_name, 0);
15741
15742   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15743
15744   /* Construct the API message */
15745   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15746
15747   mp->is_add = is_add;
15748   clib_memcpy (mp->locator_set_name, locator_set_name,
15749                vec_len (locator_set_name));
15750   vec_free (locator_set_name);
15751
15752   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15753   if (locators)
15754     clib_memcpy (mp->locators, locators, data_len);
15755   vec_free (locators);
15756
15757   /* send it... */
15758   S (mp);
15759
15760   /* Wait for a reply... */
15761   W (ret);
15762   return ret;
15763 }
15764
15765 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15766
15767 static int
15768 api_one_add_del_locator (vat_main_t * vam)
15769 {
15770   unformat_input_t *input = vam->input;
15771   vl_api_one_add_del_locator_t *mp;
15772   u32 tmp_if_index = ~0;
15773   u32 sw_if_index = ~0;
15774   u8 sw_if_index_set = 0;
15775   u8 sw_if_index_if_name_set = 0;
15776   u32 priority = ~0;
15777   u8 priority_set = 0;
15778   u32 weight = ~0;
15779   u8 weight_set = 0;
15780   u8 is_add = 1;
15781   u8 *locator_set_name = NULL;
15782   u8 locator_set_name_set = 0;
15783   int ret;
15784
15785   /* Parse args required to build the message */
15786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15787     {
15788       if (unformat (input, "del"))
15789         {
15790           is_add = 0;
15791         }
15792       else if (unformat (input, "locator-set %s", &locator_set_name))
15793         {
15794           locator_set_name_set = 1;
15795         }
15796       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15797                          &tmp_if_index))
15798         {
15799           sw_if_index_if_name_set = 1;
15800           sw_if_index = tmp_if_index;
15801         }
15802       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15803         {
15804           sw_if_index_set = 1;
15805           sw_if_index = tmp_if_index;
15806         }
15807       else if (unformat (input, "p %d", &priority))
15808         {
15809           priority_set = 1;
15810         }
15811       else if (unformat (input, "w %d", &weight))
15812         {
15813           weight_set = 1;
15814         }
15815       else
15816         break;
15817     }
15818
15819   if (locator_set_name_set == 0)
15820     {
15821       errmsg ("missing locator-set name");
15822       return -99;
15823     }
15824
15825   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15826     {
15827       errmsg ("missing sw_if_index");
15828       vec_free (locator_set_name);
15829       return -99;
15830     }
15831
15832   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15833     {
15834       errmsg ("cannot use both params interface name and sw_if_index");
15835       vec_free (locator_set_name);
15836       return -99;
15837     }
15838
15839   if (priority_set == 0)
15840     {
15841       errmsg ("missing locator-set priority");
15842       vec_free (locator_set_name);
15843       return -99;
15844     }
15845
15846   if (weight_set == 0)
15847     {
15848       errmsg ("missing locator-set weight");
15849       vec_free (locator_set_name);
15850       return -99;
15851     }
15852
15853   if (vec_len (locator_set_name) > 64)
15854     {
15855       errmsg ("locator-set name too long");
15856       vec_free (locator_set_name);
15857       return -99;
15858     }
15859   vec_add1 (locator_set_name, 0);
15860
15861   /* Construct the API message */
15862   M (ONE_ADD_DEL_LOCATOR, mp);
15863
15864   mp->is_add = is_add;
15865   mp->sw_if_index = ntohl (sw_if_index);
15866   mp->priority = priority;
15867   mp->weight = weight;
15868   clib_memcpy (mp->locator_set_name, locator_set_name,
15869                vec_len (locator_set_name));
15870   vec_free (locator_set_name);
15871
15872   /* send it... */
15873   S (mp);
15874
15875   /* Wait for a reply... */
15876   W (ret);
15877   return ret;
15878 }
15879
15880 #define api_lisp_add_del_locator api_one_add_del_locator
15881
15882 uword
15883 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15884 {
15885   u32 *key_id = va_arg (*args, u32 *);
15886   u8 *s = 0;
15887
15888   if (unformat (input, "%s", &s))
15889     {
15890       if (!strcmp ((char *) s, "sha1"))
15891         key_id[0] = HMAC_SHA_1_96;
15892       else if (!strcmp ((char *) s, "sha256"))
15893         key_id[0] = HMAC_SHA_256_128;
15894       else
15895         {
15896           clib_warning ("invalid key_id: '%s'", s);
15897           key_id[0] = HMAC_NO_KEY;
15898         }
15899     }
15900   else
15901     return 0;
15902
15903   vec_free (s);
15904   return 1;
15905 }
15906
15907 static int
15908 api_one_add_del_local_eid (vat_main_t * vam)
15909 {
15910   unformat_input_t *input = vam->input;
15911   vl_api_one_add_del_local_eid_t *mp;
15912   u8 is_add = 1;
15913   u8 eid_set = 0;
15914   lisp_eid_vat_t _eid, *eid = &_eid;
15915   u8 *locator_set_name = 0;
15916   u8 locator_set_name_set = 0;
15917   u32 vni = 0;
15918   u16 key_id = 0;
15919   u8 *key = 0;
15920   int ret;
15921
15922   /* Parse args required to build the message */
15923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15924     {
15925       if (unformat (input, "del"))
15926         {
15927           is_add = 0;
15928         }
15929       else if (unformat (input, "vni %d", &vni))
15930         {
15931           ;
15932         }
15933       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15934         {
15935           eid_set = 1;
15936         }
15937       else if (unformat (input, "locator-set %s", &locator_set_name))
15938         {
15939           locator_set_name_set = 1;
15940         }
15941       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15942         ;
15943       else if (unformat (input, "secret-key %_%v%_", &key))
15944         ;
15945       else
15946         break;
15947     }
15948
15949   if (locator_set_name_set == 0)
15950     {
15951       errmsg ("missing locator-set name");
15952       return -99;
15953     }
15954
15955   if (0 == eid_set)
15956     {
15957       errmsg ("EID address not set!");
15958       vec_free (locator_set_name);
15959       return -99;
15960     }
15961
15962   if (key && (0 == key_id))
15963     {
15964       errmsg ("invalid key_id!");
15965       return -99;
15966     }
15967
15968   if (vec_len (key) > 64)
15969     {
15970       errmsg ("key too long");
15971       vec_free (key);
15972       return -99;
15973     }
15974
15975   if (vec_len (locator_set_name) > 64)
15976     {
15977       errmsg ("locator-set name too long");
15978       vec_free (locator_set_name);
15979       return -99;
15980     }
15981   vec_add1 (locator_set_name, 0);
15982
15983   /* Construct the API message */
15984   M (ONE_ADD_DEL_LOCAL_EID, mp);
15985
15986   mp->is_add = is_add;
15987   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15988   mp->eid_type = eid->type;
15989   mp->prefix_len = eid->len;
15990   mp->vni = clib_host_to_net_u32 (vni);
15991   mp->key_id = clib_host_to_net_u16 (key_id);
15992   clib_memcpy (mp->locator_set_name, locator_set_name,
15993                vec_len (locator_set_name));
15994   clib_memcpy (mp->key, key, vec_len (key));
15995
15996   vec_free (locator_set_name);
15997   vec_free (key);
15998
15999   /* send it... */
16000   S (mp);
16001
16002   /* Wait for a reply... */
16003   W (ret);
16004   return ret;
16005 }
16006
16007 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16008
16009 static int
16010 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16011 {
16012   u32 dp_table = 0, vni = 0;;
16013   unformat_input_t *input = vam->input;
16014   vl_api_gpe_add_del_fwd_entry_t *mp;
16015   u8 is_add = 1;
16016   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16017   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16018   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16019   u32 action = ~0, w;
16020   ip4_address_t rmt_rloc4, lcl_rloc4;
16021   ip6_address_t rmt_rloc6, lcl_rloc6;
16022   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16023   int ret;
16024
16025   clib_memset (&rloc, 0, sizeof (rloc));
16026
16027   /* Parse args required to build the message */
16028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16029     {
16030       if (unformat (input, "del"))
16031         is_add = 0;
16032       else if (unformat (input, "add"))
16033         is_add = 1;
16034       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16035         {
16036           rmt_eid_set = 1;
16037         }
16038       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16039         {
16040           lcl_eid_set = 1;
16041         }
16042       else if (unformat (input, "vrf %d", &dp_table))
16043         ;
16044       else if (unformat (input, "bd %d", &dp_table))
16045         ;
16046       else if (unformat (input, "vni %d", &vni))
16047         ;
16048       else if (unformat (input, "w %d", &w))
16049         {
16050           if (!curr_rloc)
16051             {
16052               errmsg ("No RLOC configured for setting priority/weight!");
16053               return -99;
16054             }
16055           curr_rloc->weight = w;
16056         }
16057       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16058                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16059         {
16060           rloc.is_ip4 = 1;
16061
16062           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16063           rloc.weight = 0;
16064           vec_add1 (lcl_locs, rloc);
16065
16066           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16067           vec_add1 (rmt_locs, rloc);
16068           /* weight saved in rmt loc */
16069           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16070         }
16071       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16072                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16073         {
16074           rloc.is_ip4 = 0;
16075           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16076           rloc.weight = 0;
16077           vec_add1 (lcl_locs, rloc);
16078
16079           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16080           vec_add1 (rmt_locs, rloc);
16081           /* weight saved in rmt loc */
16082           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16083         }
16084       else if (unformat (input, "action %d", &action))
16085         {
16086           ;
16087         }
16088       else
16089         {
16090           clib_warning ("parse error '%U'", format_unformat_error, input);
16091           return -99;
16092         }
16093     }
16094
16095   if (!rmt_eid_set)
16096     {
16097       errmsg ("remote eid addresses not set");
16098       return -99;
16099     }
16100
16101   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16102     {
16103       errmsg ("eid types don't match");
16104       return -99;
16105     }
16106
16107   if (0 == rmt_locs && (u32) ~ 0 == action)
16108     {
16109       errmsg ("action not set for negative mapping");
16110       return -99;
16111     }
16112
16113   /* Construct the API message */
16114   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16115       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16116
16117   mp->is_add = is_add;
16118   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16119   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16120   mp->eid_type = rmt_eid->type;
16121   mp->dp_table = clib_host_to_net_u32 (dp_table);
16122   mp->vni = clib_host_to_net_u32 (vni);
16123   mp->rmt_len = rmt_eid->len;
16124   mp->lcl_len = lcl_eid->len;
16125   mp->action = action;
16126
16127   if (0 != rmt_locs && 0 != lcl_locs)
16128     {
16129       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16130       clib_memcpy (mp->locs, lcl_locs,
16131                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16132
16133       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16134       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16135                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16136     }
16137   vec_free (lcl_locs);
16138   vec_free (rmt_locs);
16139
16140   /* send it... */
16141   S (mp);
16142
16143   /* Wait for a reply... */
16144   W (ret);
16145   return ret;
16146 }
16147
16148 static int
16149 api_one_add_del_map_server (vat_main_t * vam)
16150 {
16151   unformat_input_t *input = vam->input;
16152   vl_api_one_add_del_map_server_t *mp;
16153   u8 is_add = 1;
16154   u8 ipv4_set = 0;
16155   u8 ipv6_set = 0;
16156   ip4_address_t ipv4;
16157   ip6_address_t ipv6;
16158   int ret;
16159
16160   /* Parse args required to build the message */
16161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16162     {
16163       if (unformat (input, "del"))
16164         {
16165           is_add = 0;
16166         }
16167       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16168         {
16169           ipv4_set = 1;
16170         }
16171       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16172         {
16173           ipv6_set = 1;
16174         }
16175       else
16176         break;
16177     }
16178
16179   if (ipv4_set && ipv6_set)
16180     {
16181       errmsg ("both eid v4 and v6 addresses set");
16182       return -99;
16183     }
16184
16185   if (!ipv4_set && !ipv6_set)
16186     {
16187       errmsg ("eid addresses not set");
16188       return -99;
16189     }
16190
16191   /* Construct the API message */
16192   M (ONE_ADD_DEL_MAP_SERVER, mp);
16193
16194   mp->is_add = is_add;
16195   if (ipv6_set)
16196     {
16197       mp->is_ipv6 = 1;
16198       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16199     }
16200   else
16201     {
16202       mp->is_ipv6 = 0;
16203       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16204     }
16205
16206   /* send it... */
16207   S (mp);
16208
16209   /* Wait for a reply... */
16210   W (ret);
16211   return ret;
16212 }
16213
16214 #define api_lisp_add_del_map_server api_one_add_del_map_server
16215
16216 static int
16217 api_one_add_del_map_resolver (vat_main_t * vam)
16218 {
16219   unformat_input_t *input = vam->input;
16220   vl_api_one_add_del_map_resolver_t *mp;
16221   u8 is_add = 1;
16222   u8 ipv4_set = 0;
16223   u8 ipv6_set = 0;
16224   ip4_address_t ipv4;
16225   ip6_address_t ipv6;
16226   int ret;
16227
16228   /* Parse args required to build the message */
16229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16230     {
16231       if (unformat (input, "del"))
16232         {
16233           is_add = 0;
16234         }
16235       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16236         {
16237           ipv4_set = 1;
16238         }
16239       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16240         {
16241           ipv6_set = 1;
16242         }
16243       else
16244         break;
16245     }
16246
16247   if (ipv4_set && ipv6_set)
16248     {
16249       errmsg ("both eid v4 and v6 addresses set");
16250       return -99;
16251     }
16252
16253   if (!ipv4_set && !ipv6_set)
16254     {
16255       errmsg ("eid addresses not set");
16256       return -99;
16257     }
16258
16259   /* Construct the API message */
16260   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16261
16262   mp->is_add = is_add;
16263   if (ipv6_set)
16264     {
16265       mp->is_ipv6 = 1;
16266       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16267     }
16268   else
16269     {
16270       mp->is_ipv6 = 0;
16271       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16272     }
16273
16274   /* send it... */
16275   S (mp);
16276
16277   /* Wait for a reply... */
16278   W (ret);
16279   return ret;
16280 }
16281
16282 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16283
16284 static int
16285 api_lisp_gpe_enable_disable (vat_main_t * vam)
16286 {
16287   unformat_input_t *input = vam->input;
16288   vl_api_gpe_enable_disable_t *mp;
16289   u8 is_set = 0;
16290   u8 is_en = 1;
16291   int ret;
16292
16293   /* Parse args required to build the message */
16294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16295     {
16296       if (unformat (input, "enable"))
16297         {
16298           is_set = 1;
16299           is_en = 1;
16300         }
16301       else if (unformat (input, "disable"))
16302         {
16303           is_set = 1;
16304           is_en = 0;
16305         }
16306       else
16307         break;
16308     }
16309
16310   if (is_set == 0)
16311     {
16312       errmsg ("Value not set");
16313       return -99;
16314     }
16315
16316   /* Construct the API message */
16317   M (GPE_ENABLE_DISABLE, mp);
16318
16319   mp->is_en = is_en;
16320
16321   /* send it... */
16322   S (mp);
16323
16324   /* Wait for a reply... */
16325   W (ret);
16326   return ret;
16327 }
16328
16329 static int
16330 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16331 {
16332   unformat_input_t *input = vam->input;
16333   vl_api_one_rloc_probe_enable_disable_t *mp;
16334   u8 is_set = 0;
16335   u8 is_en = 0;
16336   int ret;
16337
16338   /* Parse args required to build the message */
16339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16340     {
16341       if (unformat (input, "enable"))
16342         {
16343           is_set = 1;
16344           is_en = 1;
16345         }
16346       else if (unformat (input, "disable"))
16347         is_set = 1;
16348       else
16349         break;
16350     }
16351
16352   if (!is_set)
16353     {
16354       errmsg ("Value not set");
16355       return -99;
16356     }
16357
16358   /* Construct the API message */
16359   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16360
16361   mp->is_enabled = is_en;
16362
16363   /* send it... */
16364   S (mp);
16365
16366   /* Wait for a reply... */
16367   W (ret);
16368   return ret;
16369 }
16370
16371 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16372
16373 static int
16374 api_one_map_register_enable_disable (vat_main_t * vam)
16375 {
16376   unformat_input_t *input = vam->input;
16377   vl_api_one_map_register_enable_disable_t *mp;
16378   u8 is_set = 0;
16379   u8 is_en = 0;
16380   int ret;
16381
16382   /* Parse args required to build the message */
16383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16384     {
16385       if (unformat (input, "enable"))
16386         {
16387           is_set = 1;
16388           is_en = 1;
16389         }
16390       else if (unformat (input, "disable"))
16391         is_set = 1;
16392       else
16393         break;
16394     }
16395
16396   if (!is_set)
16397     {
16398       errmsg ("Value not set");
16399       return -99;
16400     }
16401
16402   /* Construct the API message */
16403   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16404
16405   mp->is_enabled = is_en;
16406
16407   /* send it... */
16408   S (mp);
16409
16410   /* Wait for a reply... */
16411   W (ret);
16412   return ret;
16413 }
16414
16415 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16416
16417 static int
16418 api_one_enable_disable (vat_main_t * vam)
16419 {
16420   unformat_input_t *input = vam->input;
16421   vl_api_one_enable_disable_t *mp;
16422   u8 is_set = 0;
16423   u8 is_en = 0;
16424   int ret;
16425
16426   /* Parse args required to build the message */
16427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16428     {
16429       if (unformat (input, "enable"))
16430         {
16431           is_set = 1;
16432           is_en = 1;
16433         }
16434       else if (unformat (input, "disable"))
16435         {
16436           is_set = 1;
16437         }
16438       else
16439         break;
16440     }
16441
16442   if (!is_set)
16443     {
16444       errmsg ("Value not set");
16445       return -99;
16446     }
16447
16448   /* Construct the API message */
16449   M (ONE_ENABLE_DISABLE, mp);
16450
16451   mp->is_en = is_en;
16452
16453   /* send it... */
16454   S (mp);
16455
16456   /* Wait for a reply... */
16457   W (ret);
16458   return ret;
16459 }
16460
16461 #define api_lisp_enable_disable api_one_enable_disable
16462
16463 static int
16464 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16465 {
16466   unformat_input_t *input = vam->input;
16467   vl_api_one_enable_disable_xtr_mode_t *mp;
16468   u8 is_set = 0;
16469   u8 is_en = 0;
16470   int ret;
16471
16472   /* Parse args required to build the message */
16473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16474     {
16475       if (unformat (input, "enable"))
16476         {
16477           is_set = 1;
16478           is_en = 1;
16479         }
16480       else if (unformat (input, "disable"))
16481         {
16482           is_set = 1;
16483         }
16484       else
16485         break;
16486     }
16487
16488   if (!is_set)
16489     {
16490       errmsg ("Value not set");
16491       return -99;
16492     }
16493
16494   /* Construct the API message */
16495   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16496
16497   mp->is_en = is_en;
16498
16499   /* send it... */
16500   S (mp);
16501
16502   /* Wait for a reply... */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 static int
16508 api_one_show_xtr_mode (vat_main_t * vam)
16509 {
16510   vl_api_one_show_xtr_mode_t *mp;
16511   int ret;
16512
16513   /* Construct the API message */
16514   M (ONE_SHOW_XTR_MODE, mp);
16515
16516   /* send it... */
16517   S (mp);
16518
16519   /* Wait for a reply... */
16520   W (ret);
16521   return ret;
16522 }
16523
16524 static int
16525 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16526 {
16527   unformat_input_t *input = vam->input;
16528   vl_api_one_enable_disable_pitr_mode_t *mp;
16529   u8 is_set = 0;
16530   u8 is_en = 0;
16531   int ret;
16532
16533   /* Parse args required to build the message */
16534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16535     {
16536       if (unformat (input, "enable"))
16537         {
16538           is_set = 1;
16539           is_en = 1;
16540         }
16541       else if (unformat (input, "disable"))
16542         {
16543           is_set = 1;
16544         }
16545       else
16546         break;
16547     }
16548
16549   if (!is_set)
16550     {
16551       errmsg ("Value not set");
16552       return -99;
16553     }
16554
16555   /* Construct the API message */
16556   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16557
16558   mp->is_en = is_en;
16559
16560   /* send it... */
16561   S (mp);
16562
16563   /* Wait for a reply... */
16564   W (ret);
16565   return ret;
16566 }
16567
16568 static int
16569 api_one_show_pitr_mode (vat_main_t * vam)
16570 {
16571   vl_api_one_show_pitr_mode_t *mp;
16572   int ret;
16573
16574   /* Construct the API message */
16575   M (ONE_SHOW_PITR_MODE, mp);
16576
16577   /* send it... */
16578   S (mp);
16579
16580   /* Wait for a reply... */
16581   W (ret);
16582   return ret;
16583 }
16584
16585 static int
16586 api_one_enable_disable_petr_mode (vat_main_t * vam)
16587 {
16588   unformat_input_t *input = vam->input;
16589   vl_api_one_enable_disable_petr_mode_t *mp;
16590   u8 is_set = 0;
16591   u8 is_en = 0;
16592   int ret;
16593
16594   /* Parse args required to build the message */
16595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16596     {
16597       if (unformat (input, "enable"))
16598         {
16599           is_set = 1;
16600           is_en = 1;
16601         }
16602       else if (unformat (input, "disable"))
16603         {
16604           is_set = 1;
16605         }
16606       else
16607         break;
16608     }
16609
16610   if (!is_set)
16611     {
16612       errmsg ("Value not set");
16613       return -99;
16614     }
16615
16616   /* Construct the API message */
16617   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16618
16619   mp->is_en = is_en;
16620
16621   /* send it... */
16622   S (mp);
16623
16624   /* Wait for a reply... */
16625   W (ret);
16626   return ret;
16627 }
16628
16629 static int
16630 api_one_show_petr_mode (vat_main_t * vam)
16631 {
16632   vl_api_one_show_petr_mode_t *mp;
16633   int ret;
16634
16635   /* Construct the API message */
16636   M (ONE_SHOW_PETR_MODE, mp);
16637
16638   /* send it... */
16639   S (mp);
16640
16641   /* Wait for a reply... */
16642   W (ret);
16643   return ret;
16644 }
16645
16646 static int
16647 api_show_one_map_register_state (vat_main_t * vam)
16648 {
16649   vl_api_show_one_map_register_state_t *mp;
16650   int ret;
16651
16652   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16653
16654   /* send */
16655   S (mp);
16656
16657   /* wait for reply */
16658   W (ret);
16659   return ret;
16660 }
16661
16662 #define api_show_lisp_map_register_state api_show_one_map_register_state
16663
16664 static int
16665 api_show_one_rloc_probe_state (vat_main_t * vam)
16666 {
16667   vl_api_show_one_rloc_probe_state_t *mp;
16668   int ret;
16669
16670   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16671
16672   /* send */
16673   S (mp);
16674
16675   /* wait for reply */
16676   W (ret);
16677   return ret;
16678 }
16679
16680 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16681
16682 static int
16683 api_one_add_del_ndp_entry (vat_main_t * vam)
16684 {
16685   vl_api_one_add_del_ndp_entry_t *mp;
16686   unformat_input_t *input = vam->input;
16687   u8 is_add = 1;
16688   u8 mac_set = 0;
16689   u8 bd_set = 0;
16690   u8 ip_set = 0;
16691   u8 mac[6] = { 0, };
16692   u8 ip6[16] = { 0, };
16693   u32 bd = ~0;
16694   int ret;
16695
16696   /* Parse args required to build the message */
16697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16698     {
16699       if (unformat (input, "del"))
16700         is_add = 0;
16701       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16702         mac_set = 1;
16703       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16704         ip_set = 1;
16705       else if (unformat (input, "bd %d", &bd))
16706         bd_set = 1;
16707       else
16708         {
16709           errmsg ("parse error '%U'", format_unformat_error, input);
16710           return -99;
16711         }
16712     }
16713
16714   if (!bd_set || !ip_set || (!mac_set && is_add))
16715     {
16716       errmsg ("Missing BD, IP or MAC!");
16717       return -99;
16718     }
16719
16720   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16721   mp->is_add = is_add;
16722   clib_memcpy (mp->mac, mac, 6);
16723   mp->bd = clib_host_to_net_u32 (bd);
16724   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16725
16726   /* send */
16727   S (mp);
16728
16729   /* wait for reply */
16730   W (ret);
16731   return ret;
16732 }
16733
16734 static int
16735 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16736 {
16737   vl_api_one_add_del_l2_arp_entry_t *mp;
16738   unformat_input_t *input = vam->input;
16739   u8 is_add = 1;
16740   u8 mac_set = 0;
16741   u8 bd_set = 0;
16742   u8 ip_set = 0;
16743   u8 mac[6] = { 0, };
16744   u32 ip4 = 0, bd = ~0;
16745   int ret;
16746
16747   /* Parse args required to build the message */
16748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16749     {
16750       if (unformat (input, "del"))
16751         is_add = 0;
16752       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16753         mac_set = 1;
16754       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16755         ip_set = 1;
16756       else if (unformat (input, "bd %d", &bd))
16757         bd_set = 1;
16758       else
16759         {
16760           errmsg ("parse error '%U'", format_unformat_error, input);
16761           return -99;
16762         }
16763     }
16764
16765   if (!bd_set || !ip_set || (!mac_set && is_add))
16766     {
16767       errmsg ("Missing BD, IP or MAC!");
16768       return -99;
16769     }
16770
16771   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16772   mp->is_add = is_add;
16773   clib_memcpy (mp->mac, mac, 6);
16774   mp->bd = clib_host_to_net_u32 (bd);
16775   mp->ip4 = ip4;
16776
16777   /* send */
16778   S (mp);
16779
16780   /* wait for reply */
16781   W (ret);
16782   return ret;
16783 }
16784
16785 static int
16786 api_one_ndp_bd_get (vat_main_t * vam)
16787 {
16788   vl_api_one_ndp_bd_get_t *mp;
16789   int ret;
16790
16791   M (ONE_NDP_BD_GET, mp);
16792
16793   /* send */
16794   S (mp);
16795
16796   /* wait for reply */
16797   W (ret);
16798   return ret;
16799 }
16800
16801 static int
16802 api_one_ndp_entries_get (vat_main_t * vam)
16803 {
16804   vl_api_one_ndp_entries_get_t *mp;
16805   unformat_input_t *input = vam->input;
16806   u8 bd_set = 0;
16807   u32 bd = ~0;
16808   int ret;
16809
16810   /* Parse args required to build the message */
16811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (input, "bd %d", &bd))
16814         bd_set = 1;
16815       else
16816         {
16817           errmsg ("parse error '%U'", format_unformat_error, input);
16818           return -99;
16819         }
16820     }
16821
16822   if (!bd_set)
16823     {
16824       errmsg ("Expected bridge domain!");
16825       return -99;
16826     }
16827
16828   M (ONE_NDP_ENTRIES_GET, mp);
16829   mp->bd = clib_host_to_net_u32 (bd);
16830
16831   /* send */
16832   S (mp);
16833
16834   /* wait for reply */
16835   W (ret);
16836   return ret;
16837 }
16838
16839 static int
16840 api_one_l2_arp_bd_get (vat_main_t * vam)
16841 {
16842   vl_api_one_l2_arp_bd_get_t *mp;
16843   int ret;
16844
16845   M (ONE_L2_ARP_BD_GET, mp);
16846
16847   /* send */
16848   S (mp);
16849
16850   /* wait for reply */
16851   W (ret);
16852   return ret;
16853 }
16854
16855 static int
16856 api_one_l2_arp_entries_get (vat_main_t * vam)
16857 {
16858   vl_api_one_l2_arp_entries_get_t *mp;
16859   unformat_input_t *input = vam->input;
16860   u8 bd_set = 0;
16861   u32 bd = ~0;
16862   int ret;
16863
16864   /* Parse args required to build the message */
16865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16866     {
16867       if (unformat (input, "bd %d", &bd))
16868         bd_set = 1;
16869       else
16870         {
16871           errmsg ("parse error '%U'", format_unformat_error, input);
16872           return -99;
16873         }
16874     }
16875
16876   if (!bd_set)
16877     {
16878       errmsg ("Expected bridge domain!");
16879       return -99;
16880     }
16881
16882   M (ONE_L2_ARP_ENTRIES_GET, mp);
16883   mp->bd = clib_host_to_net_u32 (bd);
16884
16885   /* send */
16886   S (mp);
16887
16888   /* wait for reply */
16889   W (ret);
16890   return ret;
16891 }
16892
16893 static int
16894 api_one_stats_enable_disable (vat_main_t * vam)
16895 {
16896   vl_api_one_stats_enable_disable_t *mp;
16897   unformat_input_t *input = vam->input;
16898   u8 is_set = 0;
16899   u8 is_en = 0;
16900   int ret;
16901
16902   /* Parse args required to build the message */
16903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16904     {
16905       if (unformat (input, "enable"))
16906         {
16907           is_set = 1;
16908           is_en = 1;
16909         }
16910       else if (unformat (input, "disable"))
16911         {
16912           is_set = 1;
16913         }
16914       else
16915         break;
16916     }
16917
16918   if (!is_set)
16919     {
16920       errmsg ("Value not set");
16921       return -99;
16922     }
16923
16924   M (ONE_STATS_ENABLE_DISABLE, mp);
16925   mp->is_en = is_en;
16926
16927   /* send */
16928   S (mp);
16929
16930   /* wait for reply */
16931   W (ret);
16932   return ret;
16933 }
16934
16935 static int
16936 api_show_one_stats_enable_disable (vat_main_t * vam)
16937 {
16938   vl_api_show_one_stats_enable_disable_t *mp;
16939   int ret;
16940
16941   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16942
16943   /* send */
16944   S (mp);
16945
16946   /* wait for reply */
16947   W (ret);
16948   return ret;
16949 }
16950
16951 static int
16952 api_show_one_map_request_mode (vat_main_t * vam)
16953 {
16954   vl_api_show_one_map_request_mode_t *mp;
16955   int ret;
16956
16957   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16958
16959   /* send */
16960   S (mp);
16961
16962   /* wait for reply */
16963   W (ret);
16964   return ret;
16965 }
16966
16967 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16968
16969 static int
16970 api_one_map_request_mode (vat_main_t * vam)
16971 {
16972   unformat_input_t *input = vam->input;
16973   vl_api_one_map_request_mode_t *mp;
16974   u8 mode = 0;
16975   int ret;
16976
16977   /* Parse args required to build the message */
16978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16979     {
16980       if (unformat (input, "dst-only"))
16981         mode = 0;
16982       else if (unformat (input, "src-dst"))
16983         mode = 1;
16984       else
16985         {
16986           errmsg ("parse error '%U'", format_unformat_error, input);
16987           return -99;
16988         }
16989     }
16990
16991   M (ONE_MAP_REQUEST_MODE, mp);
16992
16993   mp->mode = mode;
16994
16995   /* send */
16996   S (mp);
16997
16998   /* wait for reply */
16999   W (ret);
17000   return ret;
17001 }
17002
17003 #define api_lisp_map_request_mode api_one_map_request_mode
17004
17005 /**
17006  * Enable/disable ONE proxy ITR.
17007  *
17008  * @param vam vpp API test context
17009  * @return return code
17010  */
17011 static int
17012 api_one_pitr_set_locator_set (vat_main_t * vam)
17013 {
17014   u8 ls_name_set = 0;
17015   unformat_input_t *input = vam->input;
17016   vl_api_one_pitr_set_locator_set_t *mp;
17017   u8 is_add = 1;
17018   u8 *ls_name = 0;
17019   int ret;
17020
17021   /* Parse args required to build the message */
17022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17023     {
17024       if (unformat (input, "del"))
17025         is_add = 0;
17026       else if (unformat (input, "locator-set %s", &ls_name))
17027         ls_name_set = 1;
17028       else
17029         {
17030           errmsg ("parse error '%U'", format_unformat_error, input);
17031           return -99;
17032         }
17033     }
17034
17035   if (!ls_name_set)
17036     {
17037       errmsg ("locator-set name not set!");
17038       return -99;
17039     }
17040
17041   M (ONE_PITR_SET_LOCATOR_SET, mp);
17042
17043   mp->is_add = is_add;
17044   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17045   vec_free (ls_name);
17046
17047   /* send */
17048   S (mp);
17049
17050   /* wait for reply */
17051   W (ret);
17052   return ret;
17053 }
17054
17055 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17056
17057 static int
17058 api_one_nsh_set_locator_set (vat_main_t * vam)
17059 {
17060   u8 ls_name_set = 0;
17061   unformat_input_t *input = vam->input;
17062   vl_api_one_nsh_set_locator_set_t *mp;
17063   u8 is_add = 1;
17064   u8 *ls_name = 0;
17065   int ret;
17066
17067   /* Parse args required to build the message */
17068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17069     {
17070       if (unformat (input, "del"))
17071         is_add = 0;
17072       else if (unformat (input, "ls %s", &ls_name))
17073         ls_name_set = 1;
17074       else
17075         {
17076           errmsg ("parse error '%U'", format_unformat_error, input);
17077           return -99;
17078         }
17079     }
17080
17081   if (!ls_name_set && is_add)
17082     {
17083       errmsg ("locator-set name not set!");
17084       return -99;
17085     }
17086
17087   M (ONE_NSH_SET_LOCATOR_SET, mp);
17088
17089   mp->is_add = is_add;
17090   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17091   vec_free (ls_name);
17092
17093   /* send */
17094   S (mp);
17095
17096   /* wait for reply */
17097   W (ret);
17098   return ret;
17099 }
17100
17101 static int
17102 api_show_one_pitr (vat_main_t * vam)
17103 {
17104   vl_api_show_one_pitr_t *mp;
17105   int ret;
17106
17107   if (!vam->json_output)
17108     {
17109       print (vam->ofp, "%=20s", "lisp status:");
17110     }
17111
17112   M (SHOW_ONE_PITR, mp);
17113   /* send it... */
17114   S (mp);
17115
17116   /* Wait for a reply... */
17117   W (ret);
17118   return ret;
17119 }
17120
17121 #define api_show_lisp_pitr api_show_one_pitr
17122
17123 static int
17124 api_one_use_petr (vat_main_t * vam)
17125 {
17126   unformat_input_t *input = vam->input;
17127   vl_api_one_use_petr_t *mp;
17128   u8 is_add = 0;
17129   ip_address_t ip;
17130   int ret;
17131
17132   clib_memset (&ip, 0, sizeof (ip));
17133
17134   /* Parse args required to build the message */
17135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17136     {
17137       if (unformat (input, "disable"))
17138         is_add = 0;
17139       else
17140         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17141         {
17142           is_add = 1;
17143           ip_addr_version (&ip) = IP4;
17144         }
17145       else
17146         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17147         {
17148           is_add = 1;
17149           ip_addr_version (&ip) = IP6;
17150         }
17151       else
17152         {
17153           errmsg ("parse error '%U'", format_unformat_error, input);
17154           return -99;
17155         }
17156     }
17157
17158   M (ONE_USE_PETR, mp);
17159
17160   mp->is_add = is_add;
17161   if (is_add)
17162     {
17163       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17164       if (mp->is_ip4)
17165         clib_memcpy (mp->address, &ip, 4);
17166       else
17167         clib_memcpy (mp->address, &ip, 16);
17168     }
17169
17170   /* send */
17171   S (mp);
17172
17173   /* wait for reply */
17174   W (ret);
17175   return ret;
17176 }
17177
17178 #define api_lisp_use_petr api_one_use_petr
17179
17180 static int
17181 api_show_one_nsh_mapping (vat_main_t * vam)
17182 {
17183   vl_api_show_one_use_petr_t *mp;
17184   int ret;
17185
17186   if (!vam->json_output)
17187     {
17188       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17189     }
17190
17191   M (SHOW_ONE_NSH_MAPPING, mp);
17192   /* send it... */
17193   S (mp);
17194
17195   /* Wait for a reply... */
17196   W (ret);
17197   return ret;
17198 }
17199
17200 static int
17201 api_show_one_use_petr (vat_main_t * vam)
17202 {
17203   vl_api_show_one_use_petr_t *mp;
17204   int ret;
17205
17206   if (!vam->json_output)
17207     {
17208       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17209     }
17210
17211   M (SHOW_ONE_USE_PETR, mp);
17212   /* send it... */
17213   S (mp);
17214
17215   /* Wait for a reply... */
17216   W (ret);
17217   return ret;
17218 }
17219
17220 #define api_show_lisp_use_petr api_show_one_use_petr
17221
17222 /**
17223  * Add/delete mapping between vni and vrf
17224  */
17225 static int
17226 api_one_eid_table_add_del_map (vat_main_t * vam)
17227 {
17228   unformat_input_t *input = vam->input;
17229   vl_api_one_eid_table_add_del_map_t *mp;
17230   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17231   u32 vni, vrf, bd_index;
17232   int ret;
17233
17234   /* Parse args required to build the message */
17235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17236     {
17237       if (unformat (input, "del"))
17238         is_add = 0;
17239       else if (unformat (input, "vrf %d", &vrf))
17240         vrf_set = 1;
17241       else if (unformat (input, "bd_index %d", &bd_index))
17242         bd_index_set = 1;
17243       else if (unformat (input, "vni %d", &vni))
17244         vni_set = 1;
17245       else
17246         break;
17247     }
17248
17249   if (!vni_set || (!vrf_set && !bd_index_set))
17250     {
17251       errmsg ("missing arguments!");
17252       return -99;
17253     }
17254
17255   if (vrf_set && bd_index_set)
17256     {
17257       errmsg ("error: both vrf and bd entered!");
17258       return -99;
17259     }
17260
17261   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17262
17263   mp->is_add = is_add;
17264   mp->vni = htonl (vni);
17265   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17266   mp->is_l2 = bd_index_set;
17267
17268   /* send */
17269   S (mp);
17270
17271   /* wait for reply */
17272   W (ret);
17273   return ret;
17274 }
17275
17276 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17277
17278 uword
17279 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17280 {
17281   u32 *action = va_arg (*args, u32 *);
17282   u8 *s = 0;
17283
17284   if (unformat (input, "%s", &s))
17285     {
17286       if (!strcmp ((char *) s, "no-action"))
17287         action[0] = 0;
17288       else if (!strcmp ((char *) s, "natively-forward"))
17289         action[0] = 1;
17290       else if (!strcmp ((char *) s, "send-map-request"))
17291         action[0] = 2;
17292       else if (!strcmp ((char *) s, "drop"))
17293         action[0] = 3;
17294       else
17295         {
17296           clib_warning ("invalid action: '%s'", s);
17297           action[0] = 3;
17298         }
17299     }
17300   else
17301     return 0;
17302
17303   vec_free (s);
17304   return 1;
17305 }
17306
17307 /**
17308  * Add/del remote mapping to/from ONE control plane
17309  *
17310  * @param vam vpp API test context
17311  * @return return code
17312  */
17313 static int
17314 api_one_add_del_remote_mapping (vat_main_t * vam)
17315 {
17316   unformat_input_t *input = vam->input;
17317   vl_api_one_add_del_remote_mapping_t *mp;
17318   u32 vni = 0;
17319   lisp_eid_vat_t _eid, *eid = &_eid;
17320   lisp_eid_vat_t _seid, *seid = &_seid;
17321   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17322   u32 action = ~0, p, w, data_len;
17323   ip4_address_t rloc4;
17324   ip6_address_t rloc6;
17325   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17326   int ret;
17327
17328   clib_memset (&rloc, 0, sizeof (rloc));
17329
17330   /* Parse args required to build the message */
17331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17332     {
17333       if (unformat (input, "del-all"))
17334         {
17335           del_all = 1;
17336         }
17337       else if (unformat (input, "del"))
17338         {
17339           is_add = 0;
17340         }
17341       else if (unformat (input, "add"))
17342         {
17343           is_add = 1;
17344         }
17345       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17346         {
17347           eid_set = 1;
17348         }
17349       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17350         {
17351           seid_set = 1;
17352         }
17353       else if (unformat (input, "vni %d", &vni))
17354         {
17355           ;
17356         }
17357       else if (unformat (input, "p %d w %d", &p, &w))
17358         {
17359           if (!curr_rloc)
17360             {
17361               errmsg ("No RLOC configured for setting priority/weight!");
17362               return -99;
17363             }
17364           curr_rloc->priority = p;
17365           curr_rloc->weight = w;
17366         }
17367       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17368         {
17369           rloc.is_ip4 = 1;
17370           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17371           vec_add1 (rlocs, rloc);
17372           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17373         }
17374       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17375         {
17376           rloc.is_ip4 = 0;
17377           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17378           vec_add1 (rlocs, rloc);
17379           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17380         }
17381       else if (unformat (input, "action %U",
17382                          unformat_negative_mapping_action, &action))
17383         {
17384           ;
17385         }
17386       else
17387         {
17388           clib_warning ("parse error '%U'", format_unformat_error, input);
17389           return -99;
17390         }
17391     }
17392
17393   if (0 == eid_set)
17394     {
17395       errmsg ("missing params!");
17396       return -99;
17397     }
17398
17399   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17400     {
17401       errmsg ("no action set for negative map-reply!");
17402       return -99;
17403     }
17404
17405   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17406
17407   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17408   mp->is_add = is_add;
17409   mp->vni = htonl (vni);
17410   mp->action = (u8) action;
17411   mp->is_src_dst = seid_set;
17412   mp->eid_len = eid->len;
17413   mp->seid_len = seid->len;
17414   mp->del_all = del_all;
17415   mp->eid_type = eid->type;
17416   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17417   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17418
17419   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17420   clib_memcpy (mp->rlocs, rlocs, data_len);
17421   vec_free (rlocs);
17422
17423   /* send it... */
17424   S (mp);
17425
17426   /* Wait for a reply... */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17432
17433 /**
17434  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17435  * forwarding entries in data-plane accordingly.
17436  *
17437  * @param vam vpp API test context
17438  * @return return code
17439  */
17440 static int
17441 api_one_add_del_adjacency (vat_main_t * vam)
17442 {
17443   unformat_input_t *input = vam->input;
17444   vl_api_one_add_del_adjacency_t *mp;
17445   u32 vni = 0;
17446   ip4_address_t leid4, reid4;
17447   ip6_address_t leid6, reid6;
17448   u8 reid_mac[6] = { 0 };
17449   u8 leid_mac[6] = { 0 };
17450   u8 reid_type, leid_type;
17451   u32 leid_len = 0, reid_len = 0, len;
17452   u8 is_add = 1;
17453   int ret;
17454
17455   leid_type = reid_type = (u8) ~ 0;
17456
17457   /* Parse args required to build the message */
17458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17459     {
17460       if (unformat (input, "del"))
17461         {
17462           is_add = 0;
17463         }
17464       else if (unformat (input, "add"))
17465         {
17466           is_add = 1;
17467         }
17468       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17469                          &reid4, &len))
17470         {
17471           reid_type = 0;        /* ipv4 */
17472           reid_len = len;
17473         }
17474       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17475                          &reid6, &len))
17476         {
17477           reid_type = 1;        /* ipv6 */
17478           reid_len = len;
17479         }
17480       else if (unformat (input, "reid %U", unformat_ethernet_address,
17481                          reid_mac))
17482         {
17483           reid_type = 2;        /* mac */
17484         }
17485       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17486                          &leid4, &len))
17487         {
17488           leid_type = 0;        /* ipv4 */
17489           leid_len = len;
17490         }
17491       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17492                          &leid6, &len))
17493         {
17494           leid_type = 1;        /* ipv6 */
17495           leid_len = len;
17496         }
17497       else if (unformat (input, "leid %U", unformat_ethernet_address,
17498                          leid_mac))
17499         {
17500           leid_type = 2;        /* mac */
17501         }
17502       else if (unformat (input, "vni %d", &vni))
17503         {
17504           ;
17505         }
17506       else
17507         {
17508           errmsg ("parse error '%U'", format_unformat_error, input);
17509           return -99;
17510         }
17511     }
17512
17513   if ((u8) ~ 0 == reid_type)
17514     {
17515       errmsg ("missing params!");
17516       return -99;
17517     }
17518
17519   if (leid_type != reid_type)
17520     {
17521       errmsg ("remote and local EIDs are of different types!");
17522       return -99;
17523     }
17524
17525   M (ONE_ADD_DEL_ADJACENCY, mp);
17526   mp->is_add = is_add;
17527   mp->vni = htonl (vni);
17528   mp->leid_len = leid_len;
17529   mp->reid_len = reid_len;
17530   mp->eid_type = reid_type;
17531
17532   switch (mp->eid_type)
17533     {
17534     case 0:
17535       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17536       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17537       break;
17538     case 1:
17539       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17540       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17541       break;
17542     case 2:
17543       clib_memcpy (mp->leid, leid_mac, 6);
17544       clib_memcpy (mp->reid, reid_mac, 6);
17545       break;
17546     default:
17547       errmsg ("unknown EID type %d!", mp->eid_type);
17548       return 0;
17549     }
17550
17551   /* send it... */
17552   S (mp);
17553
17554   /* Wait for a reply... */
17555   W (ret);
17556   return ret;
17557 }
17558
17559 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17560
17561 uword
17562 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17563 {
17564   u32 *mode = va_arg (*args, u32 *);
17565
17566   if (unformat (input, "lisp"))
17567     *mode = 0;
17568   else if (unformat (input, "vxlan"))
17569     *mode = 1;
17570   else
17571     return 0;
17572
17573   return 1;
17574 }
17575
17576 static int
17577 api_gpe_get_encap_mode (vat_main_t * vam)
17578 {
17579   vl_api_gpe_get_encap_mode_t *mp;
17580   int ret;
17581
17582   /* Construct the API message */
17583   M (GPE_GET_ENCAP_MODE, mp);
17584
17585   /* send it... */
17586   S (mp);
17587
17588   /* Wait for a reply... */
17589   W (ret);
17590   return ret;
17591 }
17592
17593 static int
17594 api_gpe_set_encap_mode (vat_main_t * vam)
17595 {
17596   unformat_input_t *input = vam->input;
17597   vl_api_gpe_set_encap_mode_t *mp;
17598   int ret;
17599   u32 mode = 0;
17600
17601   /* Parse args required to build the message */
17602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17603     {
17604       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17605         ;
17606       else
17607         break;
17608     }
17609
17610   /* Construct the API message */
17611   M (GPE_SET_ENCAP_MODE, mp);
17612
17613   mp->mode = mode;
17614
17615   /* send it... */
17616   S (mp);
17617
17618   /* Wait for a reply... */
17619   W (ret);
17620   return ret;
17621 }
17622
17623 static int
17624 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17625 {
17626   unformat_input_t *input = vam->input;
17627   vl_api_gpe_add_del_iface_t *mp;
17628   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17629   u32 dp_table = 0, vni = 0;
17630   int ret;
17631
17632   /* Parse args required to build the message */
17633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17634     {
17635       if (unformat (input, "up"))
17636         {
17637           action_set = 1;
17638           is_add = 1;
17639         }
17640       else if (unformat (input, "down"))
17641         {
17642           action_set = 1;
17643           is_add = 0;
17644         }
17645       else if (unformat (input, "table_id %d", &dp_table))
17646         {
17647           dp_table_set = 1;
17648         }
17649       else if (unformat (input, "bd_id %d", &dp_table))
17650         {
17651           dp_table_set = 1;
17652           is_l2 = 1;
17653         }
17654       else if (unformat (input, "vni %d", &vni))
17655         {
17656           vni_set = 1;
17657         }
17658       else
17659         break;
17660     }
17661
17662   if (action_set == 0)
17663     {
17664       errmsg ("Action not set");
17665       return -99;
17666     }
17667   if (dp_table_set == 0 || vni_set == 0)
17668     {
17669       errmsg ("vni and dp_table must be set");
17670       return -99;
17671     }
17672
17673   /* Construct the API message */
17674   M (GPE_ADD_DEL_IFACE, mp);
17675
17676   mp->is_add = is_add;
17677   mp->dp_table = clib_host_to_net_u32 (dp_table);
17678   mp->is_l2 = is_l2;
17679   mp->vni = clib_host_to_net_u32 (vni);
17680
17681   /* send it... */
17682   S (mp);
17683
17684   /* Wait for a reply... */
17685   W (ret);
17686   return ret;
17687 }
17688
17689 static int
17690 api_one_map_register_fallback_threshold (vat_main_t * vam)
17691 {
17692   unformat_input_t *input = vam->input;
17693   vl_api_one_map_register_fallback_threshold_t *mp;
17694   u32 value = 0;
17695   u8 is_set = 0;
17696   int ret;
17697
17698   /* Parse args required to build the message */
17699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17700     {
17701       if (unformat (input, "%u", &value))
17702         is_set = 1;
17703       else
17704         {
17705           clib_warning ("parse error '%U'", format_unformat_error, input);
17706           return -99;
17707         }
17708     }
17709
17710   if (!is_set)
17711     {
17712       errmsg ("fallback threshold value is missing!");
17713       return -99;
17714     }
17715
17716   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17717   mp->value = clib_host_to_net_u32 (value);
17718
17719   /* send it... */
17720   S (mp);
17721
17722   /* Wait for a reply... */
17723   W (ret);
17724   return ret;
17725 }
17726
17727 static int
17728 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17729 {
17730   vl_api_show_one_map_register_fallback_threshold_t *mp;
17731   int ret;
17732
17733   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17734
17735   /* send it... */
17736   S (mp);
17737
17738   /* Wait for a reply... */
17739   W (ret);
17740   return ret;
17741 }
17742
17743 uword
17744 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17745 {
17746   u32 *proto = va_arg (*args, u32 *);
17747
17748   if (unformat (input, "udp"))
17749     *proto = 1;
17750   else if (unformat (input, "api"))
17751     *proto = 2;
17752   else
17753     return 0;
17754
17755   return 1;
17756 }
17757
17758 static int
17759 api_one_set_transport_protocol (vat_main_t * vam)
17760 {
17761   unformat_input_t *input = vam->input;
17762   vl_api_one_set_transport_protocol_t *mp;
17763   u8 is_set = 0;
17764   u32 protocol = 0;
17765   int ret;
17766
17767   /* Parse args required to build the message */
17768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17769     {
17770       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17771         is_set = 1;
17772       else
17773         {
17774           clib_warning ("parse error '%U'", format_unformat_error, input);
17775           return -99;
17776         }
17777     }
17778
17779   if (!is_set)
17780     {
17781       errmsg ("Transport protocol missing!");
17782       return -99;
17783     }
17784
17785   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17786   mp->protocol = (u8) protocol;
17787
17788   /* send it... */
17789   S (mp);
17790
17791   /* Wait for a reply... */
17792   W (ret);
17793   return ret;
17794 }
17795
17796 static int
17797 api_one_get_transport_protocol (vat_main_t * vam)
17798 {
17799   vl_api_one_get_transport_protocol_t *mp;
17800   int ret;
17801
17802   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17803
17804   /* send it... */
17805   S (mp);
17806
17807   /* Wait for a reply... */
17808   W (ret);
17809   return ret;
17810 }
17811
17812 static int
17813 api_one_map_register_set_ttl (vat_main_t * vam)
17814 {
17815   unformat_input_t *input = vam->input;
17816   vl_api_one_map_register_set_ttl_t *mp;
17817   u32 ttl = 0;
17818   u8 is_set = 0;
17819   int ret;
17820
17821   /* Parse args required to build the message */
17822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17823     {
17824       if (unformat (input, "%u", &ttl))
17825         is_set = 1;
17826       else
17827         {
17828           clib_warning ("parse error '%U'", format_unformat_error, input);
17829           return -99;
17830         }
17831     }
17832
17833   if (!is_set)
17834     {
17835       errmsg ("TTL value missing!");
17836       return -99;
17837     }
17838
17839   M (ONE_MAP_REGISTER_SET_TTL, mp);
17840   mp->ttl = clib_host_to_net_u32 (ttl);
17841
17842   /* send it... */
17843   S (mp);
17844
17845   /* Wait for a reply... */
17846   W (ret);
17847   return ret;
17848 }
17849
17850 static int
17851 api_show_one_map_register_ttl (vat_main_t * vam)
17852 {
17853   vl_api_show_one_map_register_ttl_t *mp;
17854   int ret;
17855
17856   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17857
17858   /* send it... */
17859   S (mp);
17860
17861   /* Wait for a reply... */
17862   W (ret);
17863   return ret;
17864 }
17865
17866 /**
17867  * Add/del map request itr rlocs from ONE control plane and updates
17868  *
17869  * @param vam vpp API test context
17870  * @return return code
17871  */
17872 static int
17873 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17874 {
17875   unformat_input_t *input = vam->input;
17876   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17877   u8 *locator_set_name = 0;
17878   u8 locator_set_name_set = 0;
17879   u8 is_add = 1;
17880   int ret;
17881
17882   /* Parse args required to build the message */
17883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17884     {
17885       if (unformat (input, "del"))
17886         {
17887           is_add = 0;
17888         }
17889       else if (unformat (input, "%_%v%_", &locator_set_name))
17890         {
17891           locator_set_name_set = 1;
17892         }
17893       else
17894         {
17895           clib_warning ("parse error '%U'", format_unformat_error, input);
17896           return -99;
17897         }
17898     }
17899
17900   if (is_add && !locator_set_name_set)
17901     {
17902       errmsg ("itr-rloc is not set!");
17903       return -99;
17904     }
17905
17906   if (is_add && vec_len (locator_set_name) > 64)
17907     {
17908       errmsg ("itr-rloc locator-set name too long");
17909       vec_free (locator_set_name);
17910       return -99;
17911     }
17912
17913   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17914   mp->is_add = is_add;
17915   if (is_add)
17916     {
17917       clib_memcpy (mp->locator_set_name, locator_set_name,
17918                    vec_len (locator_set_name));
17919     }
17920   else
17921     {
17922       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17923     }
17924   vec_free (locator_set_name);
17925
17926   /* send it... */
17927   S (mp);
17928
17929   /* Wait for a reply... */
17930   W (ret);
17931   return ret;
17932 }
17933
17934 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17935
17936 static int
17937 api_one_locator_dump (vat_main_t * vam)
17938 {
17939   unformat_input_t *input = vam->input;
17940   vl_api_one_locator_dump_t *mp;
17941   vl_api_control_ping_t *mp_ping;
17942   u8 is_index_set = 0, is_name_set = 0;
17943   u8 *ls_name = 0;
17944   u32 ls_index = ~0;
17945   int ret;
17946
17947   /* Parse args required to build the message */
17948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17949     {
17950       if (unformat (input, "ls_name %_%v%_", &ls_name))
17951         {
17952           is_name_set = 1;
17953         }
17954       else if (unformat (input, "ls_index %d", &ls_index))
17955         {
17956           is_index_set = 1;
17957         }
17958       else
17959         {
17960           errmsg ("parse error '%U'", format_unformat_error, input);
17961           return -99;
17962         }
17963     }
17964
17965   if (!is_index_set && !is_name_set)
17966     {
17967       errmsg ("error: expected one of index or name!");
17968       return -99;
17969     }
17970
17971   if (is_index_set && is_name_set)
17972     {
17973       errmsg ("error: only one param expected!");
17974       return -99;
17975     }
17976
17977   if (vec_len (ls_name) > 62)
17978     {
17979       errmsg ("error: locator set name too long!");
17980       return -99;
17981     }
17982
17983   if (!vam->json_output)
17984     {
17985       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17986     }
17987
17988   M (ONE_LOCATOR_DUMP, mp);
17989   mp->is_index_set = is_index_set;
17990
17991   if (is_index_set)
17992     mp->ls_index = clib_host_to_net_u32 (ls_index);
17993   else
17994     {
17995       vec_add1 (ls_name, 0);
17996       strncpy ((char *) mp->ls_name, (char *) ls_name,
17997                sizeof (mp->ls_name) - 1);
17998     }
17999
18000   /* send it... */
18001   S (mp);
18002
18003   /* Use a control ping for synchronization */
18004   MPING (CONTROL_PING, mp_ping);
18005   S (mp_ping);
18006
18007   /* Wait for a reply... */
18008   W (ret);
18009   return ret;
18010 }
18011
18012 #define api_lisp_locator_dump api_one_locator_dump
18013
18014 static int
18015 api_one_locator_set_dump (vat_main_t * vam)
18016 {
18017   vl_api_one_locator_set_dump_t *mp;
18018   vl_api_control_ping_t *mp_ping;
18019   unformat_input_t *input = vam->input;
18020   u8 filter = 0;
18021   int ret;
18022
18023   /* Parse args required to build the message */
18024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18025     {
18026       if (unformat (input, "local"))
18027         {
18028           filter = 1;
18029         }
18030       else if (unformat (input, "remote"))
18031         {
18032           filter = 2;
18033         }
18034       else
18035         {
18036           errmsg ("parse error '%U'", format_unformat_error, input);
18037           return -99;
18038         }
18039     }
18040
18041   if (!vam->json_output)
18042     {
18043       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18044     }
18045
18046   M (ONE_LOCATOR_SET_DUMP, mp);
18047
18048   mp->filter = filter;
18049
18050   /* send it... */
18051   S (mp);
18052
18053   /* Use a control ping for synchronization */
18054   MPING (CONTROL_PING, mp_ping);
18055   S (mp_ping);
18056
18057   /* Wait for a reply... */
18058   W (ret);
18059   return ret;
18060 }
18061
18062 #define api_lisp_locator_set_dump api_one_locator_set_dump
18063
18064 static int
18065 api_one_eid_table_map_dump (vat_main_t * vam)
18066 {
18067   u8 is_l2 = 0;
18068   u8 mode_set = 0;
18069   unformat_input_t *input = vam->input;
18070   vl_api_one_eid_table_map_dump_t *mp;
18071   vl_api_control_ping_t *mp_ping;
18072   int ret;
18073
18074   /* Parse args required to build the message */
18075   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18076     {
18077       if (unformat (input, "l2"))
18078         {
18079           is_l2 = 1;
18080           mode_set = 1;
18081         }
18082       else if (unformat (input, "l3"))
18083         {
18084           is_l2 = 0;
18085           mode_set = 1;
18086         }
18087       else
18088         {
18089           errmsg ("parse error '%U'", format_unformat_error, input);
18090           return -99;
18091         }
18092     }
18093
18094   if (!mode_set)
18095     {
18096       errmsg ("expected one of 'l2' or 'l3' parameter!");
18097       return -99;
18098     }
18099
18100   if (!vam->json_output)
18101     {
18102       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18103     }
18104
18105   M (ONE_EID_TABLE_MAP_DUMP, mp);
18106   mp->is_l2 = is_l2;
18107
18108   /* send it... */
18109   S (mp);
18110
18111   /* Use a control ping for synchronization */
18112   MPING (CONTROL_PING, mp_ping);
18113   S (mp_ping);
18114
18115   /* Wait for a reply... */
18116   W (ret);
18117   return ret;
18118 }
18119
18120 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18121
18122 static int
18123 api_one_eid_table_vni_dump (vat_main_t * vam)
18124 {
18125   vl_api_one_eid_table_vni_dump_t *mp;
18126   vl_api_control_ping_t *mp_ping;
18127   int ret;
18128
18129   if (!vam->json_output)
18130     {
18131       print (vam->ofp, "VNI");
18132     }
18133
18134   M (ONE_EID_TABLE_VNI_DUMP, mp);
18135
18136   /* send it... */
18137   S (mp);
18138
18139   /* Use a control ping for synchronization */
18140   MPING (CONTROL_PING, mp_ping);
18141   S (mp_ping);
18142
18143   /* Wait for a reply... */
18144   W (ret);
18145   return ret;
18146 }
18147
18148 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18149
18150 static int
18151 api_one_eid_table_dump (vat_main_t * vam)
18152 {
18153   unformat_input_t *i = vam->input;
18154   vl_api_one_eid_table_dump_t *mp;
18155   vl_api_control_ping_t *mp_ping;
18156   struct in_addr ip4;
18157   struct in6_addr ip6;
18158   u8 mac[6];
18159   u8 eid_type = ~0, eid_set = 0;
18160   u32 prefix_length = ~0, t, vni = 0;
18161   u8 filter = 0;
18162   int ret;
18163   lisp_nsh_api_t nsh;
18164
18165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18166     {
18167       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18168         {
18169           eid_set = 1;
18170           eid_type = 0;
18171           prefix_length = t;
18172         }
18173       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18174         {
18175           eid_set = 1;
18176           eid_type = 1;
18177           prefix_length = t;
18178         }
18179       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18180         {
18181           eid_set = 1;
18182           eid_type = 2;
18183         }
18184       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18185         {
18186           eid_set = 1;
18187           eid_type = 3;
18188         }
18189       else if (unformat (i, "vni %d", &t))
18190         {
18191           vni = t;
18192         }
18193       else if (unformat (i, "local"))
18194         {
18195           filter = 1;
18196         }
18197       else if (unformat (i, "remote"))
18198         {
18199           filter = 2;
18200         }
18201       else
18202         {
18203           errmsg ("parse error '%U'", format_unformat_error, i);
18204           return -99;
18205         }
18206     }
18207
18208   if (!vam->json_output)
18209     {
18210       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18211              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18212     }
18213
18214   M (ONE_EID_TABLE_DUMP, mp);
18215
18216   mp->filter = filter;
18217   if (eid_set)
18218     {
18219       mp->eid_set = 1;
18220       mp->vni = htonl (vni);
18221       mp->eid_type = eid_type;
18222       switch (eid_type)
18223         {
18224         case 0:
18225           mp->prefix_length = prefix_length;
18226           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18227           break;
18228         case 1:
18229           mp->prefix_length = prefix_length;
18230           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18231           break;
18232         case 2:
18233           clib_memcpy (mp->eid, mac, sizeof (mac));
18234           break;
18235         case 3:
18236           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18237           break;
18238         default:
18239           errmsg ("unknown EID type %d!", eid_type);
18240           return -99;
18241         }
18242     }
18243
18244   /* send it... */
18245   S (mp);
18246
18247   /* Use a control ping for synchronization */
18248   MPING (CONTROL_PING, mp_ping);
18249   S (mp_ping);
18250
18251   /* Wait for a reply... */
18252   W (ret);
18253   return ret;
18254 }
18255
18256 #define api_lisp_eid_table_dump api_one_eid_table_dump
18257
18258 static int
18259 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18260 {
18261   unformat_input_t *i = vam->input;
18262   vl_api_gpe_fwd_entries_get_t *mp;
18263   u8 vni_set = 0;
18264   u32 vni = ~0;
18265   int ret;
18266
18267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18268     {
18269       if (unformat (i, "vni %d", &vni))
18270         {
18271           vni_set = 1;
18272         }
18273       else
18274         {
18275           errmsg ("parse error '%U'", format_unformat_error, i);
18276           return -99;
18277         }
18278     }
18279
18280   if (!vni_set)
18281     {
18282       errmsg ("vni not set!");
18283       return -99;
18284     }
18285
18286   if (!vam->json_output)
18287     {
18288       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18289              "leid", "reid");
18290     }
18291
18292   M (GPE_FWD_ENTRIES_GET, mp);
18293   mp->vni = clib_host_to_net_u32 (vni);
18294
18295   /* send it... */
18296   S (mp);
18297
18298   /* Wait for a reply... */
18299   W (ret);
18300   return ret;
18301 }
18302
18303 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18304 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18305 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18306 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18307 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18308 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18309 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18310 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18311
18312 static int
18313 api_one_adjacencies_get (vat_main_t * vam)
18314 {
18315   unformat_input_t *i = vam->input;
18316   vl_api_one_adjacencies_get_t *mp;
18317   u8 vni_set = 0;
18318   u32 vni = ~0;
18319   int ret;
18320
18321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18322     {
18323       if (unformat (i, "vni %d", &vni))
18324         {
18325           vni_set = 1;
18326         }
18327       else
18328         {
18329           errmsg ("parse error '%U'", format_unformat_error, i);
18330           return -99;
18331         }
18332     }
18333
18334   if (!vni_set)
18335     {
18336       errmsg ("vni not set!");
18337       return -99;
18338     }
18339
18340   if (!vam->json_output)
18341     {
18342       print (vam->ofp, "%s %40s", "leid", "reid");
18343     }
18344
18345   M (ONE_ADJACENCIES_GET, mp);
18346   mp->vni = clib_host_to_net_u32 (vni);
18347
18348   /* send it... */
18349   S (mp);
18350
18351   /* Wait for a reply... */
18352   W (ret);
18353   return ret;
18354 }
18355
18356 #define api_lisp_adjacencies_get api_one_adjacencies_get
18357
18358 static int
18359 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18360 {
18361   unformat_input_t *i = vam->input;
18362   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18363   int ret;
18364   u8 ip_family_set = 0, is_ip4 = 1;
18365
18366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18367     {
18368       if (unformat (i, "ip4"))
18369         {
18370           ip_family_set = 1;
18371           is_ip4 = 1;
18372         }
18373       else if (unformat (i, "ip6"))
18374         {
18375           ip_family_set = 1;
18376           is_ip4 = 0;
18377         }
18378       else
18379         {
18380           errmsg ("parse error '%U'", format_unformat_error, i);
18381           return -99;
18382         }
18383     }
18384
18385   if (!ip_family_set)
18386     {
18387       errmsg ("ip family not set!");
18388       return -99;
18389     }
18390
18391   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18392   mp->is_ip4 = is_ip4;
18393
18394   /* send it... */
18395   S (mp);
18396
18397   /* Wait for a reply... */
18398   W (ret);
18399   return ret;
18400 }
18401
18402 static int
18403 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18404 {
18405   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18406   int ret;
18407
18408   if (!vam->json_output)
18409     {
18410       print (vam->ofp, "VNIs");
18411     }
18412
18413   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18414
18415   /* send it... */
18416   S (mp);
18417
18418   /* Wait for a reply... */
18419   W (ret);
18420   return ret;
18421 }
18422
18423 static int
18424 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18425 {
18426   unformat_input_t *i = vam->input;
18427   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18428   int ret = 0;
18429   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18430   struct in_addr ip4;
18431   struct in6_addr ip6;
18432   u32 table_id = 0, nh_sw_if_index = ~0;
18433
18434   clib_memset (&ip4, 0, sizeof (ip4));
18435   clib_memset (&ip6, 0, sizeof (ip6));
18436
18437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18438     {
18439       if (unformat (i, "del"))
18440         is_add = 0;
18441       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18442                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18443         {
18444           ip_set = 1;
18445           is_ip4 = 1;
18446         }
18447       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18448                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18449         {
18450           ip_set = 1;
18451           is_ip4 = 0;
18452         }
18453       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18454         {
18455           ip_set = 1;
18456           is_ip4 = 1;
18457           nh_sw_if_index = ~0;
18458         }
18459       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18460         {
18461           ip_set = 1;
18462           is_ip4 = 0;
18463           nh_sw_if_index = ~0;
18464         }
18465       else if (unformat (i, "table %d", &table_id))
18466         ;
18467       else
18468         {
18469           errmsg ("parse error '%U'", format_unformat_error, i);
18470           return -99;
18471         }
18472     }
18473
18474   if (!ip_set)
18475     {
18476       errmsg ("nh addr not set!");
18477       return -99;
18478     }
18479
18480   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18481   mp->is_add = is_add;
18482   mp->table_id = clib_host_to_net_u32 (table_id);
18483   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18484   mp->is_ip4 = is_ip4;
18485   if (is_ip4)
18486     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18487   else
18488     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18489
18490   /* send it... */
18491   S (mp);
18492
18493   /* Wait for a reply... */
18494   W (ret);
18495   return ret;
18496 }
18497
18498 static int
18499 api_one_map_server_dump (vat_main_t * vam)
18500 {
18501   vl_api_one_map_server_dump_t *mp;
18502   vl_api_control_ping_t *mp_ping;
18503   int ret;
18504
18505   if (!vam->json_output)
18506     {
18507       print (vam->ofp, "%=20s", "Map server");
18508     }
18509
18510   M (ONE_MAP_SERVER_DUMP, mp);
18511   /* send it... */
18512   S (mp);
18513
18514   /* Use a control ping for synchronization */
18515   MPING (CONTROL_PING, mp_ping);
18516   S (mp_ping);
18517
18518   /* Wait for a reply... */
18519   W (ret);
18520   return ret;
18521 }
18522
18523 #define api_lisp_map_server_dump api_one_map_server_dump
18524
18525 static int
18526 api_one_map_resolver_dump (vat_main_t * vam)
18527 {
18528   vl_api_one_map_resolver_dump_t *mp;
18529   vl_api_control_ping_t *mp_ping;
18530   int ret;
18531
18532   if (!vam->json_output)
18533     {
18534       print (vam->ofp, "%=20s", "Map resolver");
18535     }
18536
18537   M (ONE_MAP_RESOLVER_DUMP, mp);
18538   /* send it... */
18539   S (mp);
18540
18541   /* Use a control ping for synchronization */
18542   MPING (CONTROL_PING, mp_ping);
18543   S (mp_ping);
18544
18545   /* Wait for a reply... */
18546   W (ret);
18547   return ret;
18548 }
18549
18550 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18551
18552 static int
18553 api_one_stats_flush (vat_main_t * vam)
18554 {
18555   vl_api_one_stats_flush_t *mp;
18556   int ret = 0;
18557
18558   M (ONE_STATS_FLUSH, mp);
18559   S (mp);
18560   W (ret);
18561   return ret;
18562 }
18563
18564 static int
18565 api_one_stats_dump (vat_main_t * vam)
18566 {
18567   vl_api_one_stats_dump_t *mp;
18568   vl_api_control_ping_t *mp_ping;
18569   int ret;
18570
18571   M (ONE_STATS_DUMP, mp);
18572   /* send it... */
18573   S (mp);
18574
18575   /* Use a control ping for synchronization */
18576   MPING (CONTROL_PING, mp_ping);
18577   S (mp_ping);
18578
18579   /* Wait for a reply... */
18580   W (ret);
18581   return ret;
18582 }
18583
18584 static int
18585 api_show_one_status (vat_main_t * vam)
18586 {
18587   vl_api_show_one_status_t *mp;
18588   int ret;
18589
18590   if (!vam->json_output)
18591     {
18592       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18593     }
18594
18595   M (SHOW_ONE_STATUS, mp);
18596   /* send it... */
18597   S (mp);
18598   /* Wait for a reply... */
18599   W (ret);
18600   return ret;
18601 }
18602
18603 #define api_show_lisp_status api_show_one_status
18604
18605 static int
18606 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18607 {
18608   vl_api_gpe_fwd_entry_path_dump_t *mp;
18609   vl_api_control_ping_t *mp_ping;
18610   unformat_input_t *i = vam->input;
18611   u32 fwd_entry_index = ~0;
18612   int ret;
18613
18614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18615     {
18616       if (unformat (i, "index %d", &fwd_entry_index))
18617         ;
18618       else
18619         break;
18620     }
18621
18622   if (~0 == fwd_entry_index)
18623     {
18624       errmsg ("no index specified!");
18625       return -99;
18626     }
18627
18628   if (!vam->json_output)
18629     {
18630       print (vam->ofp, "first line");
18631     }
18632
18633   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18634
18635   /* send it... */
18636   S (mp);
18637   /* Use a control ping for synchronization */
18638   MPING (CONTROL_PING, mp_ping);
18639   S (mp_ping);
18640
18641   /* Wait for a reply... */
18642   W (ret);
18643   return ret;
18644 }
18645
18646 static int
18647 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18648 {
18649   vl_api_one_get_map_request_itr_rlocs_t *mp;
18650   int ret;
18651
18652   if (!vam->json_output)
18653     {
18654       print (vam->ofp, "%=20s", "itr-rlocs:");
18655     }
18656
18657   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18658   /* send it... */
18659   S (mp);
18660   /* Wait for a reply... */
18661   W (ret);
18662   return ret;
18663 }
18664
18665 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18666
18667 static int
18668 api_af_packet_create (vat_main_t * vam)
18669 {
18670   unformat_input_t *i = vam->input;
18671   vl_api_af_packet_create_t *mp;
18672   u8 *host_if_name = 0;
18673   u8 hw_addr[6];
18674   u8 random_hw_addr = 1;
18675   int ret;
18676
18677   clib_memset (hw_addr, 0, sizeof (hw_addr));
18678
18679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18680     {
18681       if (unformat (i, "name %s", &host_if_name))
18682         vec_add1 (host_if_name, 0);
18683       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18684         random_hw_addr = 0;
18685       else
18686         break;
18687     }
18688
18689   if (!vec_len (host_if_name))
18690     {
18691       errmsg ("host-interface name must be specified");
18692       return -99;
18693     }
18694
18695   if (vec_len (host_if_name) > 64)
18696     {
18697       errmsg ("host-interface name too long");
18698       return -99;
18699     }
18700
18701   M (AF_PACKET_CREATE, mp);
18702
18703   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18704   clib_memcpy (mp->hw_addr, hw_addr, 6);
18705   mp->use_random_hw_addr = random_hw_addr;
18706   vec_free (host_if_name);
18707
18708   S (mp);
18709
18710   /* *INDENT-OFF* */
18711   W2 (ret,
18712       ({
18713         if (ret == 0)
18714           fprintf (vam->ofp ? vam->ofp : stderr,
18715                    " new sw_if_index = %d\n", vam->sw_if_index);
18716       }));
18717   /* *INDENT-ON* */
18718   return ret;
18719 }
18720
18721 static int
18722 api_af_packet_delete (vat_main_t * vam)
18723 {
18724   unformat_input_t *i = vam->input;
18725   vl_api_af_packet_delete_t *mp;
18726   u8 *host_if_name = 0;
18727   int ret;
18728
18729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18730     {
18731       if (unformat (i, "name %s", &host_if_name))
18732         vec_add1 (host_if_name, 0);
18733       else
18734         break;
18735     }
18736
18737   if (!vec_len (host_if_name))
18738     {
18739       errmsg ("host-interface name must be specified");
18740       return -99;
18741     }
18742
18743   if (vec_len (host_if_name) > 64)
18744     {
18745       errmsg ("host-interface name too long");
18746       return -99;
18747     }
18748
18749   M (AF_PACKET_DELETE, mp);
18750
18751   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18752   vec_free (host_if_name);
18753
18754   S (mp);
18755   W (ret);
18756   return ret;
18757 }
18758
18759 static void vl_api_af_packet_details_t_handler
18760   (vl_api_af_packet_details_t * mp)
18761 {
18762   vat_main_t *vam = &vat_main;
18763
18764   print (vam->ofp, "%-16s %d",
18765          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18766 }
18767
18768 static void vl_api_af_packet_details_t_handler_json
18769   (vl_api_af_packet_details_t * mp)
18770 {
18771   vat_main_t *vam = &vat_main;
18772   vat_json_node_t *node = NULL;
18773
18774   if (VAT_JSON_ARRAY != vam->json_tree.type)
18775     {
18776       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18777       vat_json_init_array (&vam->json_tree);
18778     }
18779   node = vat_json_array_add (&vam->json_tree);
18780
18781   vat_json_init_object (node);
18782   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18783   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18784 }
18785
18786 static int
18787 api_af_packet_dump (vat_main_t * vam)
18788 {
18789   vl_api_af_packet_dump_t *mp;
18790   vl_api_control_ping_t *mp_ping;
18791   int ret;
18792
18793   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18794   /* Get list of tap interfaces */
18795   M (AF_PACKET_DUMP, mp);
18796   S (mp);
18797
18798   /* Use a control ping for synchronization */
18799   MPING (CONTROL_PING, mp_ping);
18800   S (mp_ping);
18801
18802   W (ret);
18803   return ret;
18804 }
18805
18806 static int
18807 api_policer_add_del (vat_main_t * vam)
18808 {
18809   unformat_input_t *i = vam->input;
18810   vl_api_policer_add_del_t *mp;
18811   u8 is_add = 1;
18812   u8 *name = 0;
18813   u32 cir = 0;
18814   u32 eir = 0;
18815   u64 cb = 0;
18816   u64 eb = 0;
18817   u8 rate_type = 0;
18818   u8 round_type = 0;
18819   u8 type = 0;
18820   u8 color_aware = 0;
18821   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18822   int ret;
18823
18824   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18825   conform_action.dscp = 0;
18826   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18827   exceed_action.dscp = 0;
18828   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18829   violate_action.dscp = 0;
18830
18831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18832     {
18833       if (unformat (i, "del"))
18834         is_add = 0;
18835       else if (unformat (i, "name %s", &name))
18836         vec_add1 (name, 0);
18837       else if (unformat (i, "cir %u", &cir))
18838         ;
18839       else if (unformat (i, "eir %u", &eir))
18840         ;
18841       else if (unformat (i, "cb %u", &cb))
18842         ;
18843       else if (unformat (i, "eb %u", &eb))
18844         ;
18845       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18846                          &rate_type))
18847         ;
18848       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18849                          &round_type))
18850         ;
18851       else if (unformat (i, "type %U", unformat_policer_type, &type))
18852         ;
18853       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18854                          &conform_action))
18855         ;
18856       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18857                          &exceed_action))
18858         ;
18859       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18860                          &violate_action))
18861         ;
18862       else if (unformat (i, "color-aware"))
18863         color_aware = 1;
18864       else
18865         break;
18866     }
18867
18868   if (!vec_len (name))
18869     {
18870       errmsg ("policer name must be specified");
18871       return -99;
18872     }
18873
18874   if (vec_len (name) > 64)
18875     {
18876       errmsg ("policer name too long");
18877       return -99;
18878     }
18879
18880   M (POLICER_ADD_DEL, mp);
18881
18882   clib_memcpy (mp->name, name, vec_len (name));
18883   vec_free (name);
18884   mp->is_add = is_add;
18885   mp->cir = ntohl (cir);
18886   mp->eir = ntohl (eir);
18887   mp->cb = clib_net_to_host_u64 (cb);
18888   mp->eb = clib_net_to_host_u64 (eb);
18889   mp->rate_type = rate_type;
18890   mp->round_type = round_type;
18891   mp->type = type;
18892   mp->conform_action_type = conform_action.action_type;
18893   mp->conform_dscp = conform_action.dscp;
18894   mp->exceed_action_type = exceed_action.action_type;
18895   mp->exceed_dscp = exceed_action.dscp;
18896   mp->violate_action_type = violate_action.action_type;
18897   mp->violate_dscp = violate_action.dscp;
18898   mp->color_aware = color_aware;
18899
18900   S (mp);
18901   W (ret);
18902   return ret;
18903 }
18904
18905 static int
18906 api_policer_dump (vat_main_t * vam)
18907 {
18908   unformat_input_t *i = vam->input;
18909   vl_api_policer_dump_t *mp;
18910   vl_api_control_ping_t *mp_ping;
18911   u8 *match_name = 0;
18912   u8 match_name_valid = 0;
18913   int ret;
18914
18915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18916     {
18917       if (unformat (i, "name %s", &match_name))
18918         {
18919           vec_add1 (match_name, 0);
18920           match_name_valid = 1;
18921         }
18922       else
18923         break;
18924     }
18925
18926   M (POLICER_DUMP, mp);
18927   mp->match_name_valid = match_name_valid;
18928   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18929   vec_free (match_name);
18930   /* send it... */
18931   S (mp);
18932
18933   /* Use a control ping for synchronization */
18934   MPING (CONTROL_PING, mp_ping);
18935   S (mp_ping);
18936
18937   /* Wait for a reply... */
18938   W (ret);
18939   return ret;
18940 }
18941
18942 static int
18943 api_policer_classify_set_interface (vat_main_t * vam)
18944 {
18945   unformat_input_t *i = vam->input;
18946   vl_api_policer_classify_set_interface_t *mp;
18947   u32 sw_if_index;
18948   int sw_if_index_set;
18949   u32 ip4_table_index = ~0;
18950   u32 ip6_table_index = ~0;
18951   u32 l2_table_index = ~0;
18952   u8 is_add = 1;
18953   int ret;
18954
18955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18956     {
18957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18958         sw_if_index_set = 1;
18959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18960         sw_if_index_set = 1;
18961       else if (unformat (i, "del"))
18962         is_add = 0;
18963       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18964         ;
18965       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18966         ;
18967       else if (unformat (i, "l2-table %d", &l2_table_index))
18968         ;
18969       else
18970         {
18971           clib_warning ("parse error '%U'", format_unformat_error, i);
18972           return -99;
18973         }
18974     }
18975
18976   if (sw_if_index_set == 0)
18977     {
18978       errmsg ("missing interface name or sw_if_index");
18979       return -99;
18980     }
18981
18982   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18983
18984   mp->sw_if_index = ntohl (sw_if_index);
18985   mp->ip4_table_index = ntohl (ip4_table_index);
18986   mp->ip6_table_index = ntohl (ip6_table_index);
18987   mp->l2_table_index = ntohl (l2_table_index);
18988   mp->is_add = is_add;
18989
18990   S (mp);
18991   W (ret);
18992   return ret;
18993 }
18994
18995 static int
18996 api_policer_classify_dump (vat_main_t * vam)
18997 {
18998   unformat_input_t *i = vam->input;
18999   vl_api_policer_classify_dump_t *mp;
19000   vl_api_control_ping_t *mp_ping;
19001   u8 type = POLICER_CLASSIFY_N_TABLES;
19002   int ret;
19003
19004   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19005     ;
19006   else
19007     {
19008       errmsg ("classify table type must be specified");
19009       return -99;
19010     }
19011
19012   if (!vam->json_output)
19013     {
19014       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19015     }
19016
19017   M (POLICER_CLASSIFY_DUMP, mp);
19018   mp->type = type;
19019   /* send it... */
19020   S (mp);
19021
19022   /* Use a control ping for synchronization */
19023   MPING (CONTROL_PING, mp_ping);
19024   S (mp_ping);
19025
19026   /* Wait for a reply... */
19027   W (ret);
19028   return ret;
19029 }
19030
19031 static int
19032 api_netmap_create (vat_main_t * vam)
19033 {
19034   unformat_input_t *i = vam->input;
19035   vl_api_netmap_create_t *mp;
19036   u8 *if_name = 0;
19037   u8 hw_addr[6];
19038   u8 random_hw_addr = 1;
19039   u8 is_pipe = 0;
19040   u8 is_master = 0;
19041   int ret;
19042
19043   clib_memset (hw_addr, 0, sizeof (hw_addr));
19044
19045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19046     {
19047       if (unformat (i, "name %s", &if_name))
19048         vec_add1 (if_name, 0);
19049       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19050         random_hw_addr = 0;
19051       else if (unformat (i, "pipe"))
19052         is_pipe = 1;
19053       else if (unformat (i, "master"))
19054         is_master = 1;
19055       else if (unformat (i, "slave"))
19056         is_master = 0;
19057       else
19058         break;
19059     }
19060
19061   if (!vec_len (if_name))
19062     {
19063       errmsg ("interface name must be specified");
19064       return -99;
19065     }
19066
19067   if (vec_len (if_name) > 64)
19068     {
19069       errmsg ("interface name too long");
19070       return -99;
19071     }
19072
19073   M (NETMAP_CREATE, mp);
19074
19075   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19076   clib_memcpy (mp->hw_addr, hw_addr, 6);
19077   mp->use_random_hw_addr = random_hw_addr;
19078   mp->is_pipe = is_pipe;
19079   mp->is_master = is_master;
19080   vec_free (if_name);
19081
19082   S (mp);
19083   W (ret);
19084   return ret;
19085 }
19086
19087 static int
19088 api_netmap_delete (vat_main_t * vam)
19089 {
19090   unformat_input_t *i = vam->input;
19091   vl_api_netmap_delete_t *mp;
19092   u8 *if_name = 0;
19093   int ret;
19094
19095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19096     {
19097       if (unformat (i, "name %s", &if_name))
19098         vec_add1 (if_name, 0);
19099       else
19100         break;
19101     }
19102
19103   if (!vec_len (if_name))
19104     {
19105       errmsg ("interface name must be specified");
19106       return -99;
19107     }
19108
19109   if (vec_len (if_name) > 64)
19110     {
19111       errmsg ("interface name too long");
19112       return -99;
19113     }
19114
19115   M (NETMAP_DELETE, mp);
19116
19117   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19118   vec_free (if_name);
19119
19120   S (mp);
19121   W (ret);
19122   return ret;
19123 }
19124
19125 static void
19126 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19127 {
19128   if (fp->afi == IP46_TYPE_IP6)
19129     print (vam->ofp,
19130            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19131            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19132            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19133            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19134            format_ip6_address, fp->next_hop);
19135   else if (fp->afi == IP46_TYPE_IP4)
19136     print (vam->ofp,
19137            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19138            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19139            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19140            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19141            format_ip4_address, fp->next_hop);
19142 }
19143
19144 static void
19145 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19146                                  vl_api_fib_path_t * fp)
19147 {
19148   struct in_addr ip4;
19149   struct in6_addr ip6;
19150
19151   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19152   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19153   vat_json_object_add_uint (node, "is_local", fp->is_local);
19154   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19155   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19156   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19157   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19158   if (fp->afi == IP46_TYPE_IP4)
19159     {
19160       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19161       vat_json_object_add_ip4 (node, "next_hop", ip4);
19162     }
19163   else if (fp->afi == IP46_TYPE_IP6)
19164     {
19165       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19166       vat_json_object_add_ip6 (node, "next_hop", ip6);
19167     }
19168 }
19169
19170 static void
19171 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19172 {
19173   vat_main_t *vam = &vat_main;
19174   int count = ntohl (mp->mt_count);
19175   vl_api_fib_path_t *fp;
19176   i32 i;
19177
19178   print (vam->ofp, "[%d]: sw_if_index %d via:",
19179          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19180   fp = mp->mt_paths;
19181   for (i = 0; i < count; i++)
19182     {
19183       vl_api_mpls_fib_path_print (vam, fp);
19184       fp++;
19185     }
19186
19187   print (vam->ofp, "");
19188 }
19189
19190 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19191 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19192
19193 static void
19194 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19195 {
19196   vat_main_t *vam = &vat_main;
19197   vat_json_node_t *node = NULL;
19198   int count = ntohl (mp->mt_count);
19199   vl_api_fib_path_t *fp;
19200   i32 i;
19201
19202   if (VAT_JSON_ARRAY != vam->json_tree.type)
19203     {
19204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19205       vat_json_init_array (&vam->json_tree);
19206     }
19207   node = vat_json_array_add (&vam->json_tree);
19208
19209   vat_json_init_object (node);
19210   vat_json_object_add_uint (node, "tunnel_index",
19211                             ntohl (mp->mt_tunnel_index));
19212   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19213
19214   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19215
19216   fp = mp->mt_paths;
19217   for (i = 0; i < count; i++)
19218     {
19219       vl_api_mpls_fib_path_json_print (node, fp);
19220       fp++;
19221     }
19222 }
19223
19224 static int
19225 api_mpls_tunnel_dump (vat_main_t * vam)
19226 {
19227   vl_api_mpls_tunnel_dump_t *mp;
19228   vl_api_control_ping_t *mp_ping;
19229   u32 sw_if_index = ~0;
19230   int ret;
19231
19232   /* Parse args required to build the message */
19233   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19234     {
19235       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19236         ;
19237     }
19238
19239   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19240
19241   M (MPLS_TUNNEL_DUMP, mp);
19242   mp->sw_if_index = htonl (sw_if_index);
19243   S (mp);
19244
19245   /* Use a control ping for synchronization */
19246   MPING (CONTROL_PING, mp_ping);
19247   S (mp_ping);
19248
19249   W (ret);
19250   return ret;
19251 }
19252
19253 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19254 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19255
19256
19257 static void
19258 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19259 {
19260   vat_main_t *vam = &vat_main;
19261   int count = ntohl (mp->count);
19262   vl_api_fib_path_t *fp;
19263   int i;
19264
19265   print (vam->ofp,
19266          "table-id %d, label %u, ess_bit %u",
19267          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19268   fp = mp->path;
19269   for (i = 0; i < count; i++)
19270     {
19271       vl_api_mpls_fib_path_print (vam, fp);
19272       fp++;
19273     }
19274 }
19275
19276 static void vl_api_mpls_fib_details_t_handler_json
19277   (vl_api_mpls_fib_details_t * mp)
19278 {
19279   vat_main_t *vam = &vat_main;
19280   int count = ntohl (mp->count);
19281   vat_json_node_t *node = NULL;
19282   vl_api_fib_path_t *fp;
19283   int i;
19284
19285   if (VAT_JSON_ARRAY != vam->json_tree.type)
19286     {
19287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19288       vat_json_init_array (&vam->json_tree);
19289     }
19290   node = vat_json_array_add (&vam->json_tree);
19291
19292   vat_json_init_object (node);
19293   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19294   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19295   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19296   vat_json_object_add_uint (node, "path_count", count);
19297   fp = mp->path;
19298   for (i = 0; i < count; i++)
19299     {
19300       vl_api_mpls_fib_path_json_print (node, fp);
19301       fp++;
19302     }
19303 }
19304
19305 static int
19306 api_mpls_fib_dump (vat_main_t * vam)
19307 {
19308   vl_api_mpls_fib_dump_t *mp;
19309   vl_api_control_ping_t *mp_ping;
19310   int ret;
19311
19312   M (MPLS_FIB_DUMP, mp);
19313   S (mp);
19314
19315   /* Use a control ping for synchronization */
19316   MPING (CONTROL_PING, mp_ping);
19317   S (mp_ping);
19318
19319   W (ret);
19320   return ret;
19321 }
19322
19323 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19324 #define vl_api_ip_fib_details_t_print vl_noop_handler
19325
19326 static void
19327 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19328 {
19329   vat_main_t *vam = &vat_main;
19330   int count = ntohl (mp->count);
19331   vl_api_fib_path_t *fp;
19332   int i;
19333
19334   print (vam->ofp,
19335          "table-id %d, prefix %U/%d stats-index %d",
19336          ntohl (mp->table_id), format_ip4_address, mp->address,
19337          mp->address_length, ntohl (mp->stats_index));
19338   fp = mp->path;
19339   for (i = 0; i < count; i++)
19340     {
19341       if (fp->afi == IP46_TYPE_IP6)
19342         print (vam->ofp,
19343                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19344                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19345                "next_hop_table %d",
19346                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19347                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19348                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19349       else if (fp->afi == IP46_TYPE_IP4)
19350         print (vam->ofp,
19351                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19352                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19353                "next_hop_table %d",
19354                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19355                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19356                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19357       fp++;
19358     }
19359 }
19360
19361 static void vl_api_ip_fib_details_t_handler_json
19362   (vl_api_ip_fib_details_t * mp)
19363 {
19364   vat_main_t *vam = &vat_main;
19365   int count = ntohl (mp->count);
19366   vat_json_node_t *node = NULL;
19367   struct in_addr ip4;
19368   struct in6_addr ip6;
19369   vl_api_fib_path_t *fp;
19370   int i;
19371
19372   if (VAT_JSON_ARRAY != vam->json_tree.type)
19373     {
19374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19375       vat_json_init_array (&vam->json_tree);
19376     }
19377   node = vat_json_array_add (&vam->json_tree);
19378
19379   vat_json_init_object (node);
19380   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19381   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19382   vat_json_object_add_ip4 (node, "prefix", ip4);
19383   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19384   vat_json_object_add_uint (node, "path_count", count);
19385   fp = mp->path;
19386   for (i = 0; i < count; i++)
19387     {
19388       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19389       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19390       vat_json_object_add_uint (node, "is_local", fp->is_local);
19391       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19392       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19393       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19394       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19395       if (fp->afi == IP46_TYPE_IP4)
19396         {
19397           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19398           vat_json_object_add_ip4 (node, "next_hop", ip4);
19399         }
19400       else if (fp->afi == IP46_TYPE_IP6)
19401         {
19402           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19403           vat_json_object_add_ip6 (node, "next_hop", ip6);
19404         }
19405     }
19406 }
19407
19408 static int
19409 api_ip_fib_dump (vat_main_t * vam)
19410 {
19411   vl_api_ip_fib_dump_t *mp;
19412   vl_api_control_ping_t *mp_ping;
19413   int ret;
19414
19415   M (IP_FIB_DUMP, mp);
19416   S (mp);
19417
19418   /* Use a control ping for synchronization */
19419   MPING (CONTROL_PING, mp_ping);
19420   S (mp_ping);
19421
19422   W (ret);
19423   return ret;
19424 }
19425
19426 static int
19427 api_ip_mfib_dump (vat_main_t * vam)
19428 {
19429   vl_api_ip_mfib_dump_t *mp;
19430   vl_api_control_ping_t *mp_ping;
19431   int ret;
19432
19433   M (IP_MFIB_DUMP, mp);
19434   S (mp);
19435
19436   /* Use a control ping for synchronization */
19437   MPING (CONTROL_PING, mp_ping);
19438   S (mp_ping);
19439
19440   W (ret);
19441   return ret;
19442 }
19443
19444 static void vl_api_ip_neighbor_details_t_handler
19445   (vl_api_ip_neighbor_details_t * mp)
19446 {
19447   vat_main_t *vam = &vat_main;
19448
19449   print (vam->ofp, "%c %U %U",
19450          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19451          format_vl_api_mac_address, &mp->neighbor.mac_address,
19452          format_vl_api_address, &mp->neighbor.ip_address);
19453 }
19454
19455 static void vl_api_ip_neighbor_details_t_handler_json
19456   (vl_api_ip_neighbor_details_t * mp)
19457 {
19458
19459   vat_main_t *vam = &vat_main;
19460   vat_json_node_t *node;
19461
19462   if (VAT_JSON_ARRAY != vam->json_tree.type)
19463     {
19464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19465       vat_json_init_array (&vam->json_tree);
19466     }
19467   node = vat_json_array_add (&vam->json_tree);
19468
19469   vat_json_init_object (node);
19470   vat_json_object_add_string_copy
19471     (node, "flag",
19472      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19473       (u8 *) "static" : (u8 *) "dynamic"));
19474
19475   vat_json_object_add_string_copy (node, "link_layer",
19476                                    format (0, "%U", format_vl_api_mac_address,
19477                                            &mp->neighbor.mac_address));
19478   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19479 }
19480
19481 static int
19482 api_ip_neighbor_dump (vat_main_t * vam)
19483 {
19484   unformat_input_t *i = vam->input;
19485   vl_api_ip_neighbor_dump_t *mp;
19486   vl_api_control_ping_t *mp_ping;
19487   u8 is_ipv6 = 0;
19488   u32 sw_if_index = ~0;
19489   int ret;
19490
19491   /* Parse args required to build the message */
19492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19493     {
19494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19495         ;
19496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19497         ;
19498       else if (unformat (i, "ip6"))
19499         is_ipv6 = 1;
19500       else
19501         break;
19502     }
19503
19504   if (sw_if_index == ~0)
19505     {
19506       errmsg ("missing interface name or sw_if_index");
19507       return -99;
19508     }
19509
19510   M (IP_NEIGHBOR_DUMP, mp);
19511   mp->is_ipv6 = (u8) is_ipv6;
19512   mp->sw_if_index = ntohl (sw_if_index);
19513   S (mp);
19514
19515   /* Use a control ping for synchronization */
19516   MPING (CONTROL_PING, mp_ping);
19517   S (mp_ping);
19518
19519   W (ret);
19520   return ret;
19521 }
19522
19523 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19524 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19525
19526 static void
19527 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19528 {
19529   vat_main_t *vam = &vat_main;
19530   int count = ntohl (mp->count);
19531   vl_api_fib_path_t *fp;
19532   int i;
19533
19534   print (vam->ofp,
19535          "table-id %d, prefix %U/%d stats-index %d",
19536          ntohl (mp->table_id), format_ip6_address, mp->address,
19537          mp->address_length, ntohl (mp->stats_index));
19538   fp = mp->path;
19539   for (i = 0; i < count; i++)
19540     {
19541       if (fp->afi == IP46_TYPE_IP6)
19542         print (vam->ofp,
19543                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19544                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19545                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19546                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19547                format_ip6_address, fp->next_hop);
19548       else if (fp->afi == IP46_TYPE_IP4)
19549         print (vam->ofp,
19550                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19551                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19552                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19553                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19554                format_ip4_address, fp->next_hop);
19555       fp++;
19556     }
19557 }
19558
19559 static void vl_api_ip6_fib_details_t_handler_json
19560   (vl_api_ip6_fib_details_t * mp)
19561 {
19562   vat_main_t *vam = &vat_main;
19563   int count = ntohl (mp->count);
19564   vat_json_node_t *node = NULL;
19565   struct in_addr ip4;
19566   struct in6_addr ip6;
19567   vl_api_fib_path_t *fp;
19568   int i;
19569
19570   if (VAT_JSON_ARRAY != vam->json_tree.type)
19571     {
19572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19573       vat_json_init_array (&vam->json_tree);
19574     }
19575   node = vat_json_array_add (&vam->json_tree);
19576
19577   vat_json_init_object (node);
19578   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19579   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19580   vat_json_object_add_ip6 (node, "prefix", ip6);
19581   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19582   vat_json_object_add_uint (node, "path_count", count);
19583   fp = mp->path;
19584   for (i = 0; i < count; i++)
19585     {
19586       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19587       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19588       vat_json_object_add_uint (node, "is_local", fp->is_local);
19589       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19590       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19591       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19592       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19593       if (fp->afi == IP46_TYPE_IP4)
19594         {
19595           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19596           vat_json_object_add_ip4 (node, "next_hop", ip4);
19597         }
19598       else if (fp->afi == IP46_TYPE_IP6)
19599         {
19600           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19601           vat_json_object_add_ip6 (node, "next_hop", ip6);
19602         }
19603     }
19604 }
19605
19606 static int
19607 api_ip6_fib_dump (vat_main_t * vam)
19608 {
19609   vl_api_ip6_fib_dump_t *mp;
19610   vl_api_control_ping_t *mp_ping;
19611   int ret;
19612
19613   M (IP6_FIB_DUMP, mp);
19614   S (mp);
19615
19616   /* Use a control ping for synchronization */
19617   MPING (CONTROL_PING, mp_ping);
19618   S (mp_ping);
19619
19620   W (ret);
19621   return ret;
19622 }
19623
19624 static int
19625 api_ip6_mfib_dump (vat_main_t * vam)
19626 {
19627   vl_api_ip6_mfib_dump_t *mp;
19628   vl_api_control_ping_t *mp_ping;
19629   int ret;
19630
19631   M (IP6_MFIB_DUMP, mp);
19632   S (mp);
19633
19634   /* Use a control ping for synchronization */
19635   MPING (CONTROL_PING, mp_ping);
19636   S (mp_ping);
19637
19638   W (ret);
19639   return ret;
19640 }
19641
19642 int
19643 api_classify_table_ids (vat_main_t * vam)
19644 {
19645   vl_api_classify_table_ids_t *mp;
19646   int ret;
19647
19648   /* Construct the API message */
19649   M (CLASSIFY_TABLE_IDS, mp);
19650   mp->context = 0;
19651
19652   S (mp);
19653   W (ret);
19654   return ret;
19655 }
19656
19657 int
19658 api_classify_table_by_interface (vat_main_t * vam)
19659 {
19660   unformat_input_t *input = vam->input;
19661   vl_api_classify_table_by_interface_t *mp;
19662
19663   u32 sw_if_index = ~0;
19664   int ret;
19665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19666     {
19667       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19668         ;
19669       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19670         ;
19671       else
19672         break;
19673     }
19674   if (sw_if_index == ~0)
19675     {
19676       errmsg ("missing interface name or sw_if_index");
19677       return -99;
19678     }
19679
19680   /* Construct the API message */
19681   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19682   mp->context = 0;
19683   mp->sw_if_index = ntohl (sw_if_index);
19684
19685   S (mp);
19686   W (ret);
19687   return ret;
19688 }
19689
19690 int
19691 api_classify_table_info (vat_main_t * vam)
19692 {
19693   unformat_input_t *input = vam->input;
19694   vl_api_classify_table_info_t *mp;
19695
19696   u32 table_id = ~0;
19697   int ret;
19698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19699     {
19700       if (unformat (input, "table_id %d", &table_id))
19701         ;
19702       else
19703         break;
19704     }
19705   if (table_id == ~0)
19706     {
19707       errmsg ("missing table id");
19708       return -99;
19709     }
19710
19711   /* Construct the API message */
19712   M (CLASSIFY_TABLE_INFO, mp);
19713   mp->context = 0;
19714   mp->table_id = ntohl (table_id);
19715
19716   S (mp);
19717   W (ret);
19718   return ret;
19719 }
19720
19721 int
19722 api_classify_session_dump (vat_main_t * vam)
19723 {
19724   unformat_input_t *input = vam->input;
19725   vl_api_classify_session_dump_t *mp;
19726   vl_api_control_ping_t *mp_ping;
19727
19728   u32 table_id = ~0;
19729   int ret;
19730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19731     {
19732       if (unformat (input, "table_id %d", &table_id))
19733         ;
19734       else
19735         break;
19736     }
19737   if (table_id == ~0)
19738     {
19739       errmsg ("missing table id");
19740       return -99;
19741     }
19742
19743   /* Construct the API message */
19744   M (CLASSIFY_SESSION_DUMP, mp);
19745   mp->context = 0;
19746   mp->table_id = ntohl (table_id);
19747   S (mp);
19748
19749   /* Use a control ping for synchronization */
19750   MPING (CONTROL_PING, mp_ping);
19751   S (mp_ping);
19752
19753   W (ret);
19754   return ret;
19755 }
19756
19757 static void
19758 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19759 {
19760   vat_main_t *vam = &vat_main;
19761
19762   print (vam->ofp, "collector_address %U, collector_port %d, "
19763          "src_address %U, vrf_id %d, path_mtu %u, "
19764          "template_interval %u, udp_checksum %d",
19765          format_ip4_address, mp->collector_address,
19766          ntohs (mp->collector_port),
19767          format_ip4_address, mp->src_address,
19768          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19769          ntohl (mp->template_interval), mp->udp_checksum);
19770
19771   vam->retval = 0;
19772   vam->result_ready = 1;
19773 }
19774
19775 static void
19776   vl_api_ipfix_exporter_details_t_handler_json
19777   (vl_api_ipfix_exporter_details_t * mp)
19778 {
19779   vat_main_t *vam = &vat_main;
19780   vat_json_node_t node;
19781   struct in_addr collector_address;
19782   struct in_addr src_address;
19783
19784   vat_json_init_object (&node);
19785   clib_memcpy (&collector_address, &mp->collector_address,
19786                sizeof (collector_address));
19787   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19788   vat_json_object_add_uint (&node, "collector_port",
19789                             ntohs (mp->collector_port));
19790   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19791   vat_json_object_add_ip4 (&node, "src_address", src_address);
19792   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19793   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19794   vat_json_object_add_uint (&node, "template_interval",
19795                             ntohl (mp->template_interval));
19796   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19797
19798   vat_json_print (vam->ofp, &node);
19799   vat_json_free (&node);
19800   vam->retval = 0;
19801   vam->result_ready = 1;
19802 }
19803
19804 int
19805 api_ipfix_exporter_dump (vat_main_t * vam)
19806 {
19807   vl_api_ipfix_exporter_dump_t *mp;
19808   int ret;
19809
19810   /* Construct the API message */
19811   M (IPFIX_EXPORTER_DUMP, mp);
19812   mp->context = 0;
19813
19814   S (mp);
19815   W (ret);
19816   return ret;
19817 }
19818
19819 static int
19820 api_ipfix_classify_stream_dump (vat_main_t * vam)
19821 {
19822   vl_api_ipfix_classify_stream_dump_t *mp;
19823   int ret;
19824
19825   /* Construct the API message */
19826   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19827   mp->context = 0;
19828
19829   S (mp);
19830   W (ret);
19831   return ret;
19832   /* NOTREACHED */
19833   return 0;
19834 }
19835
19836 static void
19837   vl_api_ipfix_classify_stream_details_t_handler
19838   (vl_api_ipfix_classify_stream_details_t * mp)
19839 {
19840   vat_main_t *vam = &vat_main;
19841   print (vam->ofp, "domain_id %d, src_port %d",
19842          ntohl (mp->domain_id), ntohs (mp->src_port));
19843   vam->retval = 0;
19844   vam->result_ready = 1;
19845 }
19846
19847 static void
19848   vl_api_ipfix_classify_stream_details_t_handler_json
19849   (vl_api_ipfix_classify_stream_details_t * mp)
19850 {
19851   vat_main_t *vam = &vat_main;
19852   vat_json_node_t node;
19853
19854   vat_json_init_object (&node);
19855   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19856   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19857
19858   vat_json_print (vam->ofp, &node);
19859   vat_json_free (&node);
19860   vam->retval = 0;
19861   vam->result_ready = 1;
19862 }
19863
19864 static int
19865 api_ipfix_classify_table_dump (vat_main_t * vam)
19866 {
19867   vl_api_ipfix_classify_table_dump_t *mp;
19868   vl_api_control_ping_t *mp_ping;
19869   int ret;
19870
19871   if (!vam->json_output)
19872     {
19873       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19874              "transport_protocol");
19875     }
19876
19877   /* Construct the API message */
19878   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19879
19880   /* send it... */
19881   S (mp);
19882
19883   /* Use a control ping for synchronization */
19884   MPING (CONTROL_PING, mp_ping);
19885   S (mp_ping);
19886
19887   W (ret);
19888   return ret;
19889 }
19890
19891 static void
19892   vl_api_ipfix_classify_table_details_t_handler
19893   (vl_api_ipfix_classify_table_details_t * mp)
19894 {
19895   vat_main_t *vam = &vat_main;
19896   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19897          mp->transport_protocol);
19898 }
19899
19900 static void
19901   vl_api_ipfix_classify_table_details_t_handler_json
19902   (vl_api_ipfix_classify_table_details_t * mp)
19903 {
19904   vat_json_node_t *node = NULL;
19905   vat_main_t *vam = &vat_main;
19906
19907   if (VAT_JSON_ARRAY != vam->json_tree.type)
19908     {
19909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19910       vat_json_init_array (&vam->json_tree);
19911     }
19912
19913   node = vat_json_array_add (&vam->json_tree);
19914   vat_json_init_object (node);
19915
19916   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19917   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19918   vat_json_object_add_uint (node, "transport_protocol",
19919                             mp->transport_protocol);
19920 }
19921
19922 static int
19923 api_sw_interface_span_enable_disable (vat_main_t * vam)
19924 {
19925   unformat_input_t *i = vam->input;
19926   vl_api_sw_interface_span_enable_disable_t *mp;
19927   u32 src_sw_if_index = ~0;
19928   u32 dst_sw_if_index = ~0;
19929   u8 state = 3;
19930   int ret;
19931   u8 is_l2 = 0;
19932
19933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19934     {
19935       if (unformat
19936           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19937         ;
19938       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19939         ;
19940       else
19941         if (unformat
19942             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19943         ;
19944       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19945         ;
19946       else if (unformat (i, "disable"))
19947         state = 0;
19948       else if (unformat (i, "rx"))
19949         state = 1;
19950       else if (unformat (i, "tx"))
19951         state = 2;
19952       else if (unformat (i, "both"))
19953         state = 3;
19954       else if (unformat (i, "l2"))
19955         is_l2 = 1;
19956       else
19957         break;
19958     }
19959
19960   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19961
19962   mp->sw_if_index_from = htonl (src_sw_if_index);
19963   mp->sw_if_index_to = htonl (dst_sw_if_index);
19964   mp->state = state;
19965   mp->is_l2 = is_l2;
19966
19967   S (mp);
19968   W (ret);
19969   return ret;
19970 }
19971
19972 static void
19973 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19974                                             * mp)
19975 {
19976   vat_main_t *vam = &vat_main;
19977   u8 *sw_if_from_name = 0;
19978   u8 *sw_if_to_name = 0;
19979   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19980   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19981   char *states[] = { "none", "rx", "tx", "both" };
19982   hash_pair_t *p;
19983
19984   /* *INDENT-OFF* */
19985   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19986   ({
19987     if ((u32) p->value[0] == sw_if_index_from)
19988       {
19989         sw_if_from_name = (u8 *)(p->key);
19990         if (sw_if_to_name)
19991           break;
19992       }
19993     if ((u32) p->value[0] == sw_if_index_to)
19994       {
19995         sw_if_to_name = (u8 *)(p->key);
19996         if (sw_if_from_name)
19997           break;
19998       }
19999   }));
20000   /* *INDENT-ON* */
20001   print (vam->ofp, "%20s => %20s (%s) %s",
20002          sw_if_from_name, sw_if_to_name, states[mp->state],
20003          mp->is_l2 ? "l2" : "device");
20004 }
20005
20006 static void
20007   vl_api_sw_interface_span_details_t_handler_json
20008   (vl_api_sw_interface_span_details_t * mp)
20009 {
20010   vat_main_t *vam = &vat_main;
20011   vat_json_node_t *node = NULL;
20012   u8 *sw_if_from_name = 0;
20013   u8 *sw_if_to_name = 0;
20014   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20015   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20016   hash_pair_t *p;
20017
20018   /* *INDENT-OFF* */
20019   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20020   ({
20021     if ((u32) p->value[0] == sw_if_index_from)
20022       {
20023         sw_if_from_name = (u8 *)(p->key);
20024         if (sw_if_to_name)
20025           break;
20026       }
20027     if ((u32) p->value[0] == sw_if_index_to)
20028       {
20029         sw_if_to_name = (u8 *)(p->key);
20030         if (sw_if_from_name)
20031           break;
20032       }
20033   }));
20034   /* *INDENT-ON* */
20035
20036   if (VAT_JSON_ARRAY != vam->json_tree.type)
20037     {
20038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20039       vat_json_init_array (&vam->json_tree);
20040     }
20041   node = vat_json_array_add (&vam->json_tree);
20042
20043   vat_json_init_object (node);
20044   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20045   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20046   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20047   if (0 != sw_if_to_name)
20048     {
20049       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20050     }
20051   vat_json_object_add_uint (node, "state", mp->state);
20052   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20053 }
20054
20055 static int
20056 api_sw_interface_span_dump (vat_main_t * vam)
20057 {
20058   unformat_input_t *input = vam->input;
20059   vl_api_sw_interface_span_dump_t *mp;
20060   vl_api_control_ping_t *mp_ping;
20061   u8 is_l2 = 0;
20062   int ret;
20063
20064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20065     {
20066       if (unformat (input, "l2"))
20067         is_l2 = 1;
20068       else
20069         break;
20070     }
20071
20072   M (SW_INTERFACE_SPAN_DUMP, mp);
20073   mp->is_l2 = is_l2;
20074   S (mp);
20075
20076   /* Use a control ping for synchronization */
20077   MPING (CONTROL_PING, mp_ping);
20078   S (mp_ping);
20079
20080   W (ret);
20081   return ret;
20082 }
20083
20084 int
20085 api_pg_create_interface (vat_main_t * vam)
20086 {
20087   unformat_input_t *input = vam->input;
20088   vl_api_pg_create_interface_t *mp;
20089
20090   u32 if_id = ~0;
20091   int ret;
20092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20093     {
20094       if (unformat (input, "if_id %d", &if_id))
20095         ;
20096       else
20097         break;
20098     }
20099   if (if_id == ~0)
20100     {
20101       errmsg ("missing pg interface index");
20102       return -99;
20103     }
20104
20105   /* Construct the API message */
20106   M (PG_CREATE_INTERFACE, mp);
20107   mp->context = 0;
20108   mp->interface_id = ntohl (if_id);
20109
20110   S (mp);
20111   W (ret);
20112   return ret;
20113 }
20114
20115 int
20116 api_pg_capture (vat_main_t * vam)
20117 {
20118   unformat_input_t *input = vam->input;
20119   vl_api_pg_capture_t *mp;
20120
20121   u32 if_id = ~0;
20122   u8 enable = 1;
20123   u32 count = 1;
20124   u8 pcap_file_set = 0;
20125   u8 *pcap_file = 0;
20126   int ret;
20127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20128     {
20129       if (unformat (input, "if_id %d", &if_id))
20130         ;
20131       else if (unformat (input, "pcap %s", &pcap_file))
20132         pcap_file_set = 1;
20133       else if (unformat (input, "count %d", &count))
20134         ;
20135       else if (unformat (input, "disable"))
20136         enable = 0;
20137       else
20138         break;
20139     }
20140   if (if_id == ~0)
20141     {
20142       errmsg ("missing pg interface index");
20143       return -99;
20144     }
20145   if (pcap_file_set > 0)
20146     {
20147       if (vec_len (pcap_file) > 255)
20148         {
20149           errmsg ("pcap file name is too long");
20150           return -99;
20151         }
20152     }
20153
20154   u32 name_len = vec_len (pcap_file);
20155   /* Construct the API message */
20156   M (PG_CAPTURE, mp);
20157   mp->context = 0;
20158   mp->interface_id = ntohl (if_id);
20159   mp->is_enabled = enable;
20160   mp->count = ntohl (count);
20161   mp->pcap_name_length = ntohl (name_len);
20162   if (pcap_file_set != 0)
20163     {
20164       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20165     }
20166   vec_free (pcap_file);
20167
20168   S (mp);
20169   W (ret);
20170   return ret;
20171 }
20172
20173 int
20174 api_pg_enable_disable (vat_main_t * vam)
20175 {
20176   unformat_input_t *input = vam->input;
20177   vl_api_pg_enable_disable_t *mp;
20178
20179   u8 enable = 1;
20180   u8 stream_name_set = 0;
20181   u8 *stream_name = 0;
20182   int ret;
20183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20184     {
20185       if (unformat (input, "stream %s", &stream_name))
20186         stream_name_set = 1;
20187       else if (unformat (input, "disable"))
20188         enable = 0;
20189       else
20190         break;
20191     }
20192
20193   if (stream_name_set > 0)
20194     {
20195       if (vec_len (stream_name) > 255)
20196         {
20197           errmsg ("stream name too long");
20198           return -99;
20199         }
20200     }
20201
20202   u32 name_len = vec_len (stream_name);
20203   /* Construct the API message */
20204   M (PG_ENABLE_DISABLE, mp);
20205   mp->context = 0;
20206   mp->is_enabled = enable;
20207   if (stream_name_set != 0)
20208     {
20209       mp->stream_name_length = ntohl (name_len);
20210       clib_memcpy (mp->stream_name, stream_name, name_len);
20211     }
20212   vec_free (stream_name);
20213
20214   S (mp);
20215   W (ret);
20216   return ret;
20217 }
20218
20219 int
20220 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20221 {
20222   unformat_input_t *input = vam->input;
20223   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20224
20225   u16 *low_ports = 0;
20226   u16 *high_ports = 0;
20227   u16 this_low;
20228   u16 this_hi;
20229   vl_api_prefix_t prefix;
20230   u32 tmp, tmp2;
20231   u8 prefix_set = 0;
20232   u32 vrf_id = ~0;
20233   u8 is_add = 1;
20234   u8 is_ipv6 = 0;
20235   int ret;
20236
20237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20238     {
20239       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20240         prefix_set = 1;
20241       else if (unformat (input, "vrf %d", &vrf_id))
20242         ;
20243       else if (unformat (input, "del"))
20244         is_add = 0;
20245       else if (unformat (input, "port %d", &tmp))
20246         {
20247           if (tmp == 0 || tmp > 65535)
20248             {
20249               errmsg ("port %d out of range", tmp);
20250               return -99;
20251             }
20252           this_low = tmp;
20253           this_hi = this_low + 1;
20254           vec_add1 (low_ports, this_low);
20255           vec_add1 (high_ports, this_hi);
20256         }
20257       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20258         {
20259           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20260             {
20261               errmsg ("incorrect range parameters");
20262               return -99;
20263             }
20264           this_low = tmp;
20265           /* Note: in debug CLI +1 is added to high before
20266              passing to real fn that does "the work"
20267              (ip_source_and_port_range_check_add_del).
20268              This fn is a wrapper around the binary API fn a
20269              control plane will call, which expects this increment
20270              to have occurred. Hence letting the binary API control
20271              plane fn do the increment for consistency between VAT
20272              and other control planes.
20273            */
20274           this_hi = tmp2;
20275           vec_add1 (low_ports, this_low);
20276           vec_add1 (high_ports, this_hi);
20277         }
20278       else
20279         break;
20280     }
20281
20282   if (prefix_set == 0)
20283     {
20284       errmsg ("<address>/<mask> not specified");
20285       return -99;
20286     }
20287
20288   if (vrf_id == ~0)
20289     {
20290       errmsg ("VRF ID required, not specified");
20291       return -99;
20292     }
20293
20294   if (vrf_id == 0)
20295     {
20296       errmsg
20297         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20298       return -99;
20299     }
20300
20301   if (vec_len (low_ports) == 0)
20302     {
20303       errmsg ("At least one port or port range required");
20304       return -99;
20305     }
20306
20307   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20308
20309   mp->is_add = is_add;
20310
20311   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20312
20313   mp->number_of_ranges = vec_len (low_ports);
20314
20315   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20316   vec_free (low_ports);
20317
20318   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20319   vec_free (high_ports);
20320
20321   mp->vrf_id = ntohl (vrf_id);
20322
20323   S (mp);
20324   W (ret);
20325   return ret;
20326 }
20327
20328 int
20329 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20330 {
20331   unformat_input_t *input = vam->input;
20332   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20333   u32 sw_if_index = ~0;
20334   int vrf_set = 0;
20335   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20336   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20337   u8 is_add = 1;
20338   int ret;
20339
20340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20341     {
20342       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20343         ;
20344       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20345         ;
20346       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20347         vrf_set = 1;
20348       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20349         vrf_set = 1;
20350       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20351         vrf_set = 1;
20352       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20353         vrf_set = 1;
20354       else if (unformat (input, "del"))
20355         is_add = 0;
20356       else
20357         break;
20358     }
20359
20360   if (sw_if_index == ~0)
20361     {
20362       errmsg ("Interface required but not specified");
20363       return -99;
20364     }
20365
20366   if (vrf_set == 0)
20367     {
20368       errmsg ("VRF ID required but not specified");
20369       return -99;
20370     }
20371
20372   if (tcp_out_vrf_id == 0
20373       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20374     {
20375       errmsg
20376         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20377       return -99;
20378     }
20379
20380   /* Construct the API message */
20381   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20382
20383   mp->sw_if_index = ntohl (sw_if_index);
20384   mp->is_add = is_add;
20385   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20386   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20387   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20388   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20389
20390   /* send it... */
20391   S (mp);
20392
20393   /* Wait for a reply... */
20394   W (ret);
20395   return ret;
20396 }
20397
20398 static int
20399 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20400 {
20401   unformat_input_t *i = vam->input;
20402   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20403   u32 local_sa_id = 0;
20404   u32 remote_sa_id = 0;
20405   vl_api_ip4_address_t src_address;
20406   vl_api_ip4_address_t dst_address;
20407   u8 is_add = 1;
20408   int ret;
20409
20410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20411     {
20412       if (unformat (i, "local_sa %d", &local_sa_id))
20413         ;
20414       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20415         ;
20416       else
20417         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20418         ;
20419       else
20420         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20421         ;
20422       else if (unformat (i, "del"))
20423         is_add = 0;
20424       else
20425         {
20426           clib_warning ("parse error '%U'", format_unformat_error, i);
20427           return -99;
20428         }
20429     }
20430
20431   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20432
20433   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20434   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20435   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20436   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20437   mp->is_add = is_add;
20438
20439   S (mp);
20440   W (ret);
20441   return ret;
20442 }
20443
20444 static int
20445 api_set_punt (vat_main_t * vam)
20446 {
20447   unformat_input_t *i = vam->input;
20448   vl_api_set_punt_t *mp;
20449   u32 ipv = ~0;
20450   u32 protocol = ~0;
20451   u32 port = ~0;
20452   int is_add = 1;
20453   int ret;
20454
20455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20456     {
20457       if (unformat (i, "ip %d", &ipv))
20458         ;
20459       else if (unformat (i, "protocol %d", &protocol))
20460         ;
20461       else if (unformat (i, "port %d", &port))
20462         ;
20463       else if (unformat (i, "del"))
20464         is_add = 0;
20465       else
20466         {
20467           clib_warning ("parse error '%U'", format_unformat_error, i);
20468           return -99;
20469         }
20470     }
20471
20472   M (SET_PUNT, mp);
20473
20474   mp->is_add = (u8) is_add;
20475   mp->punt.ipv = (u8) ipv;
20476   mp->punt.l4_protocol = (u8) protocol;
20477   mp->punt.l4_port = htons ((u16) port);
20478
20479   S (mp);
20480   W (ret);
20481   return ret;
20482 }
20483
20484 static void vl_api_ipsec_gre_tunnel_details_t_handler
20485   (vl_api_ipsec_gre_tunnel_details_t * mp)
20486 {
20487   vat_main_t *vam = &vat_main;
20488
20489   print (vam->ofp, "%11d%15U%15U%14d%14d",
20490          ntohl (mp->tunnel.sw_if_index),
20491          format_vl_api_ip4_address, mp->tunnel.src,
20492          format_vl_api_ip4_address, mp->tunnel.dst,
20493          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20494 }
20495
20496 static void
20497 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20498                                 const char *name,
20499                                 const vl_api_ip4_address_t addr)
20500 {
20501   struct in_addr ip4;
20502
20503   clib_memcpy (&ip4, addr, sizeof (ip4));
20504   vat_json_object_add_ip4 (node, name, ip4);
20505 }
20506
20507 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20508   (vl_api_ipsec_gre_tunnel_details_t * mp)
20509 {
20510   vat_main_t *vam = &vat_main;
20511   vat_json_node_t *node = NULL;
20512   struct in_addr ip4;
20513
20514   if (VAT_JSON_ARRAY != vam->json_tree.type)
20515     {
20516       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20517       vat_json_init_array (&vam->json_tree);
20518     }
20519   node = vat_json_array_add (&vam->json_tree);
20520
20521   vat_json_init_object (node);
20522   vat_json_object_add_uint (node, "sw_if_index",
20523                             ntohl (mp->tunnel.sw_if_index));
20524   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20525   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20526   vat_json_object_add_uint (node, "local_sa_id",
20527                             ntohl (mp->tunnel.local_sa_id));
20528   vat_json_object_add_uint (node, "remote_sa_id",
20529                             ntohl (mp->tunnel.remote_sa_id));
20530 }
20531
20532 static int
20533 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20534 {
20535   unformat_input_t *i = vam->input;
20536   vl_api_ipsec_gre_tunnel_dump_t *mp;
20537   vl_api_control_ping_t *mp_ping;
20538   u32 sw_if_index;
20539   u8 sw_if_index_set = 0;
20540   int ret;
20541
20542   /* Parse args required to build the message */
20543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (i, "sw_if_index %d", &sw_if_index))
20546         sw_if_index_set = 1;
20547       else
20548         break;
20549     }
20550
20551   if (sw_if_index_set == 0)
20552     {
20553       sw_if_index = ~0;
20554     }
20555
20556   if (!vam->json_output)
20557     {
20558       print (vam->ofp, "%11s%15s%15s%14s%14s",
20559              "sw_if_index", "src_address", "dst_address",
20560              "local_sa_id", "remote_sa_id");
20561     }
20562
20563   /* Get list of gre-tunnel interfaces */
20564   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20565
20566   mp->sw_if_index = htonl (sw_if_index);
20567
20568   S (mp);
20569
20570   /* Use a control ping for synchronization */
20571   MPING (CONTROL_PING, mp_ping);
20572   S (mp_ping);
20573
20574   W (ret);
20575   return ret;
20576 }
20577
20578 static int
20579 api_delete_subif (vat_main_t * vam)
20580 {
20581   unformat_input_t *i = vam->input;
20582   vl_api_delete_subif_t *mp;
20583   u32 sw_if_index = ~0;
20584   int ret;
20585
20586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20587     {
20588       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20589         ;
20590       if (unformat (i, "sw_if_index %d", &sw_if_index))
20591         ;
20592       else
20593         break;
20594     }
20595
20596   if (sw_if_index == ~0)
20597     {
20598       errmsg ("missing sw_if_index");
20599       return -99;
20600     }
20601
20602   /* Construct the API message */
20603   M (DELETE_SUBIF, mp);
20604   mp->sw_if_index = ntohl (sw_if_index);
20605
20606   S (mp);
20607   W (ret);
20608   return ret;
20609 }
20610
20611 #define foreach_pbb_vtr_op      \
20612 _("disable",  L2_VTR_DISABLED)  \
20613 _("pop",  L2_VTR_POP_2)         \
20614 _("push",  L2_VTR_PUSH_2)
20615
20616 static int
20617 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20618 {
20619   unformat_input_t *i = vam->input;
20620   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20621   u32 sw_if_index = ~0, vtr_op = ~0;
20622   u16 outer_tag = ~0;
20623   u8 dmac[6], smac[6];
20624   u8 dmac_set = 0, smac_set = 0;
20625   u16 vlanid = 0;
20626   u32 sid = ~0;
20627   u32 tmp;
20628   int ret;
20629
20630   /* Shut up coverity */
20631   clib_memset (dmac, 0, sizeof (dmac));
20632   clib_memset (smac, 0, sizeof (smac));
20633
20634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20635     {
20636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20637         ;
20638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20639         ;
20640       else if (unformat (i, "vtr_op %d", &vtr_op))
20641         ;
20642 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20643       foreach_pbb_vtr_op
20644 #undef _
20645         else if (unformat (i, "translate_pbb_stag"))
20646         {
20647           if (unformat (i, "%d", &tmp))
20648             {
20649               vtr_op = L2_VTR_TRANSLATE_2_1;
20650               outer_tag = tmp;
20651             }
20652           else
20653             {
20654               errmsg
20655                 ("translate_pbb_stag operation requires outer tag definition");
20656               return -99;
20657             }
20658         }
20659       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20660         dmac_set++;
20661       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20662         smac_set++;
20663       else if (unformat (i, "sid %d", &sid))
20664         ;
20665       else if (unformat (i, "vlanid %d", &tmp))
20666         vlanid = tmp;
20667       else
20668         {
20669           clib_warning ("parse error '%U'", format_unformat_error, i);
20670           return -99;
20671         }
20672     }
20673
20674   if ((sw_if_index == ~0) || (vtr_op == ~0))
20675     {
20676       errmsg ("missing sw_if_index or vtr operation");
20677       return -99;
20678     }
20679   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20680       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20681     {
20682       errmsg
20683         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20684       return -99;
20685     }
20686
20687   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20688   mp->sw_if_index = ntohl (sw_if_index);
20689   mp->vtr_op = ntohl (vtr_op);
20690   mp->outer_tag = ntohs (outer_tag);
20691   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20692   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20693   mp->b_vlanid = ntohs (vlanid);
20694   mp->i_sid = ntohl (sid);
20695
20696   S (mp);
20697   W (ret);
20698   return ret;
20699 }
20700
20701 static int
20702 api_flow_classify_set_interface (vat_main_t * vam)
20703 {
20704   unformat_input_t *i = vam->input;
20705   vl_api_flow_classify_set_interface_t *mp;
20706   u32 sw_if_index;
20707   int sw_if_index_set;
20708   u32 ip4_table_index = ~0;
20709   u32 ip6_table_index = ~0;
20710   u8 is_add = 1;
20711   int ret;
20712
20713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20714     {
20715       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20716         sw_if_index_set = 1;
20717       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20718         sw_if_index_set = 1;
20719       else if (unformat (i, "del"))
20720         is_add = 0;
20721       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20722         ;
20723       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20724         ;
20725       else
20726         {
20727           clib_warning ("parse error '%U'", format_unformat_error, i);
20728           return -99;
20729         }
20730     }
20731
20732   if (sw_if_index_set == 0)
20733     {
20734       errmsg ("missing interface name or sw_if_index");
20735       return -99;
20736     }
20737
20738   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20739
20740   mp->sw_if_index = ntohl (sw_if_index);
20741   mp->ip4_table_index = ntohl (ip4_table_index);
20742   mp->ip6_table_index = ntohl (ip6_table_index);
20743   mp->is_add = is_add;
20744
20745   S (mp);
20746   W (ret);
20747   return ret;
20748 }
20749
20750 static int
20751 api_flow_classify_dump (vat_main_t * vam)
20752 {
20753   unformat_input_t *i = vam->input;
20754   vl_api_flow_classify_dump_t *mp;
20755   vl_api_control_ping_t *mp_ping;
20756   u8 type = FLOW_CLASSIFY_N_TABLES;
20757   int ret;
20758
20759   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20760     ;
20761   else
20762     {
20763       errmsg ("classify table type must be specified");
20764       return -99;
20765     }
20766
20767   if (!vam->json_output)
20768     {
20769       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20770     }
20771
20772   M (FLOW_CLASSIFY_DUMP, mp);
20773   mp->type = type;
20774   /* send it... */
20775   S (mp);
20776
20777   /* Use a control ping for synchronization */
20778   MPING (CONTROL_PING, mp_ping);
20779   S (mp_ping);
20780
20781   /* Wait for a reply... */
20782   W (ret);
20783   return ret;
20784 }
20785
20786 static int
20787 api_feature_enable_disable (vat_main_t * vam)
20788 {
20789   unformat_input_t *i = vam->input;
20790   vl_api_feature_enable_disable_t *mp;
20791   u8 *arc_name = 0;
20792   u8 *feature_name = 0;
20793   u32 sw_if_index = ~0;
20794   u8 enable = 1;
20795   int ret;
20796
20797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20798     {
20799       if (unformat (i, "arc_name %s", &arc_name))
20800         ;
20801       else if (unformat (i, "feature_name %s", &feature_name))
20802         ;
20803       else
20804         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20805         ;
20806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20807         ;
20808       else if (unformat (i, "disable"))
20809         enable = 0;
20810       else
20811         break;
20812     }
20813
20814   if (arc_name == 0)
20815     {
20816       errmsg ("missing arc name");
20817       return -99;
20818     }
20819   if (vec_len (arc_name) > 63)
20820     {
20821       errmsg ("arc name too long");
20822     }
20823
20824   if (feature_name == 0)
20825     {
20826       errmsg ("missing feature name");
20827       return -99;
20828     }
20829   if (vec_len (feature_name) > 63)
20830     {
20831       errmsg ("feature name too long");
20832     }
20833
20834   if (sw_if_index == ~0)
20835     {
20836       errmsg ("missing interface name or sw_if_index");
20837       return -99;
20838     }
20839
20840   /* Construct the API message */
20841   M (FEATURE_ENABLE_DISABLE, mp);
20842   mp->sw_if_index = ntohl (sw_if_index);
20843   mp->enable = enable;
20844   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20845   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20846   vec_free (arc_name);
20847   vec_free (feature_name);
20848
20849   S (mp);
20850   W (ret);
20851   return ret;
20852 }
20853
20854 static int
20855 api_sw_interface_tag_add_del (vat_main_t * vam)
20856 {
20857   unformat_input_t *i = vam->input;
20858   vl_api_sw_interface_tag_add_del_t *mp;
20859   u32 sw_if_index = ~0;
20860   u8 *tag = 0;
20861   u8 enable = 1;
20862   int ret;
20863
20864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20865     {
20866       if (unformat (i, "tag %s", &tag))
20867         ;
20868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20869         ;
20870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20871         ;
20872       else if (unformat (i, "del"))
20873         enable = 0;
20874       else
20875         break;
20876     }
20877
20878   if (sw_if_index == ~0)
20879     {
20880       errmsg ("missing interface name or sw_if_index");
20881       return -99;
20882     }
20883
20884   if (enable && (tag == 0))
20885     {
20886       errmsg ("no tag specified");
20887       return -99;
20888     }
20889
20890   /* Construct the API message */
20891   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20892   mp->sw_if_index = ntohl (sw_if_index);
20893   mp->is_add = enable;
20894   if (enable)
20895     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20896   vec_free (tag);
20897
20898   S (mp);
20899   W (ret);
20900   return ret;
20901 }
20902
20903 static void vl_api_l2_xconnect_details_t_handler
20904   (vl_api_l2_xconnect_details_t * mp)
20905 {
20906   vat_main_t *vam = &vat_main;
20907
20908   print (vam->ofp, "%15d%15d",
20909          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20910 }
20911
20912 static void vl_api_l2_xconnect_details_t_handler_json
20913   (vl_api_l2_xconnect_details_t * mp)
20914 {
20915   vat_main_t *vam = &vat_main;
20916   vat_json_node_t *node = NULL;
20917
20918   if (VAT_JSON_ARRAY != vam->json_tree.type)
20919     {
20920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20921       vat_json_init_array (&vam->json_tree);
20922     }
20923   node = vat_json_array_add (&vam->json_tree);
20924
20925   vat_json_init_object (node);
20926   vat_json_object_add_uint (node, "rx_sw_if_index",
20927                             ntohl (mp->rx_sw_if_index));
20928   vat_json_object_add_uint (node, "tx_sw_if_index",
20929                             ntohl (mp->tx_sw_if_index));
20930 }
20931
20932 static int
20933 api_l2_xconnect_dump (vat_main_t * vam)
20934 {
20935   vl_api_l2_xconnect_dump_t *mp;
20936   vl_api_control_ping_t *mp_ping;
20937   int ret;
20938
20939   if (!vam->json_output)
20940     {
20941       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20942     }
20943
20944   M (L2_XCONNECT_DUMP, mp);
20945
20946   S (mp);
20947
20948   /* Use a control ping for synchronization */
20949   MPING (CONTROL_PING, mp_ping);
20950   S (mp_ping);
20951
20952   W (ret);
20953   return ret;
20954 }
20955
20956 static int
20957 api_hw_interface_set_mtu (vat_main_t * vam)
20958 {
20959   unformat_input_t *i = vam->input;
20960   vl_api_hw_interface_set_mtu_t *mp;
20961   u32 sw_if_index = ~0;
20962   u32 mtu = 0;
20963   int ret;
20964
20965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20966     {
20967       if (unformat (i, "mtu %d", &mtu))
20968         ;
20969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20970         ;
20971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20972         ;
20973       else
20974         break;
20975     }
20976
20977   if (sw_if_index == ~0)
20978     {
20979       errmsg ("missing interface name or sw_if_index");
20980       return -99;
20981     }
20982
20983   if (mtu == 0)
20984     {
20985       errmsg ("no mtu specified");
20986       return -99;
20987     }
20988
20989   /* Construct the API message */
20990   M (HW_INTERFACE_SET_MTU, mp);
20991   mp->sw_if_index = ntohl (sw_if_index);
20992   mp->mtu = ntohs ((u16) mtu);
20993
20994   S (mp);
20995   W (ret);
20996   return ret;
20997 }
20998
20999 static int
21000 api_p2p_ethernet_add (vat_main_t * vam)
21001 {
21002   unformat_input_t *i = vam->input;
21003   vl_api_p2p_ethernet_add_t *mp;
21004   u32 parent_if_index = ~0;
21005   u32 sub_id = ~0;
21006   u8 remote_mac[6];
21007   u8 mac_set = 0;
21008   int ret;
21009
21010   clib_memset (remote_mac, 0, sizeof (remote_mac));
21011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21012     {
21013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21014         ;
21015       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21016         ;
21017       else
21018         if (unformat
21019             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21020         mac_set++;
21021       else if (unformat (i, "sub_id %d", &sub_id))
21022         ;
21023       else
21024         {
21025           clib_warning ("parse error '%U'", format_unformat_error, i);
21026           return -99;
21027         }
21028     }
21029
21030   if (parent_if_index == ~0)
21031     {
21032       errmsg ("missing interface name or sw_if_index");
21033       return -99;
21034     }
21035   if (mac_set == 0)
21036     {
21037       errmsg ("missing remote mac address");
21038       return -99;
21039     }
21040   if (sub_id == ~0)
21041     {
21042       errmsg ("missing sub-interface id");
21043       return -99;
21044     }
21045
21046   M (P2P_ETHERNET_ADD, mp);
21047   mp->parent_if_index = ntohl (parent_if_index);
21048   mp->subif_id = ntohl (sub_id);
21049   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21050
21051   S (mp);
21052   W (ret);
21053   return ret;
21054 }
21055
21056 static int
21057 api_p2p_ethernet_del (vat_main_t * vam)
21058 {
21059   unformat_input_t *i = vam->input;
21060   vl_api_p2p_ethernet_del_t *mp;
21061   u32 parent_if_index = ~0;
21062   u8 remote_mac[6];
21063   u8 mac_set = 0;
21064   int ret;
21065
21066   clib_memset (remote_mac, 0, sizeof (remote_mac));
21067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21068     {
21069       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21070         ;
21071       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21072         ;
21073       else
21074         if (unformat
21075             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21076         mac_set++;
21077       else
21078         {
21079           clib_warning ("parse error '%U'", format_unformat_error, i);
21080           return -99;
21081         }
21082     }
21083
21084   if (parent_if_index == ~0)
21085     {
21086       errmsg ("missing interface name or sw_if_index");
21087       return -99;
21088     }
21089   if (mac_set == 0)
21090     {
21091       errmsg ("missing remote mac address");
21092       return -99;
21093     }
21094
21095   M (P2P_ETHERNET_DEL, mp);
21096   mp->parent_if_index = ntohl (parent_if_index);
21097   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21098
21099   S (mp);
21100   W (ret);
21101   return ret;
21102 }
21103
21104 static int
21105 api_lldp_config (vat_main_t * vam)
21106 {
21107   unformat_input_t *i = vam->input;
21108   vl_api_lldp_config_t *mp;
21109   int tx_hold = 0;
21110   int tx_interval = 0;
21111   u8 *sys_name = NULL;
21112   int ret;
21113
21114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21115     {
21116       if (unformat (i, "system-name %s", &sys_name))
21117         ;
21118       else if (unformat (i, "tx-hold %d", &tx_hold))
21119         ;
21120       else if (unformat (i, "tx-interval %d", &tx_interval))
21121         ;
21122       else
21123         {
21124           clib_warning ("parse error '%U'", format_unformat_error, i);
21125           return -99;
21126         }
21127     }
21128
21129   vec_add1 (sys_name, 0);
21130
21131   M (LLDP_CONFIG, mp);
21132   mp->tx_hold = htonl (tx_hold);
21133   mp->tx_interval = htonl (tx_interval);
21134   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21135   vec_free (sys_name);
21136
21137   S (mp);
21138   W (ret);
21139   return ret;
21140 }
21141
21142 static int
21143 api_sw_interface_set_lldp (vat_main_t * vam)
21144 {
21145   unformat_input_t *i = vam->input;
21146   vl_api_sw_interface_set_lldp_t *mp;
21147   u32 sw_if_index = ~0;
21148   u32 enable = 1;
21149   u8 *port_desc = NULL, *mgmt_oid = NULL;
21150   ip4_address_t ip4_addr;
21151   ip6_address_t ip6_addr;
21152   int ret;
21153
21154   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21155   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21156
21157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21158     {
21159       if (unformat (i, "disable"))
21160         enable = 0;
21161       else
21162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21163         ;
21164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21165         ;
21166       else if (unformat (i, "port-desc %s", &port_desc))
21167         ;
21168       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21169         ;
21170       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21171         ;
21172       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21173         ;
21174       else
21175         break;
21176     }
21177
21178   if (sw_if_index == ~0)
21179     {
21180       errmsg ("missing interface name or sw_if_index");
21181       return -99;
21182     }
21183
21184   /* Construct the API message */
21185   vec_add1 (port_desc, 0);
21186   vec_add1 (mgmt_oid, 0);
21187   M (SW_INTERFACE_SET_LLDP, mp);
21188   mp->sw_if_index = ntohl (sw_if_index);
21189   mp->enable = enable;
21190   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21191   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21192   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21193   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21194   vec_free (port_desc);
21195   vec_free (mgmt_oid);
21196
21197   S (mp);
21198   W (ret);
21199   return ret;
21200 }
21201
21202 static int
21203 api_tcp_configure_src_addresses (vat_main_t * vam)
21204 {
21205   vl_api_tcp_configure_src_addresses_t *mp;
21206   unformat_input_t *i = vam->input;
21207   ip4_address_t v4first, v4last;
21208   ip6_address_t v6first, v6last;
21209   u8 range_set = 0;
21210   u32 vrf_id = 0;
21211   int ret;
21212
21213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21214     {
21215       if (unformat (i, "%U - %U",
21216                     unformat_ip4_address, &v4first,
21217                     unformat_ip4_address, &v4last))
21218         {
21219           if (range_set)
21220             {
21221               errmsg ("one range per message (range already set)");
21222               return -99;
21223             }
21224           range_set = 1;
21225         }
21226       else if (unformat (i, "%U - %U",
21227                          unformat_ip6_address, &v6first,
21228                          unformat_ip6_address, &v6last))
21229         {
21230           if (range_set)
21231             {
21232               errmsg ("one range per message (range already set)");
21233               return -99;
21234             }
21235           range_set = 2;
21236         }
21237       else if (unformat (i, "vrf %d", &vrf_id))
21238         ;
21239       else
21240         break;
21241     }
21242
21243   if (range_set == 0)
21244     {
21245       errmsg ("address range not set");
21246       return -99;
21247     }
21248
21249   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21250   mp->vrf_id = ntohl (vrf_id);
21251   /* ipv6? */
21252   if (range_set == 2)
21253     {
21254       mp->is_ipv6 = 1;
21255       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21256       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21257     }
21258   else
21259     {
21260       mp->is_ipv6 = 0;
21261       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21262       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21263     }
21264   S (mp);
21265   W (ret);
21266   return ret;
21267 }
21268
21269 static void vl_api_app_namespace_add_del_reply_t_handler
21270   (vl_api_app_namespace_add_del_reply_t * mp)
21271 {
21272   vat_main_t *vam = &vat_main;
21273   i32 retval = ntohl (mp->retval);
21274   if (vam->async_mode)
21275     {
21276       vam->async_errors += (retval < 0);
21277     }
21278   else
21279     {
21280       vam->retval = retval;
21281       if (retval == 0)
21282         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21283       vam->result_ready = 1;
21284     }
21285 }
21286
21287 static void vl_api_app_namespace_add_del_reply_t_handler_json
21288   (vl_api_app_namespace_add_del_reply_t * mp)
21289 {
21290   vat_main_t *vam = &vat_main;
21291   vat_json_node_t node;
21292
21293   vat_json_init_object (&node);
21294   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21295   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21296
21297   vat_json_print (vam->ofp, &node);
21298   vat_json_free (&node);
21299
21300   vam->retval = ntohl (mp->retval);
21301   vam->result_ready = 1;
21302 }
21303
21304 static int
21305 api_app_namespace_add_del (vat_main_t * vam)
21306 {
21307   vl_api_app_namespace_add_del_t *mp;
21308   unformat_input_t *i = vam->input;
21309   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21310   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21311   u64 secret;
21312   int ret;
21313
21314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21315     {
21316       if (unformat (i, "id %_%v%_", &ns_id))
21317         ;
21318       else if (unformat (i, "secret %lu", &secret))
21319         secret_set = 1;
21320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21321         sw_if_index_set = 1;
21322       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21323         ;
21324       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21325         ;
21326       else
21327         break;
21328     }
21329   if (!ns_id || !secret_set || !sw_if_index_set)
21330     {
21331       errmsg ("namespace id, secret and sw_if_index must be set");
21332       return -99;
21333     }
21334   if (vec_len (ns_id) > 64)
21335     {
21336       errmsg ("namespace id too long");
21337       return -99;
21338     }
21339   M (APP_NAMESPACE_ADD_DEL, mp);
21340
21341   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21342   mp->namespace_id_len = vec_len (ns_id);
21343   mp->secret = clib_host_to_net_u64 (secret);
21344   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21345   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21346   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21347   vec_free (ns_id);
21348   S (mp);
21349   W (ret);
21350   return ret;
21351 }
21352
21353 static int
21354 api_sock_init_shm (vat_main_t * vam)
21355 {
21356 #if VPP_API_TEST_BUILTIN == 0
21357   unformat_input_t *i = vam->input;
21358   vl_api_shm_elem_config_t *config = 0;
21359   u64 size = 64 << 20;
21360   int rv;
21361
21362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21363     {
21364       if (unformat (i, "size %U", unformat_memory_size, &size))
21365         ;
21366       else
21367         break;
21368     }
21369
21370   /*
21371    * Canned custom ring allocator config.
21372    * Should probably parse all of this
21373    */
21374   vec_validate (config, 6);
21375   config[0].type = VL_API_VLIB_RING;
21376   config[0].size = 256;
21377   config[0].count = 32;
21378
21379   config[1].type = VL_API_VLIB_RING;
21380   config[1].size = 1024;
21381   config[1].count = 16;
21382
21383   config[2].type = VL_API_VLIB_RING;
21384   config[2].size = 4096;
21385   config[2].count = 2;
21386
21387   config[3].type = VL_API_CLIENT_RING;
21388   config[3].size = 256;
21389   config[3].count = 32;
21390
21391   config[4].type = VL_API_CLIENT_RING;
21392   config[4].size = 1024;
21393   config[4].count = 16;
21394
21395   config[5].type = VL_API_CLIENT_RING;
21396   config[5].size = 4096;
21397   config[5].count = 2;
21398
21399   config[6].type = VL_API_QUEUE;
21400   config[6].count = 128;
21401   config[6].size = sizeof (uword);
21402
21403   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21404   if (!rv)
21405     vam->client_index_invalid = 1;
21406   return rv;
21407 #else
21408   return -99;
21409 #endif
21410 }
21411
21412 static int
21413 api_dns_enable_disable (vat_main_t * vam)
21414 {
21415   unformat_input_t *line_input = vam->input;
21416   vl_api_dns_enable_disable_t *mp;
21417   u8 enable_disable = 1;
21418   int ret;
21419
21420   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21421     {
21422       if (unformat (line_input, "disable"))
21423         enable_disable = 0;
21424       if (unformat (line_input, "enable"))
21425         enable_disable = 1;
21426       else
21427         break;
21428     }
21429
21430   /* Construct the API message */
21431   M (DNS_ENABLE_DISABLE, mp);
21432   mp->enable = enable_disable;
21433
21434   /* send it... */
21435   S (mp);
21436   /* Wait for the reply */
21437   W (ret);
21438   return ret;
21439 }
21440
21441 static int
21442 api_dns_resolve_name (vat_main_t * vam)
21443 {
21444   unformat_input_t *line_input = vam->input;
21445   vl_api_dns_resolve_name_t *mp;
21446   u8 *name = 0;
21447   int ret;
21448
21449   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21450     {
21451       if (unformat (line_input, "%s", &name))
21452         ;
21453       else
21454         break;
21455     }
21456
21457   if (vec_len (name) > 127)
21458     {
21459       errmsg ("name too long");
21460       return -99;
21461     }
21462
21463   /* Construct the API message */
21464   M (DNS_RESOLVE_NAME, mp);
21465   memcpy (mp->name, name, vec_len (name));
21466   vec_free (name);
21467
21468   /* send it... */
21469   S (mp);
21470   /* Wait for the reply */
21471   W (ret);
21472   return ret;
21473 }
21474
21475 static int
21476 api_dns_resolve_ip (vat_main_t * vam)
21477 {
21478   unformat_input_t *line_input = vam->input;
21479   vl_api_dns_resolve_ip_t *mp;
21480   int is_ip6 = -1;
21481   ip4_address_t addr4;
21482   ip6_address_t addr6;
21483   int ret;
21484
21485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21486     {
21487       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21488         is_ip6 = 1;
21489       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21490         is_ip6 = 0;
21491       else
21492         break;
21493     }
21494
21495   if (is_ip6 == -1)
21496     {
21497       errmsg ("missing address");
21498       return -99;
21499     }
21500
21501   /* Construct the API message */
21502   M (DNS_RESOLVE_IP, mp);
21503   mp->is_ip6 = is_ip6;
21504   if (is_ip6)
21505     memcpy (mp->address, &addr6, sizeof (addr6));
21506   else
21507     memcpy (mp->address, &addr4, sizeof (addr4));
21508
21509   /* send it... */
21510   S (mp);
21511   /* Wait for the reply */
21512   W (ret);
21513   return ret;
21514 }
21515
21516 static int
21517 api_dns_name_server_add_del (vat_main_t * vam)
21518 {
21519   unformat_input_t *i = vam->input;
21520   vl_api_dns_name_server_add_del_t *mp;
21521   u8 is_add = 1;
21522   ip6_address_t ip6_server;
21523   ip4_address_t ip4_server;
21524   int ip6_set = 0;
21525   int ip4_set = 0;
21526   int ret = 0;
21527
21528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21529     {
21530       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21531         ip6_set = 1;
21532       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21533         ip4_set = 1;
21534       else if (unformat (i, "del"))
21535         is_add = 0;
21536       else
21537         {
21538           clib_warning ("parse error '%U'", format_unformat_error, i);
21539           return -99;
21540         }
21541     }
21542
21543   if (ip4_set && ip6_set)
21544     {
21545       errmsg ("Only one server address allowed per message");
21546       return -99;
21547     }
21548   if ((ip4_set + ip6_set) == 0)
21549     {
21550       errmsg ("Server address required");
21551       return -99;
21552     }
21553
21554   /* Construct the API message */
21555   M (DNS_NAME_SERVER_ADD_DEL, mp);
21556
21557   if (ip6_set)
21558     {
21559       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21560       mp->is_ip6 = 1;
21561     }
21562   else
21563     {
21564       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21565       mp->is_ip6 = 0;
21566     }
21567
21568   mp->is_add = is_add;
21569
21570   /* send it... */
21571   S (mp);
21572
21573   /* Wait for a reply, return good/bad news  */
21574   W (ret);
21575   return ret;
21576 }
21577
21578 static void
21579 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21580 {
21581   vat_main_t *vam = &vat_main;
21582
21583   if (mp->is_ip4)
21584     {
21585       print (vam->ofp,
21586              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21587              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21588              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21589              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21590              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21591              clib_net_to_host_u32 (mp->action_index), mp->tag);
21592     }
21593   else
21594     {
21595       print (vam->ofp,
21596              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21597              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21598              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21599              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21600              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21601              clib_net_to_host_u32 (mp->action_index), mp->tag);
21602     }
21603 }
21604
21605 static void
21606 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21607                                              mp)
21608 {
21609   vat_main_t *vam = &vat_main;
21610   vat_json_node_t *node = NULL;
21611   struct in6_addr ip6;
21612   struct in_addr ip4;
21613
21614   if (VAT_JSON_ARRAY != vam->json_tree.type)
21615     {
21616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21617       vat_json_init_array (&vam->json_tree);
21618     }
21619   node = vat_json_array_add (&vam->json_tree);
21620   vat_json_init_object (node);
21621
21622   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21623   vat_json_object_add_uint (node, "appns_index",
21624                             clib_net_to_host_u32 (mp->appns_index));
21625   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21626   vat_json_object_add_uint (node, "scope", mp->scope);
21627   vat_json_object_add_uint (node, "action_index",
21628                             clib_net_to_host_u32 (mp->action_index));
21629   vat_json_object_add_uint (node, "lcl_port",
21630                             clib_net_to_host_u16 (mp->lcl_port));
21631   vat_json_object_add_uint (node, "rmt_port",
21632                             clib_net_to_host_u16 (mp->rmt_port));
21633   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21634   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21635   vat_json_object_add_string_copy (node, "tag", mp->tag);
21636   if (mp->is_ip4)
21637     {
21638       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21639       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21640       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21641       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21642     }
21643   else
21644     {
21645       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21646       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21647       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21648       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21649     }
21650 }
21651
21652 static int
21653 api_session_rule_add_del (vat_main_t * vam)
21654 {
21655   vl_api_session_rule_add_del_t *mp;
21656   unformat_input_t *i = vam->input;
21657   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21658   u32 appns_index = 0, scope = 0;
21659   ip4_address_t lcl_ip4, rmt_ip4;
21660   ip6_address_t lcl_ip6, rmt_ip6;
21661   u8 is_ip4 = 1, conn_set = 0;
21662   u8 is_add = 1, *tag = 0;
21663   int ret;
21664
21665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21666     {
21667       if (unformat (i, "del"))
21668         is_add = 0;
21669       else if (unformat (i, "add"))
21670         ;
21671       else if (unformat (i, "proto tcp"))
21672         proto = 0;
21673       else if (unformat (i, "proto udp"))
21674         proto = 1;
21675       else if (unformat (i, "appns %d", &appns_index))
21676         ;
21677       else if (unformat (i, "scope %d", &scope))
21678         ;
21679       else if (unformat (i, "tag %_%v%_", &tag))
21680         ;
21681       else
21682         if (unformat
21683             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21684              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21685              &rmt_port))
21686         {
21687           is_ip4 = 1;
21688           conn_set = 1;
21689         }
21690       else
21691         if (unformat
21692             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21693              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21694              &rmt_port))
21695         {
21696           is_ip4 = 0;
21697           conn_set = 1;
21698         }
21699       else if (unformat (i, "action %d", &action))
21700         ;
21701       else
21702         break;
21703     }
21704   if (proto == ~0 || !conn_set || action == ~0)
21705     {
21706       errmsg ("transport proto, connection and action must be set");
21707       return -99;
21708     }
21709
21710   if (scope > 3)
21711     {
21712       errmsg ("scope should be 0-3");
21713       return -99;
21714     }
21715
21716   M (SESSION_RULE_ADD_DEL, mp);
21717
21718   mp->is_ip4 = is_ip4;
21719   mp->transport_proto = proto;
21720   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21721   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21722   mp->lcl_plen = lcl_plen;
21723   mp->rmt_plen = rmt_plen;
21724   mp->action_index = clib_host_to_net_u32 (action);
21725   mp->appns_index = clib_host_to_net_u32 (appns_index);
21726   mp->scope = scope;
21727   mp->is_add = is_add;
21728   if (is_ip4)
21729     {
21730       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21731       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21732     }
21733   else
21734     {
21735       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21736       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21737     }
21738   if (tag)
21739     {
21740       clib_memcpy (mp->tag, tag, vec_len (tag));
21741       vec_free (tag);
21742     }
21743
21744   S (mp);
21745   W (ret);
21746   return ret;
21747 }
21748
21749 static int
21750 api_session_rules_dump (vat_main_t * vam)
21751 {
21752   vl_api_session_rules_dump_t *mp;
21753   vl_api_control_ping_t *mp_ping;
21754   int ret;
21755
21756   if (!vam->json_output)
21757     {
21758       print (vam->ofp, "%=20s", "Session Rules");
21759     }
21760
21761   M (SESSION_RULES_DUMP, mp);
21762   /* send it... */
21763   S (mp);
21764
21765   /* Use a control ping for synchronization */
21766   MPING (CONTROL_PING, mp_ping);
21767   S (mp_ping);
21768
21769   /* Wait for a reply... */
21770   W (ret);
21771   return ret;
21772 }
21773
21774 static int
21775 api_ip_container_proxy_add_del (vat_main_t * vam)
21776 {
21777   vl_api_ip_container_proxy_add_del_t *mp;
21778   unformat_input_t *i = vam->input;
21779   u32 sw_if_index = ~0;
21780   vl_api_prefix_t pfx = { };
21781   u8 is_add = 1;
21782   int ret;
21783
21784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21785     {
21786       if (unformat (i, "del"))
21787         is_add = 0;
21788       else if (unformat (i, "add"))
21789         ;
21790       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21791         ;
21792       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21793         ;
21794       else
21795         break;
21796     }
21797   if (sw_if_index == ~0 || pfx.address_length == 0)
21798     {
21799       errmsg ("address and sw_if_index must be set");
21800       return -99;
21801     }
21802
21803   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21804
21805   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21806   mp->is_add = is_add;
21807   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21808
21809   S (mp);
21810   W (ret);
21811   return ret;
21812 }
21813
21814 static int
21815 api_qos_record_enable_disable (vat_main_t * vam)
21816 {
21817   unformat_input_t *i = vam->input;
21818   vl_api_qos_record_enable_disable_t *mp;
21819   u32 sw_if_index, qs = 0xff;
21820   u8 sw_if_index_set = 0;
21821   u8 enable = 1;
21822   int ret;
21823
21824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21825     {
21826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21827         sw_if_index_set = 1;
21828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21829         sw_if_index_set = 1;
21830       else if (unformat (i, "%U", unformat_qos_source, &qs))
21831         ;
21832       else if (unformat (i, "disable"))
21833         enable = 0;
21834       else
21835         {
21836           clib_warning ("parse error '%U'", format_unformat_error, i);
21837           return -99;
21838         }
21839     }
21840
21841   if (sw_if_index_set == 0)
21842     {
21843       errmsg ("missing interface name or sw_if_index");
21844       return -99;
21845     }
21846   if (qs == 0xff)
21847     {
21848       errmsg ("input location must be specified");
21849       return -99;
21850     }
21851
21852   M (QOS_RECORD_ENABLE_DISABLE, mp);
21853
21854   mp->sw_if_index = ntohl (sw_if_index);
21855   mp->input_source = qs;
21856   mp->enable = enable;
21857
21858   S (mp);
21859   W (ret);
21860   return ret;
21861 }
21862
21863
21864 static int
21865 q_or_quit (vat_main_t * vam)
21866 {
21867 #if VPP_API_TEST_BUILTIN == 0
21868   longjmp (vam->jump_buf, 1);
21869 #endif
21870   return 0;                     /* not so much */
21871 }
21872
21873 static int
21874 q (vat_main_t * vam)
21875 {
21876   return q_or_quit (vam);
21877 }
21878
21879 static int
21880 quit (vat_main_t * vam)
21881 {
21882   return q_or_quit (vam);
21883 }
21884
21885 static int
21886 comment (vat_main_t * vam)
21887 {
21888   return 0;
21889 }
21890
21891 static int
21892 statseg (vat_main_t * vam)
21893 {
21894   ssvm_private_t *ssvmp = &vam->stat_segment;
21895   ssvm_shared_header_t *shared_header = ssvmp->sh;
21896   vlib_counter_t **counters;
21897   u64 thread0_index1_packets;
21898   u64 thread0_index1_bytes;
21899   f64 vector_rate, input_rate;
21900   uword *p;
21901
21902   uword *counter_vector_by_name;
21903   if (vam->stat_segment_lockp == 0)
21904     {
21905       errmsg ("Stat segment not mapped...");
21906       return -99;
21907     }
21908
21909   /* look up "/if/rx for sw_if_index 1 as a test */
21910
21911   clib_spinlock_lock (vam->stat_segment_lockp);
21912
21913   counter_vector_by_name = (uword *) shared_header->opaque[1];
21914
21915   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21916   if (p == 0)
21917     {
21918       clib_spinlock_unlock (vam->stat_segment_lockp);
21919       errmsg ("/if/tx not found?");
21920       return -99;
21921     }
21922
21923   /* Fish per-thread vector of combined counters from shared memory */
21924   counters = (vlib_counter_t **) p[0];
21925
21926   if (vec_len (counters[0]) < 2)
21927     {
21928       clib_spinlock_unlock (vam->stat_segment_lockp);
21929       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21930       return -99;
21931     }
21932
21933   /* Read thread 0 sw_if_index 1 counter */
21934   thread0_index1_packets = counters[0][1].packets;
21935   thread0_index1_bytes = counters[0][1].bytes;
21936
21937   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21938   if (p == 0)
21939     {
21940       clib_spinlock_unlock (vam->stat_segment_lockp);
21941       errmsg ("vector_rate not found?");
21942       return -99;
21943     }
21944
21945   vector_rate = *(f64 *) (p[0]);
21946   p = hash_get_mem (counter_vector_by_name, "input_rate");
21947   if (p == 0)
21948     {
21949       clib_spinlock_unlock (vam->stat_segment_lockp);
21950       errmsg ("input_rate not found?");
21951       return -99;
21952     }
21953   input_rate = *(f64 *) (p[0]);
21954
21955   clib_spinlock_unlock (vam->stat_segment_lockp);
21956
21957   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21958          vector_rate, input_rate);
21959   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21960          thread0_index1_packets, thread0_index1_bytes);
21961
21962   return 0;
21963 }
21964
21965 static int
21966 cmd_cmp (void *a1, void *a2)
21967 {
21968   u8 **c1 = a1;
21969   u8 **c2 = a2;
21970
21971   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21972 }
21973
21974 static int
21975 help (vat_main_t * vam)
21976 {
21977   u8 **cmds = 0;
21978   u8 *name = 0;
21979   hash_pair_t *p;
21980   unformat_input_t *i = vam->input;
21981   int j;
21982
21983   if (unformat (i, "%s", &name))
21984     {
21985       uword *hs;
21986
21987       vec_add1 (name, 0);
21988
21989       hs = hash_get_mem (vam->help_by_name, name);
21990       if (hs)
21991         print (vam->ofp, "usage: %s %s", name, hs[0]);
21992       else
21993         print (vam->ofp, "No such msg / command '%s'", name);
21994       vec_free (name);
21995       return 0;
21996     }
21997
21998   print (vam->ofp, "Help is available for the following:");
21999
22000     /* *INDENT-OFF* */
22001     hash_foreach_pair (p, vam->function_by_name,
22002     ({
22003       vec_add1 (cmds, (u8 *)(p->key));
22004     }));
22005     /* *INDENT-ON* */
22006
22007   vec_sort_with_function (cmds, cmd_cmp);
22008
22009   for (j = 0; j < vec_len (cmds); j++)
22010     print (vam->ofp, "%s", cmds[j]);
22011
22012   vec_free (cmds);
22013   return 0;
22014 }
22015
22016 static int
22017 set (vat_main_t * vam)
22018 {
22019   u8 *name = 0, *value = 0;
22020   unformat_input_t *i = vam->input;
22021
22022   if (unformat (i, "%s", &name))
22023     {
22024       /* The input buffer is a vector, not a string. */
22025       value = vec_dup (i->buffer);
22026       vec_delete (value, i->index, 0);
22027       /* Almost certainly has a trailing newline */
22028       if (value[vec_len (value) - 1] == '\n')
22029         value[vec_len (value) - 1] = 0;
22030       /* Make sure it's a proper string, one way or the other */
22031       vec_add1 (value, 0);
22032       (void) clib_macro_set_value (&vam->macro_main,
22033                                    (char *) name, (char *) value);
22034     }
22035   else
22036     errmsg ("usage: set <name> <value>");
22037
22038   vec_free (name);
22039   vec_free (value);
22040   return 0;
22041 }
22042
22043 static int
22044 unset (vat_main_t * vam)
22045 {
22046   u8 *name = 0;
22047
22048   if (unformat (vam->input, "%s", &name))
22049     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22050       errmsg ("unset: %s wasn't set", name);
22051   vec_free (name);
22052   return 0;
22053 }
22054
22055 typedef struct
22056 {
22057   u8 *name;
22058   u8 *value;
22059 } macro_sort_t;
22060
22061
22062 static int
22063 macro_sort_cmp (void *a1, void *a2)
22064 {
22065   macro_sort_t *s1 = a1;
22066   macro_sort_t *s2 = a2;
22067
22068   return strcmp ((char *) (s1->name), (char *) (s2->name));
22069 }
22070
22071 static int
22072 dump_macro_table (vat_main_t * vam)
22073 {
22074   macro_sort_t *sort_me = 0, *sm;
22075   int i;
22076   hash_pair_t *p;
22077
22078     /* *INDENT-OFF* */
22079     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22080     ({
22081       vec_add2 (sort_me, sm, 1);
22082       sm->name = (u8 *)(p->key);
22083       sm->value = (u8 *) (p->value[0]);
22084     }));
22085     /* *INDENT-ON* */
22086
22087   vec_sort_with_function (sort_me, macro_sort_cmp);
22088
22089   if (vec_len (sort_me))
22090     print (vam->ofp, "%-15s%s", "Name", "Value");
22091   else
22092     print (vam->ofp, "The macro table is empty...");
22093
22094   for (i = 0; i < vec_len (sort_me); i++)
22095     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22096   return 0;
22097 }
22098
22099 static int
22100 dump_node_table (vat_main_t * vam)
22101 {
22102   int i, j;
22103   vlib_node_t *node, *next_node;
22104
22105   if (vec_len (vam->graph_nodes) == 0)
22106     {
22107       print (vam->ofp, "Node table empty, issue get_node_graph...");
22108       return 0;
22109     }
22110
22111   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22112     {
22113       node = vam->graph_nodes[0][i];
22114       print (vam->ofp, "[%d] %s", i, node->name);
22115       for (j = 0; j < vec_len (node->next_nodes); j++)
22116         {
22117           if (node->next_nodes[j] != ~0)
22118             {
22119               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22120               print (vam->ofp, "  [%d] %s", j, next_node->name);
22121             }
22122         }
22123     }
22124   return 0;
22125 }
22126
22127 static int
22128 value_sort_cmp (void *a1, void *a2)
22129 {
22130   name_sort_t *n1 = a1;
22131   name_sort_t *n2 = a2;
22132
22133   if (n1->value < n2->value)
22134     return -1;
22135   if (n1->value > n2->value)
22136     return 1;
22137   return 0;
22138 }
22139
22140
22141 static int
22142 dump_msg_api_table (vat_main_t * vam)
22143 {
22144   api_main_t *am = &api_main;
22145   name_sort_t *nses = 0, *ns;
22146   hash_pair_t *hp;
22147   int i;
22148
22149   /* *INDENT-OFF* */
22150   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22151   ({
22152     vec_add2 (nses, ns, 1);
22153     ns->name = (u8 *)(hp->key);
22154     ns->value = (u32) hp->value[0];
22155   }));
22156   /* *INDENT-ON* */
22157
22158   vec_sort_with_function (nses, value_sort_cmp);
22159
22160   for (i = 0; i < vec_len (nses); i++)
22161     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22162   vec_free (nses);
22163   return 0;
22164 }
22165
22166 static int
22167 get_msg_id (vat_main_t * vam)
22168 {
22169   u8 *name_and_crc;
22170   u32 message_index;
22171
22172   if (unformat (vam->input, "%s", &name_and_crc))
22173     {
22174       message_index = vl_msg_api_get_msg_index (name_and_crc);
22175       if (message_index == ~0)
22176         {
22177           print (vam->ofp, " '%s' not found", name_and_crc);
22178           return 0;
22179         }
22180       print (vam->ofp, " '%s' has message index %d",
22181              name_and_crc, message_index);
22182       return 0;
22183     }
22184   errmsg ("name_and_crc required...");
22185   return 0;
22186 }
22187
22188 static int
22189 search_node_table (vat_main_t * vam)
22190 {
22191   unformat_input_t *line_input = vam->input;
22192   u8 *node_to_find;
22193   int j;
22194   vlib_node_t *node, *next_node;
22195   uword *p;
22196
22197   if (vam->graph_node_index_by_name == 0)
22198     {
22199       print (vam->ofp, "Node table empty, issue get_node_graph...");
22200       return 0;
22201     }
22202
22203   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22204     {
22205       if (unformat (line_input, "%s", &node_to_find))
22206         {
22207           vec_add1 (node_to_find, 0);
22208           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22209           if (p == 0)
22210             {
22211               print (vam->ofp, "%s not found...", node_to_find);
22212               goto out;
22213             }
22214           node = vam->graph_nodes[0][p[0]];
22215           print (vam->ofp, "[%d] %s", p[0], node->name);
22216           for (j = 0; j < vec_len (node->next_nodes); j++)
22217             {
22218               if (node->next_nodes[j] != ~0)
22219                 {
22220                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22221                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22222                 }
22223             }
22224         }
22225
22226       else
22227         {
22228           clib_warning ("parse error '%U'", format_unformat_error,
22229                         line_input);
22230           return -99;
22231         }
22232
22233     out:
22234       vec_free (node_to_find);
22235
22236     }
22237
22238   return 0;
22239 }
22240
22241
22242 static int
22243 script (vat_main_t * vam)
22244 {
22245 #if (VPP_API_TEST_BUILTIN==0)
22246   u8 *s = 0;
22247   char *save_current_file;
22248   unformat_input_t save_input;
22249   jmp_buf save_jump_buf;
22250   u32 save_line_number;
22251
22252   FILE *new_fp, *save_ifp;
22253
22254   if (unformat (vam->input, "%s", &s))
22255     {
22256       new_fp = fopen ((char *) s, "r");
22257       if (new_fp == 0)
22258         {
22259           errmsg ("Couldn't open script file %s", s);
22260           vec_free (s);
22261           return -99;
22262         }
22263     }
22264   else
22265     {
22266       errmsg ("Missing script name");
22267       return -99;
22268     }
22269
22270   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22271   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22272   save_ifp = vam->ifp;
22273   save_line_number = vam->input_line_number;
22274   save_current_file = (char *) vam->current_file;
22275
22276   vam->input_line_number = 0;
22277   vam->ifp = new_fp;
22278   vam->current_file = s;
22279   do_one_file (vam);
22280
22281   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22282   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22283   vam->ifp = save_ifp;
22284   vam->input_line_number = save_line_number;
22285   vam->current_file = (u8 *) save_current_file;
22286   vec_free (s);
22287
22288   return 0;
22289 #else
22290   clib_warning ("use the exec command...");
22291   return -99;
22292 #endif
22293 }
22294
22295 static int
22296 echo (vat_main_t * vam)
22297 {
22298   print (vam->ofp, "%v", vam->input->buffer);
22299   return 0;
22300 }
22301
22302 /* List of API message constructors, CLI names map to api_xxx */
22303 #define foreach_vpe_api_msg                                             \
22304 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22305 _(sw_interface_dump,"")                                                 \
22306 _(sw_interface_set_flags,                                               \
22307   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22308 _(sw_interface_add_del_address,                                         \
22309   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22310 _(sw_interface_set_rx_mode,                                             \
22311   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22312 _(sw_interface_set_rx_placement,                                        \
22313   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22314 _(sw_interface_rx_placement_dump,                                       \
22315   "[<intfc> | sw_if_index <id>]")                                         \
22316 _(sw_interface_set_table,                                               \
22317   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22318 _(sw_interface_set_mpls_enable,                                         \
22319   "<intfc> | sw_if_index [disable | dis]")                              \
22320 _(sw_interface_set_vpath,                                               \
22321   "<intfc> | sw_if_index <id> enable | disable")                        \
22322 _(sw_interface_set_vxlan_bypass,                                        \
22323   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22324 _(sw_interface_set_geneve_bypass,                                       \
22325   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22326 _(sw_interface_set_l2_xconnect,                                         \
22327   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22328   "enable | disable")                                                   \
22329 _(sw_interface_set_l2_bridge,                                           \
22330   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22331   "[shg <split-horizon-group>] [bvi]\n"                                 \
22332   "enable | disable")                                                   \
22333 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22334 _(bridge_domain_add_del,                                                \
22335   "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") \
22336 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22337 _(l2fib_add_del,                                                        \
22338   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22339 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22340 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22341 _(l2_flags,                                                             \
22342   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22343 _(bridge_flags,                                                         \
22344   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22345 _(tap_create_v2,                                                        \
22346   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22347 _(tap_delete_v2,                                                        \
22348   "<vpp-if-name> | sw_if_index <id>")                                   \
22349 _(sw_interface_tap_v2_dump, "")                                         \
22350 _(virtio_pci_create,                                                    \
22351   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
22352 _(virtio_pci_delete,                                                    \
22353   "<vpp-if-name> | sw_if_index <id>")                                   \
22354 _(sw_interface_virtio_pci_dump, "")                                     \
22355 _(bond_create,                                                          \
22356   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22357   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22358   "[id <if-id>]")                                                       \
22359 _(bond_delete,                                                          \
22360   "<vpp-if-name> | sw_if_index <id>")                                   \
22361 _(bond_enslave,                                                         \
22362   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22363 _(bond_detach_slave,                                                    \
22364   "sw_if_index <n>")                                                    \
22365 _(sw_interface_bond_dump, "")                                           \
22366 _(sw_interface_slave_dump,                                              \
22367   "<vpp-if-name> | sw_if_index <id>")                                   \
22368 _(ip_table_add_del,                                                     \
22369   "table <n> [ipv6] [add | del]\n")                                     \
22370 _(ip_add_del_route,                                                     \
22371   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22372   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22373   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22374   "[multipath] [count <n>] [del]")                                      \
22375 _(ip_mroute_add_del,                                                    \
22376   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22377   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22378 _(mpls_table_add_del,                                                   \
22379   "table <n> [add | del]\n")                                            \
22380 _(mpls_route_add_del,                                                   \
22381   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22382   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22383   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22384   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22385   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22386   "[count <n>] [del]")                                                  \
22387 _(mpls_ip_bind_unbind,                                                  \
22388   "<label> <addr/len>")                                                 \
22389 _(mpls_tunnel_add_del,                                                  \
22390   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22391   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22392   "[l2-only]  [out-label <n>]")                                         \
22393 _(sr_mpls_policy_add,                                                   \
22394   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22395 _(sr_mpls_policy_del,                                                   \
22396   "bsid <id>")                                                          \
22397 _(bier_table_add_del,                                                   \
22398   "<label> <sub-domain> <set> <bsl> [del]")                             \
22399 _(bier_route_add_del,                                                   \
22400   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22401   "[<intfc> | sw_if_index <id>]"                                        \
22402   "[weight <n>] [del] [multipath]")                                     \
22403 _(proxy_arp_add_del,                                                    \
22404   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22405 _(proxy_arp_intfc_enable_disable,                                       \
22406   "<intfc> | sw_if_index <id> enable | disable")                        \
22407 _(sw_interface_set_unnumbered,                                          \
22408   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22409 _(ip_neighbor_add_del,                                                  \
22410   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22411   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22412 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22413 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22414   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22415   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22416   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22417 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22418 _(reset_fib, "vrf <n> [ipv6]")                                          \
22419 _(dhcp_proxy_config,                                                    \
22420   "svr <v46-address> src <v46-address>\n"                               \
22421    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22422 _(dhcp_proxy_set_vss,                                                   \
22423   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22424 _(dhcp_proxy_dump, "ip6")                                               \
22425 _(dhcp_client_config,                                                   \
22426   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22427 _(set_ip_flow_hash,                                                     \
22428   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22429 _(sw_interface_ip6_enable_disable,                                      \
22430   "<intfc> | sw_if_index <id> enable | disable")                        \
22431 _(ip6nd_proxy_add_del,                                                  \
22432   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22433 _(ip6nd_proxy_dump, "")                                                 \
22434 _(sw_interface_ip6nd_ra_prefix,                                         \
22435   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22436   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22437   "[nolink] [isno]")                                                    \
22438 _(sw_interface_ip6nd_ra_config,                                         \
22439   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22440   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22441   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22442 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22443 _(l2_patch_add_del,                                                     \
22444   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22445   "enable | disable")                                                   \
22446 _(sr_localsid_add_del,                                                  \
22447   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22448   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22449 _(classify_add_del_table,                                               \
22450   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22451   " [del] [del-chain] mask <mask-value>\n"                              \
22452   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22453   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22454 _(classify_add_del_session,                                             \
22455   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22456   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22457   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22458   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22459 _(classify_set_interface_ip_table,                                      \
22460   "<intfc> | sw_if_index <nn> table <nn>")                              \
22461 _(classify_set_interface_l2_tables,                                     \
22462   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22463   "  [other-table <nn>]")                                               \
22464 _(get_node_index, "node <node-name")                                    \
22465 _(add_node_next, "node <node-name> next <next-node-name>")              \
22466 _(l2tpv3_create_tunnel,                                                 \
22467   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22468   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22469   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22470 _(l2tpv3_set_tunnel_cookies,                                            \
22471   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22472   "[new_remote_cookie <nn>]\n")                                         \
22473 _(l2tpv3_interface_enable_disable,                                      \
22474   "<intfc> | sw_if_index <nn> enable | disable")                        \
22475 _(l2tpv3_set_lookup_key,                                                \
22476   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22477 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22478 _(vxlan_offload_rx,                                                     \
22479   "hw { <interface name> | hw_if_index <nn>} "                          \
22480   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22481 _(vxlan_add_del_tunnel,                                                 \
22482   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22483   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22484   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22485 _(geneve_add_del_tunnel,                                                \
22486   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22487   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22488   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22489 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22490 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22491 _(gre_tunnel_add_del,                                                   \
22492   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22493   "[teb | erspan <session-id>] [del]")                                  \
22494 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22495 _(l2_fib_clear_table, "")                                               \
22496 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22497 _(l2_interface_vlan_tag_rewrite,                                        \
22498   "<intfc> | sw_if_index <nn> \n"                                       \
22499   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22500   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22501 _(create_vhost_user_if,                                                 \
22502         "socket <filename> [server] [renumber <dev_instance>] "         \
22503         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22504         "[mac <mac_address>]")                                          \
22505 _(modify_vhost_user_if,                                                 \
22506         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22507         "[server] [renumber <dev_instance>]")                           \
22508 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22509 _(sw_interface_vhost_user_dump, "")                                     \
22510 _(show_version, "")                                                     \
22511 _(show_threads, "")                                                     \
22512 _(vxlan_gpe_add_del_tunnel,                                             \
22513   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22514   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22515   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22516   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22517 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22518 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22519 _(interface_name_renumber,                                              \
22520   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22521 _(input_acl_set_interface,                                              \
22522   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22523   "  [l2-table <nn>] [del]")                                            \
22524 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22525 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22526   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22527 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22528 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22529 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22530 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22531 _(ip_dump, "ipv4 | ipv6")                                               \
22532 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22533 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22534   "  spid_id <n> ")                                                     \
22535 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22536   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22537   "  integ_alg <alg> integ_key <hex>")                                  \
22538 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22539   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22540   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22541   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22542 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22543 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22544   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22545   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22546   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22547   "  [instance <n>]")     \
22548 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22549 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22550   "  <alg> <hex>\n")                                                    \
22551 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22552 _(delete_loopback,"sw_if_index <nn>")                                   \
22553 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22554 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22555 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22556 _(want_interface_events,  "enable|disable")                             \
22557 _(get_first_msg_id, "client <name>")                                    \
22558 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22559 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22560   "fib-id <nn> [ip4][ip6][default]")                                    \
22561 _(get_node_graph, " ")                                                  \
22562 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22563 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22564 _(ioam_disable, "")                                                     \
22565 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22566                             " sw_if_index <sw_if_index> p <priority> "  \
22567                             "w <weight>] [del]")                        \
22568 _(one_add_del_locator, "locator-set <locator_name> "                    \
22569                         "iface <intf> | sw_if_index <sw_if_index> "     \
22570                         "p <priority> w <weight> [del]")                \
22571 _(one_add_del_local_eid,"vni <vni> eid "                                \
22572                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22573                          "locator-set <locator_name> [del]"             \
22574                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22575 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22576 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22577 _(one_enable_disable, "enable|disable")                                 \
22578 _(one_map_register_enable_disable, "enable|disable")                    \
22579 _(one_map_register_fallback_threshold, "<value>")                       \
22580 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22581 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22582                                "[seid <seid>] "                         \
22583                                "rloc <locator> p <prio> "               \
22584                                "w <weight> [rloc <loc> ... ] "          \
22585                                "action <action> [del-all]")             \
22586 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22587                           "<local-eid>")                                \
22588 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22589 _(one_use_petr, "ip-address> | disable")                                \
22590 _(one_map_request_mode, "src-dst|dst-only")                             \
22591 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22592 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22593 _(one_locator_set_dump, "[local | remote]")                             \
22594 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22595 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22596                        "[local] | [remote]")                            \
22597 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22598 _(one_ndp_bd_get, "")                                                   \
22599 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22600 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22601 _(one_l2_arp_bd_get, "")                                                \
22602 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22603 _(one_stats_enable_disable, "enable|disable")                           \
22604 _(show_one_stats_enable_disable, "")                                    \
22605 _(one_eid_table_vni_dump, "")                                           \
22606 _(one_eid_table_map_dump, "l2|l3")                                      \
22607 _(one_map_resolver_dump, "")                                            \
22608 _(one_map_server_dump, "")                                              \
22609 _(one_adjacencies_get, "vni <vni>")                                     \
22610 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22611 _(show_one_rloc_probe_state, "")                                        \
22612 _(show_one_map_register_state, "")                                      \
22613 _(show_one_status, "")                                                  \
22614 _(one_stats_dump, "")                                                   \
22615 _(one_stats_flush, "")                                                  \
22616 _(one_get_map_request_itr_rlocs, "")                                    \
22617 _(one_map_register_set_ttl, "<ttl>")                                    \
22618 _(one_set_transport_protocol, "udp|api")                                \
22619 _(one_get_transport_protocol, "")                                       \
22620 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22621 _(one_show_xtr_mode, "")                                                \
22622 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22623 _(one_show_pitr_mode, "")                                               \
22624 _(one_enable_disable_petr_mode, "enable|disable")                       \
22625 _(one_show_petr_mode, "")                                               \
22626 _(show_one_nsh_mapping, "")                                             \
22627 _(show_one_pitr, "")                                                    \
22628 _(show_one_use_petr, "")                                                \
22629 _(show_one_map_request_mode, "")                                        \
22630 _(show_one_map_register_ttl, "")                                        \
22631 _(show_one_map_register_fallback_threshold, "")                         \
22632 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22633                             " sw_if_index <sw_if_index> p <priority> "  \
22634                             "w <weight>] [del]")                        \
22635 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22636                         "iface <intf> | sw_if_index <sw_if_index> "     \
22637                         "p <priority> w <weight> [del]")                \
22638 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22639                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22640                          "locator-set <locator_name> [del]"             \
22641                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22642 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22643 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22644 _(lisp_enable_disable, "enable|disable")                                \
22645 _(lisp_map_register_enable_disable, "enable|disable")                   \
22646 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22647 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22648                                "[seid <seid>] "                         \
22649                                "rloc <locator> p <prio> "               \
22650                                "w <weight> [rloc <loc> ... ] "          \
22651                                "action <action> [del-all]")             \
22652 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22653                           "<local-eid>")                                \
22654 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22655 _(lisp_use_petr, "<ip-address> | disable")                              \
22656 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22657 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22658 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22659 _(lisp_locator_set_dump, "[local | remote]")                            \
22660 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22661 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22662                        "[local] | [remote]")                            \
22663 _(lisp_eid_table_vni_dump, "")                                          \
22664 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22665 _(lisp_map_resolver_dump, "")                                           \
22666 _(lisp_map_server_dump, "")                                             \
22667 _(lisp_adjacencies_get, "vni <vni>")                                    \
22668 _(gpe_fwd_entry_vnis_get, "")                                           \
22669 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22670 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22671                                 "[table <table-id>]")                   \
22672 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22673 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22674 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22675 _(gpe_get_encap_mode, "")                                               \
22676 _(lisp_gpe_add_del_iface, "up|down")                                    \
22677 _(lisp_gpe_enable_disable, "enable|disable")                            \
22678 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22679   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22680 _(show_lisp_rloc_probe_state, "")                                       \
22681 _(show_lisp_map_register_state, "")                                     \
22682 _(show_lisp_status, "")                                                 \
22683 _(lisp_get_map_request_itr_rlocs, "")                                   \
22684 _(show_lisp_pitr, "")                                                   \
22685 _(show_lisp_use_petr, "")                                               \
22686 _(show_lisp_map_request_mode, "")                                       \
22687 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22688 _(af_packet_delete, "name <host interface name>")                       \
22689 _(af_packet_dump, "")                                                   \
22690 _(policer_add_del, "name <policer name> <params> [del]")                \
22691 _(policer_dump, "[name <policer name>]")                                \
22692 _(policer_classify_set_interface,                                       \
22693   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22694   "  [l2-table <nn>] [del]")                                            \
22695 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22696 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22697     "[master|slave]")                                                   \
22698 _(netmap_delete, "name <interface name>")                               \
22699 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22700 _(mpls_fib_dump, "")                                                    \
22701 _(classify_table_ids, "")                                               \
22702 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22703 _(classify_table_info, "table_id <nn>")                                 \
22704 _(classify_session_dump, "table_id <nn>")                               \
22705 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22706     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22707     "[template_interval <nn>] [udp_checksum]")                          \
22708 _(ipfix_exporter_dump, "")                                              \
22709 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22710 _(ipfix_classify_stream_dump, "")                                       \
22711 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22712 _(ipfix_classify_table_dump, "")                                        \
22713 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22714 _(sw_interface_span_dump, "[l2]")                                           \
22715 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22716 _(pg_create_interface, "if_id <nn>")                                    \
22717 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22718 _(pg_enable_disable, "[stream <id>] disable")                           \
22719 _(ip_source_and_port_range_check_add_del,                               \
22720   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22721 _(ip_source_and_port_range_check_interface_add_del,                     \
22722   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22723   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22724 _(ipsec_gre_tunnel_add_del,                                             \
22725   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22726 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22727 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22728 _(l2_interface_pbb_tag_rewrite,                                         \
22729   "<intfc> | sw_if_index <nn> \n"                                       \
22730   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22731   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22732 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22733 _(flow_classify_set_interface,                                          \
22734   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22735 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22736 _(ip_fib_dump, "")                                                      \
22737 _(ip_mfib_dump, "")                                                     \
22738 _(ip6_fib_dump, "")                                                     \
22739 _(ip6_mfib_dump, "")                                                    \
22740 _(feature_enable_disable, "arc_name <arc_name> "                        \
22741   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22742 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22743 "[disable]")                                                            \
22744 _(l2_xconnect_dump, "")                                                 \
22745 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22746 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22747 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22748 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22749 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22750 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22751 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22752   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22753 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22754 _(sock_init_shm, "size <nnn>")                                          \
22755 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22756 _(dns_enable_disable, "[enable][disable]")                              \
22757 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22758 _(dns_resolve_name, "<hostname>")                                       \
22759 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22760 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22761 _(dns_resolve_name, "<hostname>")                                       \
22762 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22763   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22764 _(session_rules_dump, "")                                               \
22765 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22766 _(output_acl_set_interface,                                             \
22767   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22768   "  [l2-table <nn>] [del]")                                            \
22769 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22770
22771 /* List of command functions, CLI names map directly to functions */
22772 #define foreach_cli_function                                    \
22773 _(comment, "usage: comment <ignore-rest-of-line>")              \
22774 _(dump_interface_table, "usage: dump_interface_table")          \
22775 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22776 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22777 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22778 _(dump_macro_table, "usage: dump_macro_table ")                 \
22779 _(dump_node_table, "usage: dump_node_table")                    \
22780 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22781 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22782 _(echo, "usage: echo <message>")                                \
22783 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22784 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22785 _(help, "usage: help")                                          \
22786 _(q, "usage: quit")                                             \
22787 _(quit, "usage: quit")                                          \
22788 _(search_node_table, "usage: search_node_table <name>...")      \
22789 _(set, "usage: set <variable-name> <value>")                    \
22790 _(script, "usage: script <file-name>")                          \
22791 _(statseg, "usage: statseg");                                   \
22792 _(unset, "usage: unset <variable-name>")
22793
22794 #define _(N,n)                                  \
22795     static void vl_api_##n##_t_handler_uni      \
22796     (vl_api_##n##_t * mp)                       \
22797     {                                           \
22798         vat_main_t * vam = &vat_main;           \
22799         if (vam->json_output) {                 \
22800             vl_api_##n##_t_handler_json(mp);    \
22801         } else {                                \
22802             vl_api_##n##_t_handler(mp);         \
22803         }                                       \
22804     }
22805 foreach_vpe_api_reply_msg;
22806 #if VPP_API_TEST_BUILTIN == 0
22807 foreach_standalone_reply_msg;
22808 #endif
22809 #undef _
22810
22811 void
22812 vat_api_hookup (vat_main_t * vam)
22813 {
22814 #define _(N,n)                                                  \
22815     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22816                            vl_api_##n##_t_handler_uni,          \
22817                            vl_noop_handler,                     \
22818                            vl_api_##n##_t_endian,               \
22819                            vl_api_##n##_t_print,                \
22820                            sizeof(vl_api_##n##_t), 1);
22821   foreach_vpe_api_reply_msg;
22822 #if VPP_API_TEST_BUILTIN == 0
22823   foreach_standalone_reply_msg;
22824 #endif
22825 #undef _
22826
22827 #if (VPP_API_TEST_BUILTIN==0)
22828   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22829
22830   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22831
22832   vam->function_by_name = hash_create_string (0, sizeof (uword));
22833
22834   vam->help_by_name = hash_create_string (0, sizeof (uword));
22835 #endif
22836
22837   /* API messages we can send */
22838 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22839   foreach_vpe_api_msg;
22840 #undef _
22841
22842   /* Help strings */
22843 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22844   foreach_vpe_api_msg;
22845 #undef _
22846
22847   /* CLI functions */
22848 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22849   foreach_cli_function;
22850 #undef _
22851
22852   /* Help strings */
22853 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22854   foreach_cli_function;
22855 #undef _
22856 }
22857
22858 #if VPP_API_TEST_BUILTIN
22859 static clib_error_t *
22860 vat_api_hookup_shim (vlib_main_t * vm)
22861 {
22862   vat_api_hookup (&vat_main);
22863   return 0;
22864 }
22865
22866 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22867 #endif
22868
22869 /*
22870  * fd.io coding-style-patch-verification: ON
22871  *
22872  * Local Variables:
22873  * eval: (c-set-style "gnu")
22874  * End:
22875  */