Punt: socket register for exception dispatched/punted packets based on reason
[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 _(reset_fib_reply)                                      \
5174 _(dhcp_proxy_config_reply)                              \
5175 _(dhcp_proxy_set_vss_reply)                             \
5176 _(dhcp_client_config_reply)                             \
5177 _(set_ip_flow_hash_reply)                               \
5178 _(sw_interface_ip6_enable_disable_reply)                \
5179 _(ip6nd_proxy_add_del_reply)                            \
5180 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5181 _(sw_interface_ip6nd_ra_config_reply)                   \
5182 _(set_arp_neighbor_limit_reply)                         \
5183 _(l2_patch_add_del_reply)                               \
5184 _(sr_mpls_policy_add_reply)                             \
5185 _(sr_mpls_policy_mod_reply)                             \
5186 _(sr_mpls_policy_del_reply)                             \
5187 _(sr_policy_add_reply)                                  \
5188 _(sr_policy_mod_reply)                                  \
5189 _(sr_policy_del_reply)                                  \
5190 _(sr_localsid_add_del_reply)                            \
5191 _(sr_steering_add_del_reply)                            \
5192 _(classify_add_del_session_reply)                       \
5193 _(classify_set_interface_ip_table_reply)                \
5194 _(classify_set_interface_l2_tables_reply)               \
5195 _(l2tpv3_set_tunnel_cookies_reply)                      \
5196 _(l2tpv3_interface_enable_disable_reply)                \
5197 _(l2tpv3_set_lookup_key_reply)                          \
5198 _(l2_fib_clear_table_reply)                             \
5199 _(l2_interface_efp_filter_reply)                        \
5200 _(l2_interface_vlan_tag_rewrite_reply)                  \
5201 _(modify_vhost_user_if_reply)                           \
5202 _(delete_vhost_user_if_reply)                           \
5203 _(ip_probe_neighbor_reply)                              \
5204 _(ip_scan_neighbor_enable_disable_reply)                \
5205 _(want_ip4_arp_events_reply)                            \
5206 _(want_ip6_nd_events_reply)                             \
5207 _(want_l2_macs_events_reply)                            \
5208 _(input_acl_set_interface_reply)                        \
5209 _(ipsec_spd_add_del_reply)                              \
5210 _(ipsec_interface_add_del_spd_reply)                    \
5211 _(ipsec_spd_entry_add_del_reply)                        \
5212 _(ipsec_sad_entry_add_del_reply)                        \
5213 _(ipsec_sa_set_key_reply)                               \
5214 _(ipsec_tunnel_if_add_del_reply)                        \
5215 _(ipsec_tunnel_if_set_key_reply)                        \
5216 _(ipsec_tunnel_if_set_sa_reply)                         \
5217 _(delete_loopback_reply)                                \
5218 _(bd_ip_mac_add_del_reply)                              \
5219 _(bd_ip_mac_flush_reply)                                \
5220 _(want_interface_events_reply)                          \
5221 _(cop_interface_enable_disable_reply)                   \
5222 _(cop_whitelist_enable_disable_reply)                   \
5223 _(sw_interface_clear_stats_reply)                       \
5224 _(ioam_enable_reply)                                    \
5225 _(ioam_disable_reply)                                   \
5226 _(one_add_del_locator_reply)                            \
5227 _(one_add_del_local_eid_reply)                          \
5228 _(one_add_del_remote_mapping_reply)                     \
5229 _(one_add_del_adjacency_reply)                          \
5230 _(one_add_del_map_resolver_reply)                       \
5231 _(one_add_del_map_server_reply)                         \
5232 _(one_enable_disable_reply)                             \
5233 _(one_rloc_probe_enable_disable_reply)                  \
5234 _(one_map_register_enable_disable_reply)                \
5235 _(one_map_register_set_ttl_reply)                       \
5236 _(one_set_transport_protocol_reply)                     \
5237 _(one_map_register_fallback_threshold_reply)            \
5238 _(one_pitr_set_locator_set_reply)                       \
5239 _(one_map_request_mode_reply)                           \
5240 _(one_add_del_map_request_itr_rlocs_reply)              \
5241 _(one_eid_table_add_del_map_reply)                      \
5242 _(one_use_petr_reply)                                   \
5243 _(one_stats_enable_disable_reply)                       \
5244 _(one_add_del_l2_arp_entry_reply)                       \
5245 _(one_add_del_ndp_entry_reply)                          \
5246 _(one_stats_flush_reply)                                \
5247 _(one_enable_disable_xtr_mode_reply)                    \
5248 _(one_enable_disable_pitr_mode_reply)                   \
5249 _(one_enable_disable_petr_mode_reply)                   \
5250 _(gpe_enable_disable_reply)                             \
5251 _(gpe_set_encap_mode_reply)                             \
5252 _(gpe_add_del_iface_reply)                              \
5253 _(gpe_add_del_native_fwd_rpath_reply)                   \
5254 _(af_packet_delete_reply)                               \
5255 _(policer_classify_set_interface_reply)                 \
5256 _(netmap_create_reply)                                  \
5257 _(netmap_delete_reply)                                  \
5258 _(set_ipfix_exporter_reply)                             \
5259 _(set_ipfix_classify_stream_reply)                      \
5260 _(ipfix_classify_table_add_del_reply)                   \
5261 _(flow_classify_set_interface_reply)                    \
5262 _(sw_interface_span_enable_disable_reply)               \
5263 _(pg_capture_reply)                                     \
5264 _(pg_enable_disable_reply)                              \
5265 _(ip_source_and_port_range_check_add_del_reply)         \
5266 _(ip_source_and_port_range_check_interface_add_del_reply)\
5267 _(delete_subif_reply)                                   \
5268 _(l2_interface_pbb_tag_rewrite_reply)                   \
5269 _(set_punt_reply)                                       \
5270 _(feature_enable_disable_reply)                         \
5271 _(sw_interface_tag_add_del_reply)                       \
5272 _(hw_interface_set_mtu_reply)                           \
5273 _(p2p_ethernet_add_reply)                               \
5274 _(p2p_ethernet_del_reply)                               \
5275 _(lldp_config_reply)                                    \
5276 _(sw_interface_set_lldp_reply)                          \
5277 _(tcp_configure_src_addresses_reply)                    \
5278 _(dns_enable_disable_reply)                             \
5279 _(dns_name_server_add_del_reply)                        \
5280 _(session_rule_add_del_reply)                           \
5281 _(ip_container_proxy_add_del_reply)                     \
5282 _(output_acl_set_interface_reply)                       \
5283 _(qos_record_enable_disable_reply)
5284
5285 #define _(n)                                    \
5286     static void vl_api_##n##_t_handler          \
5287     (vl_api_##n##_t * mp)                       \
5288     {                                           \
5289         vat_main_t * vam = &vat_main;           \
5290         i32 retval = ntohl(mp->retval);         \
5291         if (vam->async_mode) {                  \
5292             vam->async_errors += (retval < 0);  \
5293         } else {                                \
5294             vam->retval = retval;               \
5295             vam->result_ready = 1;              \
5296         }                                       \
5297     }
5298 foreach_standard_reply_retval_handler;
5299 #undef _
5300
5301 #define _(n)                                    \
5302     static void vl_api_##n##_t_handler_json     \
5303     (vl_api_##n##_t * mp)                       \
5304     {                                           \
5305         vat_main_t * vam = &vat_main;           \
5306         vat_json_node_t node;                   \
5307         vat_json_init_object(&node);            \
5308         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5309         vat_json_print(vam->ofp, &node);        \
5310         vam->retval = ntohl(mp->retval);        \
5311         vam->result_ready = 1;                  \
5312     }
5313 foreach_standard_reply_retval_handler;
5314 #undef _
5315
5316 /*
5317  * Table of message reply handlers, must include boilerplate handlers
5318  * we just generated
5319  */
5320
5321 #define foreach_vpe_api_reply_msg                                       \
5322 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5323 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5324 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5325 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5326 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5327 _(CLI_REPLY, cli_reply)                                                 \
5328 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5329 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5330   sw_interface_add_del_address_reply)                                   \
5331 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5332 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5333 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5334 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5335 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5336 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5337 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5338 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5339 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5340 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5341   sw_interface_set_l2_xconnect_reply)                                   \
5342 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5343   sw_interface_set_l2_bridge_reply)                                     \
5344 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5345 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5346 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5347 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5348 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5349 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5350 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5351 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5352 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5353 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5354 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5355 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5356 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5357 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5358 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5359 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5360 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5361 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5362 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5363 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5364 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5365 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5366 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5367 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5368 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5369 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5370 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5371 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5372 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5373 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5374   proxy_arp_intfc_enable_disable_reply)                                 \
5375 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5376 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5377   sw_interface_set_unnumbered_reply)                                    \
5378 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5379 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5380 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5381 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5382 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5383 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5384 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5385 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5386 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5387 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5388   sw_interface_ip6_enable_disable_reply)                                \
5389 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5390 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5391 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5392   sw_interface_ip6nd_ra_prefix_reply)                                   \
5393 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5394   sw_interface_ip6nd_ra_config_reply)                                   \
5395 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5396 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5397 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5398 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5399 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5400 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5401 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5402 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5403 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5404 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5405 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5406 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5407 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5408 classify_set_interface_ip_table_reply)                                  \
5409 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5410   classify_set_interface_l2_tables_reply)                               \
5411 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5412 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5413 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5414 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5415 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5416   l2tpv3_interface_enable_disable_reply)                                \
5417 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5418 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5419 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5420 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5421 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5422 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5423 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5424 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5425 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5426 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5427 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5428 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5429 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5430 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5431 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5432 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5433 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5434 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5435 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5436 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5437 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5438 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5439 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5440 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5441 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5442 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5443 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5444 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5445 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5446 _(L2_MACS_EVENT, l2_macs_event)                                         \
5447 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5448 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5449 _(IP_DETAILS, ip_details)                                               \
5450 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5451 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5452 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5453 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5454 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5455 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5456 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5457 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5458 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5459 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5460 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5461 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5462 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5463 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5464 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5465 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5466 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5467 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5468 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5469 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5470 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5471 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5472 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5473 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5474 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5475 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5476 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5477 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5478 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5479 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5480 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5481   one_map_register_enable_disable_reply)                                \
5482 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5483 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5484 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5485 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5486   one_map_register_fallback_threshold_reply)                            \
5487 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5488   one_rloc_probe_enable_disable_reply)                                  \
5489 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5490 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5491 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5492 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5493 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5494 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5495 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5496 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5497 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5498 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5499 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5500 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5501 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5502 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5503 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5504 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5505   show_one_stats_enable_disable_reply)                                  \
5506 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5507 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5508 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5509 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5510 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5511 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5512 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5513 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5514   one_enable_disable_pitr_mode_reply)                                   \
5515 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5516   one_enable_disable_petr_mode_reply)                                   \
5517 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5518 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5519 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5520 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5521 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5522 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5523 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5524 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5525 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5526 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5527 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5528 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5529   gpe_add_del_native_fwd_rpath_reply)                                   \
5530 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5531   gpe_fwd_entry_path_details)                                           \
5532 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5533 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5534   one_add_del_map_request_itr_rlocs_reply)                              \
5535 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5536   one_get_map_request_itr_rlocs_reply)                                  \
5537 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5538 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5539 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5540 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5541 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5542 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5543   show_one_map_register_state_reply)                                    \
5544 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5545 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5546   show_one_map_register_fallback_threshold_reply)                       \
5547 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5548 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5549 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5550 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5551 _(POLICER_DETAILS, policer_details)                                     \
5552 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5553 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5554 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5555 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5556 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5557 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5558 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5559 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5560 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5561 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5562 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5563 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5564 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5565 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5566 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5567 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5568 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5569 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5570 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5571 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5572 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5573 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5574 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5575 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5576 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5577  ip_source_and_port_range_check_add_del_reply)                          \
5578 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5579  ip_source_and_port_range_check_interface_add_del_reply)                \
5580 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5581 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5582 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5583 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5584 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5585 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5586 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5587 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5588 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5589 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5590 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5591 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5592 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5593 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5594 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5595 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5596 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5597 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5598 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5599 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5600 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5601 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5602 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5603 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5604 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5605 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5606 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5607 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5608
5609 #define foreach_standalone_reply_msg                                    \
5610 _(SW_INTERFACE_EVENT, sw_interface_event)
5611
5612 typedef struct
5613 {
5614   u8 *name;
5615   u32 value;
5616 } name_sort_t;
5617
5618 #define STR_VTR_OP_CASE(op)     \
5619     case L2_VTR_ ## op:         \
5620         return "" # op;
5621
5622 static const char *
5623 str_vtr_op (u32 vtr_op)
5624 {
5625   switch (vtr_op)
5626     {
5627       STR_VTR_OP_CASE (DISABLED);
5628       STR_VTR_OP_CASE (PUSH_1);
5629       STR_VTR_OP_CASE (PUSH_2);
5630       STR_VTR_OP_CASE (POP_1);
5631       STR_VTR_OP_CASE (POP_2);
5632       STR_VTR_OP_CASE (TRANSLATE_1_1);
5633       STR_VTR_OP_CASE (TRANSLATE_1_2);
5634       STR_VTR_OP_CASE (TRANSLATE_2_1);
5635       STR_VTR_OP_CASE (TRANSLATE_2_2);
5636     }
5637
5638   return "UNKNOWN";
5639 }
5640
5641 static int
5642 dump_sub_interface_table (vat_main_t * vam)
5643 {
5644   const sw_interface_subif_t *sub = NULL;
5645
5646   if (vam->json_output)
5647     {
5648       clib_warning
5649         ("JSON output supported only for VPE API calls and dump_stats_table");
5650       return -99;
5651     }
5652
5653   print (vam->ofp,
5654          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5655          "Interface", "sw_if_index",
5656          "sub id", "dot1ad", "tags", "outer id",
5657          "inner id", "exact", "default", "outer any", "inner any");
5658
5659   vec_foreach (sub, vam->sw_if_subif_table)
5660   {
5661     print (vam->ofp,
5662            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5663            sub->interface_name,
5664            sub->sw_if_index,
5665            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5666            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5667            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5668            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5669     if (sub->vtr_op != L2_VTR_DISABLED)
5670       {
5671         print (vam->ofp,
5672                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5673                "tag1: %d tag2: %d ]",
5674                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5675                sub->vtr_tag1, sub->vtr_tag2);
5676       }
5677   }
5678
5679   return 0;
5680 }
5681
5682 static int
5683 name_sort_cmp (void *a1, void *a2)
5684 {
5685   name_sort_t *n1 = a1;
5686   name_sort_t *n2 = a2;
5687
5688   return strcmp ((char *) n1->name, (char *) n2->name);
5689 }
5690
5691 static int
5692 dump_interface_table (vat_main_t * vam)
5693 {
5694   hash_pair_t *p;
5695   name_sort_t *nses = 0, *ns;
5696
5697   if (vam->json_output)
5698     {
5699       clib_warning
5700         ("JSON output supported only for VPE API calls and dump_stats_table");
5701       return -99;
5702     }
5703
5704   /* *INDENT-OFF* */
5705   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5706   ({
5707     vec_add2 (nses, ns, 1);
5708     ns->name = (u8 *)(p->key);
5709     ns->value = (u32) p->value[0];
5710   }));
5711   /* *INDENT-ON* */
5712
5713   vec_sort_with_function (nses, name_sort_cmp);
5714
5715   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5716   vec_foreach (ns, nses)
5717   {
5718     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5719   }
5720   vec_free (nses);
5721   return 0;
5722 }
5723
5724 static int
5725 dump_ip_table (vat_main_t * vam, int is_ipv6)
5726 {
5727   const ip_details_t *det = NULL;
5728   const ip_address_details_t *address = NULL;
5729   u32 i = ~0;
5730
5731   print (vam->ofp, "%-12s", "sw_if_index");
5732
5733   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5734   {
5735     i++;
5736     if (!det->present)
5737       {
5738         continue;
5739       }
5740     print (vam->ofp, "%-12d", i);
5741     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5742     if (!det->addr)
5743       {
5744         continue;
5745       }
5746     vec_foreach (address, det->addr)
5747     {
5748       print (vam->ofp,
5749              "            %-30U%-13d",
5750              is_ipv6 ? format_ip6_address : format_ip4_address,
5751              address->ip, address->prefix_length);
5752     }
5753   }
5754
5755   return 0;
5756 }
5757
5758 static int
5759 dump_ipv4_table (vat_main_t * vam)
5760 {
5761   if (vam->json_output)
5762     {
5763       clib_warning
5764         ("JSON output supported only for VPE API calls and dump_stats_table");
5765       return -99;
5766     }
5767
5768   return dump_ip_table (vam, 0);
5769 }
5770
5771 static int
5772 dump_ipv6_table (vat_main_t * vam)
5773 {
5774   if (vam->json_output)
5775     {
5776       clib_warning
5777         ("JSON output supported only for VPE API calls and dump_stats_table");
5778       return -99;
5779     }
5780
5781   return dump_ip_table (vam, 1);
5782 }
5783
5784 /*
5785  * Pass CLI buffers directly in the CLI_INBAND API message,
5786  * instead of an additional shared memory area.
5787  */
5788 static int
5789 exec_inband (vat_main_t * vam)
5790 {
5791   vl_api_cli_inband_t *mp;
5792   unformat_input_t *i = vam->input;
5793   int ret;
5794
5795   if (vec_len (i->buffer) == 0)
5796     return -1;
5797
5798   if (vam->exec_mode == 0 && unformat (i, "mode"))
5799     {
5800       vam->exec_mode = 1;
5801       return 0;
5802     }
5803   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5804     {
5805       vam->exec_mode = 0;
5806       return 0;
5807     }
5808
5809   /*
5810    * In order for the CLI command to work, it
5811    * must be a vector ending in \n, not a C-string ending
5812    * in \n\0.
5813    */
5814   u32 len = vec_len (vam->input->buffer);
5815   M2 (CLI_INBAND, mp, len);
5816   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5817
5818   S (mp);
5819   W (ret);
5820   /* json responses may or may not include a useful reply... */
5821   if (vec_len (vam->cmd_reply))
5822     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5823   return ret;
5824 }
5825
5826 int
5827 exec (vat_main_t * vam)
5828 {
5829   return exec_inband (vam);
5830 }
5831
5832 static int
5833 api_create_loopback (vat_main_t * vam)
5834 {
5835   unformat_input_t *i = vam->input;
5836   vl_api_create_loopback_t *mp;
5837   vl_api_create_loopback_instance_t *mp_lbi;
5838   u8 mac_address[6];
5839   u8 mac_set = 0;
5840   u8 is_specified = 0;
5841   u32 user_instance = 0;
5842   int ret;
5843
5844   clib_memset (mac_address, 0, sizeof (mac_address));
5845
5846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5847     {
5848       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5849         mac_set = 1;
5850       if (unformat (i, "instance %d", &user_instance))
5851         is_specified = 1;
5852       else
5853         break;
5854     }
5855
5856   if (is_specified)
5857     {
5858       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5859       mp_lbi->is_specified = is_specified;
5860       if (is_specified)
5861         mp_lbi->user_instance = htonl (user_instance);
5862       if (mac_set)
5863         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5864       S (mp_lbi);
5865     }
5866   else
5867     {
5868       /* Construct the API message */
5869       M (CREATE_LOOPBACK, mp);
5870       if (mac_set)
5871         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5872       S (mp);
5873     }
5874
5875   W (ret);
5876   return ret;
5877 }
5878
5879 static int
5880 api_delete_loopback (vat_main_t * vam)
5881 {
5882   unformat_input_t *i = vam->input;
5883   vl_api_delete_loopback_t *mp;
5884   u32 sw_if_index = ~0;
5885   int ret;
5886
5887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5888     {
5889       if (unformat (i, "sw_if_index %d", &sw_if_index))
5890         ;
5891       else
5892         break;
5893     }
5894
5895   if (sw_if_index == ~0)
5896     {
5897       errmsg ("missing sw_if_index");
5898       return -99;
5899     }
5900
5901   /* Construct the API message */
5902   M (DELETE_LOOPBACK, mp);
5903   mp->sw_if_index = ntohl (sw_if_index);
5904
5905   S (mp);
5906   W (ret);
5907   return ret;
5908 }
5909
5910 static int
5911 api_want_interface_events (vat_main_t * vam)
5912 {
5913   unformat_input_t *i = vam->input;
5914   vl_api_want_interface_events_t *mp;
5915   int enable = -1;
5916   int ret;
5917
5918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5919     {
5920       if (unformat (i, "enable"))
5921         enable = 1;
5922       else if (unformat (i, "disable"))
5923         enable = 0;
5924       else
5925         break;
5926     }
5927
5928   if (enable == -1)
5929     {
5930       errmsg ("missing enable|disable");
5931       return -99;
5932     }
5933
5934   M (WANT_INTERFACE_EVENTS, mp);
5935   mp->enable_disable = enable;
5936
5937   vam->interface_event_display = enable;
5938
5939   S (mp);
5940   W (ret);
5941   return ret;
5942 }
5943
5944
5945 /* Note: non-static, called once to set up the initial intfc table */
5946 int
5947 api_sw_interface_dump (vat_main_t * vam)
5948 {
5949   vl_api_sw_interface_dump_t *mp;
5950   vl_api_control_ping_t *mp_ping;
5951   hash_pair_t *p;
5952   name_sort_t *nses = 0, *ns;
5953   sw_interface_subif_t *sub = NULL;
5954   int ret;
5955
5956   /* Toss the old name table */
5957   /* *INDENT-OFF* */
5958   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5959   ({
5960     vec_add2 (nses, ns, 1);
5961     ns->name = (u8 *)(p->key);
5962     ns->value = (u32) p->value[0];
5963   }));
5964   /* *INDENT-ON* */
5965
5966   hash_free (vam->sw_if_index_by_interface_name);
5967
5968   vec_foreach (ns, nses) vec_free (ns->name);
5969
5970   vec_free (nses);
5971
5972   vec_foreach (sub, vam->sw_if_subif_table)
5973   {
5974     vec_free (sub->interface_name);
5975   }
5976   vec_free (vam->sw_if_subif_table);
5977
5978   /* recreate the interface name hash table */
5979   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5980
5981   /*
5982    * Ask for all interface names. Otherwise, the epic catalog of
5983    * name filters becomes ridiculously long, and vat ends up needing
5984    * to be taught about new interface types.
5985    */
5986   M (SW_INTERFACE_DUMP, mp);
5987   S (mp);
5988
5989   /* Use a control ping for synchronization */
5990   MPING (CONTROL_PING, mp_ping);
5991   S (mp_ping);
5992
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static int
5998 api_sw_interface_set_flags (vat_main_t * vam)
5999 {
6000   unformat_input_t *i = vam->input;
6001   vl_api_sw_interface_set_flags_t *mp;
6002   u32 sw_if_index;
6003   u8 sw_if_index_set = 0;
6004   u8 admin_up = 0;
6005   int ret;
6006
6007   /* Parse args required to build the message */
6008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6009     {
6010       if (unformat (i, "admin-up"))
6011         admin_up = 1;
6012       else if (unformat (i, "admin-down"))
6013         admin_up = 0;
6014       else
6015         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6016         sw_if_index_set = 1;
6017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6018         sw_if_index_set = 1;
6019       else
6020         break;
6021     }
6022
6023   if (sw_if_index_set == 0)
6024     {
6025       errmsg ("missing interface name or sw_if_index");
6026       return -99;
6027     }
6028
6029   /* Construct the API message */
6030   M (SW_INTERFACE_SET_FLAGS, mp);
6031   mp->sw_if_index = ntohl (sw_if_index);
6032   mp->admin_up_down = admin_up;
6033
6034   /* send it... */
6035   S (mp);
6036
6037   /* Wait for a reply, return the good/bad news... */
6038   W (ret);
6039   return ret;
6040 }
6041
6042 static int
6043 api_sw_interface_set_rx_mode (vat_main_t * vam)
6044 {
6045   unformat_input_t *i = vam->input;
6046   vl_api_sw_interface_set_rx_mode_t *mp;
6047   u32 sw_if_index;
6048   u8 sw_if_index_set = 0;
6049   int ret;
6050   u8 queue_id_valid = 0;
6051   u32 queue_id;
6052   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6053
6054   /* Parse args required to build the message */
6055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6056     {
6057       if (unformat (i, "queue %d", &queue_id))
6058         queue_id_valid = 1;
6059       else if (unformat (i, "polling"))
6060         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6061       else if (unformat (i, "interrupt"))
6062         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6063       else if (unformat (i, "adaptive"))
6064         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6065       else
6066         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6067         sw_if_index_set = 1;
6068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6069         sw_if_index_set = 1;
6070       else
6071         break;
6072     }
6073
6074   if (sw_if_index_set == 0)
6075     {
6076       errmsg ("missing interface name or sw_if_index");
6077       return -99;
6078     }
6079   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6080     {
6081       errmsg ("missing rx-mode");
6082       return -99;
6083     }
6084
6085   /* Construct the API message */
6086   M (SW_INTERFACE_SET_RX_MODE, mp);
6087   mp->sw_if_index = ntohl (sw_if_index);
6088   mp->mode = mode;
6089   mp->queue_id_valid = queue_id_valid;
6090   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6091
6092   /* send it... */
6093   S (mp);
6094
6095   /* Wait for a reply, return the good/bad news... */
6096   W (ret);
6097   return ret;
6098 }
6099
6100 static int
6101 api_sw_interface_set_rx_placement (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_sw_interface_set_rx_placement_t *mp;
6105   u32 sw_if_index;
6106   u8 sw_if_index_set = 0;
6107   int ret;
6108   u8 is_main = 0;
6109   u32 queue_id, thread_index;
6110
6111   /* Parse args required to build the message */
6112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6113     {
6114       if (unformat (i, "queue %d", &queue_id))
6115         ;
6116       else if (unformat (i, "main"))
6117         is_main = 1;
6118       else if (unformat (i, "worker %d", &thread_index))
6119         ;
6120       else
6121         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6122         sw_if_index_set = 1;
6123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6124         sw_if_index_set = 1;
6125       else
6126         break;
6127     }
6128
6129   if (sw_if_index_set == 0)
6130     {
6131       errmsg ("missing interface name or sw_if_index");
6132       return -99;
6133     }
6134
6135   if (is_main)
6136     thread_index = 0;
6137   /* Construct the API message */
6138   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6139   mp->sw_if_index = ntohl (sw_if_index);
6140   mp->worker_id = ntohl (thread_index);
6141   mp->queue_id = ntohl (queue_id);
6142   mp->is_main = is_main;
6143
6144   /* send it... */
6145   S (mp);
6146   /* Wait for a reply, return the good/bad news... */
6147   W (ret);
6148   return ret;
6149 }
6150
6151 static void vl_api_sw_interface_rx_placement_details_t_handler
6152   (vl_api_sw_interface_rx_placement_details_t * mp)
6153 {
6154   vat_main_t *vam = &vat_main;
6155   u32 worker_id = ntohl (mp->worker_id);
6156
6157   print (vam->ofp,
6158          "\n%-11d %-11s %-6d %-5d %-9s",
6159          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6160          worker_id, ntohl (mp->queue_id),
6161          (mp->mode ==
6162           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6163 }
6164
6165 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6166   (vl_api_sw_interface_rx_placement_details_t * mp)
6167 {
6168   vat_main_t *vam = &vat_main;
6169   vat_json_node_t *node = NULL;
6170
6171   if (VAT_JSON_ARRAY != vam->json_tree.type)
6172     {
6173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6174       vat_json_init_array (&vam->json_tree);
6175     }
6176   node = vat_json_array_add (&vam->json_tree);
6177
6178   vat_json_init_object (node);
6179   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6180   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6181   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6182   vat_json_object_add_uint (node, "mode", mp->mode);
6183 }
6184
6185 static int
6186 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_sw_interface_rx_placement_dump_t *mp;
6190   vl_api_control_ping_t *mp_ping;
6191   int ret;
6192   u32 sw_if_index;
6193   u8 sw_if_index_set = 0;
6194
6195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6196     {
6197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6198         sw_if_index_set++;
6199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6200         sw_if_index_set++;
6201       else
6202         break;
6203     }
6204
6205   print (vam->ofp,
6206          "\n%-11s %-11s %-6s %-5s %-4s",
6207          "sw_if_index", "main/worker", "thread", "queue", "mode");
6208
6209   /* Dump Interface rx placement */
6210   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6211
6212   if (sw_if_index_set)
6213     mp->sw_if_index = htonl (sw_if_index);
6214   else
6215     mp->sw_if_index = ~0;
6216
6217   S (mp);
6218
6219   /* Use a control ping for synchronization */
6220   MPING (CONTROL_PING, mp_ping);
6221   S (mp_ping);
6222
6223   W (ret);
6224   return ret;
6225 }
6226
6227 static int
6228 api_sw_interface_clear_stats (vat_main_t * vam)
6229 {
6230   unformat_input_t *i = vam->input;
6231   vl_api_sw_interface_clear_stats_t *mp;
6232   u32 sw_if_index;
6233   u8 sw_if_index_set = 0;
6234   int ret;
6235
6236   /* Parse args required to build the message */
6237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6238     {
6239       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6240         sw_if_index_set = 1;
6241       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6242         sw_if_index_set = 1;
6243       else
6244         break;
6245     }
6246
6247   /* Construct the API message */
6248   M (SW_INTERFACE_CLEAR_STATS, mp);
6249
6250   if (sw_if_index_set == 1)
6251     mp->sw_if_index = ntohl (sw_if_index);
6252   else
6253     mp->sw_if_index = ~0;
6254
6255   /* send it... */
6256   S (mp);
6257
6258   /* Wait for a reply, return the good/bad news... */
6259   W (ret);
6260   return ret;
6261 }
6262
6263 static int
6264 api_sw_interface_add_del_address (vat_main_t * vam)
6265 {
6266   unformat_input_t *i = vam->input;
6267   vl_api_sw_interface_add_del_address_t *mp;
6268   u32 sw_if_index;
6269   u8 sw_if_index_set = 0;
6270   u8 is_add = 1, del_all = 0;
6271   u32 address_length = 0;
6272   u8 v4_address_set = 0;
6273   u8 v6_address_set = 0;
6274   ip4_address_t v4address;
6275   ip6_address_t v6address;
6276   int ret;
6277
6278   /* Parse args required to build the message */
6279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6280     {
6281       if (unformat (i, "del-all"))
6282         del_all = 1;
6283       else if (unformat (i, "del"))
6284         is_add = 0;
6285       else
6286         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6287         sw_if_index_set = 1;
6288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "%U/%d",
6291                          unformat_ip4_address, &v4address, &address_length))
6292         v4_address_set = 1;
6293       else if (unformat (i, "%U/%d",
6294                          unformat_ip6_address, &v6address, &address_length))
6295         v6_address_set = 1;
6296       else
6297         break;
6298     }
6299
6300   if (sw_if_index_set == 0)
6301     {
6302       errmsg ("missing interface name or sw_if_index");
6303       return -99;
6304     }
6305   if (v4_address_set && v6_address_set)
6306     {
6307       errmsg ("both v4 and v6 addresses set");
6308       return -99;
6309     }
6310   if (!v4_address_set && !v6_address_set && !del_all)
6311     {
6312       errmsg ("no addresses set");
6313       return -99;
6314     }
6315
6316   /* Construct the API message */
6317   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6318
6319   mp->sw_if_index = ntohl (sw_if_index);
6320   mp->is_add = is_add;
6321   mp->del_all = del_all;
6322   if (v6_address_set)
6323     {
6324       mp->is_ipv6 = 1;
6325       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6326     }
6327   else
6328     {
6329       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6330     }
6331   mp->address_length = address_length;
6332
6333   /* send it... */
6334   S (mp);
6335
6336   /* Wait for a reply, return good/bad news  */
6337   W (ret);
6338   return ret;
6339 }
6340
6341 static int
6342 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6343 {
6344   unformat_input_t *i = vam->input;
6345   vl_api_sw_interface_set_mpls_enable_t *mp;
6346   u32 sw_if_index;
6347   u8 sw_if_index_set = 0;
6348   u8 enable = 1;
6349   int ret;
6350
6351   /* Parse args required to build the message */
6352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6353     {
6354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6355         sw_if_index_set = 1;
6356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6357         sw_if_index_set = 1;
6358       else if (unformat (i, "disable"))
6359         enable = 0;
6360       else if (unformat (i, "dis"))
6361         enable = 0;
6362       else
6363         break;
6364     }
6365
6366   if (sw_if_index_set == 0)
6367     {
6368       errmsg ("missing interface name or sw_if_index");
6369       return -99;
6370     }
6371
6372   /* Construct the API message */
6373   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6374
6375   mp->sw_if_index = ntohl (sw_if_index);
6376   mp->enable = enable;
6377
6378   /* send it... */
6379   S (mp);
6380
6381   /* Wait for a reply... */
6382   W (ret);
6383   return ret;
6384 }
6385
6386 static int
6387 api_sw_interface_set_table (vat_main_t * vam)
6388 {
6389   unformat_input_t *i = vam->input;
6390   vl_api_sw_interface_set_table_t *mp;
6391   u32 sw_if_index, vrf_id = 0;
6392   u8 sw_if_index_set = 0;
6393   u8 is_ipv6 = 0;
6394   int ret;
6395
6396   /* Parse args required to build the message */
6397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6398     {
6399       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6400         sw_if_index_set = 1;
6401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6402         sw_if_index_set = 1;
6403       else if (unformat (i, "vrf %d", &vrf_id))
6404         ;
6405       else if (unformat (i, "ipv6"))
6406         is_ipv6 = 1;
6407       else
6408         break;
6409     }
6410
6411   if (sw_if_index_set == 0)
6412     {
6413       errmsg ("missing interface name or sw_if_index");
6414       return -99;
6415     }
6416
6417   /* Construct the API message */
6418   M (SW_INTERFACE_SET_TABLE, mp);
6419
6420   mp->sw_if_index = ntohl (sw_if_index);
6421   mp->is_ipv6 = is_ipv6;
6422   mp->vrf_id = ntohl (vrf_id);
6423
6424   /* send it... */
6425   S (mp);
6426
6427   /* Wait for a reply... */
6428   W (ret);
6429   return ret;
6430 }
6431
6432 static void vl_api_sw_interface_get_table_reply_t_handler
6433   (vl_api_sw_interface_get_table_reply_t * mp)
6434 {
6435   vat_main_t *vam = &vat_main;
6436
6437   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6438
6439   vam->retval = ntohl (mp->retval);
6440   vam->result_ready = 1;
6441
6442 }
6443
6444 static void vl_api_sw_interface_get_table_reply_t_handler_json
6445   (vl_api_sw_interface_get_table_reply_t * mp)
6446 {
6447   vat_main_t *vam = &vat_main;
6448   vat_json_node_t node;
6449
6450   vat_json_init_object (&node);
6451   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6452   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6453
6454   vat_json_print (vam->ofp, &node);
6455   vat_json_free (&node);
6456
6457   vam->retval = ntohl (mp->retval);
6458   vam->result_ready = 1;
6459 }
6460
6461 static int
6462 api_sw_interface_get_table (vat_main_t * vam)
6463 {
6464   unformat_input_t *i = vam->input;
6465   vl_api_sw_interface_get_table_t *mp;
6466   u32 sw_if_index;
6467   u8 sw_if_index_set = 0;
6468   u8 is_ipv6 = 0;
6469   int ret;
6470
6471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6472     {
6473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6474         sw_if_index_set = 1;
6475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6476         sw_if_index_set = 1;
6477       else if (unformat (i, "ipv6"))
6478         is_ipv6 = 1;
6479       else
6480         break;
6481     }
6482
6483   if (sw_if_index_set == 0)
6484     {
6485       errmsg ("missing interface name or sw_if_index");
6486       return -99;
6487     }
6488
6489   M (SW_INTERFACE_GET_TABLE, mp);
6490   mp->sw_if_index = htonl (sw_if_index);
6491   mp->is_ipv6 = is_ipv6;
6492
6493   S (mp);
6494   W (ret);
6495   return ret;
6496 }
6497
6498 static int
6499 api_sw_interface_set_vpath (vat_main_t * vam)
6500 {
6501   unformat_input_t *i = vam->input;
6502   vl_api_sw_interface_set_vpath_t *mp;
6503   u32 sw_if_index = 0;
6504   u8 sw_if_index_set = 0;
6505   u8 is_enable = 0;
6506   int ret;
6507
6508   /* Parse args required to build the message */
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6512         sw_if_index_set = 1;
6513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6514         sw_if_index_set = 1;
6515       else if (unformat (i, "enable"))
6516         is_enable = 1;
6517       else if (unformat (i, "disable"))
6518         is_enable = 0;
6519       else
6520         break;
6521     }
6522
6523   if (sw_if_index_set == 0)
6524     {
6525       errmsg ("missing interface name or sw_if_index");
6526       return -99;
6527     }
6528
6529   /* Construct the API message */
6530   M (SW_INTERFACE_SET_VPATH, mp);
6531
6532   mp->sw_if_index = ntohl (sw_if_index);
6533   mp->enable = is_enable;
6534
6535   /* send it... */
6536   S (mp);
6537
6538   /* Wait for a reply... */
6539   W (ret);
6540   return ret;
6541 }
6542
6543 static int
6544 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6545 {
6546   unformat_input_t *i = vam->input;
6547   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6548   u32 sw_if_index = 0;
6549   u8 sw_if_index_set = 0;
6550   u8 is_enable = 1;
6551   u8 is_ipv6 = 0;
6552   int ret;
6553
6554   /* Parse args required to build the message */
6555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6556     {
6557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6558         sw_if_index_set = 1;
6559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6560         sw_if_index_set = 1;
6561       else if (unformat (i, "enable"))
6562         is_enable = 1;
6563       else if (unformat (i, "disable"))
6564         is_enable = 0;
6565       else if (unformat (i, "ip4"))
6566         is_ipv6 = 0;
6567       else if (unformat (i, "ip6"))
6568         is_ipv6 = 1;
6569       else
6570         break;
6571     }
6572
6573   if (sw_if_index_set == 0)
6574     {
6575       errmsg ("missing interface name or sw_if_index");
6576       return -99;
6577     }
6578
6579   /* Construct the API message */
6580   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6581
6582   mp->sw_if_index = ntohl (sw_if_index);
6583   mp->enable = is_enable;
6584   mp->is_ipv6 = is_ipv6;
6585
6586   /* send it... */
6587   S (mp);
6588
6589   /* Wait for a reply... */
6590   W (ret);
6591   return ret;
6592 }
6593
6594 static int
6595 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6596 {
6597   unformat_input_t *i = vam->input;
6598   vl_api_sw_interface_set_geneve_bypass_t *mp;
6599   u32 sw_if_index = 0;
6600   u8 sw_if_index_set = 0;
6601   u8 is_enable = 1;
6602   u8 is_ipv6 = 0;
6603   int ret;
6604
6605   /* Parse args required to build the message */
6606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6607     {
6608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6609         sw_if_index_set = 1;
6610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6611         sw_if_index_set = 1;
6612       else if (unformat (i, "enable"))
6613         is_enable = 1;
6614       else if (unformat (i, "disable"))
6615         is_enable = 0;
6616       else if (unformat (i, "ip4"))
6617         is_ipv6 = 0;
6618       else if (unformat (i, "ip6"))
6619         is_ipv6 = 1;
6620       else
6621         break;
6622     }
6623
6624   if (sw_if_index_set == 0)
6625     {
6626       errmsg ("missing interface name or sw_if_index");
6627       return -99;
6628     }
6629
6630   /* Construct the API message */
6631   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6632
6633   mp->sw_if_index = ntohl (sw_if_index);
6634   mp->enable = is_enable;
6635   mp->is_ipv6 = is_ipv6;
6636
6637   /* send it... */
6638   S (mp);
6639
6640   /* Wait for a reply... */
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_sw_interface_set_l2_xconnect_t *mp;
6650   u32 rx_sw_if_index;
6651   u8 rx_sw_if_index_set = 0;
6652   u32 tx_sw_if_index;
6653   u8 tx_sw_if_index_set = 0;
6654   u8 enable = 1;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6661         rx_sw_if_index_set = 1;
6662       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6663         tx_sw_if_index_set = 1;
6664       else if (unformat (i, "rx"))
6665         {
6666           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6667             {
6668               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6669                             &rx_sw_if_index))
6670                 rx_sw_if_index_set = 1;
6671             }
6672           else
6673             break;
6674         }
6675       else if (unformat (i, "tx"))
6676         {
6677           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6678             {
6679               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6680                             &tx_sw_if_index))
6681                 tx_sw_if_index_set = 1;
6682             }
6683           else
6684             break;
6685         }
6686       else if (unformat (i, "enable"))
6687         enable = 1;
6688       else if (unformat (i, "disable"))
6689         enable = 0;
6690       else
6691         break;
6692     }
6693
6694   if (rx_sw_if_index_set == 0)
6695     {
6696       errmsg ("missing rx interface name or rx_sw_if_index");
6697       return -99;
6698     }
6699
6700   if (enable && (tx_sw_if_index_set == 0))
6701     {
6702       errmsg ("missing tx interface name or tx_sw_if_index");
6703       return -99;
6704     }
6705
6706   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6707
6708   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6709   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6710   mp->enable = enable;
6711
6712   S (mp);
6713   W (ret);
6714   return ret;
6715 }
6716
6717 static int
6718 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6719 {
6720   unformat_input_t *i = vam->input;
6721   vl_api_sw_interface_set_l2_bridge_t *mp;
6722   vl_api_l2_port_type_t port_type;
6723   u32 rx_sw_if_index;
6724   u8 rx_sw_if_index_set = 0;
6725   u32 bd_id;
6726   u8 bd_id_set = 0;
6727   u32 shg = 0;
6728   u8 enable = 1;
6729   int ret;
6730
6731   port_type = L2_API_PORT_TYPE_NORMAL;
6732
6733   /* Parse args required to build the message */
6734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735     {
6736       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6737         rx_sw_if_index_set = 1;
6738       else if (unformat (i, "bd_id %d", &bd_id))
6739         bd_id_set = 1;
6740       else
6741         if (unformat
6742             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6743         rx_sw_if_index_set = 1;
6744       else if (unformat (i, "shg %d", &shg))
6745         ;
6746       else if (unformat (i, "bvi"))
6747         port_type = L2_API_PORT_TYPE_BVI;
6748       else if (unformat (i, "uu-fwd"))
6749         port_type = L2_API_PORT_TYPE_UU_FWD;
6750       else if (unformat (i, "enable"))
6751         enable = 1;
6752       else if (unformat (i, "disable"))
6753         enable = 0;
6754       else
6755         break;
6756     }
6757
6758   if (rx_sw_if_index_set == 0)
6759     {
6760       errmsg ("missing rx interface name or sw_if_index");
6761       return -99;
6762     }
6763
6764   if (enable && (bd_id_set == 0))
6765     {
6766       errmsg ("missing bridge domain");
6767       return -99;
6768     }
6769
6770   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6771
6772   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6773   mp->bd_id = ntohl (bd_id);
6774   mp->shg = (u8) shg;
6775   mp->port_type = ntohl (port_type);
6776   mp->enable = enable;
6777
6778   S (mp);
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_bridge_domain_dump (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_bridge_domain_dump_t *mp;
6788   vl_api_control_ping_t *mp_ping;
6789   u32 bd_id = ~0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "bd_id %d", &bd_id))
6796         ;
6797       else
6798         break;
6799     }
6800
6801   M (BRIDGE_DOMAIN_DUMP, mp);
6802   mp->bd_id = ntohl (bd_id);
6803   S (mp);
6804
6805   /* Use a control ping for synchronization */
6806   MPING (CONTROL_PING, mp_ping);
6807   S (mp_ping);
6808
6809   W (ret);
6810   return ret;
6811 }
6812
6813 static int
6814 api_bridge_domain_add_del (vat_main_t * vam)
6815 {
6816   unformat_input_t *i = vam->input;
6817   vl_api_bridge_domain_add_del_t *mp;
6818   u32 bd_id = ~0;
6819   u8 is_add = 1;
6820   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6821   u8 *bd_tag = NULL;
6822   u32 mac_age = 0;
6823   int ret;
6824
6825   /* Parse args required to build the message */
6826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6827     {
6828       if (unformat (i, "bd_id %d", &bd_id))
6829         ;
6830       else if (unformat (i, "flood %d", &flood))
6831         ;
6832       else if (unformat (i, "uu-flood %d", &uu_flood))
6833         ;
6834       else if (unformat (i, "forward %d", &forward))
6835         ;
6836       else if (unformat (i, "learn %d", &learn))
6837         ;
6838       else if (unformat (i, "arp-term %d", &arp_term))
6839         ;
6840       else if (unformat (i, "mac-age %d", &mac_age))
6841         ;
6842       else if (unformat (i, "bd-tag %s", &bd_tag))
6843         ;
6844       else if (unformat (i, "del"))
6845         {
6846           is_add = 0;
6847           flood = uu_flood = forward = learn = 0;
6848         }
6849       else
6850         break;
6851     }
6852
6853   if (bd_id == ~0)
6854     {
6855       errmsg ("missing bridge domain");
6856       ret = -99;
6857       goto done;
6858     }
6859
6860   if (mac_age > 255)
6861     {
6862       errmsg ("mac age must be less than 256 ");
6863       ret = -99;
6864       goto done;
6865     }
6866
6867   if ((bd_tag) && (vec_len (bd_tag) > 63))
6868     {
6869       errmsg ("bd-tag cannot be longer than 63");
6870       ret = -99;
6871       goto done;
6872     }
6873
6874   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6875
6876   mp->bd_id = ntohl (bd_id);
6877   mp->flood = flood;
6878   mp->uu_flood = uu_flood;
6879   mp->forward = forward;
6880   mp->learn = learn;
6881   mp->arp_term = arp_term;
6882   mp->is_add = is_add;
6883   mp->mac_age = (u8) mac_age;
6884   if (bd_tag)
6885     {
6886       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6887       mp->bd_tag[vec_len (bd_tag)] = 0;
6888     }
6889   S (mp);
6890   W (ret);
6891
6892 done:
6893   vec_free (bd_tag);
6894   return ret;
6895 }
6896
6897 static int
6898 api_l2fib_flush_bd (vat_main_t * vam)
6899 {
6900   unformat_input_t *i = vam->input;
6901   vl_api_l2fib_flush_bd_t *mp;
6902   u32 bd_id = ~0;
6903   int ret;
6904
6905   /* Parse args required to build the message */
6906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907     {
6908       if (unformat (i, "bd_id %d", &bd_id));
6909       else
6910         break;
6911     }
6912
6913   if (bd_id == ~0)
6914     {
6915       errmsg ("missing bridge domain");
6916       return -99;
6917     }
6918
6919   M (L2FIB_FLUSH_BD, mp);
6920
6921   mp->bd_id = htonl (bd_id);
6922
6923   S (mp);
6924   W (ret);
6925   return ret;
6926 }
6927
6928 static int
6929 api_l2fib_flush_int (vat_main_t * vam)
6930 {
6931   unformat_input_t *i = vam->input;
6932   vl_api_l2fib_flush_int_t *mp;
6933   u32 sw_if_index = ~0;
6934   int ret;
6935
6936   /* Parse args required to build the message */
6937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6938     {
6939       if (unformat (i, "sw_if_index %d", &sw_if_index));
6940       else
6941         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6942       else
6943         break;
6944     }
6945
6946   if (sw_if_index == ~0)
6947     {
6948       errmsg ("missing interface name or sw_if_index");
6949       return -99;
6950     }
6951
6952   M (L2FIB_FLUSH_INT, mp);
6953
6954   mp->sw_if_index = ntohl (sw_if_index);
6955
6956   S (mp);
6957   W (ret);
6958   return ret;
6959 }
6960
6961 static int
6962 api_l2fib_add_del (vat_main_t * vam)
6963 {
6964   unformat_input_t *i = vam->input;
6965   vl_api_l2fib_add_del_t *mp;
6966   f64 timeout;
6967   u8 mac[6] = { 0 };
6968   u8 mac_set = 0;
6969   u32 bd_id;
6970   u8 bd_id_set = 0;
6971   u32 sw_if_index = 0;
6972   u8 sw_if_index_set = 0;
6973   u8 is_add = 1;
6974   u8 static_mac = 0;
6975   u8 filter_mac = 0;
6976   u8 bvi_mac = 0;
6977   int count = 1;
6978   f64 before = 0;
6979   int j;
6980
6981   /* Parse args required to build the message */
6982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6983     {
6984       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6985         mac_set = 1;
6986       else if (unformat (i, "bd_id %d", &bd_id))
6987         bd_id_set = 1;
6988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6989         sw_if_index_set = 1;
6990       else if (unformat (i, "sw_if"))
6991         {
6992           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993             {
6994               if (unformat
6995                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6996                 sw_if_index_set = 1;
6997             }
6998           else
6999             break;
7000         }
7001       else if (unformat (i, "static"))
7002         static_mac = 1;
7003       else if (unformat (i, "filter"))
7004         {
7005           filter_mac = 1;
7006           static_mac = 1;
7007         }
7008       else if (unformat (i, "bvi"))
7009         {
7010           bvi_mac = 1;
7011           static_mac = 1;
7012         }
7013       else if (unformat (i, "del"))
7014         is_add = 0;
7015       else if (unformat (i, "count %d", &count))
7016         ;
7017       else
7018         break;
7019     }
7020
7021   if (mac_set == 0)
7022     {
7023       errmsg ("missing mac address");
7024       return -99;
7025     }
7026
7027   if (bd_id_set == 0)
7028     {
7029       errmsg ("missing bridge domain");
7030       return -99;
7031     }
7032
7033   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7034     {
7035       errmsg ("missing interface name or sw_if_index");
7036       return -99;
7037     }
7038
7039   if (count > 1)
7040     {
7041       /* Turn on async mode */
7042       vam->async_mode = 1;
7043       vam->async_errors = 0;
7044       before = vat_time_now (vam);
7045     }
7046
7047   for (j = 0; j < count; j++)
7048     {
7049       M (L2FIB_ADD_DEL, mp);
7050
7051       clib_memcpy (mp->mac, mac, 6);
7052       mp->bd_id = ntohl (bd_id);
7053       mp->is_add = is_add;
7054       mp->sw_if_index = ntohl (sw_if_index);
7055
7056       if (is_add)
7057         {
7058           mp->static_mac = static_mac;
7059           mp->filter_mac = filter_mac;
7060           mp->bvi_mac = bvi_mac;
7061         }
7062       increment_mac_address (mac);
7063       /* send it... */
7064       S (mp);
7065     }
7066
7067   if (count > 1)
7068     {
7069       vl_api_control_ping_t *mp_ping;
7070       f64 after;
7071
7072       /* Shut off async mode */
7073       vam->async_mode = 0;
7074
7075       MPING (CONTROL_PING, mp_ping);
7076       S (mp_ping);
7077
7078       timeout = vat_time_now (vam) + 1.0;
7079       while (vat_time_now (vam) < timeout)
7080         if (vam->result_ready == 1)
7081           goto out;
7082       vam->retval = -99;
7083
7084     out:
7085       if (vam->retval == -99)
7086         errmsg ("timeout");
7087
7088       if (vam->async_errors > 0)
7089         {
7090           errmsg ("%d asynchronous errors", vam->async_errors);
7091           vam->retval = -98;
7092         }
7093       vam->async_errors = 0;
7094       after = vat_time_now (vam);
7095
7096       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7097              count, after - before, count / (after - before));
7098     }
7099   else
7100     {
7101       int ret;
7102
7103       /* Wait for a reply... */
7104       W (ret);
7105       return ret;
7106     }
7107   /* Return the good/bad news */
7108   return (vam->retval);
7109 }
7110
7111 static int
7112 api_bridge_domain_set_mac_age (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_bridge_domain_set_mac_age_t *mp;
7116   u32 bd_id = ~0;
7117   u32 mac_age = 0;
7118   int ret;
7119
7120   /* Parse args required to build the message */
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "bd_id %d", &bd_id));
7124       else if (unformat (i, "mac-age %d", &mac_age));
7125       else
7126         break;
7127     }
7128
7129   if (bd_id == ~0)
7130     {
7131       errmsg ("missing bridge domain");
7132       return -99;
7133     }
7134
7135   if (mac_age > 255)
7136     {
7137       errmsg ("mac age must be less than 256 ");
7138       return -99;
7139     }
7140
7141   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7142
7143   mp->bd_id = htonl (bd_id);
7144   mp->mac_age = (u8) mac_age;
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_l2_flags (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2_flags_t *mp;
7156   u32 sw_if_index;
7157   u32 flags = 0;
7158   u8 sw_if_index_set = 0;
7159   u8 is_set = 0;
7160   int ret;
7161
7162   /* Parse args required to build the message */
7163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7164     {
7165       if (unformat (i, "sw_if_index %d", &sw_if_index))
7166         sw_if_index_set = 1;
7167       else if (unformat (i, "sw_if"))
7168         {
7169           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7170             {
7171               if (unformat
7172                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7173                 sw_if_index_set = 1;
7174             }
7175           else
7176             break;
7177         }
7178       else if (unformat (i, "learn"))
7179         flags |= L2_LEARN;
7180       else if (unformat (i, "forward"))
7181         flags |= L2_FWD;
7182       else if (unformat (i, "flood"))
7183         flags |= L2_FLOOD;
7184       else if (unformat (i, "uu-flood"))
7185         flags |= L2_UU_FLOOD;
7186       else if (unformat (i, "arp-term"))
7187         flags |= L2_ARP_TERM;
7188       else if (unformat (i, "off"))
7189         is_set = 0;
7190       else if (unformat (i, "disable"))
7191         is_set = 0;
7192       else
7193         break;
7194     }
7195
7196   if (sw_if_index_set == 0)
7197     {
7198       errmsg ("missing interface name or sw_if_index");
7199       return -99;
7200     }
7201
7202   M (L2_FLAGS, mp);
7203
7204   mp->sw_if_index = ntohl (sw_if_index);
7205   mp->feature_bitmap = ntohl (flags);
7206   mp->is_set = is_set;
7207
7208   S (mp);
7209   W (ret);
7210   return ret;
7211 }
7212
7213 static int
7214 api_bridge_flags (vat_main_t * vam)
7215 {
7216   unformat_input_t *i = vam->input;
7217   vl_api_bridge_flags_t *mp;
7218   u32 bd_id;
7219   u8 bd_id_set = 0;
7220   u8 is_set = 1;
7221   bd_flags_t flags = 0;
7222   int ret;
7223
7224   /* Parse args required to build the message */
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "bd_id %d", &bd_id))
7228         bd_id_set = 1;
7229       else if (unformat (i, "learn"))
7230         flags |= BRIDGE_API_FLAG_LEARN;
7231       else if (unformat (i, "forward"))
7232         flags |= BRIDGE_API_FLAG_FWD;
7233       else if (unformat (i, "flood"))
7234         flags |= BRIDGE_API_FLAG_FLOOD;
7235       else if (unformat (i, "uu-flood"))
7236         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7237       else if (unformat (i, "arp-term"))
7238         flags |= BRIDGE_API_FLAG_ARP_TERM;
7239       else if (unformat (i, "off"))
7240         is_set = 0;
7241       else if (unformat (i, "disable"))
7242         is_set = 0;
7243       else
7244         break;
7245     }
7246
7247   if (bd_id_set == 0)
7248     {
7249       errmsg ("missing bridge domain");
7250       return -99;
7251     }
7252
7253   M (BRIDGE_FLAGS, mp);
7254
7255   mp->bd_id = ntohl (bd_id);
7256   mp->flags = ntohl (flags);
7257   mp->is_set = is_set;
7258
7259   S (mp);
7260   W (ret);
7261   return ret;
7262 }
7263
7264 static int
7265 api_bd_ip_mac_add_del (vat_main_t * vam)
7266 {
7267   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7268   vl_api_mac_address_t mac = { 0 };
7269   unformat_input_t *i = vam->input;
7270   vl_api_bd_ip_mac_add_del_t *mp;
7271   ip46_type_t type;
7272   u32 bd_id;
7273   u8 is_ipv6 = 0;
7274   u8 is_add = 1;
7275   u8 bd_id_set = 0;
7276   u8 ip_set = 0;
7277   u8 mac_set = 0;
7278   u8 macaddr[6];
7279   int ret;
7280
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "bd_id %d", &bd_id))
7286         {
7287           bd_id_set++;
7288         }
7289       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7290         {
7291           ip_set++;
7292         }
7293       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7294         {
7295           mac_set++;
7296         }
7297       else if (unformat (i, "del"))
7298         is_add = 0;
7299       else
7300         break;
7301     }
7302
7303   if (bd_id_set == 0)
7304     {
7305       errmsg ("missing bridge domain");
7306       return -99;
7307     }
7308   else if (ip_set == 0)
7309     {
7310       errmsg ("missing IP address");
7311       return -99;
7312     }
7313   else if (mac_set == 0)
7314     {
7315       errmsg ("missing MAC address");
7316       return -99;
7317     }
7318
7319   M (BD_IP_MAC_ADD_DEL, mp);
7320
7321   mp->bd_id = ntohl (bd_id);
7322   mp->is_add = is_add;
7323
7324   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7325   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7326
7327   S (mp);
7328   W (ret);
7329   return ret;
7330 }
7331
7332 static int
7333 api_bd_ip_mac_flush (vat_main_t * vam)
7334 {
7335   unformat_input_t *i = vam->input;
7336   vl_api_bd_ip_mac_flush_t *mp;
7337   u32 bd_id;
7338   u8 bd_id_set = 0;
7339   int ret;
7340
7341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7342     {
7343       if (unformat (i, "bd_id %d", &bd_id))
7344         {
7345           bd_id_set++;
7346         }
7347       else
7348         break;
7349     }
7350
7351   if (bd_id_set == 0)
7352     {
7353       errmsg ("missing bridge domain");
7354       return -99;
7355     }
7356
7357   M (BD_IP_MAC_FLUSH, mp);
7358
7359   mp->bd_id = ntohl (bd_id);
7360
7361   S (mp);
7362   W (ret);
7363   return ret;
7364 }
7365
7366 static void vl_api_bd_ip_mac_details_t_handler
7367   (vl_api_bd_ip_mac_details_t * mp)
7368 {
7369   vat_main_t *vam = &vat_main;
7370   u8 *ip = 0;
7371
7372   if (!mp->is_ipv6)
7373     ip =
7374       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7375   else
7376     ip =
7377       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7378
7379   print (vam->ofp,
7380          "\n%-5d %-7s %-20U %-30s",
7381          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7382          format_ethernet_address, mp->mac_address, ip);
7383
7384   vec_free (ip);
7385 }
7386
7387 static void vl_api_bd_ip_mac_details_t_handler_json
7388   (vl_api_bd_ip_mac_details_t * mp)
7389 {
7390   vat_main_t *vam = &vat_main;
7391   vat_json_node_t *node = NULL;
7392
7393   if (VAT_JSON_ARRAY != vam->json_tree.type)
7394     {
7395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7396       vat_json_init_array (&vam->json_tree);
7397     }
7398   node = vat_json_array_add (&vam->json_tree);
7399
7400   vat_json_init_object (node);
7401   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7402   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7403   vat_json_object_add_string_copy (node, "mac_address",
7404                                    format (0, "%U", format_ethernet_address,
7405                                            &mp->mac_address));
7406   u8 *ip = 0;
7407
7408   if (!mp->is_ipv6)
7409     ip =
7410       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7411   else
7412     ip =
7413       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7414   vat_json_object_add_string_copy (node, "ip_address", ip);
7415   vec_free (ip);
7416 }
7417
7418 static int
7419 api_bd_ip_mac_dump (vat_main_t * vam)
7420 {
7421   unformat_input_t *i = vam->input;
7422   vl_api_bd_ip_mac_dump_t *mp;
7423   vl_api_control_ping_t *mp_ping;
7424   int ret;
7425   u32 bd_id;
7426   u8 bd_id_set = 0;
7427
7428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7429     {
7430       if (unformat (i, "bd_id %d", &bd_id))
7431         {
7432           bd_id_set++;
7433         }
7434       else
7435         break;
7436     }
7437
7438   print (vam->ofp,
7439          "\n%-5s %-7s %-20s %-30s",
7440          "bd_id", "is_ipv6", "mac_address", "ip_address");
7441
7442   /* Dump Bridge Domain Ip to Mac entries */
7443   M (BD_IP_MAC_DUMP, mp);
7444
7445   if (bd_id_set)
7446     mp->bd_id = htonl (bd_id);
7447   else
7448     mp->bd_id = ~0;
7449
7450   S (mp);
7451
7452   /* Use a control ping for synchronization */
7453   MPING (CONTROL_PING, mp_ping);
7454   S (mp_ping);
7455
7456   W (ret);
7457   return ret;
7458 }
7459
7460 static int
7461 api_tap_create_v2 (vat_main_t * vam)
7462 {
7463   unformat_input_t *i = vam->input;
7464   vl_api_tap_create_v2_t *mp;
7465   u8 mac_address[6];
7466   u8 random_mac = 1;
7467   u32 id = ~0;
7468   u8 *host_if_name = 0;
7469   u8 *host_ns = 0;
7470   u8 host_mac_addr[6];
7471   u8 host_mac_addr_set = 0;
7472   u8 *host_bridge = 0;
7473   ip4_address_t host_ip4_addr;
7474   ip4_address_t host_ip4_gw;
7475   u8 host_ip4_gw_set = 0;
7476   u32 host_ip4_prefix_len = 0;
7477   ip6_address_t host_ip6_addr;
7478   ip6_address_t host_ip6_gw;
7479   u8 host_ip6_gw_set = 0;
7480   u32 host_ip6_prefix_len = 0;
7481   int ret;
7482   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7483
7484   clib_memset (mac_address, 0, sizeof (mac_address));
7485
7486   /* Parse args required to build the message */
7487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7488     {
7489       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7490         {
7491           random_mac = 0;
7492         }
7493       else if (unformat (i, "id %u", &id))
7494         ;
7495       else if (unformat (i, "host-if-name %s", &host_if_name))
7496         ;
7497       else if (unformat (i, "host-ns %s", &host_ns))
7498         ;
7499       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7500                          host_mac_addr))
7501         host_mac_addr_set = 1;
7502       else if (unformat (i, "host-bridge %s", &host_bridge))
7503         ;
7504       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7505                          &host_ip4_addr, &host_ip4_prefix_len))
7506         ;
7507       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7508                          &host_ip6_addr, &host_ip6_prefix_len))
7509         ;
7510       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7511                          &host_ip4_gw))
7512         host_ip4_gw_set = 1;
7513       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7514                          &host_ip6_gw))
7515         host_ip6_gw_set = 1;
7516       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7517         ;
7518       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7519         ;
7520       else
7521         break;
7522     }
7523
7524   if (vec_len (host_if_name) > 63)
7525     {
7526       errmsg ("tap name too long. ");
7527       return -99;
7528     }
7529   if (vec_len (host_ns) > 63)
7530     {
7531       errmsg ("host name space too long. ");
7532       return -99;
7533     }
7534   if (vec_len (host_bridge) > 63)
7535     {
7536       errmsg ("host bridge name too long. ");
7537       return -99;
7538     }
7539   if (host_ip4_prefix_len > 32)
7540     {
7541       errmsg ("host ip4 prefix length not valid. ");
7542       return -99;
7543     }
7544   if (host_ip6_prefix_len > 128)
7545     {
7546       errmsg ("host ip6 prefix length not valid. ");
7547       return -99;
7548     }
7549   if (!is_pow2 (rx_ring_sz))
7550     {
7551       errmsg ("rx ring size must be power of 2. ");
7552       return -99;
7553     }
7554   if (rx_ring_sz > 32768)
7555     {
7556       errmsg ("rx ring size must be 32768 or lower. ");
7557       return -99;
7558     }
7559   if (!is_pow2 (tx_ring_sz))
7560     {
7561       errmsg ("tx ring size must be power of 2. ");
7562       return -99;
7563     }
7564   if (tx_ring_sz > 32768)
7565     {
7566       errmsg ("tx ring size must be 32768 or lower. ");
7567       return -99;
7568     }
7569
7570   /* Construct the API message */
7571   M (TAP_CREATE_V2, mp);
7572
7573   mp->use_random_mac = random_mac;
7574
7575   mp->id = ntohl (id);
7576   mp->host_namespace_set = host_ns != 0;
7577   mp->host_bridge_set = host_bridge != 0;
7578   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7579   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7580   mp->rx_ring_sz = ntohs (rx_ring_sz);
7581   mp->tx_ring_sz = ntohs (tx_ring_sz);
7582
7583   if (random_mac == 0)
7584     clib_memcpy (mp->mac_address, mac_address, 6);
7585   if (host_mac_addr_set)
7586     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7587   if (host_if_name)
7588     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7589   if (host_ns)
7590     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7591   if (host_bridge)
7592     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7593   if (host_ip4_prefix_len)
7594     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7595   if (host_ip6_prefix_len)
7596     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7597   if (host_ip4_gw_set)
7598     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7599   if (host_ip6_gw_set)
7600     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7601
7602   vec_free (host_ns);
7603   vec_free (host_if_name);
7604   vec_free (host_bridge);
7605
7606   /* send it... */
7607   S (mp);
7608
7609   /* Wait for a reply... */
7610   W (ret);
7611   return ret;
7612 }
7613
7614 static int
7615 api_tap_delete_v2 (vat_main_t * vam)
7616 {
7617   unformat_input_t *i = vam->input;
7618   vl_api_tap_delete_v2_t *mp;
7619   u32 sw_if_index = ~0;
7620   u8 sw_if_index_set = 0;
7621   int ret;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         sw_if_index_set = 1;
7630       else
7631         break;
7632     }
7633
7634   if (sw_if_index_set == 0)
7635     {
7636       errmsg ("missing vpp interface name. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (TAP_DELETE_V2, mp);
7642
7643   mp->sw_if_index = ntohl (sw_if_index);
7644
7645   /* send it... */
7646   S (mp);
7647
7648   /* Wait for a reply... */
7649   W (ret);
7650   return ret;
7651 }
7652
7653 uword
7654 unformat_pci_addr (unformat_input_t * input, va_list * args)
7655 {
7656   struct pci_addr_t
7657   {
7658     u16 domain;
7659     u8 bus;
7660     u8 slot:5;
7661     u8 function:3;
7662   } *addr;
7663   addr = va_arg (*args, struct pci_addr_t *);
7664   u32 x[4];
7665
7666   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7667     return 0;
7668
7669   addr->domain = x[0];
7670   addr->bus = x[1];
7671   addr->slot = x[2];
7672   addr->function = x[3];
7673
7674   return 1;
7675 }
7676
7677 static int
7678 api_virtio_pci_create (vat_main_t * vam)
7679 {
7680   unformat_input_t *i = vam->input;
7681   vl_api_virtio_pci_create_t *mp;
7682   u8 mac_address[6];
7683   u8 random_mac = 1;
7684   u8 gso_enabled = 0;
7685   u32 pci_addr = 0;
7686   u64 features = (u64) ~ (0ULL);
7687   int ret;
7688
7689   clib_memset (mac_address, 0, sizeof (mac_address));
7690
7691   /* Parse args required to build the message */
7692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7693     {
7694       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7695         {
7696           random_mac = 0;
7697         }
7698       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7699         ;
7700       else if (unformat (i, "features 0x%llx", &features))
7701         ;
7702       else if (unformat (i, "gso-enabled"))
7703         gso_enabled = 1;
7704       else
7705         break;
7706     }
7707
7708   if (pci_addr == 0)
7709     {
7710       errmsg ("pci address must be non zero. ");
7711       return -99;
7712     }
7713
7714   /* Construct the API message */
7715   M (VIRTIO_PCI_CREATE, mp);
7716
7717   mp->use_random_mac = random_mac;
7718
7719   mp->pci_addr = htonl (pci_addr);
7720   mp->features = clib_host_to_net_u64 (features);
7721
7722   if (random_mac == 0)
7723     clib_memcpy (mp->mac_address, mac_address, 6);
7724
7725   /* send it... */
7726   S (mp);
7727
7728   /* Wait for a reply... */
7729   W (ret);
7730   return ret;
7731 }
7732
7733 static int
7734 api_virtio_pci_delete (vat_main_t * vam)
7735 {
7736   unformat_input_t *i = vam->input;
7737   vl_api_virtio_pci_delete_t *mp;
7738   u32 sw_if_index = ~0;
7739   u8 sw_if_index_set = 0;
7740   int ret;
7741
7742   /* Parse args required to build the message */
7743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7744     {
7745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7746         sw_if_index_set = 1;
7747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7748         sw_if_index_set = 1;
7749       else
7750         break;
7751     }
7752
7753   if (sw_if_index_set == 0)
7754     {
7755       errmsg ("missing vpp interface name. ");
7756       return -99;
7757     }
7758
7759   /* Construct the API message */
7760   M (VIRTIO_PCI_DELETE, mp);
7761
7762   mp->sw_if_index = htonl (sw_if_index);
7763
7764   /* send it... */
7765   S (mp);
7766
7767   /* Wait for a reply... */
7768   W (ret);
7769   return ret;
7770 }
7771
7772 static int
7773 api_bond_create (vat_main_t * vam)
7774 {
7775   unformat_input_t *i = vam->input;
7776   vl_api_bond_create_t *mp;
7777   u8 mac_address[6];
7778   u8 custom_mac = 0;
7779   int ret;
7780   u8 mode;
7781   u8 lb;
7782   u8 mode_is_set = 0;
7783   u32 id = ~0;
7784
7785   clib_memset (mac_address, 0, sizeof (mac_address));
7786   lb = BOND_LB_L2;
7787
7788   /* Parse args required to build the message */
7789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7790     {
7791       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7792         mode_is_set = 1;
7793       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7794                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7795         ;
7796       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7797                          mac_address))
7798         custom_mac = 1;
7799       else if (unformat (i, "id %u", &id))
7800         ;
7801       else
7802         break;
7803     }
7804
7805   if (mode_is_set == 0)
7806     {
7807       errmsg ("Missing bond mode. ");
7808       return -99;
7809     }
7810
7811   /* Construct the API message */
7812   M (BOND_CREATE, mp);
7813
7814   mp->use_custom_mac = custom_mac;
7815
7816   mp->mode = mode;
7817   mp->lb = lb;
7818   mp->id = htonl (id);
7819
7820   if (custom_mac)
7821     clib_memcpy (mp->mac_address, mac_address, 6);
7822
7823   /* send it... */
7824   S (mp);
7825
7826   /* Wait for a reply... */
7827   W (ret);
7828   return ret;
7829 }
7830
7831 static int
7832 api_bond_delete (vat_main_t * vam)
7833 {
7834   unformat_input_t *i = vam->input;
7835   vl_api_bond_delete_t *mp;
7836   u32 sw_if_index = ~0;
7837   u8 sw_if_index_set = 0;
7838   int ret;
7839
7840   /* Parse args required to build the message */
7841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7842     {
7843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7844         sw_if_index_set = 1;
7845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7846         sw_if_index_set = 1;
7847       else
7848         break;
7849     }
7850
7851   if (sw_if_index_set == 0)
7852     {
7853       errmsg ("missing vpp interface name. ");
7854       return -99;
7855     }
7856
7857   /* Construct the API message */
7858   M (BOND_DELETE, mp);
7859
7860   mp->sw_if_index = ntohl (sw_if_index);
7861
7862   /* send it... */
7863   S (mp);
7864
7865   /* Wait for a reply... */
7866   W (ret);
7867   return ret;
7868 }
7869
7870 static int
7871 api_bond_enslave (vat_main_t * vam)
7872 {
7873   unformat_input_t *i = vam->input;
7874   vl_api_bond_enslave_t *mp;
7875   u32 bond_sw_if_index;
7876   int ret;
7877   u8 is_passive;
7878   u8 is_long_timeout;
7879   u32 bond_sw_if_index_is_set = 0;
7880   u32 sw_if_index;
7881   u8 sw_if_index_is_set = 0;
7882
7883   /* Parse args required to build the message */
7884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7885     {
7886       if (unformat (i, "sw_if_index %d", &sw_if_index))
7887         sw_if_index_is_set = 1;
7888       else if (unformat (i, "bond %u", &bond_sw_if_index))
7889         bond_sw_if_index_is_set = 1;
7890       else if (unformat (i, "passive %d", &is_passive))
7891         ;
7892       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7893         ;
7894       else
7895         break;
7896     }
7897
7898   if (bond_sw_if_index_is_set == 0)
7899     {
7900       errmsg ("Missing bond sw_if_index. ");
7901       return -99;
7902     }
7903   if (sw_if_index_is_set == 0)
7904     {
7905       errmsg ("Missing slave sw_if_index. ");
7906       return -99;
7907     }
7908
7909   /* Construct the API message */
7910   M (BOND_ENSLAVE, mp);
7911
7912   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7913   mp->sw_if_index = ntohl (sw_if_index);
7914   mp->is_long_timeout = is_long_timeout;
7915   mp->is_passive = is_passive;
7916
7917   /* send it... */
7918   S (mp);
7919
7920   /* Wait for a reply... */
7921   W (ret);
7922   return ret;
7923 }
7924
7925 static int
7926 api_bond_detach_slave (vat_main_t * vam)
7927 {
7928   unformat_input_t *i = vam->input;
7929   vl_api_bond_detach_slave_t *mp;
7930   u32 sw_if_index = ~0;
7931   u8 sw_if_index_set = 0;
7932   int ret;
7933
7934   /* Parse args required to build the message */
7935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7936     {
7937       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7938         sw_if_index_set = 1;
7939       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7940         sw_if_index_set = 1;
7941       else
7942         break;
7943     }
7944
7945   if (sw_if_index_set == 0)
7946     {
7947       errmsg ("missing vpp interface name. ");
7948       return -99;
7949     }
7950
7951   /* Construct the API message */
7952   M (BOND_DETACH_SLAVE, mp);
7953
7954   mp->sw_if_index = ntohl (sw_if_index);
7955
7956   /* send it... */
7957   S (mp);
7958
7959   /* Wait for a reply... */
7960   W (ret);
7961   return ret;
7962 }
7963
7964 static int
7965 api_ip_table_add_del (vat_main_t * vam)
7966 {
7967   unformat_input_t *i = vam->input;
7968   vl_api_ip_table_add_del_t *mp;
7969   u32 table_id = ~0;
7970   u8 is_ipv6 = 0;
7971   u8 is_add = 1;
7972   int ret = 0;
7973
7974   /* Parse args required to build the message */
7975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7976     {
7977       if (unformat (i, "ipv6"))
7978         is_ipv6 = 1;
7979       else if (unformat (i, "del"))
7980         is_add = 0;
7981       else if (unformat (i, "add"))
7982         is_add = 1;
7983       else if (unformat (i, "table %d", &table_id))
7984         ;
7985       else
7986         {
7987           clib_warning ("parse error '%U'", format_unformat_error, i);
7988           return -99;
7989         }
7990     }
7991
7992   if (~0 == table_id)
7993     {
7994       errmsg ("missing table-ID");
7995       return -99;
7996     }
7997
7998   /* Construct the API message */
7999   M (IP_TABLE_ADD_DEL, mp);
8000
8001   mp->table_id = ntohl (table_id);
8002   mp->is_ipv6 = is_ipv6;
8003   mp->is_add = is_add;
8004
8005   /* send it... */
8006   S (mp);
8007
8008   /* Wait for a reply... */
8009   W (ret);
8010
8011   return ret;
8012 }
8013
8014 static int
8015 api_ip_add_del_route (vat_main_t * vam)
8016 {
8017   unformat_input_t *i = vam->input;
8018   vl_api_ip_add_del_route_t *mp;
8019   u32 sw_if_index = ~0, vrf_id = 0;
8020   u8 is_ipv6 = 0;
8021   u8 is_local = 0, is_drop = 0;
8022   u8 is_unreach = 0, is_prohibit = 0;
8023   u8 is_add = 1;
8024   u32 next_hop_weight = 1;
8025   u8 is_multipath = 0;
8026   u8 address_set = 0;
8027   u8 address_length_set = 0;
8028   u32 next_hop_table_id = 0;
8029   u32 resolve_attempts = 0;
8030   u32 dst_address_length = 0;
8031   u8 next_hop_set = 0;
8032   ip4_address_t v4_dst_address, v4_next_hop_address;
8033   ip6_address_t v6_dst_address, v6_next_hop_address;
8034   int count = 1;
8035   int j;
8036   f64 before = 0;
8037   u32 random_add_del = 0;
8038   u32 *random_vector = 0;
8039   uword *random_hash;
8040   u32 random_seed = 0xdeaddabe;
8041   u32 classify_table_index = ~0;
8042   u8 is_classify = 0;
8043   u8 resolve_host = 0, resolve_attached = 0;
8044   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8045   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8046   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8047
8048   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8049   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8050   /* Parse args required to build the message */
8051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8052     {
8053       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8054         ;
8055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8056         ;
8057       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8058         {
8059           address_set = 1;
8060           is_ipv6 = 0;
8061         }
8062       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8063         {
8064           address_set = 1;
8065           is_ipv6 = 1;
8066         }
8067       else if (unformat (i, "/%d", &dst_address_length))
8068         {
8069           address_length_set = 1;
8070         }
8071
8072       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8073                                          &v4_next_hop_address))
8074         {
8075           next_hop_set = 1;
8076         }
8077       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8078                                          &v6_next_hop_address))
8079         {
8080           next_hop_set = 1;
8081         }
8082       else
8083         if (unformat
8084             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8085         {
8086           next_hop_set = 1;
8087         }
8088       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8089         {
8090           next_hop_set = 1;
8091         }
8092       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8093         ;
8094       else if (unformat (i, "weight %d", &next_hop_weight))
8095         ;
8096       else if (unformat (i, "drop"))
8097         {
8098           is_drop = 1;
8099         }
8100       else if (unformat (i, "null-send-unreach"))
8101         {
8102           is_unreach = 1;
8103         }
8104       else if (unformat (i, "null-send-prohibit"))
8105         {
8106           is_prohibit = 1;
8107         }
8108       else if (unformat (i, "local"))
8109         {
8110           is_local = 1;
8111         }
8112       else if (unformat (i, "classify %d", &classify_table_index))
8113         {
8114           is_classify = 1;
8115         }
8116       else if (unformat (i, "del"))
8117         is_add = 0;
8118       else if (unformat (i, "add"))
8119         is_add = 1;
8120       else if (unformat (i, "resolve-via-host"))
8121         resolve_host = 1;
8122       else if (unformat (i, "resolve-via-attached"))
8123         resolve_attached = 1;
8124       else if (unformat (i, "multipath"))
8125         is_multipath = 1;
8126       else if (unformat (i, "vrf %d", &vrf_id))
8127         ;
8128       else if (unformat (i, "count %d", &count))
8129         ;
8130       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8131         ;
8132       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8133         ;
8134       else if (unformat (i, "out-label %d", &next_hop_out_label))
8135         {
8136           vl_api_fib_mpls_label_t fib_label = {
8137             .label = ntohl (next_hop_out_label),
8138             .ttl = 64,
8139             .exp = 0,
8140           };
8141           vec_add1 (next_hop_out_label_stack, fib_label);
8142         }
8143       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8144         ;
8145       else if (unformat (i, "random"))
8146         random_add_del = 1;
8147       else if (unformat (i, "seed %d", &random_seed))
8148         ;
8149       else
8150         {
8151           clib_warning ("parse error '%U'", format_unformat_error, i);
8152           return -99;
8153         }
8154     }
8155
8156   if (!next_hop_set && !is_drop && !is_local &&
8157       !is_classify && !is_unreach && !is_prohibit &&
8158       MPLS_LABEL_INVALID == next_hop_via_label)
8159     {
8160       errmsg
8161         ("next hop / local / drop / unreach / prohibit / classify not set");
8162       return -99;
8163     }
8164
8165   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8166     {
8167       errmsg ("next hop and next-hop via label set");
8168       return -99;
8169     }
8170   if (address_set == 0)
8171     {
8172       errmsg ("missing addresses");
8173       return -99;
8174     }
8175
8176   if (address_length_set == 0)
8177     {
8178       errmsg ("missing address length");
8179       return -99;
8180     }
8181
8182   /* Generate a pile of unique, random routes */
8183   if (random_add_del)
8184     {
8185       u32 this_random_address;
8186       random_hash = hash_create (count, sizeof (uword));
8187
8188       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8189       for (j = 0; j <= count; j++)
8190         {
8191           do
8192             {
8193               this_random_address = random_u32 (&random_seed);
8194               this_random_address =
8195                 clib_host_to_net_u32 (this_random_address);
8196             }
8197           while (hash_get (random_hash, this_random_address));
8198           vec_add1 (random_vector, this_random_address);
8199           hash_set (random_hash, this_random_address, 1);
8200         }
8201       hash_free (random_hash);
8202       v4_dst_address.as_u32 = random_vector[0];
8203     }
8204
8205   if (count > 1)
8206     {
8207       /* Turn on async mode */
8208       vam->async_mode = 1;
8209       vam->async_errors = 0;
8210       before = vat_time_now (vam);
8211     }
8212
8213   for (j = 0; j < count; j++)
8214     {
8215       /* Construct the API message */
8216       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8217           vec_len (next_hop_out_label_stack));
8218
8219       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8220       mp->table_id = ntohl (vrf_id);
8221
8222       mp->is_add = is_add;
8223       mp->is_drop = is_drop;
8224       mp->is_unreach = is_unreach;
8225       mp->is_prohibit = is_prohibit;
8226       mp->is_ipv6 = is_ipv6;
8227       mp->is_local = is_local;
8228       mp->is_classify = is_classify;
8229       mp->is_multipath = is_multipath;
8230       mp->is_resolve_host = resolve_host;
8231       mp->is_resolve_attached = resolve_attached;
8232       mp->next_hop_weight = next_hop_weight;
8233       mp->next_hop_preference = 0;
8234       mp->dst_address_length = dst_address_length;
8235       mp->next_hop_table_id = ntohl (next_hop_table_id);
8236       mp->classify_table_index = ntohl (classify_table_index);
8237       mp->next_hop_via_label = ntohl (next_hop_via_label);
8238       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8239       if (0 != mp->next_hop_n_out_labels)
8240         {
8241           memcpy (mp->next_hop_out_label_stack,
8242                   next_hop_out_label_stack,
8243                   (vec_len (next_hop_out_label_stack) *
8244                    sizeof (vl_api_fib_mpls_label_t)));
8245           vec_free (next_hop_out_label_stack);
8246         }
8247
8248       if (is_ipv6)
8249         {
8250           clib_memcpy (mp->dst_address, &v6_dst_address,
8251                        sizeof (v6_dst_address));
8252           if (next_hop_set)
8253             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8254                          sizeof (v6_next_hop_address));
8255           increment_v6_address (&v6_dst_address);
8256         }
8257       else
8258         {
8259           clib_memcpy (mp->dst_address, &v4_dst_address,
8260                        sizeof (v4_dst_address));
8261           if (next_hop_set)
8262             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8263                          sizeof (v4_next_hop_address));
8264           if (random_add_del)
8265             v4_dst_address.as_u32 = random_vector[j + 1];
8266           else
8267             increment_v4_address (&v4_dst_address);
8268         }
8269       /* send it... */
8270       S (mp);
8271       /* If we receive SIGTERM, stop now... */
8272       if (vam->do_exit)
8273         break;
8274     }
8275
8276   /* When testing multiple add/del ops, use a control-ping to sync */
8277   if (count > 1)
8278     {
8279       vl_api_control_ping_t *mp_ping;
8280       f64 after;
8281       f64 timeout;
8282
8283       /* Shut off async mode */
8284       vam->async_mode = 0;
8285
8286       MPING (CONTROL_PING, mp_ping);
8287       S (mp_ping);
8288
8289       timeout = vat_time_now (vam) + 1.0;
8290       while (vat_time_now (vam) < timeout)
8291         if (vam->result_ready == 1)
8292           goto out;
8293       vam->retval = -99;
8294
8295     out:
8296       if (vam->retval == -99)
8297         errmsg ("timeout");
8298
8299       if (vam->async_errors > 0)
8300         {
8301           errmsg ("%d asynchronous errors", vam->async_errors);
8302           vam->retval = -98;
8303         }
8304       vam->async_errors = 0;
8305       after = vat_time_now (vam);
8306
8307       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8308       if (j > 0)
8309         count = j;
8310
8311       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8312              count, after - before, count / (after - before));
8313     }
8314   else
8315     {
8316       int ret;
8317
8318       /* Wait for a reply... */
8319       W (ret);
8320       return ret;
8321     }
8322
8323   /* Return the good/bad news */
8324   return (vam->retval);
8325 }
8326
8327 static int
8328 api_ip_mroute_add_del (vat_main_t * vam)
8329 {
8330   unformat_input_t *i = vam->input;
8331   vl_api_ip_mroute_add_del_t *mp;
8332   u32 sw_if_index = ~0, vrf_id = 0;
8333   u8 is_ipv6 = 0;
8334   u8 is_local = 0;
8335   u8 is_add = 1;
8336   u8 address_set = 0;
8337   u32 grp_address_length = 0;
8338   ip4_address_t v4_grp_address, v4_src_address;
8339   ip6_address_t v6_grp_address, v6_src_address;
8340   mfib_itf_flags_t iflags = 0;
8341   mfib_entry_flags_t eflags = 0;
8342   int ret;
8343
8344   /* Parse args required to build the message */
8345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8346     {
8347       if (unformat (i, "sw_if_index %d", &sw_if_index))
8348         ;
8349       else if (unformat (i, "%U %U",
8350                          unformat_ip4_address, &v4_src_address,
8351                          unformat_ip4_address, &v4_grp_address))
8352         {
8353           grp_address_length = 64;
8354           address_set = 1;
8355           is_ipv6 = 0;
8356         }
8357       else if (unformat (i, "%U %U",
8358                          unformat_ip6_address, &v6_src_address,
8359                          unformat_ip6_address, &v6_grp_address))
8360         {
8361           grp_address_length = 256;
8362           address_set = 1;
8363           is_ipv6 = 1;
8364         }
8365       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8366         {
8367           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8368           grp_address_length = 32;
8369           address_set = 1;
8370           is_ipv6 = 0;
8371         }
8372       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8373         {
8374           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8375           grp_address_length = 128;
8376           address_set = 1;
8377           is_ipv6 = 1;
8378         }
8379       else if (unformat (i, "/%d", &grp_address_length))
8380         ;
8381       else if (unformat (i, "local"))
8382         {
8383           is_local = 1;
8384         }
8385       else if (unformat (i, "del"))
8386         is_add = 0;
8387       else if (unformat (i, "add"))
8388         is_add = 1;
8389       else if (unformat (i, "vrf %d", &vrf_id))
8390         ;
8391       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8392         ;
8393       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8394         ;
8395       else
8396         {
8397           clib_warning ("parse error '%U'", format_unformat_error, i);
8398           return -99;
8399         }
8400     }
8401
8402   if (address_set == 0)
8403     {
8404       errmsg ("missing addresses\n");
8405       return -99;
8406     }
8407
8408   /* Construct the API message */
8409   M (IP_MROUTE_ADD_DEL, mp);
8410
8411   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8412   mp->table_id = ntohl (vrf_id);
8413
8414   mp->is_add = is_add;
8415   mp->is_ipv6 = is_ipv6;
8416   mp->is_local = is_local;
8417   mp->itf_flags = ntohl (iflags);
8418   mp->entry_flags = ntohl (eflags);
8419   mp->grp_address_length = grp_address_length;
8420   mp->grp_address_length = ntohs (mp->grp_address_length);
8421
8422   if (is_ipv6)
8423     {
8424       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8425       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8426     }
8427   else
8428     {
8429       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8430       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8431
8432     }
8433
8434   /* send it... */
8435   S (mp);
8436   /* Wait for a reply... */
8437   W (ret);
8438   return ret;
8439 }
8440
8441 static int
8442 api_mpls_table_add_del (vat_main_t * vam)
8443 {
8444   unformat_input_t *i = vam->input;
8445   vl_api_mpls_table_add_del_t *mp;
8446   u32 table_id = ~0;
8447   u8 is_add = 1;
8448   int ret = 0;
8449
8450   /* Parse args required to build the message */
8451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (i, "table %d", &table_id))
8454         ;
8455       else if (unformat (i, "del"))
8456         is_add = 0;
8457       else if (unformat (i, "add"))
8458         is_add = 1;
8459       else
8460         {
8461           clib_warning ("parse error '%U'", format_unformat_error, i);
8462           return -99;
8463         }
8464     }
8465
8466   if (~0 == table_id)
8467     {
8468       errmsg ("missing table-ID");
8469       return -99;
8470     }
8471
8472   /* Construct the API message */
8473   M (MPLS_TABLE_ADD_DEL, mp);
8474
8475   mp->mt_table_id = ntohl (table_id);
8476   mp->mt_is_add = is_add;
8477
8478   /* send it... */
8479   S (mp);
8480
8481   /* Wait for a reply... */
8482   W (ret);
8483
8484   return ret;
8485 }
8486
8487 static int
8488 api_mpls_route_add_del (vat_main_t * vam)
8489 {
8490   unformat_input_t *i = vam->input;
8491   vl_api_mpls_route_add_del_t *mp;
8492   u32 sw_if_index = ~0, table_id = 0;
8493   u8 is_add = 1;
8494   u32 next_hop_weight = 1;
8495   u8 is_multipath = 0;
8496   u32 next_hop_table_id = 0;
8497   u8 next_hop_set = 0;
8498   ip4_address_t v4_next_hop_address = {
8499     .as_u32 = 0,
8500   };
8501   ip6_address_t v6_next_hop_address = { {0} };
8502   int count = 1;
8503   int j;
8504   f64 before = 0;
8505   u32 classify_table_index = ~0;
8506   u8 is_classify = 0;
8507   u8 resolve_host = 0, resolve_attached = 0;
8508   u8 is_interface_rx = 0;
8509   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8510   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8511   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8512   mpls_label_t local_label = MPLS_LABEL_INVALID;
8513   u8 is_eos = 0;
8514   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8515
8516   /* Parse args required to build the message */
8517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8518     {
8519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8520         ;
8521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8522         ;
8523       else if (unformat (i, "%d", &local_label))
8524         ;
8525       else if (unformat (i, "eos"))
8526         is_eos = 1;
8527       else if (unformat (i, "non-eos"))
8528         is_eos = 0;
8529       else if (unformat (i, "via %U", unformat_ip4_address,
8530                          &v4_next_hop_address))
8531         {
8532           next_hop_set = 1;
8533           next_hop_proto = DPO_PROTO_IP4;
8534         }
8535       else if (unformat (i, "via %U", unformat_ip6_address,
8536                          &v6_next_hop_address))
8537         {
8538           next_hop_set = 1;
8539           next_hop_proto = DPO_PROTO_IP6;
8540         }
8541       else if (unformat (i, "weight %d", &next_hop_weight))
8542         ;
8543       else if (unformat (i, "classify %d", &classify_table_index))
8544         {
8545           is_classify = 1;
8546         }
8547       else if (unformat (i, "del"))
8548         is_add = 0;
8549       else if (unformat (i, "add"))
8550         is_add = 1;
8551       else if (unformat (i, "resolve-via-host"))
8552         resolve_host = 1;
8553       else if (unformat (i, "resolve-via-attached"))
8554         resolve_attached = 1;
8555       else if (unformat (i, "multipath"))
8556         is_multipath = 1;
8557       else if (unformat (i, "count %d", &count))
8558         ;
8559       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8560         {
8561           next_hop_set = 1;
8562           next_hop_proto = DPO_PROTO_IP4;
8563         }
8564       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8565         {
8566           next_hop_set = 1;
8567           next_hop_proto = DPO_PROTO_IP6;
8568         }
8569       else
8570         if (unformat
8571             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8572              &sw_if_index))
8573         {
8574           next_hop_set = 1;
8575           next_hop_proto = DPO_PROTO_ETHERNET;
8576           is_interface_rx = 1;
8577         }
8578       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8579         {
8580           next_hop_set = 1;
8581           next_hop_proto = DPO_PROTO_ETHERNET;
8582           is_interface_rx = 1;
8583         }
8584       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8585         next_hop_set = 1;
8586       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8587         next_hop_set = 1;
8588       else if (unformat (i, "out-label %d", &next_hop_out_label))
8589         {
8590           vl_api_fib_mpls_label_t fib_label = {
8591             .label = ntohl (next_hop_out_label),
8592             .ttl = 64,
8593             .exp = 0,
8594           };
8595           vec_add1 (next_hop_out_label_stack, fib_label);
8596         }
8597       else
8598         {
8599           clib_warning ("parse error '%U'", format_unformat_error, i);
8600           return -99;
8601         }
8602     }
8603
8604   if (!next_hop_set && !is_classify)
8605     {
8606       errmsg ("next hop / classify not set");
8607       return -99;
8608     }
8609
8610   if (MPLS_LABEL_INVALID == local_label)
8611     {
8612       errmsg ("missing label");
8613       return -99;
8614     }
8615
8616   if (count > 1)
8617     {
8618       /* Turn on async mode */
8619       vam->async_mode = 1;
8620       vam->async_errors = 0;
8621       before = vat_time_now (vam);
8622     }
8623
8624   for (j = 0; j < count; j++)
8625     {
8626       /* Construct the API message */
8627       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8628           vec_len (next_hop_out_label_stack));
8629
8630       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8631       mp->mr_table_id = ntohl (table_id);
8632
8633       mp->mr_is_add = is_add;
8634       mp->mr_next_hop_proto = next_hop_proto;
8635       mp->mr_is_classify = is_classify;
8636       mp->mr_is_multipath = is_multipath;
8637       mp->mr_is_resolve_host = resolve_host;
8638       mp->mr_is_resolve_attached = resolve_attached;
8639       mp->mr_is_interface_rx = is_interface_rx;
8640       mp->mr_next_hop_weight = next_hop_weight;
8641       mp->mr_next_hop_preference = 0;
8642       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8643       mp->mr_classify_table_index = ntohl (classify_table_index);
8644       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8645       mp->mr_label = ntohl (local_label);
8646       mp->mr_eos = is_eos;
8647
8648       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8649       if (0 != mp->mr_next_hop_n_out_labels)
8650         {
8651           memcpy (mp->mr_next_hop_out_label_stack,
8652                   next_hop_out_label_stack,
8653                   vec_len (next_hop_out_label_stack) *
8654                   sizeof (vl_api_fib_mpls_label_t));
8655           vec_free (next_hop_out_label_stack);
8656         }
8657
8658       if (next_hop_set)
8659         {
8660           if (DPO_PROTO_IP4 == next_hop_proto)
8661             {
8662               clib_memcpy (mp->mr_next_hop,
8663                            &v4_next_hop_address,
8664                            sizeof (v4_next_hop_address));
8665             }
8666           else if (DPO_PROTO_IP6 == next_hop_proto)
8667
8668             {
8669               clib_memcpy (mp->mr_next_hop,
8670                            &v6_next_hop_address,
8671                            sizeof (v6_next_hop_address));
8672             }
8673         }
8674       local_label++;
8675
8676       /* send it... */
8677       S (mp);
8678       /* If we receive SIGTERM, stop now... */
8679       if (vam->do_exit)
8680         break;
8681     }
8682
8683   /* When testing multiple add/del ops, use a control-ping to sync */
8684   if (count > 1)
8685     {
8686       vl_api_control_ping_t *mp_ping;
8687       f64 after;
8688       f64 timeout;
8689
8690       /* Shut off async mode */
8691       vam->async_mode = 0;
8692
8693       MPING (CONTROL_PING, mp_ping);
8694       S (mp_ping);
8695
8696       timeout = vat_time_now (vam) + 1.0;
8697       while (vat_time_now (vam) < timeout)
8698         if (vam->result_ready == 1)
8699           goto out;
8700       vam->retval = -99;
8701
8702     out:
8703       if (vam->retval == -99)
8704         errmsg ("timeout");
8705
8706       if (vam->async_errors > 0)
8707         {
8708           errmsg ("%d asynchronous errors", vam->async_errors);
8709           vam->retval = -98;
8710         }
8711       vam->async_errors = 0;
8712       after = vat_time_now (vam);
8713
8714       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8715       if (j > 0)
8716         count = j;
8717
8718       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8719              count, after - before, count / (after - before));
8720     }
8721   else
8722     {
8723       int ret;
8724
8725       /* Wait for a reply... */
8726       W (ret);
8727       return ret;
8728     }
8729
8730   /* Return the good/bad news */
8731   return (vam->retval);
8732 }
8733
8734 static int
8735 api_mpls_ip_bind_unbind (vat_main_t * vam)
8736 {
8737   unformat_input_t *i = vam->input;
8738   vl_api_mpls_ip_bind_unbind_t *mp;
8739   u32 ip_table_id = 0;
8740   u8 is_bind = 1;
8741   u8 is_ip4 = 1;
8742   ip4_address_t v4_address;
8743   ip6_address_t v6_address;
8744   u32 address_length;
8745   u8 address_set = 0;
8746   mpls_label_t local_label = MPLS_LABEL_INVALID;
8747   int ret;
8748
8749   /* Parse args required to build the message */
8750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8751     {
8752       if (unformat (i, "%U/%d", unformat_ip4_address,
8753                     &v4_address, &address_length))
8754         {
8755           is_ip4 = 1;
8756           address_set = 1;
8757         }
8758       else if (unformat (i, "%U/%d", unformat_ip6_address,
8759                          &v6_address, &address_length))
8760         {
8761           is_ip4 = 0;
8762           address_set = 1;
8763         }
8764       else if (unformat (i, "%d", &local_label))
8765         ;
8766       else if (unformat (i, "table-id %d", &ip_table_id))
8767         ;
8768       else if (unformat (i, "unbind"))
8769         is_bind = 0;
8770       else if (unformat (i, "bind"))
8771         is_bind = 1;
8772       else
8773         {
8774           clib_warning ("parse error '%U'", format_unformat_error, i);
8775           return -99;
8776         }
8777     }
8778
8779   if (!address_set)
8780     {
8781       errmsg ("IP address not set");
8782       return -99;
8783     }
8784
8785   if (MPLS_LABEL_INVALID == local_label)
8786     {
8787       errmsg ("missing label");
8788       return -99;
8789     }
8790
8791   /* Construct the API message */
8792   M (MPLS_IP_BIND_UNBIND, mp);
8793
8794   mp->mb_is_bind = is_bind;
8795   mp->mb_is_ip4 = is_ip4;
8796   mp->mb_ip_table_id = ntohl (ip_table_id);
8797   mp->mb_mpls_table_id = 0;
8798   mp->mb_label = ntohl (local_label);
8799   mp->mb_address_length = address_length;
8800
8801   if (is_ip4)
8802     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8803   else
8804     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8805
8806   /* send it... */
8807   S (mp);
8808
8809   /* Wait for a reply... */
8810   W (ret);
8811   return ret;
8812 }
8813
8814 static int
8815 api_sr_mpls_policy_add (vat_main_t * vam)
8816 {
8817   unformat_input_t *i = vam->input;
8818   vl_api_sr_mpls_policy_add_t *mp;
8819   u32 bsid = 0;
8820   u32 weight = 1;
8821   u8 type = 0;
8822   u8 n_segments = 0;
8823   u32 sid;
8824   u32 *segments = NULL;
8825   int ret;
8826
8827   /* Parse args required to build the message */
8828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8829     {
8830       if (unformat (i, "bsid %d", &bsid))
8831         ;
8832       else if (unformat (i, "weight %d", &weight))
8833         ;
8834       else if (unformat (i, "spray"))
8835         type = 1;
8836       else if (unformat (i, "next %d", &sid))
8837         {
8838           n_segments += 1;
8839           vec_add1 (segments, htonl (sid));
8840         }
8841       else
8842         {
8843           clib_warning ("parse error '%U'", format_unformat_error, i);
8844           return -99;
8845         }
8846     }
8847
8848   if (bsid == 0)
8849     {
8850       errmsg ("bsid not set");
8851       return -99;
8852     }
8853
8854   if (n_segments == 0)
8855     {
8856       errmsg ("no sid in segment stack");
8857       return -99;
8858     }
8859
8860   /* Construct the API message */
8861   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8862
8863   mp->bsid = htonl (bsid);
8864   mp->weight = htonl (weight);
8865   mp->type = type;
8866   mp->n_segments = n_segments;
8867   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8868   vec_free (segments);
8869
8870   /* send it... */
8871   S (mp);
8872
8873   /* Wait for a reply... */
8874   W (ret);
8875   return ret;
8876 }
8877
8878 static int
8879 api_sr_mpls_policy_del (vat_main_t * vam)
8880 {
8881   unformat_input_t *i = vam->input;
8882   vl_api_sr_mpls_policy_del_t *mp;
8883   u32 bsid = 0;
8884   int ret;
8885
8886   /* Parse args required to build the message */
8887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8888     {
8889       if (unformat (i, "bsid %d", &bsid))
8890         ;
8891       else
8892         {
8893           clib_warning ("parse error '%U'", format_unformat_error, i);
8894           return -99;
8895         }
8896     }
8897
8898   if (bsid == 0)
8899     {
8900       errmsg ("bsid not set");
8901       return -99;
8902     }
8903
8904   /* Construct the API message */
8905   M (SR_MPLS_POLICY_DEL, mp);
8906
8907   mp->bsid = htonl (bsid);
8908
8909   /* send it... */
8910   S (mp);
8911
8912   /* Wait for a reply... */
8913   W (ret);
8914   return ret;
8915 }
8916
8917 static int
8918 api_bier_table_add_del (vat_main_t * vam)
8919 {
8920   unformat_input_t *i = vam->input;
8921   vl_api_bier_table_add_del_t *mp;
8922   u8 is_add = 1;
8923   u32 set = 0, sub_domain = 0, hdr_len = 3;
8924   mpls_label_t local_label = MPLS_LABEL_INVALID;
8925   int ret;
8926
8927   /* Parse args required to build the message */
8928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8929     {
8930       if (unformat (i, "sub-domain %d", &sub_domain))
8931         ;
8932       else if (unformat (i, "set %d", &set))
8933         ;
8934       else if (unformat (i, "label %d", &local_label))
8935         ;
8936       else if (unformat (i, "hdr-len %d", &hdr_len))
8937         ;
8938       else if (unformat (i, "add"))
8939         is_add = 1;
8940       else if (unformat (i, "del"))
8941         is_add = 0;
8942       else
8943         {
8944           clib_warning ("parse error '%U'", format_unformat_error, i);
8945           return -99;
8946         }
8947     }
8948
8949   if (MPLS_LABEL_INVALID == local_label)
8950     {
8951       errmsg ("missing label\n");
8952       return -99;
8953     }
8954
8955   /* Construct the API message */
8956   M (BIER_TABLE_ADD_DEL, mp);
8957
8958   mp->bt_is_add = is_add;
8959   mp->bt_label = ntohl (local_label);
8960   mp->bt_tbl_id.bt_set = set;
8961   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8962   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8963
8964   /* send it... */
8965   S (mp);
8966
8967   /* Wait for a reply... */
8968   W (ret);
8969
8970   return (ret);
8971 }
8972
8973 static int
8974 api_bier_route_add_del (vat_main_t * vam)
8975 {
8976   unformat_input_t *i = vam->input;
8977   vl_api_bier_route_add_del_t *mp;
8978   u8 is_add = 1;
8979   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8980   ip4_address_t v4_next_hop_address;
8981   ip6_address_t v6_next_hop_address;
8982   u8 next_hop_set = 0;
8983   u8 next_hop_proto_is_ip4 = 1;
8984   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8985   int ret;
8986
8987   /* Parse args required to build the message */
8988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8989     {
8990       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8991         {
8992           next_hop_proto_is_ip4 = 1;
8993           next_hop_set = 1;
8994         }
8995       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8996         {
8997           next_hop_proto_is_ip4 = 0;
8998           next_hop_set = 1;
8999         }
9000       if (unformat (i, "sub-domain %d", &sub_domain))
9001         ;
9002       else if (unformat (i, "set %d", &set))
9003         ;
9004       else if (unformat (i, "hdr-len %d", &hdr_len))
9005         ;
9006       else if (unformat (i, "bp %d", &bp))
9007         ;
9008       else if (unformat (i, "add"))
9009         is_add = 1;
9010       else if (unformat (i, "del"))
9011         is_add = 0;
9012       else if (unformat (i, "out-label %d", &next_hop_out_label))
9013         ;
9014       else
9015         {
9016           clib_warning ("parse error '%U'", format_unformat_error, i);
9017           return -99;
9018         }
9019     }
9020
9021   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9022     {
9023       errmsg ("next hop / label set\n");
9024       return -99;
9025     }
9026   if (0 == bp)
9027     {
9028       errmsg ("bit=position not set\n");
9029       return -99;
9030     }
9031
9032   /* Construct the API message */
9033   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9034
9035   mp->br_is_add = is_add;
9036   mp->br_tbl_id.bt_set = set;
9037   mp->br_tbl_id.bt_sub_domain = sub_domain;
9038   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9039   mp->br_bp = ntohs (bp);
9040   mp->br_n_paths = 1;
9041   mp->br_paths[0].n_labels = 1;
9042   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9043   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9044
9045   if (next_hop_proto_is_ip4)
9046     {
9047       clib_memcpy (mp->br_paths[0].next_hop,
9048                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9049     }
9050   else
9051     {
9052       clib_memcpy (mp->br_paths[0].next_hop,
9053                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9054     }
9055
9056   /* send it... */
9057   S (mp);
9058
9059   /* Wait for a reply... */
9060   W (ret);
9061
9062   return (ret);
9063 }
9064
9065 static int
9066 api_proxy_arp_add_del (vat_main_t * vam)
9067 {
9068   unformat_input_t *i = vam->input;
9069   vl_api_proxy_arp_add_del_t *mp;
9070   u32 vrf_id = 0;
9071   u8 is_add = 1;
9072   vl_api_ip4_address_t lo, hi;
9073   u8 range_set = 0;
9074   int ret;
9075
9076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9077     {
9078       if (unformat (i, "vrf %d", &vrf_id))
9079         ;
9080       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9081                          unformat_vl_api_ip4_address, &hi))
9082         range_set = 1;
9083       else if (unformat (i, "del"))
9084         is_add = 0;
9085       else
9086         {
9087           clib_warning ("parse error '%U'", format_unformat_error, i);
9088           return -99;
9089         }
9090     }
9091
9092   if (range_set == 0)
9093     {
9094       errmsg ("address range not set");
9095       return -99;
9096     }
9097
9098   M (PROXY_ARP_ADD_DEL, mp);
9099
9100   mp->proxy.table_id = ntohl (vrf_id);
9101   mp->is_add = is_add;
9102   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9103   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9104
9105   S (mp);
9106   W (ret);
9107   return ret;
9108 }
9109
9110 static int
9111 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9115   u32 sw_if_index;
9116   u8 enable = 1;
9117   u8 sw_if_index_set = 0;
9118   int ret;
9119
9120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9123         sw_if_index_set = 1;
9124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9125         sw_if_index_set = 1;
9126       else if (unformat (i, "enable"))
9127         enable = 1;
9128       else if (unformat (i, "disable"))
9129         enable = 0;
9130       else
9131         {
9132           clib_warning ("parse error '%U'", format_unformat_error, i);
9133           return -99;
9134         }
9135     }
9136
9137   if (sw_if_index_set == 0)
9138     {
9139       errmsg ("missing interface name or sw_if_index");
9140       return -99;
9141     }
9142
9143   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9144
9145   mp->sw_if_index = ntohl (sw_if_index);
9146   mp->enable_disable = enable;
9147
9148   S (mp);
9149   W (ret);
9150   return ret;
9151 }
9152
9153 static int
9154 api_mpls_tunnel_add_del (vat_main_t * vam)
9155 {
9156   unformat_input_t *i = vam->input;
9157   vl_api_mpls_tunnel_add_del_t *mp;
9158
9159   u8 is_add = 1;
9160   u8 l2_only = 0;
9161   u32 sw_if_index = ~0;
9162   u32 next_hop_sw_if_index = ~0;
9163   u32 next_hop_proto_is_ip4 = 1;
9164
9165   u32 next_hop_table_id = 0;
9166   ip4_address_t v4_next_hop_address = {
9167     .as_u32 = 0,
9168   };
9169   ip6_address_t v6_next_hop_address = { {0} };
9170   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9171   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9172   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9173   int ret;
9174
9175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9176     {
9177       if (unformat (i, "add"))
9178         is_add = 1;
9179       else
9180         if (unformat
9181             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9182         is_add = 0;
9183       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9184         is_add = 0;
9185       else if (unformat (i, "via %U",
9186                          unformat_ip4_address, &v4_next_hop_address))
9187         {
9188           next_hop_proto_is_ip4 = 1;
9189         }
9190       else if (unformat (i, "via %U",
9191                          unformat_ip6_address, &v6_next_hop_address))
9192         {
9193           next_hop_proto_is_ip4 = 0;
9194         }
9195       else if (unformat (i, "via-label %d", &next_hop_via_label))
9196         ;
9197       else
9198         if (unformat
9199             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9200         ;
9201       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9202         ;
9203       else if (unformat (i, "l2-only"))
9204         l2_only = 1;
9205       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9206         ;
9207       else if (unformat (i, "out-label %d", &next_hop_out_label))
9208         {
9209           vl_api_fib_mpls_label_t fib_label = {
9210             .label = ntohl (next_hop_out_label),
9211             .ttl = 64,
9212             .exp = 0,
9213           };
9214           vec_add1 (next_hop_out_label_stack, fib_label);
9215         }
9216       else
9217         {
9218           clib_warning ("parse error '%U'", format_unformat_error, i);
9219           return -99;
9220         }
9221     }
9222
9223   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9224       vec_len (next_hop_out_label_stack));
9225
9226   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9227   mp->mt_sw_if_index = ntohl (sw_if_index);
9228   mp->mt_is_add = is_add;
9229   mp->mt_l2_only = l2_only;
9230   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9231   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9232   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9233   mp->mt_next_hop_weight = 1;
9234   mp->mt_next_hop_preference = 0;
9235
9236   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9237
9238   if (0 != mp->mt_next_hop_n_out_labels)
9239     {
9240       clib_memcpy (mp->mt_next_hop_out_label_stack,
9241                    next_hop_out_label_stack,
9242                    (vec_len (next_hop_out_label_stack) *
9243                     sizeof (vl_api_fib_mpls_label_t)));
9244       vec_free (next_hop_out_label_stack);
9245     }
9246
9247   if (next_hop_proto_is_ip4)
9248     {
9249       clib_memcpy (mp->mt_next_hop,
9250                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9251     }
9252   else
9253     {
9254       clib_memcpy (mp->mt_next_hop,
9255                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9256     }
9257
9258   S (mp);
9259   W (ret);
9260   return ret;
9261 }
9262
9263 static int
9264 api_sw_interface_set_unnumbered (vat_main_t * vam)
9265 {
9266   unformat_input_t *i = vam->input;
9267   vl_api_sw_interface_set_unnumbered_t *mp;
9268   u32 sw_if_index;
9269   u32 unnum_sw_index = ~0;
9270   u8 is_add = 1;
9271   u8 sw_if_index_set = 0;
9272   int ret;
9273
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9277         sw_if_index_set = 1;
9278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9279         sw_if_index_set = 1;
9280       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9281         ;
9282       else if (unformat (i, "del"))
9283         is_add = 0;
9284       else
9285         {
9286           clib_warning ("parse error '%U'", format_unformat_error, i);
9287           return -99;
9288         }
9289     }
9290
9291   if (sw_if_index_set == 0)
9292     {
9293       errmsg ("missing interface name or sw_if_index");
9294       return -99;
9295     }
9296
9297   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9298
9299   mp->sw_if_index = ntohl (sw_if_index);
9300   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9301   mp->is_add = is_add;
9302
9303   S (mp);
9304   W (ret);
9305   return ret;
9306 }
9307
9308 static int
9309 api_ip_neighbor_add_del (vat_main_t * vam)
9310 {
9311   vl_api_mac_address_t mac_address;
9312   unformat_input_t *i = vam->input;
9313   vl_api_ip_neighbor_add_del_t *mp;
9314   vl_api_address_t ip_address;
9315   u32 sw_if_index;
9316   u8 sw_if_index_set = 0;
9317   u8 is_add = 1;
9318   u8 mac_set = 0;
9319   u8 address_set = 0;
9320   int ret;
9321   ip_neighbor_flags_t flags;
9322
9323   flags = IP_NEIGHBOR_FLAG_NONE;
9324   clib_memset (&ip_address, 0, sizeof (ip_address));
9325   clib_memset (&mac_address, 0, sizeof (mac_address));
9326   /* Parse args required to build the message */
9327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9328     {
9329       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9330         {
9331           mac_set = 1;
9332         }
9333       else if (unformat (i, "del"))
9334         is_add = 0;
9335       else
9336         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9337         sw_if_index_set = 1;
9338       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9339         sw_if_index_set = 1;
9340       else if (unformat (i, "static"))
9341         flags |= IP_NEIGHBOR_FLAG_STATIC;
9342       else if (unformat (i, "no-fib-entry"))
9343         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9344       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9345         address_set = 1;
9346       else
9347         {
9348           clib_warning ("parse error '%U'", format_unformat_error, i);
9349           return -99;
9350         }
9351     }
9352
9353   if (sw_if_index_set == 0)
9354     {
9355       errmsg ("missing interface name or sw_if_index");
9356       return -99;
9357     }
9358   if (!address_set)
9359     {
9360       errmsg ("no address set");
9361       return -99;
9362     }
9363
9364   /* Construct the API message */
9365   M (IP_NEIGHBOR_ADD_DEL, mp);
9366
9367   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9368   mp->is_add = is_add;
9369   mp->neighbor.flags = htonl (flags);
9370   if (mac_set)
9371     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9372                  sizeof (mac_address));
9373   if (address_set)
9374     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9375
9376   /* send it... */
9377   S (mp);
9378
9379   /* Wait for a reply, return good/bad news  */
9380   W (ret);
9381   return ret;
9382 }
9383
9384 static int
9385 api_create_vlan_subif (vat_main_t * vam)
9386 {
9387   unformat_input_t *i = vam->input;
9388   vl_api_create_vlan_subif_t *mp;
9389   u32 sw_if_index;
9390   u8 sw_if_index_set = 0;
9391   u32 vlan_id;
9392   u8 vlan_id_set = 0;
9393   int ret;
9394
9395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9396     {
9397       if (unformat (i, "sw_if_index %d", &sw_if_index))
9398         sw_if_index_set = 1;
9399       else
9400         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9401         sw_if_index_set = 1;
9402       else if (unformat (i, "vlan %d", &vlan_id))
9403         vlan_id_set = 1;
9404       else
9405         {
9406           clib_warning ("parse error '%U'", format_unformat_error, i);
9407           return -99;
9408         }
9409     }
9410
9411   if (sw_if_index_set == 0)
9412     {
9413       errmsg ("missing interface name or sw_if_index");
9414       return -99;
9415     }
9416
9417   if (vlan_id_set == 0)
9418     {
9419       errmsg ("missing vlan_id");
9420       return -99;
9421     }
9422   M (CREATE_VLAN_SUBIF, mp);
9423
9424   mp->sw_if_index = ntohl (sw_if_index);
9425   mp->vlan_id = ntohl (vlan_id);
9426
9427   S (mp);
9428   W (ret);
9429   return ret;
9430 }
9431
9432 #define foreach_create_subif_bit                \
9433 _(no_tags)                                      \
9434 _(one_tag)                                      \
9435 _(two_tags)                                     \
9436 _(dot1ad)                                       \
9437 _(exact_match)                                  \
9438 _(default_sub)                                  \
9439 _(outer_vlan_id_any)                            \
9440 _(inner_vlan_id_any)
9441
9442 static int
9443 api_create_subif (vat_main_t * vam)
9444 {
9445   unformat_input_t *i = vam->input;
9446   vl_api_create_subif_t *mp;
9447   u32 sw_if_index;
9448   u8 sw_if_index_set = 0;
9449   u32 sub_id;
9450   u8 sub_id_set = 0;
9451   u32 no_tags = 0;
9452   u32 one_tag = 0;
9453   u32 two_tags = 0;
9454   u32 dot1ad = 0;
9455   u32 exact_match = 0;
9456   u32 default_sub = 0;
9457   u32 outer_vlan_id_any = 0;
9458   u32 inner_vlan_id_any = 0;
9459   u32 tmp;
9460   u16 outer_vlan_id = 0;
9461   u16 inner_vlan_id = 0;
9462   int ret;
9463
9464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9465     {
9466       if (unformat (i, "sw_if_index %d", &sw_if_index))
9467         sw_if_index_set = 1;
9468       else
9469         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9470         sw_if_index_set = 1;
9471       else if (unformat (i, "sub_id %d", &sub_id))
9472         sub_id_set = 1;
9473       else if (unformat (i, "outer_vlan_id %d", &tmp))
9474         outer_vlan_id = tmp;
9475       else if (unformat (i, "inner_vlan_id %d", &tmp))
9476         inner_vlan_id = tmp;
9477
9478 #define _(a) else if (unformat (i, #a)) a = 1 ;
9479       foreach_create_subif_bit
9480 #undef _
9481         else
9482         {
9483           clib_warning ("parse error '%U'", format_unformat_error, i);
9484           return -99;
9485         }
9486     }
9487
9488   if (sw_if_index_set == 0)
9489     {
9490       errmsg ("missing interface name or sw_if_index");
9491       return -99;
9492     }
9493
9494   if (sub_id_set == 0)
9495     {
9496       errmsg ("missing sub_id");
9497       return -99;
9498     }
9499   M (CREATE_SUBIF, mp);
9500
9501   mp->sw_if_index = ntohl (sw_if_index);
9502   mp->sub_id = ntohl (sub_id);
9503
9504 #define _(a) mp->a = a;
9505   foreach_create_subif_bit;
9506 #undef _
9507
9508   mp->outer_vlan_id = ntohs (outer_vlan_id);
9509   mp->inner_vlan_id = ntohs (inner_vlan_id);
9510
9511   S (mp);
9512   W (ret);
9513   return ret;
9514 }
9515
9516 static int
9517 api_reset_fib (vat_main_t * vam)
9518 {
9519   unformat_input_t *i = vam->input;
9520   vl_api_reset_fib_t *mp;
9521   u32 vrf_id = 0;
9522   u8 is_ipv6 = 0;
9523   u8 vrf_id_set = 0;
9524
9525   int ret;
9526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9527     {
9528       if (unformat (i, "vrf %d", &vrf_id))
9529         vrf_id_set = 1;
9530       else if (unformat (i, "ipv6"))
9531         is_ipv6 = 1;
9532       else
9533         {
9534           clib_warning ("parse error '%U'", format_unformat_error, i);
9535           return -99;
9536         }
9537     }
9538
9539   if (vrf_id_set == 0)
9540     {
9541       errmsg ("missing vrf id");
9542       return -99;
9543     }
9544
9545   M (RESET_FIB, mp);
9546
9547   mp->vrf_id = ntohl (vrf_id);
9548   mp->is_ipv6 = is_ipv6;
9549
9550   S (mp);
9551   W (ret);
9552   return ret;
9553 }
9554
9555 static int
9556 api_dhcp_proxy_config (vat_main_t * vam)
9557 {
9558   unformat_input_t *i = vam->input;
9559   vl_api_dhcp_proxy_config_t *mp;
9560   u32 rx_vrf_id = 0;
9561   u32 server_vrf_id = 0;
9562   u8 is_add = 1;
9563   u8 v4_address_set = 0;
9564   u8 v6_address_set = 0;
9565   ip4_address_t v4address;
9566   ip6_address_t v6address;
9567   u8 v4_src_address_set = 0;
9568   u8 v6_src_address_set = 0;
9569   ip4_address_t v4srcaddress;
9570   ip6_address_t v6srcaddress;
9571   int ret;
9572
9573   /* Parse args required to build the message */
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "del"))
9577         is_add = 0;
9578       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9579         ;
9580       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9581         ;
9582       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9583         v4_address_set = 1;
9584       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9585         v6_address_set = 1;
9586       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9587         v4_src_address_set = 1;
9588       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9589         v6_src_address_set = 1;
9590       else
9591         break;
9592     }
9593
9594   if (v4_address_set && v6_address_set)
9595     {
9596       errmsg ("both v4 and v6 server addresses set");
9597       return -99;
9598     }
9599   if (!v4_address_set && !v6_address_set)
9600     {
9601       errmsg ("no server addresses set");
9602       return -99;
9603     }
9604
9605   if (v4_src_address_set && v6_src_address_set)
9606     {
9607       errmsg ("both v4 and v6  src addresses set");
9608       return -99;
9609     }
9610   if (!v4_src_address_set && !v6_src_address_set)
9611     {
9612       errmsg ("no src addresses set");
9613       return -99;
9614     }
9615
9616   if (!(v4_src_address_set && v4_address_set) &&
9617       !(v6_src_address_set && v6_address_set))
9618     {
9619       errmsg ("no matching server and src addresses set");
9620       return -99;
9621     }
9622
9623   /* Construct the API message */
9624   M (DHCP_PROXY_CONFIG, mp);
9625
9626   mp->is_add = is_add;
9627   mp->rx_vrf_id = ntohl (rx_vrf_id);
9628   mp->server_vrf_id = ntohl (server_vrf_id);
9629   if (v6_address_set)
9630     {
9631       mp->is_ipv6 = 1;
9632       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9633       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9634     }
9635   else
9636     {
9637       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9638       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9639     }
9640
9641   /* send it... */
9642   S (mp);
9643
9644   /* Wait for a reply, return good/bad news  */
9645   W (ret);
9646   return ret;
9647 }
9648
9649 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9650 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9651
9652 static void
9653 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9654 {
9655   vat_main_t *vam = &vat_main;
9656   u32 i, count = mp->count;
9657   vl_api_dhcp_server_t *s;
9658
9659   if (mp->is_ipv6)
9660     print (vam->ofp,
9661            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9662            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9663            ntohl (mp->rx_vrf_id),
9664            format_ip6_address, mp->dhcp_src_address,
9665            mp->vss_type, mp->vss_vpn_ascii_id,
9666            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9667   else
9668     print (vam->ofp,
9669            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9670            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9671            ntohl (mp->rx_vrf_id),
9672            format_ip4_address, mp->dhcp_src_address,
9673            mp->vss_type, mp->vss_vpn_ascii_id,
9674            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9675
9676   for (i = 0; i < count; i++)
9677     {
9678       s = &mp->servers[i];
9679
9680       if (mp->is_ipv6)
9681         print (vam->ofp,
9682                " Server Table-ID %d, Server Address %U",
9683                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9684       else
9685         print (vam->ofp,
9686                " Server Table-ID %d, Server Address %U",
9687                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9688     }
9689 }
9690
9691 static void vl_api_dhcp_proxy_details_t_handler_json
9692   (vl_api_dhcp_proxy_details_t * mp)
9693 {
9694   vat_main_t *vam = &vat_main;
9695   vat_json_node_t *node = NULL;
9696   u32 i, count = mp->count;
9697   struct in_addr ip4;
9698   struct in6_addr ip6;
9699   vl_api_dhcp_server_t *s;
9700
9701   if (VAT_JSON_ARRAY != vam->json_tree.type)
9702     {
9703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9704       vat_json_init_array (&vam->json_tree);
9705     }
9706   node = vat_json_array_add (&vam->json_tree);
9707
9708   vat_json_init_object (node);
9709   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9710   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9711                              sizeof (mp->vss_type));
9712   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9713                                    mp->vss_vpn_ascii_id);
9714   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9715   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9716
9717   if (mp->is_ipv6)
9718     {
9719       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9720       vat_json_object_add_ip6 (node, "src_address", ip6);
9721     }
9722   else
9723     {
9724       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9725       vat_json_object_add_ip4 (node, "src_address", ip4);
9726     }
9727
9728   for (i = 0; i < count; i++)
9729     {
9730       s = &mp->servers[i];
9731
9732       vat_json_object_add_uint (node, "server-table-id",
9733                                 ntohl (s->server_vrf_id));
9734
9735       if (mp->is_ipv6)
9736         {
9737           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9738           vat_json_object_add_ip4 (node, "src_address", ip4);
9739         }
9740       else
9741         {
9742           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9743           vat_json_object_add_ip6 (node, "server_address", ip6);
9744         }
9745     }
9746 }
9747
9748 static int
9749 api_dhcp_proxy_dump (vat_main_t * vam)
9750 {
9751   unformat_input_t *i = vam->input;
9752   vl_api_control_ping_t *mp_ping;
9753   vl_api_dhcp_proxy_dump_t *mp;
9754   u8 is_ipv6 = 0;
9755   int ret;
9756
9757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9758     {
9759       if (unformat (i, "ipv6"))
9760         is_ipv6 = 1;
9761       else
9762         {
9763           clib_warning ("parse error '%U'", format_unformat_error, i);
9764           return -99;
9765         }
9766     }
9767
9768   M (DHCP_PROXY_DUMP, mp);
9769
9770   mp->is_ip6 = is_ipv6;
9771   S (mp);
9772
9773   /* Use a control ping for synchronization */
9774   MPING (CONTROL_PING, mp_ping);
9775   S (mp_ping);
9776
9777   W (ret);
9778   return ret;
9779 }
9780
9781 static int
9782 api_dhcp_proxy_set_vss (vat_main_t * vam)
9783 {
9784   unformat_input_t *i = vam->input;
9785   vl_api_dhcp_proxy_set_vss_t *mp;
9786   u8 is_ipv6 = 0;
9787   u8 is_add = 1;
9788   u32 tbl_id = ~0;
9789   u8 vss_type = VSS_TYPE_DEFAULT;
9790   u8 *vpn_ascii_id = 0;
9791   u32 oui = 0;
9792   u32 fib_id = 0;
9793   int ret;
9794
9795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9796     {
9797       if (unformat (i, "tbl_id %d", &tbl_id))
9798         ;
9799       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9800         vss_type = VSS_TYPE_ASCII;
9801       else if (unformat (i, "fib_id %d", &fib_id))
9802         vss_type = VSS_TYPE_VPN_ID;
9803       else if (unformat (i, "oui %d", &oui))
9804         vss_type = VSS_TYPE_VPN_ID;
9805       else if (unformat (i, "ipv6"))
9806         is_ipv6 = 1;
9807       else if (unformat (i, "del"))
9808         is_add = 0;
9809       else
9810         break;
9811     }
9812
9813   if (tbl_id == ~0)
9814     {
9815       errmsg ("missing tbl_id ");
9816       vec_free (vpn_ascii_id);
9817       return -99;
9818     }
9819
9820   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9821     {
9822       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9823       vec_free (vpn_ascii_id);
9824       return -99;
9825     }
9826
9827   M (DHCP_PROXY_SET_VSS, mp);
9828   mp->tbl_id = ntohl (tbl_id);
9829   mp->vss_type = vss_type;
9830   if (vpn_ascii_id)
9831     {
9832       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9833       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9834     }
9835   mp->vpn_index = ntohl (fib_id);
9836   mp->oui = ntohl (oui);
9837   mp->is_ipv6 = is_ipv6;
9838   mp->is_add = is_add;
9839
9840   S (mp);
9841   W (ret);
9842
9843   vec_free (vpn_ascii_id);
9844   return ret;
9845 }
9846
9847 static int
9848 api_dhcp_client_config (vat_main_t * vam)
9849 {
9850   unformat_input_t *i = vam->input;
9851   vl_api_dhcp_client_config_t *mp;
9852   u32 sw_if_index;
9853   u8 sw_if_index_set = 0;
9854   u8 is_add = 1;
9855   u8 *hostname = 0;
9856   u8 disable_event = 0;
9857   int ret;
9858
9859   /* Parse args required to build the message */
9860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9861     {
9862       if (unformat (i, "del"))
9863         is_add = 0;
9864       else
9865         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9866         sw_if_index_set = 1;
9867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9868         sw_if_index_set = 1;
9869       else if (unformat (i, "hostname %s", &hostname))
9870         ;
9871       else if (unformat (i, "disable_event"))
9872         disable_event = 1;
9873       else
9874         break;
9875     }
9876
9877   if (sw_if_index_set == 0)
9878     {
9879       errmsg ("missing interface name or sw_if_index");
9880       return -99;
9881     }
9882
9883   if (vec_len (hostname) > 63)
9884     {
9885       errmsg ("hostname too long");
9886     }
9887   vec_add1 (hostname, 0);
9888
9889   /* Construct the API message */
9890   M (DHCP_CLIENT_CONFIG, mp);
9891
9892   mp->is_add = is_add;
9893   mp->client.sw_if_index = htonl (sw_if_index);
9894   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9895   vec_free (hostname);
9896   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9897   mp->client.pid = htonl (getpid ());
9898
9899   /* send it... */
9900   S (mp);
9901
9902   /* Wait for a reply, return good/bad news  */
9903   W (ret);
9904   return ret;
9905 }
9906
9907 static int
9908 api_set_ip_flow_hash (vat_main_t * vam)
9909 {
9910   unformat_input_t *i = vam->input;
9911   vl_api_set_ip_flow_hash_t *mp;
9912   u32 vrf_id = 0;
9913   u8 is_ipv6 = 0;
9914   u8 vrf_id_set = 0;
9915   u8 src = 0;
9916   u8 dst = 0;
9917   u8 sport = 0;
9918   u8 dport = 0;
9919   u8 proto = 0;
9920   u8 reverse = 0;
9921   int ret;
9922
9923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9924     {
9925       if (unformat (i, "vrf %d", &vrf_id))
9926         vrf_id_set = 1;
9927       else if (unformat (i, "ipv6"))
9928         is_ipv6 = 1;
9929       else if (unformat (i, "src"))
9930         src = 1;
9931       else if (unformat (i, "dst"))
9932         dst = 1;
9933       else if (unformat (i, "sport"))
9934         sport = 1;
9935       else if (unformat (i, "dport"))
9936         dport = 1;
9937       else if (unformat (i, "proto"))
9938         proto = 1;
9939       else if (unformat (i, "reverse"))
9940         reverse = 1;
9941
9942       else
9943         {
9944           clib_warning ("parse error '%U'", format_unformat_error, i);
9945           return -99;
9946         }
9947     }
9948
9949   if (vrf_id_set == 0)
9950     {
9951       errmsg ("missing vrf id");
9952       return -99;
9953     }
9954
9955   M (SET_IP_FLOW_HASH, mp);
9956   mp->src = src;
9957   mp->dst = dst;
9958   mp->sport = sport;
9959   mp->dport = dport;
9960   mp->proto = proto;
9961   mp->reverse = reverse;
9962   mp->vrf_id = ntohl (vrf_id);
9963   mp->is_ipv6 = is_ipv6;
9964
9965   S (mp);
9966   W (ret);
9967   return ret;
9968 }
9969
9970 static int
9971 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9972 {
9973   unformat_input_t *i = vam->input;
9974   vl_api_sw_interface_ip6_enable_disable_t *mp;
9975   u32 sw_if_index;
9976   u8 sw_if_index_set = 0;
9977   u8 enable = 0;
9978   int ret;
9979
9980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9981     {
9982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9983         sw_if_index_set = 1;
9984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9985         sw_if_index_set = 1;
9986       else if (unformat (i, "enable"))
9987         enable = 1;
9988       else if (unformat (i, "disable"))
9989         enable = 0;
9990       else
9991         {
9992           clib_warning ("parse error '%U'", format_unformat_error, i);
9993           return -99;
9994         }
9995     }
9996
9997   if (sw_if_index_set == 0)
9998     {
9999       errmsg ("missing interface name or sw_if_index");
10000       return -99;
10001     }
10002
10003   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10004
10005   mp->sw_if_index = ntohl (sw_if_index);
10006   mp->enable = enable;
10007
10008   S (mp);
10009   W (ret);
10010   return ret;
10011 }
10012
10013 static int
10014 api_ip6nd_proxy_add_del (vat_main_t * vam)
10015 {
10016   unformat_input_t *i = vam->input;
10017   vl_api_ip6nd_proxy_add_del_t *mp;
10018   u32 sw_if_index = ~0;
10019   u8 v6_address_set = 0;
10020   vl_api_ip6_address_t v6address;
10021   u8 is_del = 0;
10022   int ret;
10023
10024   /* Parse args required to build the message */
10025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10026     {
10027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10028         ;
10029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10030         ;
10031       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10032         v6_address_set = 1;
10033       if (unformat (i, "del"))
10034         is_del = 1;
10035       else
10036         {
10037           clib_warning ("parse error '%U'", format_unformat_error, i);
10038           return -99;
10039         }
10040     }
10041
10042   if (sw_if_index == ~0)
10043     {
10044       errmsg ("missing interface name or sw_if_index");
10045       return -99;
10046     }
10047   if (!v6_address_set)
10048     {
10049       errmsg ("no address set");
10050       return -99;
10051     }
10052
10053   /* Construct the API message */
10054   M (IP6ND_PROXY_ADD_DEL, mp);
10055
10056   mp->is_del = is_del;
10057   mp->sw_if_index = ntohl (sw_if_index);
10058   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10059
10060   /* send it... */
10061   S (mp);
10062
10063   /* Wait for a reply, return good/bad news  */
10064   W (ret);
10065   return ret;
10066 }
10067
10068 static int
10069 api_ip6nd_proxy_dump (vat_main_t * vam)
10070 {
10071   vl_api_ip6nd_proxy_dump_t *mp;
10072   vl_api_control_ping_t *mp_ping;
10073   int ret;
10074
10075   M (IP6ND_PROXY_DUMP, mp);
10076
10077   S (mp);
10078
10079   /* Use a control ping for synchronization */
10080   MPING (CONTROL_PING, mp_ping);
10081   S (mp_ping);
10082
10083   W (ret);
10084   return ret;
10085 }
10086
10087 static void vl_api_ip6nd_proxy_details_t_handler
10088   (vl_api_ip6nd_proxy_details_t * mp)
10089 {
10090   vat_main_t *vam = &vat_main;
10091
10092   print (vam->ofp, "host %U sw_if_index %d",
10093          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10094 }
10095
10096 static void vl_api_ip6nd_proxy_details_t_handler_json
10097   (vl_api_ip6nd_proxy_details_t * mp)
10098 {
10099   vat_main_t *vam = &vat_main;
10100   struct in6_addr ip6;
10101   vat_json_node_t *node = NULL;
10102
10103   if (VAT_JSON_ARRAY != vam->json_tree.type)
10104     {
10105       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10106       vat_json_init_array (&vam->json_tree);
10107     }
10108   node = vat_json_array_add (&vam->json_tree);
10109
10110   vat_json_init_object (node);
10111   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10112
10113   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10114   vat_json_object_add_ip6 (node, "host", ip6);
10115 }
10116
10117 static int
10118 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10119 {
10120   unformat_input_t *i = vam->input;
10121   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10122   u32 sw_if_index;
10123   u8 sw_if_index_set = 0;
10124   u32 address_length = 0;
10125   u8 v6_address_set = 0;
10126   vl_api_prefix_t pfx;
10127   u8 use_default = 0;
10128   u8 no_advertise = 0;
10129   u8 off_link = 0;
10130   u8 no_autoconfig = 0;
10131   u8 no_onlink = 0;
10132   u8 is_no = 0;
10133   u32 val_lifetime = 0;
10134   u32 pref_lifetime = 0;
10135   int ret;
10136
10137   /* Parse args required to build the message */
10138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10139     {
10140       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10141         sw_if_index_set = 1;
10142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10143         sw_if_index_set = 1;
10144       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10145         v6_address_set = 1;
10146       else if (unformat (i, "val_life %d", &val_lifetime))
10147         ;
10148       else if (unformat (i, "pref_life %d", &pref_lifetime))
10149         ;
10150       else if (unformat (i, "def"))
10151         use_default = 1;
10152       else if (unformat (i, "noadv"))
10153         no_advertise = 1;
10154       else if (unformat (i, "offl"))
10155         off_link = 1;
10156       else if (unformat (i, "noauto"))
10157         no_autoconfig = 1;
10158       else if (unformat (i, "nolink"))
10159         no_onlink = 1;
10160       else if (unformat (i, "isno"))
10161         is_no = 1;
10162       else
10163         {
10164           clib_warning ("parse error '%U'", format_unformat_error, i);
10165           return -99;
10166         }
10167     }
10168
10169   if (sw_if_index_set == 0)
10170     {
10171       errmsg ("missing interface name or sw_if_index");
10172       return -99;
10173     }
10174   if (!v6_address_set)
10175     {
10176       errmsg ("no address set");
10177       return -99;
10178     }
10179
10180   /* Construct the API message */
10181   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10182
10183   mp->sw_if_index = ntohl (sw_if_index);
10184   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10185   mp->use_default = use_default;
10186   mp->no_advertise = no_advertise;
10187   mp->off_link = off_link;
10188   mp->no_autoconfig = no_autoconfig;
10189   mp->no_onlink = no_onlink;
10190   mp->is_no = is_no;
10191   mp->val_lifetime = ntohl (val_lifetime);
10192   mp->pref_lifetime = ntohl (pref_lifetime);
10193
10194   /* send it... */
10195   S (mp);
10196
10197   /* Wait for a reply, return good/bad news  */
10198   W (ret);
10199   return ret;
10200 }
10201
10202 static int
10203 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10204 {
10205   unformat_input_t *i = vam->input;
10206   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10207   u32 sw_if_index;
10208   u8 sw_if_index_set = 0;
10209   u8 suppress = 0;
10210   u8 managed = 0;
10211   u8 other = 0;
10212   u8 ll_option = 0;
10213   u8 send_unicast = 0;
10214   u8 cease = 0;
10215   u8 is_no = 0;
10216   u8 default_router = 0;
10217   u32 max_interval = 0;
10218   u32 min_interval = 0;
10219   u32 lifetime = 0;
10220   u32 initial_count = 0;
10221   u32 initial_interval = 0;
10222   int ret;
10223
10224
10225   /* Parse args required to build the message */
10226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10227     {
10228       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10229         sw_if_index_set = 1;
10230       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10231         sw_if_index_set = 1;
10232       else if (unformat (i, "maxint %d", &max_interval))
10233         ;
10234       else if (unformat (i, "minint %d", &min_interval))
10235         ;
10236       else if (unformat (i, "life %d", &lifetime))
10237         ;
10238       else if (unformat (i, "count %d", &initial_count))
10239         ;
10240       else if (unformat (i, "interval %d", &initial_interval))
10241         ;
10242       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10243         suppress = 1;
10244       else if (unformat (i, "managed"))
10245         managed = 1;
10246       else if (unformat (i, "other"))
10247         other = 1;
10248       else if (unformat (i, "ll"))
10249         ll_option = 1;
10250       else if (unformat (i, "send"))
10251         send_unicast = 1;
10252       else if (unformat (i, "cease"))
10253         cease = 1;
10254       else if (unformat (i, "isno"))
10255         is_no = 1;
10256       else if (unformat (i, "def"))
10257         default_router = 1;
10258       else
10259         {
10260           clib_warning ("parse error '%U'", format_unformat_error, i);
10261           return -99;
10262         }
10263     }
10264
10265   if (sw_if_index_set == 0)
10266     {
10267       errmsg ("missing interface name or sw_if_index");
10268       return -99;
10269     }
10270
10271   /* Construct the API message */
10272   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10273
10274   mp->sw_if_index = ntohl (sw_if_index);
10275   mp->max_interval = ntohl (max_interval);
10276   mp->min_interval = ntohl (min_interval);
10277   mp->lifetime = ntohl (lifetime);
10278   mp->initial_count = ntohl (initial_count);
10279   mp->initial_interval = ntohl (initial_interval);
10280   mp->suppress = suppress;
10281   mp->managed = managed;
10282   mp->other = other;
10283   mp->ll_option = ll_option;
10284   mp->send_unicast = send_unicast;
10285   mp->cease = cease;
10286   mp->is_no = is_no;
10287   mp->default_router = default_router;
10288
10289   /* send it... */
10290   S (mp);
10291
10292   /* Wait for a reply, return good/bad news  */
10293   W (ret);
10294   return ret;
10295 }
10296
10297 static int
10298 api_set_arp_neighbor_limit (vat_main_t * vam)
10299 {
10300   unformat_input_t *i = vam->input;
10301   vl_api_set_arp_neighbor_limit_t *mp;
10302   u32 arp_nbr_limit;
10303   u8 limit_set = 0;
10304   u8 is_ipv6 = 0;
10305   int ret;
10306
10307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10308     {
10309       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10310         limit_set = 1;
10311       else if (unformat (i, "ipv6"))
10312         is_ipv6 = 1;
10313       else
10314         {
10315           clib_warning ("parse error '%U'", format_unformat_error, i);
10316           return -99;
10317         }
10318     }
10319
10320   if (limit_set == 0)
10321     {
10322       errmsg ("missing limit value");
10323       return -99;
10324     }
10325
10326   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10327
10328   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10329   mp->is_ipv6 = is_ipv6;
10330
10331   S (mp);
10332   W (ret);
10333   return ret;
10334 }
10335
10336 static int
10337 api_l2_patch_add_del (vat_main_t * vam)
10338 {
10339   unformat_input_t *i = vam->input;
10340   vl_api_l2_patch_add_del_t *mp;
10341   u32 rx_sw_if_index;
10342   u8 rx_sw_if_index_set = 0;
10343   u32 tx_sw_if_index;
10344   u8 tx_sw_if_index_set = 0;
10345   u8 is_add = 1;
10346   int ret;
10347
10348   /* Parse args required to build the message */
10349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10350     {
10351       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10352         rx_sw_if_index_set = 1;
10353       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10354         tx_sw_if_index_set = 1;
10355       else if (unformat (i, "rx"))
10356         {
10357           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10358             {
10359               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10360                             &rx_sw_if_index))
10361                 rx_sw_if_index_set = 1;
10362             }
10363           else
10364             break;
10365         }
10366       else if (unformat (i, "tx"))
10367         {
10368           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10369             {
10370               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10371                             &tx_sw_if_index))
10372                 tx_sw_if_index_set = 1;
10373             }
10374           else
10375             break;
10376         }
10377       else if (unformat (i, "del"))
10378         is_add = 0;
10379       else
10380         break;
10381     }
10382
10383   if (rx_sw_if_index_set == 0)
10384     {
10385       errmsg ("missing rx interface name or rx_sw_if_index");
10386       return -99;
10387     }
10388
10389   if (tx_sw_if_index_set == 0)
10390     {
10391       errmsg ("missing tx interface name or tx_sw_if_index");
10392       return -99;
10393     }
10394
10395   M (L2_PATCH_ADD_DEL, mp);
10396
10397   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10398   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10399   mp->is_add = is_add;
10400
10401   S (mp);
10402   W (ret);
10403   return ret;
10404 }
10405
10406 u8 is_del;
10407 u8 localsid_addr[16];
10408 u8 end_psp;
10409 u8 behavior;
10410 u32 sw_if_index;
10411 u32 vlan_index;
10412 u32 fib_table;
10413 u8 nh_addr[16];
10414
10415 static int
10416 api_sr_localsid_add_del (vat_main_t * vam)
10417 {
10418   unformat_input_t *i = vam->input;
10419   vl_api_sr_localsid_add_del_t *mp;
10420
10421   u8 is_del;
10422   ip6_address_t localsid;
10423   u8 end_psp = 0;
10424   u8 behavior = ~0;
10425   u32 sw_if_index;
10426   u32 fib_table = ~(u32) 0;
10427   ip6_address_t nh_addr6;
10428   ip4_address_t nh_addr4;
10429   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10430   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10431
10432   bool nexthop_set = 0;
10433
10434   int ret;
10435
10436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10437     {
10438       if (unformat (i, "del"))
10439         is_del = 1;
10440       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10441       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10442         nexthop_set = 1;
10443       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10444         nexthop_set = 1;
10445       else if (unformat (i, "behavior %u", &behavior));
10446       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10447       else if (unformat (i, "fib-table %u", &fib_table));
10448       else if (unformat (i, "end.psp %u", &behavior));
10449       else
10450         break;
10451     }
10452
10453   M (SR_LOCALSID_ADD_DEL, mp);
10454
10455   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10456   if (nexthop_set)
10457     {
10458       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10459       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10460     }
10461   mp->behavior = behavior;
10462   mp->sw_if_index = ntohl (sw_if_index);
10463   mp->fib_table = ntohl (fib_table);
10464   mp->end_psp = end_psp;
10465   mp->is_del = is_del;
10466
10467   S (mp);
10468   W (ret);
10469   return ret;
10470 }
10471
10472 static int
10473 api_ioam_enable (vat_main_t * vam)
10474 {
10475   unformat_input_t *input = vam->input;
10476   vl_api_ioam_enable_t *mp;
10477   u32 id = 0;
10478   int has_trace_option = 0;
10479   int has_pot_option = 0;
10480   int has_seqno_option = 0;
10481   int has_analyse_option = 0;
10482   int ret;
10483
10484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10485     {
10486       if (unformat (input, "trace"))
10487         has_trace_option = 1;
10488       else if (unformat (input, "pot"))
10489         has_pot_option = 1;
10490       else if (unformat (input, "seqno"))
10491         has_seqno_option = 1;
10492       else if (unformat (input, "analyse"))
10493         has_analyse_option = 1;
10494       else
10495         break;
10496     }
10497   M (IOAM_ENABLE, mp);
10498   mp->id = htons (id);
10499   mp->seqno = has_seqno_option;
10500   mp->analyse = has_analyse_option;
10501   mp->pot_enable = has_pot_option;
10502   mp->trace_enable = has_trace_option;
10503
10504   S (mp);
10505   W (ret);
10506   return ret;
10507 }
10508
10509
10510 static int
10511 api_ioam_disable (vat_main_t * vam)
10512 {
10513   vl_api_ioam_disable_t *mp;
10514   int ret;
10515
10516   M (IOAM_DISABLE, mp);
10517   S (mp);
10518   W (ret);
10519   return ret;
10520 }
10521
10522 #define foreach_tcp_proto_field                 \
10523 _(src_port)                                     \
10524 _(dst_port)
10525
10526 #define foreach_udp_proto_field                 \
10527 _(src_port)                                     \
10528 _(dst_port)
10529
10530 #define foreach_ip4_proto_field                 \
10531 _(src_address)                                  \
10532 _(dst_address)                                  \
10533 _(tos)                                          \
10534 _(length)                                       \
10535 _(fragment_id)                                  \
10536 _(ttl)                                          \
10537 _(protocol)                                     \
10538 _(checksum)
10539
10540 typedef struct
10541 {
10542   u16 src_port, dst_port;
10543 } tcpudp_header_t;
10544
10545 #if VPP_API_TEST_BUILTIN == 0
10546 uword
10547 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10548 {
10549   u8 **maskp = va_arg (*args, u8 **);
10550   u8 *mask = 0;
10551   u8 found_something = 0;
10552   tcp_header_t *tcp;
10553
10554 #define _(a) u8 a=0;
10555   foreach_tcp_proto_field;
10556 #undef _
10557
10558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10559     {
10560       if (0);
10561 #define _(a) else if (unformat (input, #a)) a=1;
10562       foreach_tcp_proto_field
10563 #undef _
10564         else
10565         break;
10566     }
10567
10568 #define _(a) found_something += a;
10569   foreach_tcp_proto_field;
10570 #undef _
10571
10572   if (found_something == 0)
10573     return 0;
10574
10575   vec_validate (mask, sizeof (*tcp) - 1);
10576
10577   tcp = (tcp_header_t *) mask;
10578
10579 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10580   foreach_tcp_proto_field;
10581 #undef _
10582
10583   *maskp = mask;
10584   return 1;
10585 }
10586
10587 uword
10588 unformat_udp_mask (unformat_input_t * input, va_list * args)
10589 {
10590   u8 **maskp = va_arg (*args, u8 **);
10591   u8 *mask = 0;
10592   u8 found_something = 0;
10593   udp_header_t *udp;
10594
10595 #define _(a) u8 a=0;
10596   foreach_udp_proto_field;
10597 #undef _
10598
10599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10600     {
10601       if (0);
10602 #define _(a) else if (unformat (input, #a)) a=1;
10603       foreach_udp_proto_field
10604 #undef _
10605         else
10606         break;
10607     }
10608
10609 #define _(a) found_something += a;
10610   foreach_udp_proto_field;
10611 #undef _
10612
10613   if (found_something == 0)
10614     return 0;
10615
10616   vec_validate (mask, sizeof (*udp) - 1);
10617
10618   udp = (udp_header_t *) mask;
10619
10620 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10621   foreach_udp_proto_field;
10622 #undef _
10623
10624   *maskp = mask;
10625   return 1;
10626 }
10627
10628 uword
10629 unformat_l4_mask (unformat_input_t * input, va_list * args)
10630 {
10631   u8 **maskp = va_arg (*args, u8 **);
10632   u16 src_port = 0, dst_port = 0;
10633   tcpudp_header_t *tcpudp;
10634
10635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10638         return 1;
10639       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10640         return 1;
10641       else if (unformat (input, "src_port"))
10642         src_port = 0xFFFF;
10643       else if (unformat (input, "dst_port"))
10644         dst_port = 0xFFFF;
10645       else
10646         return 0;
10647     }
10648
10649   if (!src_port && !dst_port)
10650     return 0;
10651
10652   u8 *mask = 0;
10653   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10654
10655   tcpudp = (tcpudp_header_t *) mask;
10656   tcpudp->src_port = src_port;
10657   tcpudp->dst_port = dst_port;
10658
10659   *maskp = mask;
10660
10661   return 1;
10662 }
10663
10664 uword
10665 unformat_ip4_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   ip4_header_t *ip;
10671
10672 #define _(a) u8 a=0;
10673   foreach_ip4_proto_field;
10674 #undef _
10675   u8 version = 0;
10676   u8 hdr_length = 0;
10677
10678
10679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (input, "version"))
10682         version = 1;
10683       else if (unformat (input, "hdr_length"))
10684         hdr_length = 1;
10685       else if (unformat (input, "src"))
10686         src_address = 1;
10687       else if (unformat (input, "dst"))
10688         dst_address = 1;
10689       else if (unformat (input, "proto"))
10690         protocol = 1;
10691
10692 #define _(a) else if (unformat (input, #a)) a=1;
10693       foreach_ip4_proto_field
10694 #undef _
10695         else
10696         break;
10697     }
10698
10699 #define _(a) found_something += a;
10700   foreach_ip4_proto_field;
10701 #undef _
10702
10703   if (found_something == 0)
10704     return 0;
10705
10706   vec_validate (mask, sizeof (*ip) - 1);
10707
10708   ip = (ip4_header_t *) mask;
10709
10710 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10711   foreach_ip4_proto_field;
10712 #undef _
10713
10714   ip->ip_version_and_header_length = 0;
10715
10716   if (version)
10717     ip->ip_version_and_header_length |= 0xF0;
10718
10719   if (hdr_length)
10720     ip->ip_version_and_header_length |= 0x0F;
10721
10722   *maskp = mask;
10723   return 1;
10724 }
10725
10726 #define foreach_ip6_proto_field                 \
10727 _(src_address)                                  \
10728 _(dst_address)                                  \
10729 _(payload_length)                               \
10730 _(hop_limit)                                    \
10731 _(protocol)
10732
10733 uword
10734 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10735 {
10736   u8 **maskp = va_arg (*args, u8 **);
10737   u8 *mask = 0;
10738   u8 found_something = 0;
10739   ip6_header_t *ip;
10740   u32 ip_version_traffic_class_and_flow_label;
10741
10742 #define _(a) u8 a=0;
10743   foreach_ip6_proto_field;
10744 #undef _
10745   u8 version = 0;
10746   u8 traffic_class = 0;
10747   u8 flow_label = 0;
10748
10749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10750     {
10751       if (unformat (input, "version"))
10752         version = 1;
10753       else if (unformat (input, "traffic-class"))
10754         traffic_class = 1;
10755       else if (unformat (input, "flow-label"))
10756         flow_label = 1;
10757       else if (unformat (input, "src"))
10758         src_address = 1;
10759       else if (unformat (input, "dst"))
10760         dst_address = 1;
10761       else if (unformat (input, "proto"))
10762         protocol = 1;
10763
10764 #define _(a) else if (unformat (input, #a)) a=1;
10765       foreach_ip6_proto_field
10766 #undef _
10767         else
10768         break;
10769     }
10770
10771 #define _(a) found_something += a;
10772   foreach_ip6_proto_field;
10773 #undef _
10774
10775   if (found_something == 0)
10776     return 0;
10777
10778   vec_validate (mask, sizeof (*ip) - 1);
10779
10780   ip = (ip6_header_t *) mask;
10781
10782 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10783   foreach_ip6_proto_field;
10784 #undef _
10785
10786   ip_version_traffic_class_and_flow_label = 0;
10787
10788   if (version)
10789     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10790
10791   if (traffic_class)
10792     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10793
10794   if (flow_label)
10795     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10796
10797   ip->ip_version_traffic_class_and_flow_label =
10798     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10799
10800   *maskp = mask;
10801   return 1;
10802 }
10803
10804 uword
10805 unformat_l3_mask (unformat_input_t * input, va_list * args)
10806 {
10807   u8 **maskp = va_arg (*args, u8 **);
10808
10809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10810     {
10811       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10812         return 1;
10813       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10814         return 1;
10815       else
10816         break;
10817     }
10818   return 0;
10819 }
10820
10821 uword
10822 unformat_l2_mask (unformat_input_t * input, va_list * args)
10823 {
10824   u8 **maskp = va_arg (*args, u8 **);
10825   u8 *mask = 0;
10826   u8 src = 0;
10827   u8 dst = 0;
10828   u8 proto = 0;
10829   u8 tag1 = 0;
10830   u8 tag2 = 0;
10831   u8 ignore_tag1 = 0;
10832   u8 ignore_tag2 = 0;
10833   u8 cos1 = 0;
10834   u8 cos2 = 0;
10835   u8 dot1q = 0;
10836   u8 dot1ad = 0;
10837   int len = 14;
10838
10839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10840     {
10841       if (unformat (input, "src"))
10842         src = 1;
10843       else if (unformat (input, "dst"))
10844         dst = 1;
10845       else if (unformat (input, "proto"))
10846         proto = 1;
10847       else if (unformat (input, "tag1"))
10848         tag1 = 1;
10849       else if (unformat (input, "tag2"))
10850         tag2 = 1;
10851       else if (unformat (input, "ignore-tag1"))
10852         ignore_tag1 = 1;
10853       else if (unformat (input, "ignore-tag2"))
10854         ignore_tag2 = 1;
10855       else if (unformat (input, "cos1"))
10856         cos1 = 1;
10857       else if (unformat (input, "cos2"))
10858         cos2 = 1;
10859       else if (unformat (input, "dot1q"))
10860         dot1q = 1;
10861       else if (unformat (input, "dot1ad"))
10862         dot1ad = 1;
10863       else
10864         break;
10865     }
10866   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10867        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10868     return 0;
10869
10870   if (tag1 || ignore_tag1 || cos1 || dot1q)
10871     len = 18;
10872   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10873     len = 22;
10874
10875   vec_validate (mask, len - 1);
10876
10877   if (dst)
10878     clib_memset (mask, 0xff, 6);
10879
10880   if (src)
10881     clib_memset (mask + 6, 0xff, 6);
10882
10883   if (tag2 || dot1ad)
10884     {
10885       /* inner vlan tag */
10886       if (tag2)
10887         {
10888           mask[19] = 0xff;
10889           mask[18] = 0x0f;
10890         }
10891       if (cos2)
10892         mask[18] |= 0xe0;
10893       if (proto)
10894         mask[21] = mask[20] = 0xff;
10895       if (tag1)
10896         {
10897           mask[15] = 0xff;
10898           mask[14] = 0x0f;
10899         }
10900       if (cos1)
10901         mask[14] |= 0xe0;
10902       *maskp = mask;
10903       return 1;
10904     }
10905   if (tag1 | dot1q)
10906     {
10907       if (tag1)
10908         {
10909           mask[15] = 0xff;
10910           mask[14] = 0x0f;
10911         }
10912       if (cos1)
10913         mask[14] |= 0xe0;
10914       if (proto)
10915         mask[16] = mask[17] = 0xff;
10916
10917       *maskp = mask;
10918       return 1;
10919     }
10920   if (cos2)
10921     mask[18] |= 0xe0;
10922   if (cos1)
10923     mask[14] |= 0xe0;
10924   if (proto)
10925     mask[12] = mask[13] = 0xff;
10926
10927   *maskp = mask;
10928   return 1;
10929 }
10930
10931 uword
10932 unformat_classify_mask (unformat_input_t * input, va_list * args)
10933 {
10934   u8 **maskp = va_arg (*args, u8 **);
10935   u32 *skipp = va_arg (*args, u32 *);
10936   u32 *matchp = va_arg (*args, u32 *);
10937   u32 match;
10938   u8 *mask = 0;
10939   u8 *l2 = 0;
10940   u8 *l3 = 0;
10941   u8 *l4 = 0;
10942   int i;
10943
10944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10945     {
10946       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10947         ;
10948       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10949         ;
10950       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10951         ;
10952       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10953         ;
10954       else
10955         break;
10956     }
10957
10958   if (l4 && !l3)
10959     {
10960       vec_free (mask);
10961       vec_free (l2);
10962       vec_free (l4);
10963       return 0;
10964     }
10965
10966   if (mask || l2 || l3 || l4)
10967     {
10968       if (l2 || l3 || l4)
10969         {
10970           /* "With a free Ethernet header in every package" */
10971           if (l2 == 0)
10972             vec_validate (l2, 13);
10973           mask = l2;
10974           if (vec_len (l3))
10975             {
10976               vec_append (mask, l3);
10977               vec_free (l3);
10978             }
10979           if (vec_len (l4))
10980             {
10981               vec_append (mask, l4);
10982               vec_free (l4);
10983             }
10984         }
10985
10986       /* Scan forward looking for the first significant mask octet */
10987       for (i = 0; i < vec_len (mask); i++)
10988         if (mask[i])
10989           break;
10990
10991       /* compute (skip, match) params */
10992       *skipp = i / sizeof (u32x4);
10993       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10994
10995       /* Pad mask to an even multiple of the vector size */
10996       while (vec_len (mask) % sizeof (u32x4))
10997         vec_add1 (mask, 0);
10998
10999       match = vec_len (mask) / sizeof (u32x4);
11000
11001       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11002         {
11003           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11004           if (*tmp || *(tmp + 1))
11005             break;
11006           match--;
11007         }
11008       if (match == 0)
11009         clib_warning ("BUG: match 0");
11010
11011       _vec_len (mask) = match * sizeof (u32x4);
11012
11013       *matchp = match;
11014       *maskp = mask;
11015
11016       return 1;
11017     }
11018
11019   return 0;
11020 }
11021 #endif /* VPP_API_TEST_BUILTIN */
11022
11023 #define foreach_l2_next                         \
11024 _(drop, DROP)                                   \
11025 _(ethernet, ETHERNET_INPUT)                     \
11026 _(ip4, IP4_INPUT)                               \
11027 _(ip6, IP6_INPUT)
11028
11029 uword
11030 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11031 {
11032   u32 *miss_next_indexp = va_arg (*args, u32 *);
11033   u32 next_index = 0;
11034   u32 tmp;
11035
11036 #define _(n,N) \
11037   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11038   foreach_l2_next;
11039 #undef _
11040
11041   if (unformat (input, "%d", &tmp))
11042     {
11043       next_index = tmp;
11044       goto out;
11045     }
11046
11047   return 0;
11048
11049 out:
11050   *miss_next_indexp = next_index;
11051   return 1;
11052 }
11053
11054 #define foreach_ip_next                         \
11055 _(drop, DROP)                                   \
11056 _(local, LOCAL)                                 \
11057 _(rewrite, REWRITE)
11058
11059 uword
11060 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11061 {
11062   u32 *miss_next_indexp = va_arg (*args, u32 *);
11063   u32 next_index = 0;
11064   u32 tmp;
11065
11066 #define _(n,N) \
11067   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11068   foreach_ip_next;
11069 #undef _
11070
11071   if (unformat (input, "%d", &tmp))
11072     {
11073       next_index = tmp;
11074       goto out;
11075     }
11076
11077   return 0;
11078
11079 out:
11080   *miss_next_indexp = next_index;
11081   return 1;
11082 }
11083
11084 #define foreach_acl_next                        \
11085 _(deny, DENY)
11086
11087 uword
11088 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11089 {
11090   u32 *miss_next_indexp = va_arg (*args, u32 *);
11091   u32 next_index = 0;
11092   u32 tmp;
11093
11094 #define _(n,N) \
11095   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11096   foreach_acl_next;
11097 #undef _
11098
11099   if (unformat (input, "permit"))
11100     {
11101       next_index = ~0;
11102       goto out;
11103     }
11104   else if (unformat (input, "%d", &tmp))
11105     {
11106       next_index = tmp;
11107       goto out;
11108     }
11109
11110   return 0;
11111
11112 out:
11113   *miss_next_indexp = next_index;
11114   return 1;
11115 }
11116
11117 uword
11118 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11119 {
11120   u32 *r = va_arg (*args, u32 *);
11121
11122   if (unformat (input, "conform-color"))
11123     *r = POLICE_CONFORM;
11124   else if (unformat (input, "exceed-color"))
11125     *r = POLICE_EXCEED;
11126   else
11127     return 0;
11128
11129   return 1;
11130 }
11131
11132 static int
11133 api_classify_add_del_table (vat_main_t * vam)
11134 {
11135   unformat_input_t *i = vam->input;
11136   vl_api_classify_add_del_table_t *mp;
11137
11138   u32 nbuckets = 2;
11139   u32 skip = ~0;
11140   u32 match = ~0;
11141   int is_add = 1;
11142   int del_chain = 0;
11143   u32 table_index = ~0;
11144   u32 next_table_index = ~0;
11145   u32 miss_next_index = ~0;
11146   u32 memory_size = 32 << 20;
11147   u8 *mask = 0;
11148   u32 current_data_flag = 0;
11149   int current_data_offset = 0;
11150   int ret;
11151
11152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11153     {
11154       if (unformat (i, "del"))
11155         is_add = 0;
11156       else if (unformat (i, "del-chain"))
11157         {
11158           is_add = 0;
11159           del_chain = 1;
11160         }
11161       else if (unformat (i, "buckets %d", &nbuckets))
11162         ;
11163       else if (unformat (i, "memory_size %d", &memory_size))
11164         ;
11165       else if (unformat (i, "skip %d", &skip))
11166         ;
11167       else if (unformat (i, "match %d", &match))
11168         ;
11169       else if (unformat (i, "table %d", &table_index))
11170         ;
11171       else if (unformat (i, "mask %U", unformat_classify_mask,
11172                          &mask, &skip, &match))
11173         ;
11174       else if (unformat (i, "next-table %d", &next_table_index))
11175         ;
11176       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11177                          &miss_next_index))
11178         ;
11179       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11180                          &miss_next_index))
11181         ;
11182       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11183                          &miss_next_index))
11184         ;
11185       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11186         ;
11187       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11188         ;
11189       else
11190         break;
11191     }
11192
11193   if (is_add && mask == 0)
11194     {
11195       errmsg ("Mask required");
11196       return -99;
11197     }
11198
11199   if (is_add && skip == ~0)
11200     {
11201       errmsg ("skip count required");
11202       return -99;
11203     }
11204
11205   if (is_add && match == ~0)
11206     {
11207       errmsg ("match count required");
11208       return -99;
11209     }
11210
11211   if (!is_add && table_index == ~0)
11212     {
11213       errmsg ("table index required for delete");
11214       return -99;
11215     }
11216
11217   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11218
11219   mp->is_add = is_add;
11220   mp->del_chain = del_chain;
11221   mp->table_index = ntohl (table_index);
11222   mp->nbuckets = ntohl (nbuckets);
11223   mp->memory_size = ntohl (memory_size);
11224   mp->skip_n_vectors = ntohl (skip);
11225   mp->match_n_vectors = ntohl (match);
11226   mp->next_table_index = ntohl (next_table_index);
11227   mp->miss_next_index = ntohl (miss_next_index);
11228   mp->current_data_flag = ntohl (current_data_flag);
11229   mp->current_data_offset = ntohl (current_data_offset);
11230   mp->mask_len = ntohl (vec_len (mask));
11231   clib_memcpy (mp->mask, mask, vec_len (mask));
11232
11233   vec_free (mask);
11234
11235   S (mp);
11236   W (ret);
11237   return ret;
11238 }
11239
11240 #if VPP_API_TEST_BUILTIN == 0
11241 uword
11242 unformat_l4_match (unformat_input_t * input, va_list * args)
11243 {
11244   u8 **matchp = va_arg (*args, u8 **);
11245
11246   u8 *proto_header = 0;
11247   int src_port = 0;
11248   int dst_port = 0;
11249
11250   tcpudp_header_t h;
11251
11252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11253     {
11254       if (unformat (input, "src_port %d", &src_port))
11255         ;
11256       else if (unformat (input, "dst_port %d", &dst_port))
11257         ;
11258       else
11259         return 0;
11260     }
11261
11262   h.src_port = clib_host_to_net_u16 (src_port);
11263   h.dst_port = clib_host_to_net_u16 (dst_port);
11264   vec_validate (proto_header, sizeof (h) - 1);
11265   memcpy (proto_header, &h, sizeof (h));
11266
11267   *matchp = proto_header;
11268
11269   return 1;
11270 }
11271
11272 uword
11273 unformat_ip4_match (unformat_input_t * input, va_list * args)
11274 {
11275   u8 **matchp = va_arg (*args, u8 **);
11276   u8 *match = 0;
11277   ip4_header_t *ip;
11278   int version = 0;
11279   u32 version_val;
11280   int hdr_length = 0;
11281   u32 hdr_length_val;
11282   int src = 0, dst = 0;
11283   ip4_address_t src_val, dst_val;
11284   int proto = 0;
11285   u32 proto_val;
11286   int tos = 0;
11287   u32 tos_val;
11288   int length = 0;
11289   u32 length_val;
11290   int fragment_id = 0;
11291   u32 fragment_id_val;
11292   int ttl = 0;
11293   int ttl_val;
11294   int checksum = 0;
11295   u32 checksum_val;
11296
11297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11298     {
11299       if (unformat (input, "version %d", &version_val))
11300         version = 1;
11301       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11302         hdr_length = 1;
11303       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11304         src = 1;
11305       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11306         dst = 1;
11307       else if (unformat (input, "proto %d", &proto_val))
11308         proto = 1;
11309       else if (unformat (input, "tos %d", &tos_val))
11310         tos = 1;
11311       else if (unformat (input, "length %d", &length_val))
11312         length = 1;
11313       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11314         fragment_id = 1;
11315       else if (unformat (input, "ttl %d", &ttl_val))
11316         ttl = 1;
11317       else if (unformat (input, "checksum %d", &checksum_val))
11318         checksum = 1;
11319       else
11320         break;
11321     }
11322
11323   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11324       + ttl + checksum == 0)
11325     return 0;
11326
11327   /*
11328    * Aligned because we use the real comparison functions
11329    */
11330   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11331
11332   ip = (ip4_header_t *) match;
11333
11334   /* These are realistically matched in practice */
11335   if (src)
11336     ip->src_address.as_u32 = src_val.as_u32;
11337
11338   if (dst)
11339     ip->dst_address.as_u32 = dst_val.as_u32;
11340
11341   if (proto)
11342     ip->protocol = proto_val;
11343
11344
11345   /* These are not, but they're included for completeness */
11346   if (version)
11347     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11348
11349   if (hdr_length)
11350     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11351
11352   if (tos)
11353     ip->tos = tos_val;
11354
11355   if (length)
11356     ip->length = clib_host_to_net_u16 (length_val);
11357
11358   if (ttl)
11359     ip->ttl = ttl_val;
11360
11361   if (checksum)
11362     ip->checksum = clib_host_to_net_u16 (checksum_val);
11363
11364   *matchp = match;
11365   return 1;
11366 }
11367
11368 uword
11369 unformat_ip6_match (unformat_input_t * input, va_list * args)
11370 {
11371   u8 **matchp = va_arg (*args, u8 **);
11372   u8 *match = 0;
11373   ip6_header_t *ip;
11374   int version = 0;
11375   u32 version_val;
11376   u8 traffic_class = 0;
11377   u32 traffic_class_val = 0;
11378   u8 flow_label = 0;
11379   u8 flow_label_val;
11380   int src = 0, dst = 0;
11381   ip6_address_t src_val, dst_val;
11382   int proto = 0;
11383   u32 proto_val;
11384   int payload_length = 0;
11385   u32 payload_length_val;
11386   int hop_limit = 0;
11387   int hop_limit_val;
11388   u32 ip_version_traffic_class_and_flow_label;
11389
11390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11391     {
11392       if (unformat (input, "version %d", &version_val))
11393         version = 1;
11394       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11395         traffic_class = 1;
11396       else if (unformat (input, "flow_label %d", &flow_label_val))
11397         flow_label = 1;
11398       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11399         src = 1;
11400       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11401         dst = 1;
11402       else if (unformat (input, "proto %d", &proto_val))
11403         proto = 1;
11404       else if (unformat (input, "payload_length %d", &payload_length_val))
11405         payload_length = 1;
11406       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11407         hop_limit = 1;
11408       else
11409         break;
11410     }
11411
11412   if (version + traffic_class + flow_label + src + dst + proto +
11413       payload_length + hop_limit == 0)
11414     return 0;
11415
11416   /*
11417    * Aligned because we use the real comparison functions
11418    */
11419   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11420
11421   ip = (ip6_header_t *) match;
11422
11423   if (src)
11424     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11425
11426   if (dst)
11427     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11428
11429   if (proto)
11430     ip->protocol = proto_val;
11431
11432   ip_version_traffic_class_and_flow_label = 0;
11433
11434   if (version)
11435     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11436
11437   if (traffic_class)
11438     ip_version_traffic_class_and_flow_label |=
11439       (traffic_class_val & 0xFF) << 20;
11440
11441   if (flow_label)
11442     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11443
11444   ip->ip_version_traffic_class_and_flow_label =
11445     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11446
11447   if (payload_length)
11448     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11449
11450   if (hop_limit)
11451     ip->hop_limit = hop_limit_val;
11452
11453   *matchp = match;
11454   return 1;
11455 }
11456
11457 uword
11458 unformat_l3_match (unformat_input_t * input, va_list * args)
11459 {
11460   u8 **matchp = va_arg (*args, u8 **);
11461
11462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11463     {
11464       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11465         return 1;
11466       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11467         return 1;
11468       else
11469         break;
11470     }
11471   return 0;
11472 }
11473
11474 uword
11475 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11476 {
11477   u8 *tagp = va_arg (*args, u8 *);
11478   u32 tag;
11479
11480   if (unformat (input, "%d", &tag))
11481     {
11482       tagp[0] = (tag >> 8) & 0x0F;
11483       tagp[1] = tag & 0xFF;
11484       return 1;
11485     }
11486
11487   return 0;
11488 }
11489
11490 uword
11491 unformat_l2_match (unformat_input_t * input, va_list * args)
11492 {
11493   u8 **matchp = va_arg (*args, u8 **);
11494   u8 *match = 0;
11495   u8 src = 0;
11496   u8 src_val[6];
11497   u8 dst = 0;
11498   u8 dst_val[6];
11499   u8 proto = 0;
11500   u16 proto_val;
11501   u8 tag1 = 0;
11502   u8 tag1_val[2];
11503   u8 tag2 = 0;
11504   u8 tag2_val[2];
11505   int len = 14;
11506   u8 ignore_tag1 = 0;
11507   u8 ignore_tag2 = 0;
11508   u8 cos1 = 0;
11509   u8 cos2 = 0;
11510   u32 cos1_val = 0;
11511   u32 cos2_val = 0;
11512
11513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11514     {
11515       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11516         src = 1;
11517       else
11518         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11519         dst = 1;
11520       else if (unformat (input, "proto %U",
11521                          unformat_ethernet_type_host_byte_order, &proto_val))
11522         proto = 1;
11523       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11524         tag1 = 1;
11525       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11526         tag2 = 1;
11527       else if (unformat (input, "ignore-tag1"))
11528         ignore_tag1 = 1;
11529       else if (unformat (input, "ignore-tag2"))
11530         ignore_tag2 = 1;
11531       else if (unformat (input, "cos1 %d", &cos1_val))
11532         cos1 = 1;
11533       else if (unformat (input, "cos2 %d", &cos2_val))
11534         cos2 = 1;
11535       else
11536         break;
11537     }
11538   if ((src + dst + proto + tag1 + tag2 +
11539        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11540     return 0;
11541
11542   if (tag1 || ignore_tag1 || cos1)
11543     len = 18;
11544   if (tag2 || ignore_tag2 || cos2)
11545     len = 22;
11546
11547   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11548
11549   if (dst)
11550     clib_memcpy (match, dst_val, 6);
11551
11552   if (src)
11553     clib_memcpy (match + 6, src_val, 6);
11554
11555   if (tag2)
11556     {
11557       /* inner vlan tag */
11558       match[19] = tag2_val[1];
11559       match[18] = tag2_val[0];
11560       if (cos2)
11561         match[18] |= (cos2_val & 0x7) << 5;
11562       if (proto)
11563         {
11564           match[21] = proto_val & 0xff;
11565           match[20] = proto_val >> 8;
11566         }
11567       if (tag1)
11568         {
11569           match[15] = tag1_val[1];
11570           match[14] = tag1_val[0];
11571         }
11572       if (cos1)
11573         match[14] |= (cos1_val & 0x7) << 5;
11574       *matchp = match;
11575       return 1;
11576     }
11577   if (tag1)
11578     {
11579       match[15] = tag1_val[1];
11580       match[14] = tag1_val[0];
11581       if (proto)
11582         {
11583           match[17] = proto_val & 0xff;
11584           match[16] = proto_val >> 8;
11585         }
11586       if (cos1)
11587         match[14] |= (cos1_val & 0x7) << 5;
11588
11589       *matchp = match;
11590       return 1;
11591     }
11592   if (cos2)
11593     match[18] |= (cos2_val & 0x7) << 5;
11594   if (cos1)
11595     match[14] |= (cos1_val & 0x7) << 5;
11596   if (proto)
11597     {
11598       match[13] = proto_val & 0xff;
11599       match[12] = proto_val >> 8;
11600     }
11601
11602   *matchp = match;
11603   return 1;
11604 }
11605
11606 uword
11607 unformat_qos_source (unformat_input_t * input, va_list * args)
11608 {
11609   int *qs = va_arg (*args, int *);
11610
11611   if (unformat (input, "ip"))
11612     *qs = QOS_SOURCE_IP;
11613   else if (unformat (input, "mpls"))
11614     *qs = QOS_SOURCE_MPLS;
11615   else if (unformat (input, "ext"))
11616     *qs = QOS_SOURCE_EXT;
11617   else if (unformat (input, "vlan"))
11618     *qs = QOS_SOURCE_VLAN;
11619   else
11620     return 0;
11621
11622   return 1;
11623 }
11624 #endif
11625
11626 uword
11627 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11628 {
11629   u8 **matchp = va_arg (*args, u8 **);
11630   u32 skip_n_vectors = va_arg (*args, u32);
11631   u32 match_n_vectors = va_arg (*args, u32);
11632
11633   u8 *match = 0;
11634   u8 *l2 = 0;
11635   u8 *l3 = 0;
11636   u8 *l4 = 0;
11637
11638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (input, "hex %U", unformat_hex_string, &match))
11641         ;
11642       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11643         ;
11644       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11645         ;
11646       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11647         ;
11648       else
11649         break;
11650     }
11651
11652   if (l4 && !l3)
11653     {
11654       vec_free (match);
11655       vec_free (l2);
11656       vec_free (l4);
11657       return 0;
11658     }
11659
11660   if (match || l2 || l3 || l4)
11661     {
11662       if (l2 || l3 || l4)
11663         {
11664           /* "Win a free Ethernet header in every packet" */
11665           if (l2 == 0)
11666             vec_validate_aligned (l2, 13, sizeof (u32x4));
11667           match = l2;
11668           if (vec_len (l3))
11669             {
11670               vec_append_aligned (match, l3, sizeof (u32x4));
11671               vec_free (l3);
11672             }
11673           if (vec_len (l4))
11674             {
11675               vec_append_aligned (match, l4, sizeof (u32x4));
11676               vec_free (l4);
11677             }
11678         }
11679
11680       /* Make sure the vector is big enough even if key is all 0's */
11681       vec_validate_aligned
11682         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11683          sizeof (u32x4));
11684
11685       /* Set size, include skipped vectors */
11686       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11687
11688       *matchp = match;
11689
11690       return 1;
11691     }
11692
11693   return 0;
11694 }
11695
11696 static int
11697 api_classify_add_del_session (vat_main_t * vam)
11698 {
11699   unformat_input_t *i = vam->input;
11700   vl_api_classify_add_del_session_t *mp;
11701   int is_add = 1;
11702   u32 table_index = ~0;
11703   u32 hit_next_index = ~0;
11704   u32 opaque_index = ~0;
11705   u8 *match = 0;
11706   i32 advance = 0;
11707   u32 skip_n_vectors = 0;
11708   u32 match_n_vectors = 0;
11709   u32 action = 0;
11710   u32 metadata = 0;
11711   int ret;
11712
11713   /*
11714    * Warning: you have to supply skip_n and match_n
11715    * because the API client cant simply look at the classify
11716    * table object.
11717    */
11718
11719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11720     {
11721       if (unformat (i, "del"))
11722         is_add = 0;
11723       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11724                          &hit_next_index))
11725         ;
11726       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11727                          &hit_next_index))
11728         ;
11729       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11730                          &hit_next_index))
11731         ;
11732       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11733         ;
11734       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11735         ;
11736       else if (unformat (i, "opaque-index %d", &opaque_index))
11737         ;
11738       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11739         ;
11740       else if (unformat (i, "match_n %d", &match_n_vectors))
11741         ;
11742       else if (unformat (i, "match %U", api_unformat_classify_match,
11743                          &match, skip_n_vectors, match_n_vectors))
11744         ;
11745       else if (unformat (i, "advance %d", &advance))
11746         ;
11747       else if (unformat (i, "table-index %d", &table_index))
11748         ;
11749       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11750         action = 1;
11751       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11752         action = 2;
11753       else if (unformat (i, "action %d", &action))
11754         ;
11755       else if (unformat (i, "metadata %d", &metadata))
11756         ;
11757       else
11758         break;
11759     }
11760
11761   if (table_index == ~0)
11762     {
11763       errmsg ("Table index required");
11764       return -99;
11765     }
11766
11767   if (is_add && match == 0)
11768     {
11769       errmsg ("Match value required");
11770       return -99;
11771     }
11772
11773   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11774
11775   mp->is_add = is_add;
11776   mp->table_index = ntohl (table_index);
11777   mp->hit_next_index = ntohl (hit_next_index);
11778   mp->opaque_index = ntohl (opaque_index);
11779   mp->advance = ntohl (advance);
11780   mp->action = action;
11781   mp->metadata = ntohl (metadata);
11782   mp->match_len = ntohl (vec_len (match));
11783   clib_memcpy (mp->match, match, vec_len (match));
11784   vec_free (match);
11785
11786   S (mp);
11787   W (ret);
11788   return ret;
11789 }
11790
11791 static int
11792 api_classify_set_interface_ip_table (vat_main_t * vam)
11793 {
11794   unformat_input_t *i = vam->input;
11795   vl_api_classify_set_interface_ip_table_t *mp;
11796   u32 sw_if_index;
11797   int sw_if_index_set;
11798   u32 table_index = ~0;
11799   u8 is_ipv6 = 0;
11800   int ret;
11801
11802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11803     {
11804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11805         sw_if_index_set = 1;
11806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11807         sw_if_index_set = 1;
11808       else if (unformat (i, "table %d", &table_index))
11809         ;
11810       else
11811         {
11812           clib_warning ("parse error '%U'", format_unformat_error, i);
11813           return -99;
11814         }
11815     }
11816
11817   if (sw_if_index_set == 0)
11818     {
11819       errmsg ("missing interface name or sw_if_index");
11820       return -99;
11821     }
11822
11823
11824   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11825
11826   mp->sw_if_index = ntohl (sw_if_index);
11827   mp->table_index = ntohl (table_index);
11828   mp->is_ipv6 = is_ipv6;
11829
11830   S (mp);
11831   W (ret);
11832   return ret;
11833 }
11834
11835 static int
11836 api_classify_set_interface_l2_tables (vat_main_t * vam)
11837 {
11838   unformat_input_t *i = vam->input;
11839   vl_api_classify_set_interface_l2_tables_t *mp;
11840   u32 sw_if_index;
11841   int sw_if_index_set;
11842   u32 ip4_table_index = ~0;
11843   u32 ip6_table_index = ~0;
11844   u32 other_table_index = ~0;
11845   u32 is_input = 1;
11846   int ret;
11847
11848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11849     {
11850       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11851         sw_if_index_set = 1;
11852       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11853         sw_if_index_set = 1;
11854       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11855         ;
11856       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11857         ;
11858       else if (unformat (i, "other-table %d", &other_table_index))
11859         ;
11860       else if (unformat (i, "is-input %d", &is_input))
11861         ;
11862       else
11863         {
11864           clib_warning ("parse error '%U'", format_unformat_error, i);
11865           return -99;
11866         }
11867     }
11868
11869   if (sw_if_index_set == 0)
11870     {
11871       errmsg ("missing interface name or sw_if_index");
11872       return -99;
11873     }
11874
11875
11876   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11877
11878   mp->sw_if_index = ntohl (sw_if_index);
11879   mp->ip4_table_index = ntohl (ip4_table_index);
11880   mp->ip6_table_index = ntohl (ip6_table_index);
11881   mp->other_table_index = ntohl (other_table_index);
11882   mp->is_input = (u8) is_input;
11883
11884   S (mp);
11885   W (ret);
11886   return ret;
11887 }
11888
11889 static int
11890 api_set_ipfix_exporter (vat_main_t * vam)
11891 {
11892   unformat_input_t *i = vam->input;
11893   vl_api_set_ipfix_exporter_t *mp;
11894   ip4_address_t collector_address;
11895   u8 collector_address_set = 0;
11896   u32 collector_port = ~0;
11897   ip4_address_t src_address;
11898   u8 src_address_set = 0;
11899   u32 vrf_id = ~0;
11900   u32 path_mtu = ~0;
11901   u32 template_interval = ~0;
11902   u8 udp_checksum = 0;
11903   int ret;
11904
11905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (i, "collector_address %U", unformat_ip4_address,
11908                     &collector_address))
11909         collector_address_set = 1;
11910       else if (unformat (i, "collector_port %d", &collector_port))
11911         ;
11912       else if (unformat (i, "src_address %U", unformat_ip4_address,
11913                          &src_address))
11914         src_address_set = 1;
11915       else if (unformat (i, "vrf_id %d", &vrf_id))
11916         ;
11917       else if (unformat (i, "path_mtu %d", &path_mtu))
11918         ;
11919       else if (unformat (i, "template_interval %d", &template_interval))
11920         ;
11921       else if (unformat (i, "udp_checksum"))
11922         udp_checksum = 1;
11923       else
11924         break;
11925     }
11926
11927   if (collector_address_set == 0)
11928     {
11929       errmsg ("collector_address required");
11930       return -99;
11931     }
11932
11933   if (src_address_set == 0)
11934     {
11935       errmsg ("src_address required");
11936       return -99;
11937     }
11938
11939   M (SET_IPFIX_EXPORTER, mp);
11940
11941   memcpy (mp->collector_address, collector_address.data,
11942           sizeof (collector_address.data));
11943   mp->collector_port = htons ((u16) collector_port);
11944   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11945   mp->vrf_id = htonl (vrf_id);
11946   mp->path_mtu = htonl (path_mtu);
11947   mp->template_interval = htonl (template_interval);
11948   mp->udp_checksum = udp_checksum;
11949
11950   S (mp);
11951   W (ret);
11952   return ret;
11953 }
11954
11955 static int
11956 api_set_ipfix_classify_stream (vat_main_t * vam)
11957 {
11958   unformat_input_t *i = vam->input;
11959   vl_api_set_ipfix_classify_stream_t *mp;
11960   u32 domain_id = 0;
11961   u32 src_port = UDP_DST_PORT_ipfix;
11962   int ret;
11963
11964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11965     {
11966       if (unformat (i, "domain %d", &domain_id))
11967         ;
11968       else if (unformat (i, "src_port %d", &src_port))
11969         ;
11970       else
11971         {
11972           errmsg ("unknown input `%U'", format_unformat_error, i);
11973           return -99;
11974         }
11975     }
11976
11977   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11978
11979   mp->domain_id = htonl (domain_id);
11980   mp->src_port = htons ((u16) src_port);
11981
11982   S (mp);
11983   W (ret);
11984   return ret;
11985 }
11986
11987 static int
11988 api_ipfix_classify_table_add_del (vat_main_t * vam)
11989 {
11990   unformat_input_t *i = vam->input;
11991   vl_api_ipfix_classify_table_add_del_t *mp;
11992   int is_add = -1;
11993   u32 classify_table_index = ~0;
11994   u8 ip_version = 0;
11995   u8 transport_protocol = 255;
11996   int ret;
11997
11998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11999     {
12000       if (unformat (i, "add"))
12001         is_add = 1;
12002       else if (unformat (i, "del"))
12003         is_add = 0;
12004       else if (unformat (i, "table %d", &classify_table_index))
12005         ;
12006       else if (unformat (i, "ip4"))
12007         ip_version = 4;
12008       else if (unformat (i, "ip6"))
12009         ip_version = 6;
12010       else if (unformat (i, "tcp"))
12011         transport_protocol = 6;
12012       else if (unformat (i, "udp"))
12013         transport_protocol = 17;
12014       else
12015         {
12016           errmsg ("unknown input `%U'", format_unformat_error, i);
12017           return -99;
12018         }
12019     }
12020
12021   if (is_add == -1)
12022     {
12023       errmsg ("expecting: add|del");
12024       return -99;
12025     }
12026   if (classify_table_index == ~0)
12027     {
12028       errmsg ("classifier table not specified");
12029       return -99;
12030     }
12031   if (ip_version == 0)
12032     {
12033       errmsg ("IP version not specified");
12034       return -99;
12035     }
12036
12037   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12038
12039   mp->is_add = is_add;
12040   mp->table_id = htonl (classify_table_index);
12041   mp->ip_version = ip_version;
12042   mp->transport_protocol = transport_protocol;
12043
12044   S (mp);
12045   W (ret);
12046   return ret;
12047 }
12048
12049 static int
12050 api_get_node_index (vat_main_t * vam)
12051 {
12052   unformat_input_t *i = vam->input;
12053   vl_api_get_node_index_t *mp;
12054   u8 *name = 0;
12055   int ret;
12056
12057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12058     {
12059       if (unformat (i, "node %s", &name))
12060         ;
12061       else
12062         break;
12063     }
12064   if (name == 0)
12065     {
12066       errmsg ("node name required");
12067       return -99;
12068     }
12069   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12070     {
12071       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12072       return -99;
12073     }
12074
12075   M (GET_NODE_INDEX, mp);
12076   clib_memcpy (mp->node_name, name, vec_len (name));
12077   vec_free (name);
12078
12079   S (mp);
12080   W (ret);
12081   return ret;
12082 }
12083
12084 static int
12085 api_get_next_index (vat_main_t * vam)
12086 {
12087   unformat_input_t *i = vam->input;
12088   vl_api_get_next_index_t *mp;
12089   u8 *node_name = 0, *next_node_name = 0;
12090   int ret;
12091
12092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12093     {
12094       if (unformat (i, "node-name %s", &node_name))
12095         ;
12096       else if (unformat (i, "next-node-name %s", &next_node_name))
12097         break;
12098     }
12099
12100   if (node_name == 0)
12101     {
12102       errmsg ("node name required");
12103       return -99;
12104     }
12105   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12106     {
12107       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12108       return -99;
12109     }
12110
12111   if (next_node_name == 0)
12112     {
12113       errmsg ("next node name required");
12114       return -99;
12115     }
12116   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12117     {
12118       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12119       return -99;
12120     }
12121
12122   M (GET_NEXT_INDEX, mp);
12123   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12124   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12125   vec_free (node_name);
12126   vec_free (next_node_name);
12127
12128   S (mp);
12129   W (ret);
12130   return ret;
12131 }
12132
12133 static int
12134 api_add_node_next (vat_main_t * vam)
12135 {
12136   unformat_input_t *i = vam->input;
12137   vl_api_add_node_next_t *mp;
12138   u8 *name = 0;
12139   u8 *next = 0;
12140   int ret;
12141
12142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12143     {
12144       if (unformat (i, "node %s", &name))
12145         ;
12146       else if (unformat (i, "next %s", &next))
12147         ;
12148       else
12149         break;
12150     }
12151   if (name == 0)
12152     {
12153       errmsg ("node name required");
12154       return -99;
12155     }
12156   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12157     {
12158       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12159       return -99;
12160     }
12161   if (next == 0)
12162     {
12163       errmsg ("next node required");
12164       return -99;
12165     }
12166   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12167     {
12168       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12169       return -99;
12170     }
12171
12172   M (ADD_NODE_NEXT, mp);
12173   clib_memcpy (mp->node_name, name, vec_len (name));
12174   clib_memcpy (mp->next_name, next, vec_len (next));
12175   vec_free (name);
12176   vec_free (next);
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static int
12184 api_l2tpv3_create_tunnel (vat_main_t * vam)
12185 {
12186   unformat_input_t *i = vam->input;
12187   ip6_address_t client_address, our_address;
12188   int client_address_set = 0;
12189   int our_address_set = 0;
12190   u32 local_session_id = 0;
12191   u32 remote_session_id = 0;
12192   u64 local_cookie = 0;
12193   u64 remote_cookie = 0;
12194   u8 l2_sublayer_present = 0;
12195   vl_api_l2tpv3_create_tunnel_t *mp;
12196   int ret;
12197
12198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12199     {
12200       if (unformat (i, "client_address %U", unformat_ip6_address,
12201                     &client_address))
12202         client_address_set = 1;
12203       else if (unformat (i, "our_address %U", unformat_ip6_address,
12204                          &our_address))
12205         our_address_set = 1;
12206       else if (unformat (i, "local_session_id %d", &local_session_id))
12207         ;
12208       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12209         ;
12210       else if (unformat (i, "local_cookie %lld", &local_cookie))
12211         ;
12212       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12213         ;
12214       else if (unformat (i, "l2-sublayer-present"))
12215         l2_sublayer_present = 1;
12216       else
12217         break;
12218     }
12219
12220   if (client_address_set == 0)
12221     {
12222       errmsg ("client_address required");
12223       return -99;
12224     }
12225
12226   if (our_address_set == 0)
12227     {
12228       errmsg ("our_address required");
12229       return -99;
12230     }
12231
12232   M (L2TPV3_CREATE_TUNNEL, mp);
12233
12234   clib_memcpy (mp->client_address, client_address.as_u8,
12235                sizeof (mp->client_address));
12236
12237   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12238
12239   mp->local_session_id = ntohl (local_session_id);
12240   mp->remote_session_id = ntohl (remote_session_id);
12241   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12242   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12243   mp->l2_sublayer_present = l2_sublayer_present;
12244   mp->is_ipv6 = 1;
12245
12246   S (mp);
12247   W (ret);
12248   return ret;
12249 }
12250
12251 static int
12252 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12253 {
12254   unformat_input_t *i = vam->input;
12255   u32 sw_if_index;
12256   u8 sw_if_index_set = 0;
12257   u64 new_local_cookie = 0;
12258   u64 new_remote_cookie = 0;
12259   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12260   int ret;
12261
12262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12263     {
12264       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12265         sw_if_index_set = 1;
12266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12267         sw_if_index_set = 1;
12268       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12269         ;
12270       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12271         ;
12272       else
12273         break;
12274     }
12275
12276   if (sw_if_index_set == 0)
12277     {
12278       errmsg ("missing interface name or sw_if_index");
12279       return -99;
12280     }
12281
12282   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12283
12284   mp->sw_if_index = ntohl (sw_if_index);
12285   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12286   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12287
12288   S (mp);
12289   W (ret);
12290   return ret;
12291 }
12292
12293 static int
12294 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12295 {
12296   unformat_input_t *i = vam->input;
12297   vl_api_l2tpv3_interface_enable_disable_t *mp;
12298   u32 sw_if_index;
12299   u8 sw_if_index_set = 0;
12300   u8 enable_disable = 1;
12301   int ret;
12302
12303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12304     {
12305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12306         sw_if_index_set = 1;
12307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12308         sw_if_index_set = 1;
12309       else if (unformat (i, "enable"))
12310         enable_disable = 1;
12311       else if (unformat (i, "disable"))
12312         enable_disable = 0;
12313       else
12314         break;
12315     }
12316
12317   if (sw_if_index_set == 0)
12318     {
12319       errmsg ("missing interface name or sw_if_index");
12320       return -99;
12321     }
12322
12323   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12324
12325   mp->sw_if_index = ntohl (sw_if_index);
12326   mp->enable_disable = enable_disable;
12327
12328   S (mp);
12329   W (ret);
12330   return ret;
12331 }
12332
12333 static int
12334 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12335 {
12336   unformat_input_t *i = vam->input;
12337   vl_api_l2tpv3_set_lookup_key_t *mp;
12338   u8 key = ~0;
12339   int ret;
12340
12341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12342     {
12343       if (unformat (i, "lookup_v6_src"))
12344         key = L2T_LOOKUP_SRC_ADDRESS;
12345       else if (unformat (i, "lookup_v6_dst"))
12346         key = L2T_LOOKUP_DST_ADDRESS;
12347       else if (unformat (i, "lookup_session_id"))
12348         key = L2T_LOOKUP_SESSION_ID;
12349       else
12350         break;
12351     }
12352
12353   if (key == (u8) ~ 0)
12354     {
12355       errmsg ("l2tp session lookup key unset");
12356       return -99;
12357     }
12358
12359   M (L2TPV3_SET_LOOKUP_KEY, mp);
12360
12361   mp->key = key;
12362
12363   S (mp);
12364   W (ret);
12365   return ret;
12366 }
12367
12368 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12369   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12370 {
12371   vat_main_t *vam = &vat_main;
12372
12373   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12374          format_ip6_address, mp->our_address,
12375          format_ip6_address, mp->client_address,
12376          clib_net_to_host_u32 (mp->sw_if_index));
12377
12378   print (vam->ofp,
12379          "   local cookies %016llx %016llx remote cookie %016llx",
12380          clib_net_to_host_u64 (mp->local_cookie[0]),
12381          clib_net_to_host_u64 (mp->local_cookie[1]),
12382          clib_net_to_host_u64 (mp->remote_cookie));
12383
12384   print (vam->ofp, "   local session-id %d remote session-id %d",
12385          clib_net_to_host_u32 (mp->local_session_id),
12386          clib_net_to_host_u32 (mp->remote_session_id));
12387
12388   print (vam->ofp, "   l2 specific sublayer %s\n",
12389          mp->l2_sublayer_present ? "preset" : "absent");
12390
12391 }
12392
12393 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12394   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12395 {
12396   vat_main_t *vam = &vat_main;
12397   vat_json_node_t *node = NULL;
12398   struct in6_addr addr;
12399
12400   if (VAT_JSON_ARRAY != vam->json_tree.type)
12401     {
12402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12403       vat_json_init_array (&vam->json_tree);
12404     }
12405   node = vat_json_array_add (&vam->json_tree);
12406
12407   vat_json_init_object (node);
12408
12409   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12410   vat_json_object_add_ip6 (node, "our_address", addr);
12411   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12412   vat_json_object_add_ip6 (node, "client_address", addr);
12413
12414   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12415   vat_json_init_array (lc);
12416   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12417   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12418   vat_json_object_add_uint (node, "remote_cookie",
12419                             clib_net_to_host_u64 (mp->remote_cookie));
12420
12421   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12422   vat_json_object_add_uint (node, "local_session_id",
12423                             clib_net_to_host_u32 (mp->local_session_id));
12424   vat_json_object_add_uint (node, "remote_session_id",
12425                             clib_net_to_host_u32 (mp->remote_session_id));
12426   vat_json_object_add_string_copy (node, "l2_sublayer",
12427                                    mp->l2_sublayer_present ? (u8 *) "present"
12428                                    : (u8 *) "absent");
12429 }
12430
12431 static int
12432 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12433 {
12434   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12435   vl_api_control_ping_t *mp_ping;
12436   int ret;
12437
12438   /* Get list of l2tpv3-tunnel interfaces */
12439   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12440   S (mp);
12441
12442   /* Use a control ping for synchronization */
12443   MPING (CONTROL_PING, mp_ping);
12444   S (mp_ping);
12445
12446   W (ret);
12447   return ret;
12448 }
12449
12450
12451 static void vl_api_sw_interface_tap_v2_details_t_handler
12452   (vl_api_sw_interface_tap_v2_details_t * mp)
12453 {
12454   vat_main_t *vam = &vat_main;
12455
12456   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12457                     mp->host_ip4_prefix_len);
12458   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12459                     mp->host_ip6_prefix_len);
12460
12461   print (vam->ofp,
12462          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12463          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12464          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12465          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12466          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12467
12468   vec_free (ip4);
12469   vec_free (ip6);
12470 }
12471
12472 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12473   (vl_api_sw_interface_tap_v2_details_t * mp)
12474 {
12475   vat_main_t *vam = &vat_main;
12476   vat_json_node_t *node = NULL;
12477
12478   if (VAT_JSON_ARRAY != vam->json_tree.type)
12479     {
12480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12481       vat_json_init_array (&vam->json_tree);
12482     }
12483   node = vat_json_array_add (&vam->json_tree);
12484
12485   vat_json_init_object (node);
12486   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12487   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12488   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12489   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12490   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12491   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12492   vat_json_object_add_string_copy (node, "host_mac_addr",
12493                                    format (0, "%U", format_ethernet_address,
12494                                            &mp->host_mac_addr));
12495   vat_json_object_add_string_copy (node, "host_namespace",
12496                                    mp->host_namespace);
12497   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12498   vat_json_object_add_string_copy (node, "host_ip4_addr",
12499                                    format (0, "%U/%d", format_ip4_address,
12500                                            mp->host_ip4_addr,
12501                                            mp->host_ip4_prefix_len));
12502   vat_json_object_add_string_copy (node, "host_ip6_addr",
12503                                    format (0, "%U/%d", format_ip6_address,
12504                                            mp->host_ip6_addr,
12505                                            mp->host_ip6_prefix_len));
12506
12507 }
12508
12509 static int
12510 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12511 {
12512   vl_api_sw_interface_tap_v2_dump_t *mp;
12513   vl_api_control_ping_t *mp_ping;
12514   int ret;
12515
12516   print (vam->ofp,
12517          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12518          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12519          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12520          "host_ip6_addr");
12521
12522   /* Get list of tap interfaces */
12523   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12524   S (mp);
12525
12526   /* Use a control ping for synchronization */
12527   MPING (CONTROL_PING, mp_ping);
12528   S (mp_ping);
12529
12530   W (ret);
12531   return ret;
12532 }
12533
12534 static void vl_api_sw_interface_virtio_pci_details_t_handler
12535   (vl_api_sw_interface_virtio_pci_details_t * mp)
12536 {
12537   vat_main_t *vam = &vat_main;
12538
12539   typedef union
12540   {
12541     struct
12542     {
12543       u16 domain;
12544       u8 bus;
12545       u8 slot:5;
12546       u8 function:3;
12547     };
12548     u32 as_u32;
12549   } pci_addr_t;
12550   pci_addr_t addr;
12551   addr.as_u32 = ntohl (mp->pci_addr);
12552   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12553                          addr.slot, addr.function);
12554
12555   print (vam->ofp,
12556          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12557          pci_addr, ntohl (mp->sw_if_index),
12558          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12559          format_ethernet_address, mp->mac_addr,
12560          clib_net_to_host_u64 (mp->features));
12561   vec_free (pci_addr);
12562 }
12563
12564 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12565   (vl_api_sw_interface_virtio_pci_details_t * mp)
12566 {
12567   vat_main_t *vam = &vat_main;
12568   vat_json_node_t *node = NULL;
12569
12570   if (VAT_JSON_ARRAY != vam->json_tree.type)
12571     {
12572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12573       vat_json_init_array (&vam->json_tree);
12574     }
12575   node = vat_json_array_add (&vam->json_tree);
12576
12577   vat_json_init_object (node);
12578   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12579   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12580   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12581   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12582   vat_json_object_add_uint (node, "features",
12583                             clib_net_to_host_u64 (mp->features));
12584   vat_json_object_add_string_copy (node, "mac_addr",
12585                                    format (0, "%U", format_ethernet_address,
12586                                            &mp->mac_addr));
12587 }
12588
12589 static int
12590 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12591 {
12592   vl_api_sw_interface_virtio_pci_dump_t *mp;
12593   vl_api_control_ping_t *mp_ping;
12594   int ret;
12595
12596   print (vam->ofp,
12597          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12598          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12599          "mac_addr", "features");
12600
12601   /* Get list of tap interfaces */
12602   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12603   S (mp);
12604
12605   /* Use a control ping for synchronization */
12606   MPING (CONTROL_PING, mp_ping);
12607   S (mp_ping);
12608
12609   W (ret);
12610   return ret;
12611 }
12612
12613 static int
12614 api_vxlan_offload_rx (vat_main_t * vam)
12615 {
12616   unformat_input_t *line_input = vam->input;
12617   vl_api_vxlan_offload_rx_t *mp;
12618   u32 hw_if_index = ~0, rx_if_index = ~0;
12619   u8 is_add = 1;
12620   int ret;
12621
12622   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12623     {
12624       if (unformat (line_input, "del"))
12625         is_add = 0;
12626       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12627                          &hw_if_index))
12628         ;
12629       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12630         ;
12631       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12632                          &rx_if_index))
12633         ;
12634       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12635         ;
12636       else
12637         {
12638           errmsg ("parse error '%U'", format_unformat_error, line_input);
12639           return -99;
12640         }
12641     }
12642
12643   if (hw_if_index == ~0)
12644     {
12645       errmsg ("no hw interface");
12646       return -99;
12647     }
12648
12649   if (rx_if_index == ~0)
12650     {
12651       errmsg ("no rx tunnel");
12652       return -99;
12653     }
12654
12655   M (VXLAN_OFFLOAD_RX, mp);
12656
12657   mp->hw_if_index = ntohl (hw_if_index);
12658   mp->sw_if_index = ntohl (rx_if_index);
12659   mp->enable = is_add;
12660
12661   S (mp);
12662   W (ret);
12663   return ret;
12664 }
12665
12666 static uword unformat_vxlan_decap_next
12667   (unformat_input_t * input, va_list * args)
12668 {
12669   u32 *result = va_arg (*args, u32 *);
12670   u32 tmp;
12671
12672   if (unformat (input, "l2"))
12673     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12674   else if (unformat (input, "%d", &tmp))
12675     *result = tmp;
12676   else
12677     return 0;
12678   return 1;
12679 }
12680
12681 static int
12682 api_vxlan_add_del_tunnel (vat_main_t * vam)
12683 {
12684   unformat_input_t *line_input = vam->input;
12685   vl_api_vxlan_add_del_tunnel_t *mp;
12686   ip46_address_t src, dst;
12687   u8 is_add = 1;
12688   u8 ipv4_set = 0, ipv6_set = 0;
12689   u8 src_set = 0;
12690   u8 dst_set = 0;
12691   u8 grp_set = 0;
12692   u32 instance = ~0;
12693   u32 mcast_sw_if_index = ~0;
12694   u32 encap_vrf_id = 0;
12695   u32 decap_next_index = ~0;
12696   u32 vni = 0;
12697   int ret;
12698
12699   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12700   clib_memset (&src, 0, sizeof src);
12701   clib_memset (&dst, 0, sizeof dst);
12702
12703   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12704     {
12705       if (unformat (line_input, "del"))
12706         is_add = 0;
12707       else if (unformat (line_input, "instance %d", &instance))
12708         ;
12709       else
12710         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12711         {
12712           ipv4_set = 1;
12713           src_set = 1;
12714         }
12715       else
12716         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12717         {
12718           ipv4_set = 1;
12719           dst_set = 1;
12720         }
12721       else
12722         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12723         {
12724           ipv6_set = 1;
12725           src_set = 1;
12726         }
12727       else
12728         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12729         {
12730           ipv6_set = 1;
12731           dst_set = 1;
12732         }
12733       else if (unformat (line_input, "group %U %U",
12734                          unformat_ip4_address, &dst.ip4,
12735                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12736         {
12737           grp_set = dst_set = 1;
12738           ipv4_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U",
12741                          unformat_ip4_address, &dst.ip4))
12742         {
12743           grp_set = dst_set = 1;
12744           ipv4_set = 1;
12745         }
12746       else if (unformat (line_input, "group %U %U",
12747                          unformat_ip6_address, &dst.ip6,
12748                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12749         {
12750           grp_set = dst_set = 1;
12751           ipv6_set = 1;
12752         }
12753       else if (unformat (line_input, "group %U",
12754                          unformat_ip6_address, &dst.ip6))
12755         {
12756           grp_set = dst_set = 1;
12757           ipv6_set = 1;
12758         }
12759       else
12760         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12761         ;
12762       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12763         ;
12764       else if (unformat (line_input, "decap-next %U",
12765                          unformat_vxlan_decap_next, &decap_next_index))
12766         ;
12767       else if (unformat (line_input, "vni %d", &vni))
12768         ;
12769       else
12770         {
12771           errmsg ("parse error '%U'", format_unformat_error, line_input);
12772           return -99;
12773         }
12774     }
12775
12776   if (src_set == 0)
12777     {
12778       errmsg ("tunnel src address not specified");
12779       return -99;
12780     }
12781   if (dst_set == 0)
12782     {
12783       errmsg ("tunnel dst address not specified");
12784       return -99;
12785     }
12786
12787   if (grp_set && !ip46_address_is_multicast (&dst))
12788     {
12789       errmsg ("tunnel group address not multicast");
12790       return -99;
12791     }
12792   if (grp_set && mcast_sw_if_index == ~0)
12793     {
12794       errmsg ("tunnel nonexistent multicast device");
12795       return -99;
12796     }
12797   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12798     {
12799       errmsg ("tunnel dst address must be unicast");
12800       return -99;
12801     }
12802
12803
12804   if (ipv4_set && ipv6_set)
12805     {
12806       errmsg ("both IPv4 and IPv6 addresses specified");
12807       return -99;
12808     }
12809
12810   if ((vni == 0) || (vni >> 24))
12811     {
12812       errmsg ("vni not specified or out of range");
12813       return -99;
12814     }
12815
12816   M (VXLAN_ADD_DEL_TUNNEL, mp);
12817
12818   if (ipv6_set)
12819     {
12820       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12821       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12822     }
12823   else
12824     {
12825       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12826       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12827     }
12828
12829   mp->instance = htonl (instance);
12830   mp->encap_vrf_id = ntohl (encap_vrf_id);
12831   mp->decap_next_index = ntohl (decap_next_index);
12832   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12833   mp->vni = ntohl (vni);
12834   mp->is_add = is_add;
12835   mp->is_ipv6 = ipv6_set;
12836
12837   S (mp);
12838   W (ret);
12839   return ret;
12840 }
12841
12842 static void vl_api_vxlan_tunnel_details_t_handler
12843   (vl_api_vxlan_tunnel_details_t * mp)
12844 {
12845   vat_main_t *vam = &vat_main;
12846   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12847   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12848
12849   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12850          ntohl (mp->sw_if_index),
12851          ntohl (mp->instance),
12852          format_ip46_address, &src, IP46_TYPE_ANY,
12853          format_ip46_address, &dst, IP46_TYPE_ANY,
12854          ntohl (mp->encap_vrf_id),
12855          ntohl (mp->decap_next_index), ntohl (mp->vni),
12856          ntohl (mp->mcast_sw_if_index));
12857 }
12858
12859 static void vl_api_vxlan_tunnel_details_t_handler_json
12860   (vl_api_vxlan_tunnel_details_t * mp)
12861 {
12862   vat_main_t *vam = &vat_main;
12863   vat_json_node_t *node = NULL;
12864
12865   if (VAT_JSON_ARRAY != vam->json_tree.type)
12866     {
12867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12868       vat_json_init_array (&vam->json_tree);
12869     }
12870   node = vat_json_array_add (&vam->json_tree);
12871
12872   vat_json_init_object (node);
12873   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12874
12875   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12876
12877   if (mp->is_ipv6)
12878     {
12879       struct in6_addr ip6;
12880
12881       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12882       vat_json_object_add_ip6 (node, "src_address", ip6);
12883       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12884       vat_json_object_add_ip6 (node, "dst_address", ip6);
12885     }
12886   else
12887     {
12888       struct in_addr ip4;
12889
12890       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12891       vat_json_object_add_ip4 (node, "src_address", ip4);
12892       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12893       vat_json_object_add_ip4 (node, "dst_address", ip4);
12894     }
12895   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12896   vat_json_object_add_uint (node, "decap_next_index",
12897                             ntohl (mp->decap_next_index));
12898   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12899   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12900   vat_json_object_add_uint (node, "mcast_sw_if_index",
12901                             ntohl (mp->mcast_sw_if_index));
12902 }
12903
12904 static int
12905 api_vxlan_tunnel_dump (vat_main_t * vam)
12906 {
12907   unformat_input_t *i = vam->input;
12908   vl_api_vxlan_tunnel_dump_t *mp;
12909   vl_api_control_ping_t *mp_ping;
12910   u32 sw_if_index;
12911   u8 sw_if_index_set = 0;
12912   int ret;
12913
12914   /* Parse args required to build the message */
12915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12916     {
12917       if (unformat (i, "sw_if_index %d", &sw_if_index))
12918         sw_if_index_set = 1;
12919       else
12920         break;
12921     }
12922
12923   if (sw_if_index_set == 0)
12924     {
12925       sw_if_index = ~0;
12926     }
12927
12928   if (!vam->json_output)
12929     {
12930       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12931              "sw_if_index", "instance", "src_address", "dst_address",
12932              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12933     }
12934
12935   /* Get list of vxlan-tunnel interfaces */
12936   M (VXLAN_TUNNEL_DUMP, mp);
12937
12938   mp->sw_if_index = htonl (sw_if_index);
12939
12940   S (mp);
12941
12942   /* Use a control ping for synchronization */
12943   MPING (CONTROL_PING, mp_ping);
12944   S (mp_ping);
12945
12946   W (ret);
12947   return ret;
12948 }
12949
12950 static uword unformat_geneve_decap_next
12951   (unformat_input_t * input, va_list * args)
12952 {
12953   u32 *result = va_arg (*args, u32 *);
12954   u32 tmp;
12955
12956   if (unformat (input, "l2"))
12957     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12958   else if (unformat (input, "%d", &tmp))
12959     *result = tmp;
12960   else
12961     return 0;
12962   return 1;
12963 }
12964
12965 static int
12966 api_geneve_add_del_tunnel (vat_main_t * vam)
12967 {
12968   unformat_input_t *line_input = vam->input;
12969   vl_api_geneve_add_del_tunnel_t *mp;
12970   ip46_address_t src, dst;
12971   u8 is_add = 1;
12972   u8 ipv4_set = 0, ipv6_set = 0;
12973   u8 src_set = 0;
12974   u8 dst_set = 0;
12975   u8 grp_set = 0;
12976   u32 mcast_sw_if_index = ~0;
12977   u32 encap_vrf_id = 0;
12978   u32 decap_next_index = ~0;
12979   u32 vni = 0;
12980   int ret;
12981
12982   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12983   clib_memset (&src, 0, sizeof src);
12984   clib_memset (&dst, 0, sizeof dst);
12985
12986   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12987     {
12988       if (unformat (line_input, "del"))
12989         is_add = 0;
12990       else
12991         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12992         {
12993           ipv4_set = 1;
12994           src_set = 1;
12995         }
12996       else
12997         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12998         {
12999           ipv4_set = 1;
13000           dst_set = 1;
13001         }
13002       else
13003         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13004         {
13005           ipv6_set = 1;
13006           src_set = 1;
13007         }
13008       else
13009         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13010         {
13011           ipv6_set = 1;
13012           dst_set = 1;
13013         }
13014       else if (unformat (line_input, "group %U %U",
13015                          unformat_ip4_address, &dst.ip4,
13016                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13017         {
13018           grp_set = dst_set = 1;
13019           ipv4_set = 1;
13020         }
13021       else if (unformat (line_input, "group %U",
13022                          unformat_ip4_address, &dst.ip4))
13023         {
13024           grp_set = dst_set = 1;
13025           ipv4_set = 1;
13026         }
13027       else if (unformat (line_input, "group %U %U",
13028                          unformat_ip6_address, &dst.ip6,
13029                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13030         {
13031           grp_set = dst_set = 1;
13032           ipv6_set = 1;
13033         }
13034       else if (unformat (line_input, "group %U",
13035                          unformat_ip6_address, &dst.ip6))
13036         {
13037           grp_set = dst_set = 1;
13038           ipv6_set = 1;
13039         }
13040       else
13041         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13042         ;
13043       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13044         ;
13045       else if (unformat (line_input, "decap-next %U",
13046                          unformat_geneve_decap_next, &decap_next_index))
13047         ;
13048       else if (unformat (line_input, "vni %d", &vni))
13049         ;
13050       else
13051         {
13052           errmsg ("parse error '%U'", format_unformat_error, line_input);
13053           return -99;
13054         }
13055     }
13056
13057   if (src_set == 0)
13058     {
13059       errmsg ("tunnel src address not specified");
13060       return -99;
13061     }
13062   if (dst_set == 0)
13063     {
13064       errmsg ("tunnel dst address not specified");
13065       return -99;
13066     }
13067
13068   if (grp_set && !ip46_address_is_multicast (&dst))
13069     {
13070       errmsg ("tunnel group address not multicast");
13071       return -99;
13072     }
13073   if (grp_set && mcast_sw_if_index == ~0)
13074     {
13075       errmsg ("tunnel nonexistent multicast device");
13076       return -99;
13077     }
13078   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13079     {
13080       errmsg ("tunnel dst address must be unicast");
13081       return -99;
13082     }
13083
13084
13085   if (ipv4_set && ipv6_set)
13086     {
13087       errmsg ("both IPv4 and IPv6 addresses specified");
13088       return -99;
13089     }
13090
13091   if ((vni == 0) || (vni >> 24))
13092     {
13093       errmsg ("vni not specified or out of range");
13094       return -99;
13095     }
13096
13097   M (GENEVE_ADD_DEL_TUNNEL, mp);
13098
13099   if (ipv6_set)
13100     {
13101       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13102       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13103     }
13104   else
13105     {
13106       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13107       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13108     }
13109   mp->encap_vrf_id = ntohl (encap_vrf_id);
13110   mp->decap_next_index = ntohl (decap_next_index);
13111   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13112   mp->vni = ntohl (vni);
13113   mp->is_add = is_add;
13114   mp->is_ipv6 = ipv6_set;
13115
13116   S (mp);
13117   W (ret);
13118   return ret;
13119 }
13120
13121 static void vl_api_geneve_tunnel_details_t_handler
13122   (vl_api_geneve_tunnel_details_t * mp)
13123 {
13124   vat_main_t *vam = &vat_main;
13125   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13126   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13127
13128   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13129          ntohl (mp->sw_if_index),
13130          format_ip46_address, &src, IP46_TYPE_ANY,
13131          format_ip46_address, &dst, IP46_TYPE_ANY,
13132          ntohl (mp->encap_vrf_id),
13133          ntohl (mp->decap_next_index), ntohl (mp->vni),
13134          ntohl (mp->mcast_sw_if_index));
13135 }
13136
13137 static void vl_api_geneve_tunnel_details_t_handler_json
13138   (vl_api_geneve_tunnel_details_t * mp)
13139 {
13140   vat_main_t *vam = &vat_main;
13141   vat_json_node_t *node = NULL;
13142
13143   if (VAT_JSON_ARRAY != vam->json_tree.type)
13144     {
13145       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13146       vat_json_init_array (&vam->json_tree);
13147     }
13148   node = vat_json_array_add (&vam->json_tree);
13149
13150   vat_json_init_object (node);
13151   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13152   if (mp->is_ipv6)
13153     {
13154       struct in6_addr ip6;
13155
13156       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13157       vat_json_object_add_ip6 (node, "src_address", ip6);
13158       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13159       vat_json_object_add_ip6 (node, "dst_address", ip6);
13160     }
13161   else
13162     {
13163       struct in_addr ip4;
13164
13165       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13166       vat_json_object_add_ip4 (node, "src_address", ip4);
13167       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13168       vat_json_object_add_ip4 (node, "dst_address", ip4);
13169     }
13170   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13171   vat_json_object_add_uint (node, "decap_next_index",
13172                             ntohl (mp->decap_next_index));
13173   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13174   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13175   vat_json_object_add_uint (node, "mcast_sw_if_index",
13176                             ntohl (mp->mcast_sw_if_index));
13177 }
13178
13179 static int
13180 api_geneve_tunnel_dump (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_geneve_tunnel_dump_t *mp;
13184   vl_api_control_ping_t *mp_ping;
13185   u32 sw_if_index;
13186   u8 sw_if_index_set = 0;
13187   int ret;
13188
13189   /* Parse args required to build the message */
13190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13191     {
13192       if (unformat (i, "sw_if_index %d", &sw_if_index))
13193         sw_if_index_set = 1;
13194       else
13195         break;
13196     }
13197
13198   if (sw_if_index_set == 0)
13199     {
13200       sw_if_index = ~0;
13201     }
13202
13203   if (!vam->json_output)
13204     {
13205       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13206              "sw_if_index", "local_address", "remote_address",
13207              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13208     }
13209
13210   /* Get list of geneve-tunnel interfaces */
13211   M (GENEVE_TUNNEL_DUMP, mp);
13212
13213   mp->sw_if_index = htonl (sw_if_index);
13214
13215   S (mp);
13216
13217   /* Use a control ping for synchronization */
13218   M (CONTROL_PING, mp_ping);
13219   S (mp_ping);
13220
13221   W (ret);
13222   return ret;
13223 }
13224
13225 static int
13226 api_gre_tunnel_add_del (vat_main_t * vam)
13227 {
13228   unformat_input_t *line_input = vam->input;
13229   vl_api_address_t src = { }, dst =
13230   {
13231   };
13232   vl_api_gre_tunnel_add_del_t *mp;
13233   vl_api_gre_tunnel_type_t t_type;
13234   u8 is_add = 1;
13235   u8 ipv4_set = 0;
13236   u8 ipv6_set = 0;
13237   u8 src_set = 0;
13238   u8 dst_set = 0;
13239   u32 outer_fib_id = 0;
13240   u32 session_id = 0;
13241   u32 instance = ~0;
13242   int ret;
13243
13244   t_type = GRE_API_TUNNEL_TYPE_L3;
13245
13246   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13247     {
13248       if (unformat (line_input, "del"))
13249         is_add = 0;
13250       else if (unformat (line_input, "instance %d", &instance))
13251         ;
13252       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13253         {
13254           src_set = 1;
13255         }
13256       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13257         {
13258           dst_set = 1;
13259         }
13260       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13261         ;
13262       else if (unformat (line_input, "teb"))
13263         t_type = GRE_API_TUNNEL_TYPE_TEB;
13264       else if (unformat (line_input, "erspan %d", &session_id))
13265         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13266       else
13267         {
13268           errmsg ("parse error '%U'", format_unformat_error, line_input);
13269           return -99;
13270         }
13271     }
13272
13273   if (src_set == 0)
13274     {
13275       errmsg ("tunnel src address not specified");
13276       return -99;
13277     }
13278   if (dst_set == 0)
13279     {
13280       errmsg ("tunnel dst address not specified");
13281       return -99;
13282     }
13283
13284   M (GRE_TUNNEL_ADD_DEL, mp);
13285
13286   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13287   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13288
13289   mp->tunnel.instance = htonl (instance);
13290   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13291   mp->is_add = is_add;
13292   mp->tunnel.session_id = htons ((u16) session_id);
13293   mp->tunnel.type = htonl (t_type);
13294
13295   S (mp);
13296   W (ret);
13297   return ret;
13298 }
13299
13300 static void vl_api_gre_tunnel_details_t_handler
13301   (vl_api_gre_tunnel_details_t * mp)
13302 {
13303   vat_main_t *vam = &vat_main;
13304
13305   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13306          ntohl (mp->tunnel.sw_if_index),
13307          ntohl (mp->tunnel.instance),
13308          format_vl_api_address, &mp->tunnel.src,
13309          format_vl_api_address, &mp->tunnel.dst,
13310          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13311          ntohl (mp->tunnel.session_id));
13312 }
13313
13314 static void
13315 vat_json_object_add_address (vat_json_node_t * node,
13316                              const char *str, const vl_api_address_t * addr)
13317 {
13318   if (ADDRESS_IP6 == addr->af)
13319     {
13320       struct in6_addr ip6;
13321
13322       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13323       vat_json_object_add_ip6 (node, str, ip6);
13324     }
13325   else
13326     {
13327       struct in_addr ip4;
13328
13329       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13330       vat_json_object_add_ip4 (node, str, ip4);
13331     }
13332 }
13333
13334 static void vl_api_gre_tunnel_details_t_handler_json
13335   (vl_api_gre_tunnel_details_t * mp)
13336 {
13337   vat_main_t *vam = &vat_main;
13338   vat_json_node_t *node = NULL;
13339   struct in_addr ip4;
13340   struct in6_addr ip6;
13341
13342   if (VAT_JSON_ARRAY != vam->json_tree.type)
13343     {
13344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13345       vat_json_init_array (&vam->json_tree);
13346     }
13347   node = vat_json_array_add (&vam->json_tree);
13348
13349   vat_json_init_object (node);
13350   vat_json_object_add_uint (node, "sw_if_index",
13351                             ntohl (mp->tunnel.sw_if_index));
13352   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13353
13354   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13355   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13356   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13357   vat_json_object_add_uint (node, "outer_fib_id",
13358                             ntohl (mp->tunnel.outer_fib_id));
13359   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13360 }
13361
13362 static int
13363 api_gre_tunnel_dump (vat_main_t * vam)
13364 {
13365   unformat_input_t *i = vam->input;
13366   vl_api_gre_tunnel_dump_t *mp;
13367   vl_api_control_ping_t *mp_ping;
13368   u32 sw_if_index;
13369   u8 sw_if_index_set = 0;
13370   int ret;
13371
13372   /* Parse args required to build the message */
13373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374     {
13375       if (unformat (i, "sw_if_index %d", &sw_if_index))
13376         sw_if_index_set = 1;
13377       else
13378         break;
13379     }
13380
13381   if (sw_if_index_set == 0)
13382     {
13383       sw_if_index = ~0;
13384     }
13385
13386   if (!vam->json_output)
13387     {
13388       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13389              "sw_if_index", "instance", "src_address", "dst_address",
13390              "tunnel_type", "outer_fib_id", "session_id");
13391     }
13392
13393   /* Get list of gre-tunnel interfaces */
13394   M (GRE_TUNNEL_DUMP, mp);
13395
13396   mp->sw_if_index = htonl (sw_if_index);
13397
13398   S (mp);
13399
13400   /* Use a control ping for synchronization */
13401   MPING (CONTROL_PING, mp_ping);
13402   S (mp_ping);
13403
13404   W (ret);
13405   return ret;
13406 }
13407
13408 static int
13409 api_l2_fib_clear_table (vat_main_t * vam)
13410 {
13411 //  unformat_input_t * i = vam->input;
13412   vl_api_l2_fib_clear_table_t *mp;
13413   int ret;
13414
13415   M (L2_FIB_CLEAR_TABLE, mp);
13416
13417   S (mp);
13418   W (ret);
13419   return ret;
13420 }
13421
13422 static int
13423 api_l2_interface_efp_filter (vat_main_t * vam)
13424 {
13425   unformat_input_t *i = vam->input;
13426   vl_api_l2_interface_efp_filter_t *mp;
13427   u32 sw_if_index;
13428   u8 enable = 1;
13429   u8 sw_if_index_set = 0;
13430   int ret;
13431
13432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13433     {
13434       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13435         sw_if_index_set = 1;
13436       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13437         sw_if_index_set = 1;
13438       else if (unformat (i, "enable"))
13439         enable = 1;
13440       else if (unformat (i, "disable"))
13441         enable = 0;
13442       else
13443         {
13444           clib_warning ("parse error '%U'", format_unformat_error, i);
13445           return -99;
13446         }
13447     }
13448
13449   if (sw_if_index_set == 0)
13450     {
13451       errmsg ("missing sw_if_index");
13452       return -99;
13453     }
13454
13455   M (L2_INTERFACE_EFP_FILTER, mp);
13456
13457   mp->sw_if_index = ntohl (sw_if_index);
13458   mp->enable_disable = enable;
13459
13460   S (mp);
13461   W (ret);
13462   return ret;
13463 }
13464
13465 #define foreach_vtr_op                          \
13466 _("disable",  L2_VTR_DISABLED)                  \
13467 _("push-1",  L2_VTR_PUSH_1)                     \
13468 _("push-2",  L2_VTR_PUSH_2)                     \
13469 _("pop-1",  L2_VTR_POP_1)                       \
13470 _("pop-2",  L2_VTR_POP_2)                       \
13471 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13472 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13473 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13474 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13475
13476 static int
13477 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13478 {
13479   unformat_input_t *i = vam->input;
13480   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13481   u32 sw_if_index;
13482   u8 sw_if_index_set = 0;
13483   u8 vtr_op_set = 0;
13484   u32 vtr_op = 0;
13485   u32 push_dot1q = 1;
13486   u32 tag1 = ~0;
13487   u32 tag2 = ~0;
13488   int ret;
13489
13490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13491     {
13492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13493         sw_if_index_set = 1;
13494       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13495         sw_if_index_set = 1;
13496       else if (unformat (i, "vtr_op %d", &vtr_op))
13497         vtr_op_set = 1;
13498 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13499       foreach_vtr_op
13500 #undef _
13501         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13502         ;
13503       else if (unformat (i, "tag1 %d", &tag1))
13504         ;
13505       else if (unformat (i, "tag2 %d", &tag2))
13506         ;
13507       else
13508         {
13509           clib_warning ("parse error '%U'", format_unformat_error, i);
13510           return -99;
13511         }
13512     }
13513
13514   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13515     {
13516       errmsg ("missing vtr operation or sw_if_index");
13517       return -99;
13518     }
13519
13520   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13521   mp->sw_if_index = ntohl (sw_if_index);
13522   mp->vtr_op = ntohl (vtr_op);
13523   mp->push_dot1q = ntohl (push_dot1q);
13524   mp->tag1 = ntohl (tag1);
13525   mp->tag2 = ntohl (tag2);
13526
13527   S (mp);
13528   W (ret);
13529   return ret;
13530 }
13531
13532 static int
13533 api_create_vhost_user_if (vat_main_t * vam)
13534 {
13535   unformat_input_t *i = vam->input;
13536   vl_api_create_vhost_user_if_t *mp;
13537   u8 *file_name;
13538   u8 is_server = 0;
13539   u8 file_name_set = 0;
13540   u32 custom_dev_instance = ~0;
13541   u8 hwaddr[6];
13542   u8 use_custom_mac = 0;
13543   u8 disable_mrg_rxbuf = 0;
13544   u8 disable_indirect_desc = 0;
13545   u8 *tag = 0;
13546   int ret;
13547
13548   /* Shut up coverity */
13549   clib_memset (hwaddr, 0, sizeof (hwaddr));
13550
13551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13552     {
13553       if (unformat (i, "socket %s", &file_name))
13554         {
13555           file_name_set = 1;
13556         }
13557       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13558         ;
13559       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13560         use_custom_mac = 1;
13561       else if (unformat (i, "server"))
13562         is_server = 1;
13563       else if (unformat (i, "disable_mrg_rxbuf"))
13564         disable_mrg_rxbuf = 1;
13565       else if (unformat (i, "disable_indirect_desc"))
13566         disable_indirect_desc = 1;
13567       else if (unformat (i, "tag %s", &tag))
13568         ;
13569       else
13570         break;
13571     }
13572
13573   if (file_name_set == 0)
13574     {
13575       errmsg ("missing socket file name");
13576       return -99;
13577     }
13578
13579   if (vec_len (file_name) > 255)
13580     {
13581       errmsg ("socket file name too long");
13582       return -99;
13583     }
13584   vec_add1 (file_name, 0);
13585
13586   M (CREATE_VHOST_USER_IF, mp);
13587
13588   mp->is_server = is_server;
13589   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13590   mp->disable_indirect_desc = disable_indirect_desc;
13591   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13592   vec_free (file_name);
13593   if (custom_dev_instance != ~0)
13594     {
13595       mp->renumber = 1;
13596       mp->custom_dev_instance = ntohl (custom_dev_instance);
13597     }
13598
13599   mp->use_custom_mac = use_custom_mac;
13600   clib_memcpy (mp->mac_address, hwaddr, 6);
13601   if (tag)
13602     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13603   vec_free (tag);
13604
13605   S (mp);
13606   W (ret);
13607   return ret;
13608 }
13609
13610 static int
13611 api_modify_vhost_user_if (vat_main_t * vam)
13612 {
13613   unformat_input_t *i = vam->input;
13614   vl_api_modify_vhost_user_if_t *mp;
13615   u8 *file_name;
13616   u8 is_server = 0;
13617   u8 file_name_set = 0;
13618   u32 custom_dev_instance = ~0;
13619   u8 sw_if_index_set = 0;
13620   u32 sw_if_index = (u32) ~ 0;
13621   int ret;
13622
13623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13624     {
13625       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13626         sw_if_index_set = 1;
13627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13628         sw_if_index_set = 1;
13629       else if (unformat (i, "socket %s", &file_name))
13630         {
13631           file_name_set = 1;
13632         }
13633       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13634         ;
13635       else if (unformat (i, "server"))
13636         is_server = 1;
13637       else
13638         break;
13639     }
13640
13641   if (sw_if_index_set == 0)
13642     {
13643       errmsg ("missing sw_if_index or interface name");
13644       return -99;
13645     }
13646
13647   if (file_name_set == 0)
13648     {
13649       errmsg ("missing socket file name");
13650       return -99;
13651     }
13652
13653   if (vec_len (file_name) > 255)
13654     {
13655       errmsg ("socket file name too long");
13656       return -99;
13657     }
13658   vec_add1 (file_name, 0);
13659
13660   M (MODIFY_VHOST_USER_IF, mp);
13661
13662   mp->sw_if_index = ntohl (sw_if_index);
13663   mp->is_server = is_server;
13664   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13665   vec_free (file_name);
13666   if (custom_dev_instance != ~0)
13667     {
13668       mp->renumber = 1;
13669       mp->custom_dev_instance = ntohl (custom_dev_instance);
13670     }
13671
13672   S (mp);
13673   W (ret);
13674   return ret;
13675 }
13676
13677 static int
13678 api_delete_vhost_user_if (vat_main_t * vam)
13679 {
13680   unformat_input_t *i = vam->input;
13681   vl_api_delete_vhost_user_if_t *mp;
13682   u32 sw_if_index = ~0;
13683   u8 sw_if_index_set = 0;
13684   int ret;
13685
13686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13689         sw_if_index_set = 1;
13690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13691         sw_if_index_set = 1;
13692       else
13693         break;
13694     }
13695
13696   if (sw_if_index_set == 0)
13697     {
13698       errmsg ("missing sw_if_index or interface name");
13699       return -99;
13700     }
13701
13702
13703   M (DELETE_VHOST_USER_IF, mp);
13704
13705   mp->sw_if_index = ntohl (sw_if_index);
13706
13707   S (mp);
13708   W (ret);
13709   return ret;
13710 }
13711
13712 static void vl_api_sw_interface_vhost_user_details_t_handler
13713   (vl_api_sw_interface_vhost_user_details_t * mp)
13714 {
13715   vat_main_t *vam = &vat_main;
13716
13717   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13718          (char *) mp->interface_name,
13719          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13720          clib_net_to_host_u64 (mp->features), mp->is_server,
13721          ntohl (mp->num_regions), (char *) mp->sock_filename);
13722   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13723 }
13724
13725 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13726   (vl_api_sw_interface_vhost_user_details_t * mp)
13727 {
13728   vat_main_t *vam = &vat_main;
13729   vat_json_node_t *node = NULL;
13730
13731   if (VAT_JSON_ARRAY != vam->json_tree.type)
13732     {
13733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13734       vat_json_init_array (&vam->json_tree);
13735     }
13736   node = vat_json_array_add (&vam->json_tree);
13737
13738   vat_json_init_object (node);
13739   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13740   vat_json_object_add_string_copy (node, "interface_name",
13741                                    mp->interface_name);
13742   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13743                             ntohl (mp->virtio_net_hdr_sz));
13744   vat_json_object_add_uint (node, "features",
13745                             clib_net_to_host_u64 (mp->features));
13746   vat_json_object_add_uint (node, "is_server", mp->is_server);
13747   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13748   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13749   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13750 }
13751
13752 static int
13753 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13754 {
13755   vl_api_sw_interface_vhost_user_dump_t *mp;
13756   vl_api_control_ping_t *mp_ping;
13757   int ret;
13758   print (vam->ofp,
13759          "Interface name            idx hdr_sz features server regions filename");
13760
13761   /* Get list of vhost-user interfaces */
13762   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13763   S (mp);
13764
13765   /* Use a control ping for synchronization */
13766   MPING (CONTROL_PING, mp_ping);
13767   S (mp_ping);
13768
13769   W (ret);
13770   return ret;
13771 }
13772
13773 static int
13774 api_show_version (vat_main_t * vam)
13775 {
13776   vl_api_show_version_t *mp;
13777   int ret;
13778
13779   M (SHOW_VERSION, mp);
13780
13781   S (mp);
13782   W (ret);
13783   return ret;
13784 }
13785
13786
13787 static int
13788 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13789 {
13790   unformat_input_t *line_input = vam->input;
13791   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13792   ip4_address_t local4, remote4;
13793   ip6_address_t local6, remote6;
13794   u8 is_add = 1;
13795   u8 ipv4_set = 0, ipv6_set = 0;
13796   u8 local_set = 0;
13797   u8 remote_set = 0;
13798   u8 grp_set = 0;
13799   u32 mcast_sw_if_index = ~0;
13800   u32 encap_vrf_id = 0;
13801   u32 decap_vrf_id = 0;
13802   u8 protocol = ~0;
13803   u32 vni;
13804   u8 vni_set = 0;
13805   int ret;
13806
13807   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13808   clib_memset (&local4, 0, sizeof local4);
13809   clib_memset (&remote4, 0, sizeof remote4);
13810   clib_memset (&local6, 0, sizeof local6);
13811   clib_memset (&remote6, 0, sizeof remote6);
13812
13813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13814     {
13815       if (unformat (line_input, "del"))
13816         is_add = 0;
13817       else if (unformat (line_input, "local %U",
13818                          unformat_ip4_address, &local4))
13819         {
13820           local_set = 1;
13821           ipv4_set = 1;
13822         }
13823       else if (unformat (line_input, "remote %U",
13824                          unformat_ip4_address, &remote4))
13825         {
13826           remote_set = 1;
13827           ipv4_set = 1;
13828         }
13829       else if (unformat (line_input, "local %U",
13830                          unformat_ip6_address, &local6))
13831         {
13832           local_set = 1;
13833           ipv6_set = 1;
13834         }
13835       else if (unformat (line_input, "remote %U",
13836                          unformat_ip6_address, &remote6))
13837         {
13838           remote_set = 1;
13839           ipv6_set = 1;
13840         }
13841       else if (unformat (line_input, "group %U %U",
13842                          unformat_ip4_address, &remote4,
13843                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13844         {
13845           grp_set = remote_set = 1;
13846           ipv4_set = 1;
13847         }
13848       else if (unformat (line_input, "group %U",
13849                          unformat_ip4_address, &remote4))
13850         {
13851           grp_set = remote_set = 1;
13852           ipv4_set = 1;
13853         }
13854       else if (unformat (line_input, "group %U %U",
13855                          unformat_ip6_address, &remote6,
13856                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13857         {
13858           grp_set = remote_set = 1;
13859           ipv6_set = 1;
13860         }
13861       else if (unformat (line_input, "group %U",
13862                          unformat_ip6_address, &remote6))
13863         {
13864           grp_set = remote_set = 1;
13865           ipv6_set = 1;
13866         }
13867       else
13868         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13869         ;
13870       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13871         ;
13872       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13873         ;
13874       else if (unformat (line_input, "vni %d", &vni))
13875         vni_set = 1;
13876       else if (unformat (line_input, "next-ip4"))
13877         protocol = 1;
13878       else if (unformat (line_input, "next-ip6"))
13879         protocol = 2;
13880       else if (unformat (line_input, "next-ethernet"))
13881         protocol = 3;
13882       else if (unformat (line_input, "next-nsh"))
13883         protocol = 4;
13884       else
13885         {
13886           errmsg ("parse error '%U'", format_unformat_error, line_input);
13887           return -99;
13888         }
13889     }
13890
13891   if (local_set == 0)
13892     {
13893       errmsg ("tunnel local address not specified");
13894       return -99;
13895     }
13896   if (remote_set == 0)
13897     {
13898       errmsg ("tunnel remote address not specified");
13899       return -99;
13900     }
13901   if (grp_set && mcast_sw_if_index == ~0)
13902     {
13903       errmsg ("tunnel nonexistent multicast device");
13904       return -99;
13905     }
13906   if (ipv4_set && ipv6_set)
13907     {
13908       errmsg ("both IPv4 and IPv6 addresses specified");
13909       return -99;
13910     }
13911
13912   if (vni_set == 0)
13913     {
13914       errmsg ("vni not specified");
13915       return -99;
13916     }
13917
13918   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13919
13920
13921   if (ipv6_set)
13922     {
13923       clib_memcpy (&mp->local, &local6, sizeof (local6));
13924       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13925     }
13926   else
13927     {
13928       clib_memcpy (&mp->local, &local4, sizeof (local4));
13929       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13930     }
13931
13932   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13933   mp->encap_vrf_id = ntohl (encap_vrf_id);
13934   mp->decap_vrf_id = ntohl (decap_vrf_id);
13935   mp->protocol = protocol;
13936   mp->vni = ntohl (vni);
13937   mp->is_add = is_add;
13938   mp->is_ipv6 = ipv6_set;
13939
13940   S (mp);
13941   W (ret);
13942   return ret;
13943 }
13944
13945 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13946   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13947 {
13948   vat_main_t *vam = &vat_main;
13949   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13950   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13951
13952   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13953          ntohl (mp->sw_if_index),
13954          format_ip46_address, &local, IP46_TYPE_ANY,
13955          format_ip46_address, &remote, IP46_TYPE_ANY,
13956          ntohl (mp->vni), mp->protocol,
13957          ntohl (mp->mcast_sw_if_index),
13958          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13959 }
13960
13961
13962 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13963   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13964 {
13965   vat_main_t *vam = &vat_main;
13966   vat_json_node_t *node = NULL;
13967   struct in_addr ip4;
13968   struct in6_addr ip6;
13969
13970   if (VAT_JSON_ARRAY != vam->json_tree.type)
13971     {
13972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13973       vat_json_init_array (&vam->json_tree);
13974     }
13975   node = vat_json_array_add (&vam->json_tree);
13976
13977   vat_json_init_object (node);
13978   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13979   if (mp->is_ipv6)
13980     {
13981       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13982       vat_json_object_add_ip6 (node, "local", ip6);
13983       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13984       vat_json_object_add_ip6 (node, "remote", ip6);
13985     }
13986   else
13987     {
13988       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13989       vat_json_object_add_ip4 (node, "local", ip4);
13990       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13991       vat_json_object_add_ip4 (node, "remote", ip4);
13992     }
13993   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13994   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13995   vat_json_object_add_uint (node, "mcast_sw_if_index",
13996                             ntohl (mp->mcast_sw_if_index));
13997   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13998   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13999   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14000 }
14001
14002 static int
14003 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14004 {
14005   unformat_input_t *i = vam->input;
14006   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14007   vl_api_control_ping_t *mp_ping;
14008   u32 sw_if_index;
14009   u8 sw_if_index_set = 0;
14010   int ret;
14011
14012   /* Parse args required to build the message */
14013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (i, "sw_if_index %d", &sw_if_index))
14016         sw_if_index_set = 1;
14017       else
14018         break;
14019     }
14020
14021   if (sw_if_index_set == 0)
14022     {
14023       sw_if_index = ~0;
14024     }
14025
14026   if (!vam->json_output)
14027     {
14028       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14029              "sw_if_index", "local", "remote", "vni",
14030              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14031     }
14032
14033   /* Get list of vxlan-tunnel interfaces */
14034   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14035
14036   mp->sw_if_index = htonl (sw_if_index);
14037
14038   S (mp);
14039
14040   /* Use a control ping for synchronization */
14041   MPING (CONTROL_PING, mp_ping);
14042   S (mp_ping);
14043
14044   W (ret);
14045   return ret;
14046 }
14047
14048 static void vl_api_l2_fib_table_details_t_handler
14049   (vl_api_l2_fib_table_details_t * mp)
14050 {
14051   vat_main_t *vam = &vat_main;
14052
14053   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14054          "       %d       %d     %d",
14055          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14056          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14057          mp->bvi_mac);
14058 }
14059
14060 static void vl_api_l2_fib_table_details_t_handler_json
14061   (vl_api_l2_fib_table_details_t * mp)
14062 {
14063   vat_main_t *vam = &vat_main;
14064   vat_json_node_t *node = NULL;
14065
14066   if (VAT_JSON_ARRAY != vam->json_tree.type)
14067     {
14068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14069       vat_json_init_array (&vam->json_tree);
14070     }
14071   node = vat_json_array_add (&vam->json_tree);
14072
14073   vat_json_init_object (node);
14074   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14075   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14076   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14077   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14078   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14079   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14080 }
14081
14082 static int
14083 api_l2_fib_table_dump (vat_main_t * vam)
14084 {
14085   unformat_input_t *i = vam->input;
14086   vl_api_l2_fib_table_dump_t *mp;
14087   vl_api_control_ping_t *mp_ping;
14088   u32 bd_id;
14089   u8 bd_id_set = 0;
14090   int ret;
14091
14092   /* Parse args required to build the message */
14093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14094     {
14095       if (unformat (i, "bd_id %d", &bd_id))
14096         bd_id_set = 1;
14097       else
14098         break;
14099     }
14100
14101   if (bd_id_set == 0)
14102     {
14103       errmsg ("missing bridge domain");
14104       return -99;
14105     }
14106
14107   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14108
14109   /* Get list of l2 fib entries */
14110   M (L2_FIB_TABLE_DUMP, mp);
14111
14112   mp->bd_id = ntohl (bd_id);
14113   S (mp);
14114
14115   /* Use a control ping for synchronization */
14116   MPING (CONTROL_PING, mp_ping);
14117   S (mp_ping);
14118
14119   W (ret);
14120   return ret;
14121 }
14122
14123
14124 static int
14125 api_interface_name_renumber (vat_main_t * vam)
14126 {
14127   unformat_input_t *line_input = vam->input;
14128   vl_api_interface_name_renumber_t *mp;
14129   u32 sw_if_index = ~0;
14130   u32 new_show_dev_instance = ~0;
14131   int ret;
14132
14133   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14134     {
14135       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14136                     &sw_if_index))
14137         ;
14138       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14139         ;
14140       else if (unformat (line_input, "new_show_dev_instance %d",
14141                          &new_show_dev_instance))
14142         ;
14143       else
14144         break;
14145     }
14146
14147   if (sw_if_index == ~0)
14148     {
14149       errmsg ("missing interface name or sw_if_index");
14150       return -99;
14151     }
14152
14153   if (new_show_dev_instance == ~0)
14154     {
14155       errmsg ("missing new_show_dev_instance");
14156       return -99;
14157     }
14158
14159   M (INTERFACE_NAME_RENUMBER, mp);
14160
14161   mp->sw_if_index = ntohl (sw_if_index);
14162   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14163
14164   S (mp);
14165   W (ret);
14166   return ret;
14167 }
14168
14169 static int
14170 api_ip_probe_neighbor (vat_main_t * vam)
14171 {
14172   unformat_input_t *i = vam->input;
14173   vl_api_ip_probe_neighbor_t *mp;
14174   vl_api_address_t dst_adr;
14175   u8 int_set = 0;
14176   u8 adr_set = 0;
14177   u32 sw_if_index;
14178   int ret;
14179
14180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14181     {
14182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14183         int_set = 1;
14184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14185         int_set = 1;
14186       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14187         adr_set = 1;
14188       else
14189         break;
14190     }
14191
14192   if (int_set == 0)
14193     {
14194       errmsg ("missing interface");
14195       return -99;
14196     }
14197
14198   if (adr_set == 0)
14199     {
14200       errmsg ("missing addresses");
14201       return -99;
14202     }
14203
14204   M (IP_PROBE_NEIGHBOR, mp);
14205
14206   mp->sw_if_index = ntohl (sw_if_index);
14207   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14208
14209   S (mp);
14210   W (ret);
14211   return ret;
14212 }
14213
14214 static int
14215 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14216 {
14217   unformat_input_t *i = vam->input;
14218   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14219   u8 mode = IP_SCAN_V46_NEIGHBORS;
14220   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14221   int ret;
14222
14223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14224     {
14225       if (unformat (i, "ip4"))
14226         mode = IP_SCAN_V4_NEIGHBORS;
14227       else if (unformat (i, "ip6"))
14228         mode = IP_SCAN_V6_NEIGHBORS;
14229       if (unformat (i, "both"))
14230         mode = IP_SCAN_V46_NEIGHBORS;
14231       else if (unformat (i, "disable"))
14232         mode = IP_SCAN_DISABLED;
14233       else if (unformat (i, "interval %d", &interval))
14234         ;
14235       else if (unformat (i, "max-time %d", &time))
14236         ;
14237       else if (unformat (i, "max-update %d", &update))
14238         ;
14239       else if (unformat (i, "delay %d", &delay))
14240         ;
14241       else if (unformat (i, "stale %d", &stale))
14242         ;
14243       else
14244         break;
14245     }
14246
14247   if (interval > 255)
14248     {
14249       errmsg ("interval cannot exceed 255 minutes.");
14250       return -99;
14251     }
14252   if (time > 255)
14253     {
14254       errmsg ("max-time cannot exceed 255 usec.");
14255       return -99;
14256     }
14257   if (update > 255)
14258     {
14259       errmsg ("max-update cannot exceed 255.");
14260       return -99;
14261     }
14262   if (delay > 255)
14263     {
14264       errmsg ("delay cannot exceed 255 msec.");
14265       return -99;
14266     }
14267   if (stale > 255)
14268     {
14269       errmsg ("stale cannot exceed 255 minutes.");
14270       return -99;
14271     }
14272
14273   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14274   mp->mode = mode;
14275   mp->scan_interval = interval;
14276   mp->max_proc_time = time;
14277   mp->max_update = update;
14278   mp->scan_int_delay = delay;
14279   mp->stale_threshold = stale;
14280
14281   S (mp);
14282   W (ret);
14283   return ret;
14284 }
14285
14286 static int
14287 api_want_ip4_arp_events (vat_main_t * vam)
14288 {
14289   unformat_input_t *line_input = vam->input;
14290   vl_api_want_ip4_arp_events_t *mp;
14291   ip4_address_t address;
14292   int address_set = 0;
14293   u32 enable_disable = 1;
14294   int ret;
14295
14296   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14297     {
14298       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14299         address_set = 1;
14300       else if (unformat (line_input, "del"))
14301         enable_disable = 0;
14302       else
14303         break;
14304     }
14305
14306   if (address_set == 0)
14307     {
14308       errmsg ("missing addresses");
14309       return -99;
14310     }
14311
14312   M (WANT_IP4_ARP_EVENTS, mp);
14313   mp->enable_disable = enable_disable;
14314   mp->pid = htonl (getpid ());
14315   clib_memcpy (mp->ip, &address, sizeof (address));
14316
14317   S (mp);
14318   W (ret);
14319   return ret;
14320 }
14321
14322 static int
14323 api_want_ip6_nd_events (vat_main_t * vam)
14324 {
14325   unformat_input_t *line_input = vam->input;
14326   vl_api_want_ip6_nd_events_t *mp;
14327   vl_api_ip6_address_t address;
14328   int address_set = 0;
14329   u32 enable_disable = 1;
14330   int ret;
14331
14332   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14333     {
14334       if (unformat
14335           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14336         address_set = 1;
14337       else if (unformat (line_input, "del"))
14338         enable_disable = 0;
14339       else
14340         break;
14341     }
14342
14343   if (address_set == 0)
14344     {
14345       errmsg ("missing addresses");
14346       return -99;
14347     }
14348
14349   M (WANT_IP6_ND_EVENTS, mp);
14350   mp->enable_disable = enable_disable;
14351   mp->pid = htonl (getpid ());
14352   clib_memcpy (&mp->ip, &address, sizeof (address));
14353
14354   S (mp);
14355   W (ret);
14356   return ret;
14357 }
14358
14359 static int
14360 api_want_l2_macs_events (vat_main_t * vam)
14361 {
14362   unformat_input_t *line_input = vam->input;
14363   vl_api_want_l2_macs_events_t *mp;
14364   u8 enable_disable = 1;
14365   u32 scan_delay = 0;
14366   u32 max_macs_in_event = 0;
14367   u32 learn_limit = 0;
14368   int ret;
14369
14370   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14371     {
14372       if (unformat (line_input, "learn-limit %d", &learn_limit))
14373         ;
14374       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14375         ;
14376       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14377         ;
14378       else if (unformat (line_input, "disable"))
14379         enable_disable = 0;
14380       else
14381         break;
14382     }
14383
14384   M (WANT_L2_MACS_EVENTS, mp);
14385   mp->enable_disable = enable_disable;
14386   mp->pid = htonl (getpid ());
14387   mp->learn_limit = htonl (learn_limit);
14388   mp->scan_delay = (u8) scan_delay;
14389   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14390   S (mp);
14391   W (ret);
14392   return ret;
14393 }
14394
14395 static int
14396 api_input_acl_set_interface (vat_main_t * vam)
14397 {
14398   unformat_input_t *i = vam->input;
14399   vl_api_input_acl_set_interface_t *mp;
14400   u32 sw_if_index;
14401   int sw_if_index_set;
14402   u32 ip4_table_index = ~0;
14403   u32 ip6_table_index = ~0;
14404   u32 l2_table_index = ~0;
14405   u8 is_add = 1;
14406   int ret;
14407
14408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14409     {
14410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14411         sw_if_index_set = 1;
14412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14413         sw_if_index_set = 1;
14414       else if (unformat (i, "del"))
14415         is_add = 0;
14416       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14417         ;
14418       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14419         ;
14420       else if (unformat (i, "l2-table %d", &l2_table_index))
14421         ;
14422       else
14423         {
14424           clib_warning ("parse error '%U'", format_unformat_error, i);
14425           return -99;
14426         }
14427     }
14428
14429   if (sw_if_index_set == 0)
14430     {
14431       errmsg ("missing interface name or sw_if_index");
14432       return -99;
14433     }
14434
14435   M (INPUT_ACL_SET_INTERFACE, mp);
14436
14437   mp->sw_if_index = ntohl (sw_if_index);
14438   mp->ip4_table_index = ntohl (ip4_table_index);
14439   mp->ip6_table_index = ntohl (ip6_table_index);
14440   mp->l2_table_index = ntohl (l2_table_index);
14441   mp->is_add = is_add;
14442
14443   S (mp);
14444   W (ret);
14445   return ret;
14446 }
14447
14448 static int
14449 api_output_acl_set_interface (vat_main_t * vam)
14450 {
14451   unformat_input_t *i = vam->input;
14452   vl_api_output_acl_set_interface_t *mp;
14453   u32 sw_if_index;
14454   int sw_if_index_set;
14455   u32 ip4_table_index = ~0;
14456   u32 ip6_table_index = ~0;
14457   u32 l2_table_index = ~0;
14458   u8 is_add = 1;
14459   int ret;
14460
14461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14462     {
14463       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14464         sw_if_index_set = 1;
14465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14466         sw_if_index_set = 1;
14467       else if (unformat (i, "del"))
14468         is_add = 0;
14469       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14470         ;
14471       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14472         ;
14473       else if (unformat (i, "l2-table %d", &l2_table_index))
14474         ;
14475       else
14476         {
14477           clib_warning ("parse error '%U'", format_unformat_error, i);
14478           return -99;
14479         }
14480     }
14481
14482   if (sw_if_index_set == 0)
14483     {
14484       errmsg ("missing interface name or sw_if_index");
14485       return -99;
14486     }
14487
14488   M (OUTPUT_ACL_SET_INTERFACE, mp);
14489
14490   mp->sw_if_index = ntohl (sw_if_index);
14491   mp->ip4_table_index = ntohl (ip4_table_index);
14492   mp->ip6_table_index = ntohl (ip6_table_index);
14493   mp->l2_table_index = ntohl (l2_table_index);
14494   mp->is_add = is_add;
14495
14496   S (mp);
14497   W (ret);
14498   return ret;
14499 }
14500
14501 static int
14502 api_ip_address_dump (vat_main_t * vam)
14503 {
14504   unformat_input_t *i = vam->input;
14505   vl_api_ip_address_dump_t *mp;
14506   vl_api_control_ping_t *mp_ping;
14507   u32 sw_if_index = ~0;
14508   u8 sw_if_index_set = 0;
14509   u8 ipv4_set = 0;
14510   u8 ipv6_set = 0;
14511   int ret;
14512
14513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14514     {
14515       if (unformat (i, "sw_if_index %d", &sw_if_index))
14516         sw_if_index_set = 1;
14517       else
14518         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14519         sw_if_index_set = 1;
14520       else if (unformat (i, "ipv4"))
14521         ipv4_set = 1;
14522       else if (unformat (i, "ipv6"))
14523         ipv6_set = 1;
14524       else
14525         break;
14526     }
14527
14528   if (ipv4_set && ipv6_set)
14529     {
14530       errmsg ("ipv4 and ipv6 flags cannot be both set");
14531       return -99;
14532     }
14533
14534   if ((!ipv4_set) && (!ipv6_set))
14535     {
14536       errmsg ("no ipv4 nor ipv6 flag set");
14537       return -99;
14538     }
14539
14540   if (sw_if_index_set == 0)
14541     {
14542       errmsg ("missing interface name or sw_if_index");
14543       return -99;
14544     }
14545
14546   vam->current_sw_if_index = sw_if_index;
14547   vam->is_ipv6 = ipv6_set;
14548
14549   M (IP_ADDRESS_DUMP, mp);
14550   mp->sw_if_index = ntohl (sw_if_index);
14551   mp->is_ipv6 = ipv6_set;
14552   S (mp);
14553
14554   /* Use a control ping for synchronization */
14555   MPING (CONTROL_PING, mp_ping);
14556   S (mp_ping);
14557
14558   W (ret);
14559   return ret;
14560 }
14561
14562 static int
14563 api_ip_dump (vat_main_t * vam)
14564 {
14565   vl_api_ip_dump_t *mp;
14566   vl_api_control_ping_t *mp_ping;
14567   unformat_input_t *in = vam->input;
14568   int ipv4_set = 0;
14569   int ipv6_set = 0;
14570   int is_ipv6;
14571   int i;
14572   int ret;
14573
14574   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14575     {
14576       if (unformat (in, "ipv4"))
14577         ipv4_set = 1;
14578       else if (unformat (in, "ipv6"))
14579         ipv6_set = 1;
14580       else
14581         break;
14582     }
14583
14584   if (ipv4_set && ipv6_set)
14585     {
14586       errmsg ("ipv4 and ipv6 flags cannot be both set");
14587       return -99;
14588     }
14589
14590   if ((!ipv4_set) && (!ipv6_set))
14591     {
14592       errmsg ("no ipv4 nor ipv6 flag set");
14593       return -99;
14594     }
14595
14596   is_ipv6 = ipv6_set;
14597   vam->is_ipv6 = is_ipv6;
14598
14599   /* free old data */
14600   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14601     {
14602       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14603     }
14604   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14605
14606   M (IP_DUMP, mp);
14607   mp->is_ipv6 = ipv6_set;
14608   S (mp);
14609
14610   /* Use a control ping for synchronization */
14611   MPING (CONTROL_PING, mp_ping);
14612   S (mp_ping);
14613
14614   W (ret);
14615   return ret;
14616 }
14617
14618 static int
14619 api_ipsec_spd_add_del (vat_main_t * vam)
14620 {
14621   unformat_input_t *i = vam->input;
14622   vl_api_ipsec_spd_add_del_t *mp;
14623   u32 spd_id = ~0;
14624   u8 is_add = 1;
14625   int ret;
14626
14627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (i, "spd_id %d", &spd_id))
14630         ;
14631       else if (unformat (i, "del"))
14632         is_add = 0;
14633       else
14634         {
14635           clib_warning ("parse error '%U'", format_unformat_error, i);
14636           return -99;
14637         }
14638     }
14639   if (spd_id == ~0)
14640     {
14641       errmsg ("spd_id must be set");
14642       return -99;
14643     }
14644
14645   M (IPSEC_SPD_ADD_DEL, mp);
14646
14647   mp->spd_id = ntohl (spd_id);
14648   mp->is_add = is_add;
14649
14650   S (mp);
14651   W (ret);
14652   return ret;
14653 }
14654
14655 static int
14656 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14657 {
14658   unformat_input_t *i = vam->input;
14659   vl_api_ipsec_interface_add_del_spd_t *mp;
14660   u32 sw_if_index;
14661   u8 sw_if_index_set = 0;
14662   u32 spd_id = (u32) ~ 0;
14663   u8 is_add = 1;
14664   int ret;
14665
14666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14667     {
14668       if (unformat (i, "del"))
14669         is_add = 0;
14670       else if (unformat (i, "spd_id %d", &spd_id))
14671         ;
14672       else
14673         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14674         sw_if_index_set = 1;
14675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14676         sw_if_index_set = 1;
14677       else
14678         {
14679           clib_warning ("parse error '%U'", format_unformat_error, i);
14680           return -99;
14681         }
14682
14683     }
14684
14685   if (spd_id == (u32) ~ 0)
14686     {
14687       errmsg ("spd_id must be set");
14688       return -99;
14689     }
14690
14691   if (sw_if_index_set == 0)
14692     {
14693       errmsg ("missing interface name or sw_if_index");
14694       return -99;
14695     }
14696
14697   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14698
14699   mp->spd_id = ntohl (spd_id);
14700   mp->sw_if_index = ntohl (sw_if_index);
14701   mp->is_add = is_add;
14702
14703   S (mp);
14704   W (ret);
14705   return ret;
14706 }
14707
14708 static int
14709 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14710 {
14711   unformat_input_t *i = vam->input;
14712   vl_api_ipsec_spd_entry_add_del_t *mp;
14713   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14714   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14715   i32 priority = 0;
14716   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14717   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14718   vl_api_address_t laddr_start = { }, laddr_stop =
14719   {
14720   }, raddr_start =
14721   {
14722   }, raddr_stop =
14723   {
14724   };
14725   int ret;
14726
14727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14728     {
14729       if (unformat (i, "del"))
14730         is_add = 0;
14731       if (unformat (i, "outbound"))
14732         is_outbound = 1;
14733       if (unformat (i, "inbound"))
14734         is_outbound = 0;
14735       else if (unformat (i, "spd_id %d", &spd_id))
14736         ;
14737       else if (unformat (i, "sa_id %d", &sa_id))
14738         ;
14739       else if (unformat (i, "priority %d", &priority))
14740         ;
14741       else if (unformat (i, "protocol %d", &protocol))
14742         ;
14743       else if (unformat (i, "lport_start %d", &lport_start))
14744         ;
14745       else if (unformat (i, "lport_stop %d", &lport_stop))
14746         ;
14747       else if (unformat (i, "rport_start %d", &rport_start))
14748         ;
14749       else if (unformat (i, "rport_stop %d", &rport_stop))
14750         ;
14751       else if (unformat (i, "laddr_start %U",
14752                          unformat_vl_api_address, &laddr_start))
14753         is_ip_any = 0;
14754       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14755                          &laddr_stop))
14756         is_ip_any = 0;
14757       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14758                          &raddr_start))
14759         is_ip_any = 0;
14760       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14761                          &raddr_stop))
14762         is_ip_any = 0;
14763       else
14764         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14765         {
14766           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14767             {
14768               clib_warning ("unsupported action: 'resolve'");
14769               return -99;
14770             }
14771         }
14772       else
14773         {
14774           clib_warning ("parse error '%U'", format_unformat_error, i);
14775           return -99;
14776         }
14777
14778     }
14779
14780   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14781
14782   mp->is_add = is_add;
14783
14784   mp->entry.spd_id = ntohl (spd_id);
14785   mp->entry.priority = ntohl (priority);
14786   mp->entry.is_outbound = is_outbound;
14787
14788   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14789                sizeof (vl_api_address_t));
14790   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14791                sizeof (vl_api_address_t));
14792   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14793                sizeof (vl_api_address_t));
14794   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14795                sizeof (vl_api_address_t));
14796
14797   mp->entry.protocol = (u8) protocol;
14798   mp->entry.local_port_start = ntohs ((u16) lport_start);
14799   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14800   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14801   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14802   mp->entry.policy = (u8) policy;
14803   mp->entry.sa_id = ntohl (sa_id);
14804
14805   S (mp);
14806   W (ret);
14807   return ret;
14808 }
14809
14810 static int
14811 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14812 {
14813   unformat_input_t *i = vam->input;
14814   vl_api_ipsec_sad_entry_add_del_t *mp;
14815   u32 sad_id = 0, spi = 0;
14816   u8 *ck = 0, *ik = 0;
14817   u8 is_add = 1;
14818
14819   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14820   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14821   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14822   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14823   vl_api_address_t tun_src, tun_dst;
14824   int ret;
14825
14826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14827     {
14828       if (unformat (i, "del"))
14829         is_add = 0;
14830       else if (unformat (i, "sad_id %d", &sad_id))
14831         ;
14832       else if (unformat (i, "spi %d", &spi))
14833         ;
14834       else if (unformat (i, "esp"))
14835         protocol = IPSEC_API_PROTO_ESP;
14836       else
14837         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14838         {
14839           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14840           if (ADDRESS_IP6 == tun_src.af)
14841             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14842         }
14843       else
14844         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14845         {
14846           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14847           if (ADDRESS_IP6 == tun_src.af)
14848             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14849         }
14850       else
14851         if (unformat (i, "crypto_alg %U",
14852                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14853         ;
14854       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14855         ;
14856       else if (unformat (i, "integ_alg %U",
14857                          unformat_ipsec_api_integ_alg, &integ_alg))
14858         ;
14859       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14860         ;
14861       else
14862         {
14863           clib_warning ("parse error '%U'", format_unformat_error, i);
14864           return -99;
14865         }
14866
14867     }
14868
14869   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14870
14871   mp->is_add = is_add;
14872   mp->entry.sad_id = ntohl (sad_id);
14873   mp->entry.protocol = protocol;
14874   mp->entry.spi = ntohl (spi);
14875   mp->entry.flags = flags;
14876
14877   mp->entry.crypto_algorithm = crypto_alg;
14878   mp->entry.integrity_algorithm = integ_alg;
14879   mp->entry.crypto_key.length = vec_len (ck);
14880   mp->entry.integrity_key.length = vec_len (ik);
14881
14882   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14883     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14884
14885   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14886     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14887
14888   if (ck)
14889     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14890   if (ik)
14891     clib_memcpy (mp->entry.integrity_key.data, ik,
14892                  mp->entry.integrity_key.length);
14893
14894   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14895     {
14896       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14897                    sizeof (mp->entry.tunnel_src));
14898       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14899                    sizeof (mp->entry.tunnel_dst));
14900     }
14901
14902   S (mp);
14903   W (ret);
14904   return ret;
14905 }
14906
14907 static int
14908 api_ipsec_sa_set_key (vat_main_t * vam)
14909 {
14910   unformat_input_t *i = vam->input;
14911   vl_api_ipsec_sa_set_key_t *mp;
14912   u32 sa_id;
14913   u8 *ck = 0, *ik = 0;
14914   int ret;
14915
14916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14917     {
14918       if (unformat (i, "sa_id %d", &sa_id))
14919         ;
14920       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14921         ;
14922       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14923         ;
14924       else
14925         {
14926           clib_warning ("parse error '%U'", format_unformat_error, i);
14927           return -99;
14928         }
14929     }
14930
14931   M (IPSEC_SA_SET_KEY, mp);
14932
14933   mp->sa_id = ntohl (sa_id);
14934   mp->crypto_key.length = vec_len (ck);
14935   mp->integrity_key.length = vec_len (ik);
14936
14937   if (mp->crypto_key.length > sizeof (mp->crypto_key.data))
14938     mp->crypto_key.length = sizeof (mp->crypto_key.data);
14939
14940   if (mp->integrity_key.length > sizeof (mp->integrity_key.data))
14941     mp->integrity_key.length = sizeof (mp->integrity_key.data);
14942
14943   if (ck)
14944     clib_memcpy (mp->crypto_key.data, ck, mp->crypto_key.length);
14945   if (ik)
14946     clib_memcpy (mp->integrity_key.data, ik, mp->integrity_key.length);
14947
14948   S (mp);
14949   W (ret);
14950   return ret;
14951 }
14952
14953 static int
14954 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14955 {
14956   unformat_input_t *i = vam->input;
14957   vl_api_ipsec_tunnel_if_add_del_t *mp;
14958   u32 local_spi = 0, remote_spi = 0;
14959   u32 crypto_alg = 0, integ_alg = 0;
14960   u8 *lck = NULL, *rck = NULL;
14961   u8 *lik = NULL, *rik = NULL;
14962   vl_api_address_t local_ip = { 0 };
14963   vl_api_address_t remote_ip = { 0 };
14964   f64 before = 0;
14965   u8 is_add = 1;
14966   u8 esn = 0;
14967   u8 anti_replay = 0;
14968   u8 renumber = 0;
14969   u32 instance = ~0;
14970   u32 count = 1, jj;
14971   int ret;
14972
14973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14974     {
14975       if (unformat (i, "del"))
14976         is_add = 0;
14977       else if (unformat (i, "esn"))
14978         esn = 1;
14979       else if (unformat (i, "anti-replay"))
14980         anti_replay = 1;
14981       else if (unformat (i, "count %d", &count))
14982         ;
14983       else if (unformat (i, "local_spi %d", &local_spi))
14984         ;
14985       else if (unformat (i, "remote_spi %d", &remote_spi))
14986         ;
14987       else
14988         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14989         ;
14990       else
14991         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14992         ;
14993       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14994         ;
14995       else
14996         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14997         ;
14998       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14999         ;
15000       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15001         ;
15002       else
15003         if (unformat
15004             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
15005         {
15006           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15007             {
15008               errmsg ("unsupported crypto-alg: '%U'\n",
15009                       format_ipsec_crypto_alg, crypto_alg);
15010               return -99;
15011             }
15012         }
15013       else
15014         if (unformat
15015             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
15016         {
15017           if (integ_alg >= IPSEC_INTEG_N_ALG)
15018             {
15019               errmsg ("unsupported integ-alg: '%U'\n",
15020                       format_ipsec_integ_alg, integ_alg);
15021               return -99;
15022             }
15023         }
15024       else if (unformat (i, "instance %u", &instance))
15025         renumber = 1;
15026       else
15027         {
15028           errmsg ("parse error '%U'\n", format_unformat_error, i);
15029           return -99;
15030         }
15031     }
15032
15033   if (count > 1)
15034     {
15035       /* Turn on async mode */
15036       vam->async_mode = 1;
15037       vam->async_errors = 0;
15038       before = vat_time_now (vam);
15039     }
15040
15041   for (jj = 0; jj < count; jj++)
15042     {
15043       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15044
15045       mp->is_add = is_add;
15046       mp->esn = esn;
15047       mp->anti_replay = anti_replay;
15048
15049       if (jj > 0)
15050         increment_vl_address (&remote_ip);
15051
15052       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15053       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15054
15055       mp->local_spi = htonl (local_spi + jj);
15056       mp->remote_spi = htonl (remote_spi + jj);
15057       mp->crypto_alg = (u8) crypto_alg;
15058
15059       mp->local_crypto_key_len = 0;
15060       if (lck)
15061         {
15062           mp->local_crypto_key_len = vec_len (lck);
15063           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15064             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15065           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15066         }
15067
15068       mp->remote_crypto_key_len = 0;
15069       if (rck)
15070         {
15071           mp->remote_crypto_key_len = vec_len (rck);
15072           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15073             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15074           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15075         }
15076
15077       mp->integ_alg = (u8) integ_alg;
15078
15079       mp->local_integ_key_len = 0;
15080       if (lik)
15081         {
15082           mp->local_integ_key_len = vec_len (lik);
15083           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15084             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15085           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15086         }
15087
15088       mp->remote_integ_key_len = 0;
15089       if (rik)
15090         {
15091           mp->remote_integ_key_len = vec_len (rik);
15092           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15093             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15094           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15095         }
15096
15097       if (renumber)
15098         {
15099           mp->renumber = renumber;
15100           mp->show_instance = ntohl (instance);
15101         }
15102       S (mp);
15103     }
15104
15105   /* When testing multiple add/del ops, use a control-ping to sync */
15106   if (count > 1)
15107     {
15108       vl_api_control_ping_t *mp_ping;
15109       f64 after;
15110       f64 timeout;
15111
15112       /* Shut off async mode */
15113       vam->async_mode = 0;
15114
15115       MPING (CONTROL_PING, mp_ping);
15116       S (mp_ping);
15117
15118       timeout = vat_time_now (vam) + 1.0;
15119       while (vat_time_now (vam) < timeout)
15120         if (vam->result_ready == 1)
15121           goto out;
15122       vam->retval = -99;
15123
15124     out:
15125       if (vam->retval == -99)
15126         errmsg ("timeout");
15127
15128       if (vam->async_errors > 0)
15129         {
15130           errmsg ("%d asynchronous errors", vam->async_errors);
15131           vam->retval = -98;
15132         }
15133       vam->async_errors = 0;
15134       after = vat_time_now (vam);
15135
15136       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15137       if (jj > 0)
15138         count = jj;
15139
15140       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15141              count, after - before, count / (after - before));
15142     }
15143   else
15144     {
15145       /* Wait for a reply... */
15146       W (ret);
15147       return ret;
15148     }
15149
15150   return ret;
15151 }
15152
15153 static void
15154 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15155 {
15156   vat_main_t *vam = &vat_main;
15157
15158   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15159          "crypto_key %U integ_alg %u integ_key %U flags %x "
15160          "tunnel_src_addr %U tunnel_dst_addr %U "
15161          "salt %u seq_outbound %lu last_seq_inbound %lu "
15162          "replay_window %lu\n",
15163          ntohl (mp->entry.sad_id),
15164          ntohl (mp->sw_if_index),
15165          ntohl (mp->entry.spi),
15166          ntohl (mp->entry.protocol),
15167          ntohl (mp->entry.crypto_algorithm),
15168          format_hex_bytes, mp->entry.crypto_key.data,
15169          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15170          format_hex_bytes, mp->entry.integrity_key.data,
15171          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15172          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15173          &mp->entry.tunnel_dst, ntohl (mp->salt),
15174          clib_net_to_host_u64 (mp->seq_outbound),
15175          clib_net_to_host_u64 (mp->last_seq_inbound),
15176          clib_net_to_host_u64 (mp->replay_window));
15177 }
15178
15179 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15180 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15181
15182 static void vl_api_ipsec_sa_details_t_handler_json
15183   (vl_api_ipsec_sa_details_t * mp)
15184 {
15185   vat_main_t *vam = &vat_main;
15186   vat_json_node_t *node = NULL;
15187   vl_api_ipsec_sad_flags_t flags;
15188
15189   if (VAT_JSON_ARRAY != vam->json_tree.type)
15190     {
15191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15192       vat_json_init_array (&vam->json_tree);
15193     }
15194   node = vat_json_array_add (&vam->json_tree);
15195
15196   vat_json_init_object (node);
15197   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15198   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15199   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15200   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15201   vat_json_object_add_uint (node, "crypto_alg",
15202                             ntohl (mp->entry.crypto_algorithm));
15203   vat_json_object_add_uint (node, "integ_alg",
15204                             ntohl (mp->entry.integrity_algorithm));
15205   flags = ntohl (mp->entry.flags);
15206   vat_json_object_add_uint (node, "use_esn",
15207                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15208   vat_json_object_add_uint (node, "use_anti_replay",
15209                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15210   vat_json_object_add_uint (node, "is_tunnel",
15211                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15212   vat_json_object_add_uint (node, "is_tunnel_ip6",
15213                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15214   vat_json_object_add_uint (node, "udp_encap",
15215                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15216   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15217                              mp->entry.crypto_key.length);
15218   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15219                              mp->entry.integrity_key.length);
15220   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15221   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15222   vat_json_object_add_uint (node, "replay_window",
15223                             clib_net_to_host_u64 (mp->replay_window));
15224 }
15225
15226 static int
15227 api_ipsec_sa_dump (vat_main_t * vam)
15228 {
15229   unformat_input_t *i = vam->input;
15230   vl_api_ipsec_sa_dump_t *mp;
15231   vl_api_control_ping_t *mp_ping;
15232   u32 sa_id = ~0;
15233   int ret;
15234
15235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15236     {
15237       if (unformat (i, "sa_id %d", &sa_id))
15238         ;
15239       else
15240         {
15241           clib_warning ("parse error '%U'", format_unformat_error, i);
15242           return -99;
15243         }
15244     }
15245
15246   M (IPSEC_SA_DUMP, mp);
15247
15248   mp->sa_id = ntohl (sa_id);
15249
15250   S (mp);
15251
15252   /* Use a control ping for synchronization */
15253   M (CONTROL_PING, mp_ping);
15254   S (mp_ping);
15255
15256   W (ret);
15257   return ret;
15258 }
15259
15260 static int
15261 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15262 {
15263   unformat_input_t *i = vam->input;
15264   vl_api_ipsec_tunnel_if_set_key_t *mp;
15265   u32 sw_if_index = ~0;
15266   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15267   u8 *key = 0;
15268   u32 alg = ~0;
15269   int ret;
15270
15271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15272     {
15273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15274         ;
15275       else
15276         if (unformat
15277             (i, "local crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15278         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15279       else
15280         if (unformat
15281             (i, "remote crypto %U", unformat_ipsec_api_crypto_alg, &alg))
15282         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15283       else
15284         if (unformat
15285             (i, "local integ %U", unformat_ipsec_api_integ_alg, &alg))
15286         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15287       else
15288         if (unformat
15289             (i, "remote integ %U", unformat_ipsec_api_integ_alg, &alg))
15290         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15291       else if (unformat (i, "%U", unformat_hex_string, &key))
15292         ;
15293       else
15294         {
15295           clib_warning ("parse error '%U'", format_unformat_error, i);
15296           return -99;
15297         }
15298     }
15299
15300   if (sw_if_index == ~0)
15301     {
15302       errmsg ("interface must be specified");
15303       return -99;
15304     }
15305
15306   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15307     {
15308       errmsg ("key type must be specified");
15309       return -99;
15310     }
15311
15312   if (alg == ~0)
15313     {
15314       errmsg ("algorithm must be specified");
15315       return -99;
15316     }
15317
15318   if (vec_len (key) == 0)
15319     {
15320       errmsg ("key must be specified");
15321       return -99;
15322     }
15323
15324   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15325
15326   mp->sw_if_index = htonl (sw_if_index);
15327   mp->alg = alg;
15328   mp->key_type = key_type;
15329   mp->key_len = vec_len (key);
15330   clib_memcpy (mp->key, key, vec_len (key));
15331
15332   S (mp);
15333   W (ret);
15334
15335   return ret;
15336 }
15337
15338 static int
15339 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15340 {
15341   unformat_input_t *i = vam->input;
15342   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15343   u32 sw_if_index = ~0;
15344   u32 sa_id = ~0;
15345   u8 is_outbound = (u8) ~ 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 if (unformat (i, "sa_id %d", &sa_id))
15353         ;
15354       else if (unformat (i, "outbound"))
15355         is_outbound = 1;
15356       else if (unformat (i, "inbound"))
15357         is_outbound = 0;
15358       else
15359         {
15360           clib_warning ("parse error '%U'", format_unformat_error, i);
15361           return -99;
15362         }
15363     }
15364
15365   if (sw_if_index == ~0)
15366     {
15367       errmsg ("interface must be specified");
15368       return -99;
15369     }
15370
15371   if (sa_id == ~0)
15372     {
15373       errmsg ("SA ID must be specified");
15374       return -99;
15375     }
15376
15377   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15378
15379   mp->sw_if_index = htonl (sw_if_index);
15380   mp->sa_id = htonl (sa_id);
15381   mp->is_outbound = is_outbound;
15382
15383   S (mp);
15384   W (ret);
15385
15386   return ret;
15387 }
15388
15389 static int
15390 api_get_first_msg_id (vat_main_t * vam)
15391 {
15392   vl_api_get_first_msg_id_t *mp;
15393   unformat_input_t *i = vam->input;
15394   u8 *name;
15395   u8 name_set = 0;
15396   int ret;
15397
15398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15399     {
15400       if (unformat (i, "client %s", &name))
15401         name_set = 1;
15402       else
15403         break;
15404     }
15405
15406   if (name_set == 0)
15407     {
15408       errmsg ("missing client name");
15409       return -99;
15410     }
15411   vec_add1 (name, 0);
15412
15413   if (vec_len (name) > 63)
15414     {
15415       errmsg ("client name too long");
15416       return -99;
15417     }
15418
15419   M (GET_FIRST_MSG_ID, mp);
15420   clib_memcpy (mp->name, name, vec_len (name));
15421   S (mp);
15422   W (ret);
15423   return ret;
15424 }
15425
15426 static int
15427 api_cop_interface_enable_disable (vat_main_t * vam)
15428 {
15429   unformat_input_t *line_input = vam->input;
15430   vl_api_cop_interface_enable_disable_t *mp;
15431   u32 sw_if_index = ~0;
15432   u8 enable_disable = 1;
15433   int ret;
15434
15435   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15436     {
15437       if (unformat (line_input, "disable"))
15438         enable_disable = 0;
15439       if (unformat (line_input, "enable"))
15440         enable_disable = 1;
15441       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15442                          vam, &sw_if_index))
15443         ;
15444       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15445         ;
15446       else
15447         break;
15448     }
15449
15450   if (sw_if_index == ~0)
15451     {
15452       errmsg ("missing interface name or sw_if_index");
15453       return -99;
15454     }
15455
15456   /* Construct the API message */
15457   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15458   mp->sw_if_index = ntohl (sw_if_index);
15459   mp->enable_disable = enable_disable;
15460
15461   /* send it... */
15462   S (mp);
15463   /* Wait for the reply */
15464   W (ret);
15465   return ret;
15466 }
15467
15468 static int
15469 api_cop_whitelist_enable_disable (vat_main_t * vam)
15470 {
15471   unformat_input_t *line_input = vam->input;
15472   vl_api_cop_whitelist_enable_disable_t *mp;
15473   u32 sw_if_index = ~0;
15474   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15475   u32 fib_id = 0;
15476   int ret;
15477
15478   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15479     {
15480       if (unformat (line_input, "ip4"))
15481         ip4 = 1;
15482       else if (unformat (line_input, "ip6"))
15483         ip6 = 1;
15484       else if (unformat (line_input, "default"))
15485         default_cop = 1;
15486       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15487                          vam, &sw_if_index))
15488         ;
15489       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15490         ;
15491       else if (unformat (line_input, "fib-id %d", &fib_id))
15492         ;
15493       else
15494         break;
15495     }
15496
15497   if (sw_if_index == ~0)
15498     {
15499       errmsg ("missing interface name or sw_if_index");
15500       return -99;
15501     }
15502
15503   /* Construct the API message */
15504   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15505   mp->sw_if_index = ntohl (sw_if_index);
15506   mp->fib_id = ntohl (fib_id);
15507   mp->ip4 = ip4;
15508   mp->ip6 = ip6;
15509   mp->default_cop = default_cop;
15510
15511   /* send it... */
15512   S (mp);
15513   /* Wait for the reply */
15514   W (ret);
15515   return ret;
15516 }
15517
15518 static int
15519 api_get_node_graph (vat_main_t * vam)
15520 {
15521   vl_api_get_node_graph_t *mp;
15522   int ret;
15523
15524   M (GET_NODE_GRAPH, mp);
15525
15526   /* send it... */
15527   S (mp);
15528   /* Wait for the reply */
15529   W (ret);
15530   return ret;
15531 }
15532
15533 /* *INDENT-OFF* */
15534 /** Used for parsing LISP eids */
15535 typedef CLIB_PACKED(struct{
15536   u8 addr[16];   /**< eid address */
15537   u32 len;       /**< prefix length if IP */
15538   u8 type;      /**< type of eid */
15539 }) lisp_eid_vat_t;
15540 /* *INDENT-ON* */
15541
15542 static uword
15543 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15544 {
15545   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15546
15547   clib_memset (a, 0, sizeof (a[0]));
15548
15549   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15550     {
15551       a->type = 0;              /* ipv4 type */
15552     }
15553   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15554     {
15555       a->type = 1;              /* ipv6 type */
15556     }
15557   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15558     {
15559       a->type = 2;              /* mac type */
15560     }
15561   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15562     {
15563       a->type = 3;              /* NSH type */
15564       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15565       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15566     }
15567   else
15568     {
15569       return 0;
15570     }
15571
15572   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15573     {
15574       return 0;
15575     }
15576
15577   return 1;
15578 }
15579
15580 static int
15581 lisp_eid_size_vat (u8 type)
15582 {
15583   switch (type)
15584     {
15585     case 0:
15586       return 4;
15587     case 1:
15588       return 16;
15589     case 2:
15590       return 6;
15591     case 3:
15592       return 5;
15593     }
15594   return 0;
15595 }
15596
15597 static void
15598 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15599 {
15600   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15601 }
15602
15603 static int
15604 api_one_add_del_locator_set (vat_main_t * vam)
15605 {
15606   unformat_input_t *input = vam->input;
15607   vl_api_one_add_del_locator_set_t *mp;
15608   u8 is_add = 1;
15609   u8 *locator_set_name = NULL;
15610   u8 locator_set_name_set = 0;
15611   vl_api_local_locator_t locator, *locators = 0;
15612   u32 sw_if_index, priority, weight;
15613   u32 data_len = 0;
15614
15615   int ret;
15616   /* Parse args required to build the message */
15617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15618     {
15619       if (unformat (input, "del"))
15620         {
15621           is_add = 0;
15622         }
15623       else if (unformat (input, "locator-set %s", &locator_set_name))
15624         {
15625           locator_set_name_set = 1;
15626         }
15627       else if (unformat (input, "sw_if_index %u p %u w %u",
15628                          &sw_if_index, &priority, &weight))
15629         {
15630           locator.sw_if_index = htonl (sw_if_index);
15631           locator.priority = priority;
15632           locator.weight = weight;
15633           vec_add1 (locators, locator);
15634         }
15635       else
15636         if (unformat
15637             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15638              &sw_if_index, &priority, &weight))
15639         {
15640           locator.sw_if_index = htonl (sw_if_index);
15641           locator.priority = priority;
15642           locator.weight = weight;
15643           vec_add1 (locators, locator);
15644         }
15645       else
15646         break;
15647     }
15648
15649   if (locator_set_name_set == 0)
15650     {
15651       errmsg ("missing locator-set name");
15652       vec_free (locators);
15653       return -99;
15654     }
15655
15656   if (vec_len (locator_set_name) > 64)
15657     {
15658       errmsg ("locator-set name too long");
15659       vec_free (locator_set_name);
15660       vec_free (locators);
15661       return -99;
15662     }
15663   vec_add1 (locator_set_name, 0);
15664
15665   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15666
15667   /* Construct the API message */
15668   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15669
15670   mp->is_add = is_add;
15671   clib_memcpy (mp->locator_set_name, locator_set_name,
15672                vec_len (locator_set_name));
15673   vec_free (locator_set_name);
15674
15675   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15676   if (locators)
15677     clib_memcpy (mp->locators, locators, data_len);
15678   vec_free (locators);
15679
15680   /* send it... */
15681   S (mp);
15682
15683   /* Wait for a reply... */
15684   W (ret);
15685   return ret;
15686 }
15687
15688 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15689
15690 static int
15691 api_one_add_del_locator (vat_main_t * vam)
15692 {
15693   unformat_input_t *input = vam->input;
15694   vl_api_one_add_del_locator_t *mp;
15695   u32 tmp_if_index = ~0;
15696   u32 sw_if_index = ~0;
15697   u8 sw_if_index_set = 0;
15698   u8 sw_if_index_if_name_set = 0;
15699   u32 priority = ~0;
15700   u8 priority_set = 0;
15701   u32 weight = ~0;
15702   u8 weight_set = 0;
15703   u8 is_add = 1;
15704   u8 *locator_set_name = NULL;
15705   u8 locator_set_name_set = 0;
15706   int ret;
15707
15708   /* Parse args required to build the message */
15709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15710     {
15711       if (unformat (input, "del"))
15712         {
15713           is_add = 0;
15714         }
15715       else if (unformat (input, "locator-set %s", &locator_set_name))
15716         {
15717           locator_set_name_set = 1;
15718         }
15719       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15720                          &tmp_if_index))
15721         {
15722           sw_if_index_if_name_set = 1;
15723           sw_if_index = tmp_if_index;
15724         }
15725       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15726         {
15727           sw_if_index_set = 1;
15728           sw_if_index = tmp_if_index;
15729         }
15730       else if (unformat (input, "p %d", &priority))
15731         {
15732           priority_set = 1;
15733         }
15734       else if (unformat (input, "w %d", &weight))
15735         {
15736           weight_set = 1;
15737         }
15738       else
15739         break;
15740     }
15741
15742   if (locator_set_name_set == 0)
15743     {
15744       errmsg ("missing locator-set name");
15745       return -99;
15746     }
15747
15748   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15749     {
15750       errmsg ("missing sw_if_index");
15751       vec_free (locator_set_name);
15752       return -99;
15753     }
15754
15755   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15756     {
15757       errmsg ("cannot use both params interface name and sw_if_index");
15758       vec_free (locator_set_name);
15759       return -99;
15760     }
15761
15762   if (priority_set == 0)
15763     {
15764       errmsg ("missing locator-set priority");
15765       vec_free (locator_set_name);
15766       return -99;
15767     }
15768
15769   if (weight_set == 0)
15770     {
15771       errmsg ("missing locator-set weight");
15772       vec_free (locator_set_name);
15773       return -99;
15774     }
15775
15776   if (vec_len (locator_set_name) > 64)
15777     {
15778       errmsg ("locator-set name too long");
15779       vec_free (locator_set_name);
15780       return -99;
15781     }
15782   vec_add1 (locator_set_name, 0);
15783
15784   /* Construct the API message */
15785   M (ONE_ADD_DEL_LOCATOR, mp);
15786
15787   mp->is_add = is_add;
15788   mp->sw_if_index = ntohl (sw_if_index);
15789   mp->priority = priority;
15790   mp->weight = weight;
15791   clib_memcpy (mp->locator_set_name, locator_set_name,
15792                vec_len (locator_set_name));
15793   vec_free (locator_set_name);
15794
15795   /* send it... */
15796   S (mp);
15797
15798   /* Wait for a reply... */
15799   W (ret);
15800   return ret;
15801 }
15802
15803 #define api_lisp_add_del_locator api_one_add_del_locator
15804
15805 uword
15806 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15807 {
15808   u32 *key_id = va_arg (*args, u32 *);
15809   u8 *s = 0;
15810
15811   if (unformat (input, "%s", &s))
15812     {
15813       if (!strcmp ((char *) s, "sha1"))
15814         key_id[0] = HMAC_SHA_1_96;
15815       else if (!strcmp ((char *) s, "sha256"))
15816         key_id[0] = HMAC_SHA_256_128;
15817       else
15818         {
15819           clib_warning ("invalid key_id: '%s'", s);
15820           key_id[0] = HMAC_NO_KEY;
15821         }
15822     }
15823   else
15824     return 0;
15825
15826   vec_free (s);
15827   return 1;
15828 }
15829
15830 static int
15831 api_one_add_del_local_eid (vat_main_t * vam)
15832 {
15833   unformat_input_t *input = vam->input;
15834   vl_api_one_add_del_local_eid_t *mp;
15835   u8 is_add = 1;
15836   u8 eid_set = 0;
15837   lisp_eid_vat_t _eid, *eid = &_eid;
15838   u8 *locator_set_name = 0;
15839   u8 locator_set_name_set = 0;
15840   u32 vni = 0;
15841   u16 key_id = 0;
15842   u8 *key = 0;
15843   int ret;
15844
15845   /* Parse args required to build the message */
15846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15847     {
15848       if (unformat (input, "del"))
15849         {
15850           is_add = 0;
15851         }
15852       else if (unformat (input, "vni %d", &vni))
15853         {
15854           ;
15855         }
15856       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15857         {
15858           eid_set = 1;
15859         }
15860       else if (unformat (input, "locator-set %s", &locator_set_name))
15861         {
15862           locator_set_name_set = 1;
15863         }
15864       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15865         ;
15866       else if (unformat (input, "secret-key %_%v%_", &key))
15867         ;
15868       else
15869         break;
15870     }
15871
15872   if (locator_set_name_set == 0)
15873     {
15874       errmsg ("missing locator-set name");
15875       return -99;
15876     }
15877
15878   if (0 == eid_set)
15879     {
15880       errmsg ("EID address not set!");
15881       vec_free (locator_set_name);
15882       return -99;
15883     }
15884
15885   if (key && (0 == key_id))
15886     {
15887       errmsg ("invalid key_id!");
15888       return -99;
15889     }
15890
15891   if (vec_len (key) > 64)
15892     {
15893       errmsg ("key too long");
15894       vec_free (key);
15895       return -99;
15896     }
15897
15898   if (vec_len (locator_set_name) > 64)
15899     {
15900       errmsg ("locator-set name too long");
15901       vec_free (locator_set_name);
15902       return -99;
15903     }
15904   vec_add1 (locator_set_name, 0);
15905
15906   /* Construct the API message */
15907   M (ONE_ADD_DEL_LOCAL_EID, mp);
15908
15909   mp->is_add = is_add;
15910   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15911   mp->eid_type = eid->type;
15912   mp->prefix_len = eid->len;
15913   mp->vni = clib_host_to_net_u32 (vni);
15914   mp->key_id = clib_host_to_net_u16 (key_id);
15915   clib_memcpy (mp->locator_set_name, locator_set_name,
15916                vec_len (locator_set_name));
15917   clib_memcpy (mp->key, key, vec_len (key));
15918
15919   vec_free (locator_set_name);
15920   vec_free (key);
15921
15922   /* send it... */
15923   S (mp);
15924
15925   /* Wait for a reply... */
15926   W (ret);
15927   return ret;
15928 }
15929
15930 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15931
15932 static int
15933 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15934 {
15935   u32 dp_table = 0, vni = 0;;
15936   unformat_input_t *input = vam->input;
15937   vl_api_gpe_add_del_fwd_entry_t *mp;
15938   u8 is_add = 1;
15939   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15940   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15941   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15942   u32 action = ~0, w;
15943   ip4_address_t rmt_rloc4, lcl_rloc4;
15944   ip6_address_t rmt_rloc6, lcl_rloc6;
15945   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15946   int ret;
15947
15948   clib_memset (&rloc, 0, sizeof (rloc));
15949
15950   /* Parse args required to build the message */
15951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15952     {
15953       if (unformat (input, "del"))
15954         is_add = 0;
15955       else if (unformat (input, "add"))
15956         is_add = 1;
15957       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15958         {
15959           rmt_eid_set = 1;
15960         }
15961       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15962         {
15963           lcl_eid_set = 1;
15964         }
15965       else if (unformat (input, "vrf %d", &dp_table))
15966         ;
15967       else if (unformat (input, "bd %d", &dp_table))
15968         ;
15969       else if (unformat (input, "vni %d", &vni))
15970         ;
15971       else if (unformat (input, "w %d", &w))
15972         {
15973           if (!curr_rloc)
15974             {
15975               errmsg ("No RLOC configured for setting priority/weight!");
15976               return -99;
15977             }
15978           curr_rloc->weight = w;
15979         }
15980       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15981                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15982         {
15983           rloc.is_ip4 = 1;
15984
15985           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15986           rloc.weight = 0;
15987           vec_add1 (lcl_locs, rloc);
15988
15989           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15990           vec_add1 (rmt_locs, rloc);
15991           /* weight saved in rmt loc */
15992           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15993         }
15994       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15995                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15996         {
15997           rloc.is_ip4 = 0;
15998           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15999           rloc.weight = 0;
16000           vec_add1 (lcl_locs, rloc);
16001
16002           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16003           vec_add1 (rmt_locs, rloc);
16004           /* weight saved in rmt loc */
16005           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16006         }
16007       else if (unformat (input, "action %d", &action))
16008         {
16009           ;
16010         }
16011       else
16012         {
16013           clib_warning ("parse error '%U'", format_unformat_error, input);
16014           return -99;
16015         }
16016     }
16017
16018   if (!rmt_eid_set)
16019     {
16020       errmsg ("remote eid addresses not set");
16021       return -99;
16022     }
16023
16024   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16025     {
16026       errmsg ("eid types don't match");
16027       return -99;
16028     }
16029
16030   if (0 == rmt_locs && (u32) ~ 0 == action)
16031     {
16032       errmsg ("action not set for negative mapping");
16033       return -99;
16034     }
16035
16036   /* Construct the API message */
16037   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16038       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16039
16040   mp->is_add = is_add;
16041   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16042   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16043   mp->eid_type = rmt_eid->type;
16044   mp->dp_table = clib_host_to_net_u32 (dp_table);
16045   mp->vni = clib_host_to_net_u32 (vni);
16046   mp->rmt_len = rmt_eid->len;
16047   mp->lcl_len = lcl_eid->len;
16048   mp->action = action;
16049
16050   if (0 != rmt_locs && 0 != lcl_locs)
16051     {
16052       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16053       clib_memcpy (mp->locs, lcl_locs,
16054                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16055
16056       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16057       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16058                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16059     }
16060   vec_free (lcl_locs);
16061   vec_free (rmt_locs);
16062
16063   /* send it... */
16064   S (mp);
16065
16066   /* Wait for a reply... */
16067   W (ret);
16068   return ret;
16069 }
16070
16071 static int
16072 api_one_add_del_map_server (vat_main_t * vam)
16073 {
16074   unformat_input_t *input = vam->input;
16075   vl_api_one_add_del_map_server_t *mp;
16076   u8 is_add = 1;
16077   u8 ipv4_set = 0;
16078   u8 ipv6_set = 0;
16079   ip4_address_t ipv4;
16080   ip6_address_t ipv6;
16081   int ret;
16082
16083   /* Parse args required to build the message */
16084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16085     {
16086       if (unformat (input, "del"))
16087         {
16088           is_add = 0;
16089         }
16090       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16091         {
16092           ipv4_set = 1;
16093         }
16094       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16095         {
16096           ipv6_set = 1;
16097         }
16098       else
16099         break;
16100     }
16101
16102   if (ipv4_set && ipv6_set)
16103     {
16104       errmsg ("both eid v4 and v6 addresses set");
16105       return -99;
16106     }
16107
16108   if (!ipv4_set && !ipv6_set)
16109     {
16110       errmsg ("eid addresses not set");
16111       return -99;
16112     }
16113
16114   /* Construct the API message */
16115   M (ONE_ADD_DEL_MAP_SERVER, mp);
16116
16117   mp->is_add = is_add;
16118   if (ipv6_set)
16119     {
16120       mp->is_ipv6 = 1;
16121       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16122     }
16123   else
16124     {
16125       mp->is_ipv6 = 0;
16126       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16127     }
16128
16129   /* send it... */
16130   S (mp);
16131
16132   /* Wait for a reply... */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 #define api_lisp_add_del_map_server api_one_add_del_map_server
16138
16139 static int
16140 api_one_add_del_map_resolver (vat_main_t * vam)
16141 {
16142   unformat_input_t *input = vam->input;
16143   vl_api_one_add_del_map_resolver_t *mp;
16144   u8 is_add = 1;
16145   u8 ipv4_set = 0;
16146   u8 ipv6_set = 0;
16147   ip4_address_t ipv4;
16148   ip6_address_t ipv6;
16149   int ret;
16150
16151   /* Parse args required to build the message */
16152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16153     {
16154       if (unformat (input, "del"))
16155         {
16156           is_add = 0;
16157         }
16158       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16159         {
16160           ipv4_set = 1;
16161         }
16162       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16163         {
16164           ipv6_set = 1;
16165         }
16166       else
16167         break;
16168     }
16169
16170   if (ipv4_set && ipv6_set)
16171     {
16172       errmsg ("both eid v4 and v6 addresses set");
16173       return -99;
16174     }
16175
16176   if (!ipv4_set && !ipv6_set)
16177     {
16178       errmsg ("eid addresses not set");
16179       return -99;
16180     }
16181
16182   /* Construct the API message */
16183   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16184
16185   mp->is_add = is_add;
16186   if (ipv6_set)
16187     {
16188       mp->is_ipv6 = 1;
16189       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16190     }
16191   else
16192     {
16193       mp->is_ipv6 = 0;
16194       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16195     }
16196
16197   /* send it... */
16198   S (mp);
16199
16200   /* Wait for a reply... */
16201   W (ret);
16202   return ret;
16203 }
16204
16205 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16206
16207 static int
16208 api_lisp_gpe_enable_disable (vat_main_t * vam)
16209 {
16210   unformat_input_t *input = vam->input;
16211   vl_api_gpe_enable_disable_t *mp;
16212   u8 is_set = 0;
16213   u8 is_en = 1;
16214   int ret;
16215
16216   /* Parse args required to build the message */
16217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16218     {
16219       if (unformat (input, "enable"))
16220         {
16221           is_set = 1;
16222           is_en = 1;
16223         }
16224       else if (unformat (input, "disable"))
16225         {
16226           is_set = 1;
16227           is_en = 0;
16228         }
16229       else
16230         break;
16231     }
16232
16233   if (is_set == 0)
16234     {
16235       errmsg ("Value not set");
16236       return -99;
16237     }
16238
16239   /* Construct the API message */
16240   M (GPE_ENABLE_DISABLE, mp);
16241
16242   mp->is_en = is_en;
16243
16244   /* send it... */
16245   S (mp);
16246
16247   /* Wait for a reply... */
16248   W (ret);
16249   return ret;
16250 }
16251
16252 static int
16253 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16254 {
16255   unformat_input_t *input = vam->input;
16256   vl_api_one_rloc_probe_enable_disable_t *mp;
16257   u8 is_set = 0;
16258   u8 is_en = 0;
16259   int ret;
16260
16261   /* Parse args required to build the message */
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "enable"))
16265         {
16266           is_set = 1;
16267           is_en = 1;
16268         }
16269       else if (unformat (input, "disable"))
16270         is_set = 1;
16271       else
16272         break;
16273     }
16274
16275   if (!is_set)
16276     {
16277       errmsg ("Value not set");
16278       return -99;
16279     }
16280
16281   /* Construct the API message */
16282   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16283
16284   mp->is_enabled = is_en;
16285
16286   /* send it... */
16287   S (mp);
16288
16289   /* Wait for a reply... */
16290   W (ret);
16291   return ret;
16292 }
16293
16294 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16295
16296 static int
16297 api_one_map_register_enable_disable (vat_main_t * vam)
16298 {
16299   unformat_input_t *input = vam->input;
16300   vl_api_one_map_register_enable_disable_t *mp;
16301   u8 is_set = 0;
16302   u8 is_en = 0;
16303   int ret;
16304
16305   /* Parse args required to build the message */
16306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (input, "enable"))
16309         {
16310           is_set = 1;
16311           is_en = 1;
16312         }
16313       else if (unformat (input, "disable"))
16314         is_set = 1;
16315       else
16316         break;
16317     }
16318
16319   if (!is_set)
16320     {
16321       errmsg ("Value not set");
16322       return -99;
16323     }
16324
16325   /* Construct the API message */
16326   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16327
16328   mp->is_enabled = is_en;
16329
16330   /* send it... */
16331   S (mp);
16332
16333   /* Wait for a reply... */
16334   W (ret);
16335   return ret;
16336 }
16337
16338 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16339
16340 static int
16341 api_one_enable_disable (vat_main_t * vam)
16342 {
16343   unformat_input_t *input = vam->input;
16344   vl_api_one_enable_disable_t *mp;
16345   u8 is_set = 0;
16346   u8 is_en = 0;
16347   int ret;
16348
16349   /* Parse args required to build the message */
16350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16351     {
16352       if (unformat (input, "enable"))
16353         {
16354           is_set = 1;
16355           is_en = 1;
16356         }
16357       else if (unformat (input, "disable"))
16358         {
16359           is_set = 1;
16360         }
16361       else
16362         break;
16363     }
16364
16365   if (!is_set)
16366     {
16367       errmsg ("Value not set");
16368       return -99;
16369     }
16370
16371   /* Construct the API message */
16372   M (ONE_ENABLE_DISABLE, mp);
16373
16374   mp->is_en = is_en;
16375
16376   /* send it... */
16377   S (mp);
16378
16379   /* Wait for a reply... */
16380   W (ret);
16381   return ret;
16382 }
16383
16384 #define api_lisp_enable_disable api_one_enable_disable
16385
16386 static int
16387 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16388 {
16389   unformat_input_t *input = vam->input;
16390   vl_api_one_enable_disable_xtr_mode_t *mp;
16391   u8 is_set = 0;
16392   u8 is_en = 0;
16393   int ret;
16394
16395   /* Parse args required to build the message */
16396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16397     {
16398       if (unformat (input, "enable"))
16399         {
16400           is_set = 1;
16401           is_en = 1;
16402         }
16403       else if (unformat (input, "disable"))
16404         {
16405           is_set = 1;
16406         }
16407       else
16408         break;
16409     }
16410
16411   if (!is_set)
16412     {
16413       errmsg ("Value not set");
16414       return -99;
16415     }
16416
16417   /* Construct the API message */
16418   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16419
16420   mp->is_en = is_en;
16421
16422   /* send it... */
16423   S (mp);
16424
16425   /* Wait for a reply... */
16426   W (ret);
16427   return ret;
16428 }
16429
16430 static int
16431 api_one_show_xtr_mode (vat_main_t * vam)
16432 {
16433   vl_api_one_show_xtr_mode_t *mp;
16434   int ret;
16435
16436   /* Construct the API message */
16437   M (ONE_SHOW_XTR_MODE, mp);
16438
16439   /* send it... */
16440   S (mp);
16441
16442   /* Wait for a reply... */
16443   W (ret);
16444   return ret;
16445 }
16446
16447 static int
16448 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16449 {
16450   unformat_input_t *input = vam->input;
16451   vl_api_one_enable_disable_pitr_mode_t *mp;
16452   u8 is_set = 0;
16453   u8 is_en = 0;
16454   int ret;
16455
16456   /* Parse args required to build the message */
16457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16458     {
16459       if (unformat (input, "enable"))
16460         {
16461           is_set = 1;
16462           is_en = 1;
16463         }
16464       else if (unformat (input, "disable"))
16465         {
16466           is_set = 1;
16467         }
16468       else
16469         break;
16470     }
16471
16472   if (!is_set)
16473     {
16474       errmsg ("Value not set");
16475       return -99;
16476     }
16477
16478   /* Construct the API message */
16479   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16480
16481   mp->is_en = is_en;
16482
16483   /* send it... */
16484   S (mp);
16485
16486   /* Wait for a reply... */
16487   W (ret);
16488   return ret;
16489 }
16490
16491 static int
16492 api_one_show_pitr_mode (vat_main_t * vam)
16493 {
16494   vl_api_one_show_pitr_mode_t *mp;
16495   int ret;
16496
16497   /* Construct the API message */
16498   M (ONE_SHOW_PITR_MODE, mp);
16499
16500   /* send it... */
16501   S (mp);
16502
16503   /* Wait for a reply... */
16504   W (ret);
16505   return ret;
16506 }
16507
16508 static int
16509 api_one_enable_disable_petr_mode (vat_main_t * vam)
16510 {
16511   unformat_input_t *input = vam->input;
16512   vl_api_one_enable_disable_petr_mode_t *mp;
16513   u8 is_set = 0;
16514   u8 is_en = 0;
16515   int ret;
16516
16517   /* Parse args required to build the message */
16518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16519     {
16520       if (unformat (input, "enable"))
16521         {
16522           is_set = 1;
16523           is_en = 1;
16524         }
16525       else if (unformat (input, "disable"))
16526         {
16527           is_set = 1;
16528         }
16529       else
16530         break;
16531     }
16532
16533   if (!is_set)
16534     {
16535       errmsg ("Value not set");
16536       return -99;
16537     }
16538
16539   /* Construct the API message */
16540   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16541
16542   mp->is_en = is_en;
16543
16544   /* send it... */
16545   S (mp);
16546
16547   /* Wait for a reply... */
16548   W (ret);
16549   return ret;
16550 }
16551
16552 static int
16553 api_one_show_petr_mode (vat_main_t * vam)
16554 {
16555   vl_api_one_show_petr_mode_t *mp;
16556   int ret;
16557
16558   /* Construct the API message */
16559   M (ONE_SHOW_PETR_MODE, mp);
16560
16561   /* send it... */
16562   S (mp);
16563
16564   /* Wait for a reply... */
16565   W (ret);
16566   return ret;
16567 }
16568
16569 static int
16570 api_show_one_map_register_state (vat_main_t * vam)
16571 {
16572   vl_api_show_one_map_register_state_t *mp;
16573   int ret;
16574
16575   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16576
16577   /* send */
16578   S (mp);
16579
16580   /* wait for reply */
16581   W (ret);
16582   return ret;
16583 }
16584
16585 #define api_show_lisp_map_register_state api_show_one_map_register_state
16586
16587 static int
16588 api_show_one_rloc_probe_state (vat_main_t * vam)
16589 {
16590   vl_api_show_one_rloc_probe_state_t *mp;
16591   int ret;
16592
16593   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16594
16595   /* send */
16596   S (mp);
16597
16598   /* wait for reply */
16599   W (ret);
16600   return ret;
16601 }
16602
16603 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16604
16605 static int
16606 api_one_add_del_ndp_entry (vat_main_t * vam)
16607 {
16608   vl_api_one_add_del_ndp_entry_t *mp;
16609   unformat_input_t *input = vam->input;
16610   u8 is_add = 1;
16611   u8 mac_set = 0;
16612   u8 bd_set = 0;
16613   u8 ip_set = 0;
16614   u8 mac[6] = { 0, };
16615   u8 ip6[16] = { 0, };
16616   u32 bd = ~0;
16617   int ret;
16618
16619   /* Parse args required to build the message */
16620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16621     {
16622       if (unformat (input, "del"))
16623         is_add = 0;
16624       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16625         mac_set = 1;
16626       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16627         ip_set = 1;
16628       else if (unformat (input, "bd %d", &bd))
16629         bd_set = 1;
16630       else
16631         {
16632           errmsg ("parse error '%U'", format_unformat_error, input);
16633           return -99;
16634         }
16635     }
16636
16637   if (!bd_set || !ip_set || (!mac_set && is_add))
16638     {
16639       errmsg ("Missing BD, IP or MAC!");
16640       return -99;
16641     }
16642
16643   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16644   mp->is_add = is_add;
16645   clib_memcpy (mp->mac, mac, 6);
16646   mp->bd = clib_host_to_net_u32 (bd);
16647   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16648
16649   /* send */
16650   S (mp);
16651
16652   /* wait for reply */
16653   W (ret);
16654   return ret;
16655 }
16656
16657 static int
16658 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16659 {
16660   vl_api_one_add_del_l2_arp_entry_t *mp;
16661   unformat_input_t *input = vam->input;
16662   u8 is_add = 1;
16663   u8 mac_set = 0;
16664   u8 bd_set = 0;
16665   u8 ip_set = 0;
16666   u8 mac[6] = { 0, };
16667   u32 ip4 = 0, bd = ~0;
16668   int ret;
16669
16670   /* Parse args required to build the message */
16671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16672     {
16673       if (unformat (input, "del"))
16674         is_add = 0;
16675       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16676         mac_set = 1;
16677       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16678         ip_set = 1;
16679       else if (unformat (input, "bd %d", &bd))
16680         bd_set = 1;
16681       else
16682         {
16683           errmsg ("parse error '%U'", format_unformat_error, input);
16684           return -99;
16685         }
16686     }
16687
16688   if (!bd_set || !ip_set || (!mac_set && is_add))
16689     {
16690       errmsg ("Missing BD, IP or MAC!");
16691       return -99;
16692     }
16693
16694   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16695   mp->is_add = is_add;
16696   clib_memcpy (mp->mac, mac, 6);
16697   mp->bd = clib_host_to_net_u32 (bd);
16698   mp->ip4 = ip4;
16699
16700   /* send */
16701   S (mp);
16702
16703   /* wait for reply */
16704   W (ret);
16705   return ret;
16706 }
16707
16708 static int
16709 api_one_ndp_bd_get (vat_main_t * vam)
16710 {
16711   vl_api_one_ndp_bd_get_t *mp;
16712   int ret;
16713
16714   M (ONE_NDP_BD_GET, mp);
16715
16716   /* send */
16717   S (mp);
16718
16719   /* wait for reply */
16720   W (ret);
16721   return ret;
16722 }
16723
16724 static int
16725 api_one_ndp_entries_get (vat_main_t * vam)
16726 {
16727   vl_api_one_ndp_entries_get_t *mp;
16728   unformat_input_t *input = vam->input;
16729   u8 bd_set = 0;
16730   u32 bd = ~0;
16731   int ret;
16732
16733   /* Parse args required to build the message */
16734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16735     {
16736       if (unformat (input, "bd %d", &bd))
16737         bd_set = 1;
16738       else
16739         {
16740           errmsg ("parse error '%U'", format_unformat_error, input);
16741           return -99;
16742         }
16743     }
16744
16745   if (!bd_set)
16746     {
16747       errmsg ("Expected bridge domain!");
16748       return -99;
16749     }
16750
16751   M (ONE_NDP_ENTRIES_GET, mp);
16752   mp->bd = clib_host_to_net_u32 (bd);
16753
16754   /* send */
16755   S (mp);
16756
16757   /* wait for reply */
16758   W (ret);
16759   return ret;
16760 }
16761
16762 static int
16763 api_one_l2_arp_bd_get (vat_main_t * vam)
16764 {
16765   vl_api_one_l2_arp_bd_get_t *mp;
16766   int ret;
16767
16768   M (ONE_L2_ARP_BD_GET, mp);
16769
16770   /* send */
16771   S (mp);
16772
16773   /* wait for reply */
16774   W (ret);
16775   return ret;
16776 }
16777
16778 static int
16779 api_one_l2_arp_entries_get (vat_main_t * vam)
16780 {
16781   vl_api_one_l2_arp_entries_get_t *mp;
16782   unformat_input_t *input = vam->input;
16783   u8 bd_set = 0;
16784   u32 bd = ~0;
16785   int ret;
16786
16787   /* Parse args required to build the message */
16788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16789     {
16790       if (unformat (input, "bd %d", &bd))
16791         bd_set = 1;
16792       else
16793         {
16794           errmsg ("parse error '%U'", format_unformat_error, input);
16795           return -99;
16796         }
16797     }
16798
16799   if (!bd_set)
16800     {
16801       errmsg ("Expected bridge domain!");
16802       return -99;
16803     }
16804
16805   M (ONE_L2_ARP_ENTRIES_GET, mp);
16806   mp->bd = clib_host_to_net_u32 (bd);
16807
16808   /* send */
16809   S (mp);
16810
16811   /* wait for reply */
16812   W (ret);
16813   return ret;
16814 }
16815
16816 static int
16817 api_one_stats_enable_disable (vat_main_t * vam)
16818 {
16819   vl_api_one_stats_enable_disable_t *mp;
16820   unformat_input_t *input = vam->input;
16821   u8 is_set = 0;
16822   u8 is_en = 0;
16823   int ret;
16824
16825   /* Parse args required to build the message */
16826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16827     {
16828       if (unformat (input, "enable"))
16829         {
16830           is_set = 1;
16831           is_en = 1;
16832         }
16833       else if (unformat (input, "disable"))
16834         {
16835           is_set = 1;
16836         }
16837       else
16838         break;
16839     }
16840
16841   if (!is_set)
16842     {
16843       errmsg ("Value not set");
16844       return -99;
16845     }
16846
16847   M (ONE_STATS_ENABLE_DISABLE, mp);
16848   mp->is_en = is_en;
16849
16850   /* send */
16851   S (mp);
16852
16853   /* wait for reply */
16854   W (ret);
16855   return ret;
16856 }
16857
16858 static int
16859 api_show_one_stats_enable_disable (vat_main_t * vam)
16860 {
16861   vl_api_show_one_stats_enable_disable_t *mp;
16862   int ret;
16863
16864   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16865
16866   /* send */
16867   S (mp);
16868
16869   /* wait for reply */
16870   W (ret);
16871   return ret;
16872 }
16873
16874 static int
16875 api_show_one_map_request_mode (vat_main_t * vam)
16876 {
16877   vl_api_show_one_map_request_mode_t *mp;
16878   int ret;
16879
16880   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16881
16882   /* send */
16883   S (mp);
16884
16885   /* wait for reply */
16886   W (ret);
16887   return ret;
16888 }
16889
16890 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16891
16892 static int
16893 api_one_map_request_mode (vat_main_t * vam)
16894 {
16895   unformat_input_t *input = vam->input;
16896   vl_api_one_map_request_mode_t *mp;
16897   u8 mode = 0;
16898   int ret;
16899
16900   /* Parse args required to build the message */
16901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (input, "dst-only"))
16904         mode = 0;
16905       else if (unformat (input, "src-dst"))
16906         mode = 1;
16907       else
16908         {
16909           errmsg ("parse error '%U'", format_unformat_error, input);
16910           return -99;
16911         }
16912     }
16913
16914   M (ONE_MAP_REQUEST_MODE, mp);
16915
16916   mp->mode = mode;
16917
16918   /* send */
16919   S (mp);
16920
16921   /* wait for reply */
16922   W (ret);
16923   return ret;
16924 }
16925
16926 #define api_lisp_map_request_mode api_one_map_request_mode
16927
16928 /**
16929  * Enable/disable ONE proxy ITR.
16930  *
16931  * @param vam vpp API test context
16932  * @return return code
16933  */
16934 static int
16935 api_one_pitr_set_locator_set (vat_main_t * vam)
16936 {
16937   u8 ls_name_set = 0;
16938   unformat_input_t *input = vam->input;
16939   vl_api_one_pitr_set_locator_set_t *mp;
16940   u8 is_add = 1;
16941   u8 *ls_name = 0;
16942   int ret;
16943
16944   /* Parse args required to build the message */
16945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16946     {
16947       if (unformat (input, "del"))
16948         is_add = 0;
16949       else if (unformat (input, "locator-set %s", &ls_name))
16950         ls_name_set = 1;
16951       else
16952         {
16953           errmsg ("parse error '%U'", format_unformat_error, input);
16954           return -99;
16955         }
16956     }
16957
16958   if (!ls_name_set)
16959     {
16960       errmsg ("locator-set name not set!");
16961       return -99;
16962     }
16963
16964   M (ONE_PITR_SET_LOCATOR_SET, mp);
16965
16966   mp->is_add = is_add;
16967   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16968   vec_free (ls_name);
16969
16970   /* send */
16971   S (mp);
16972
16973   /* wait for reply */
16974   W (ret);
16975   return ret;
16976 }
16977
16978 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16979
16980 static int
16981 api_one_nsh_set_locator_set (vat_main_t * vam)
16982 {
16983   u8 ls_name_set = 0;
16984   unformat_input_t *input = vam->input;
16985   vl_api_one_nsh_set_locator_set_t *mp;
16986   u8 is_add = 1;
16987   u8 *ls_name = 0;
16988   int ret;
16989
16990   /* Parse args required to build the message */
16991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16992     {
16993       if (unformat (input, "del"))
16994         is_add = 0;
16995       else if (unformat (input, "ls %s", &ls_name))
16996         ls_name_set = 1;
16997       else
16998         {
16999           errmsg ("parse error '%U'", format_unformat_error, input);
17000           return -99;
17001         }
17002     }
17003
17004   if (!ls_name_set && is_add)
17005     {
17006       errmsg ("locator-set name not set!");
17007       return -99;
17008     }
17009
17010   M (ONE_NSH_SET_LOCATOR_SET, mp);
17011
17012   mp->is_add = is_add;
17013   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17014   vec_free (ls_name);
17015
17016   /* send */
17017   S (mp);
17018
17019   /* wait for reply */
17020   W (ret);
17021   return ret;
17022 }
17023
17024 static int
17025 api_show_one_pitr (vat_main_t * vam)
17026 {
17027   vl_api_show_one_pitr_t *mp;
17028   int ret;
17029
17030   if (!vam->json_output)
17031     {
17032       print (vam->ofp, "%=20s", "lisp status:");
17033     }
17034
17035   M (SHOW_ONE_PITR, mp);
17036   /* send it... */
17037   S (mp);
17038
17039   /* Wait for a reply... */
17040   W (ret);
17041   return ret;
17042 }
17043
17044 #define api_show_lisp_pitr api_show_one_pitr
17045
17046 static int
17047 api_one_use_petr (vat_main_t * vam)
17048 {
17049   unformat_input_t *input = vam->input;
17050   vl_api_one_use_petr_t *mp;
17051   u8 is_add = 0;
17052   ip_address_t ip;
17053   int ret;
17054
17055   clib_memset (&ip, 0, sizeof (ip));
17056
17057   /* Parse args required to build the message */
17058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17059     {
17060       if (unformat (input, "disable"))
17061         is_add = 0;
17062       else
17063         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17064         {
17065           is_add = 1;
17066           ip_addr_version (&ip) = IP4;
17067         }
17068       else
17069         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17070         {
17071           is_add = 1;
17072           ip_addr_version (&ip) = IP6;
17073         }
17074       else
17075         {
17076           errmsg ("parse error '%U'", format_unformat_error, input);
17077           return -99;
17078         }
17079     }
17080
17081   M (ONE_USE_PETR, mp);
17082
17083   mp->is_add = is_add;
17084   if (is_add)
17085     {
17086       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17087       if (mp->is_ip4)
17088         clib_memcpy (mp->address, &ip, 4);
17089       else
17090         clib_memcpy (mp->address, &ip, 16);
17091     }
17092
17093   /* send */
17094   S (mp);
17095
17096   /* wait for reply */
17097   W (ret);
17098   return ret;
17099 }
17100
17101 #define api_lisp_use_petr api_one_use_petr
17102
17103 static int
17104 api_show_one_nsh_mapping (vat_main_t * vam)
17105 {
17106   vl_api_show_one_use_petr_t *mp;
17107   int ret;
17108
17109   if (!vam->json_output)
17110     {
17111       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17112     }
17113
17114   M (SHOW_ONE_NSH_MAPPING, mp);
17115   /* send it... */
17116   S (mp);
17117
17118   /* Wait for a reply... */
17119   W (ret);
17120   return ret;
17121 }
17122
17123 static int
17124 api_show_one_use_petr (vat_main_t * vam)
17125 {
17126   vl_api_show_one_use_petr_t *mp;
17127   int ret;
17128
17129   if (!vam->json_output)
17130     {
17131       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17132     }
17133
17134   M (SHOW_ONE_USE_PETR, mp);
17135   /* send it... */
17136   S (mp);
17137
17138   /* Wait for a reply... */
17139   W (ret);
17140   return ret;
17141 }
17142
17143 #define api_show_lisp_use_petr api_show_one_use_petr
17144
17145 /**
17146  * Add/delete mapping between vni and vrf
17147  */
17148 static int
17149 api_one_eid_table_add_del_map (vat_main_t * vam)
17150 {
17151   unformat_input_t *input = vam->input;
17152   vl_api_one_eid_table_add_del_map_t *mp;
17153   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17154   u32 vni, vrf, bd_index;
17155   int ret;
17156
17157   /* Parse args required to build the message */
17158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17159     {
17160       if (unformat (input, "del"))
17161         is_add = 0;
17162       else if (unformat (input, "vrf %d", &vrf))
17163         vrf_set = 1;
17164       else if (unformat (input, "bd_index %d", &bd_index))
17165         bd_index_set = 1;
17166       else if (unformat (input, "vni %d", &vni))
17167         vni_set = 1;
17168       else
17169         break;
17170     }
17171
17172   if (!vni_set || (!vrf_set && !bd_index_set))
17173     {
17174       errmsg ("missing arguments!");
17175       return -99;
17176     }
17177
17178   if (vrf_set && bd_index_set)
17179     {
17180       errmsg ("error: both vrf and bd entered!");
17181       return -99;
17182     }
17183
17184   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17185
17186   mp->is_add = is_add;
17187   mp->vni = htonl (vni);
17188   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17189   mp->is_l2 = bd_index_set;
17190
17191   /* send */
17192   S (mp);
17193
17194   /* wait for reply */
17195   W (ret);
17196   return ret;
17197 }
17198
17199 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17200
17201 uword
17202 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17203 {
17204   u32 *action = va_arg (*args, u32 *);
17205   u8 *s = 0;
17206
17207   if (unformat (input, "%s", &s))
17208     {
17209       if (!strcmp ((char *) s, "no-action"))
17210         action[0] = 0;
17211       else if (!strcmp ((char *) s, "natively-forward"))
17212         action[0] = 1;
17213       else if (!strcmp ((char *) s, "send-map-request"))
17214         action[0] = 2;
17215       else if (!strcmp ((char *) s, "drop"))
17216         action[0] = 3;
17217       else
17218         {
17219           clib_warning ("invalid action: '%s'", s);
17220           action[0] = 3;
17221         }
17222     }
17223   else
17224     return 0;
17225
17226   vec_free (s);
17227   return 1;
17228 }
17229
17230 /**
17231  * Add/del remote mapping to/from ONE control plane
17232  *
17233  * @param vam vpp API test context
17234  * @return return code
17235  */
17236 static int
17237 api_one_add_del_remote_mapping (vat_main_t * vam)
17238 {
17239   unformat_input_t *input = vam->input;
17240   vl_api_one_add_del_remote_mapping_t *mp;
17241   u32 vni = 0;
17242   lisp_eid_vat_t _eid, *eid = &_eid;
17243   lisp_eid_vat_t _seid, *seid = &_seid;
17244   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17245   u32 action = ~0, p, w, data_len;
17246   ip4_address_t rloc4;
17247   ip6_address_t rloc6;
17248   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17249   int ret;
17250
17251   clib_memset (&rloc, 0, sizeof (rloc));
17252
17253   /* Parse args required to build the message */
17254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17255     {
17256       if (unformat (input, "del-all"))
17257         {
17258           del_all = 1;
17259         }
17260       else if (unformat (input, "del"))
17261         {
17262           is_add = 0;
17263         }
17264       else if (unformat (input, "add"))
17265         {
17266           is_add = 1;
17267         }
17268       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17269         {
17270           eid_set = 1;
17271         }
17272       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17273         {
17274           seid_set = 1;
17275         }
17276       else if (unformat (input, "vni %d", &vni))
17277         {
17278           ;
17279         }
17280       else if (unformat (input, "p %d w %d", &p, &w))
17281         {
17282           if (!curr_rloc)
17283             {
17284               errmsg ("No RLOC configured for setting priority/weight!");
17285               return -99;
17286             }
17287           curr_rloc->priority = p;
17288           curr_rloc->weight = w;
17289         }
17290       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17291         {
17292           rloc.is_ip4 = 1;
17293           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17294           vec_add1 (rlocs, rloc);
17295           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17296         }
17297       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17298         {
17299           rloc.is_ip4 = 0;
17300           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17301           vec_add1 (rlocs, rloc);
17302           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17303         }
17304       else if (unformat (input, "action %U",
17305                          unformat_negative_mapping_action, &action))
17306         {
17307           ;
17308         }
17309       else
17310         {
17311           clib_warning ("parse error '%U'", format_unformat_error, input);
17312           return -99;
17313         }
17314     }
17315
17316   if (0 == eid_set)
17317     {
17318       errmsg ("missing params!");
17319       return -99;
17320     }
17321
17322   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17323     {
17324       errmsg ("no action set for negative map-reply!");
17325       return -99;
17326     }
17327
17328   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17329
17330   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17331   mp->is_add = is_add;
17332   mp->vni = htonl (vni);
17333   mp->action = (u8) action;
17334   mp->is_src_dst = seid_set;
17335   mp->eid_len = eid->len;
17336   mp->seid_len = seid->len;
17337   mp->del_all = del_all;
17338   mp->eid_type = eid->type;
17339   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17340   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17341
17342   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17343   clib_memcpy (mp->rlocs, rlocs, data_len);
17344   vec_free (rlocs);
17345
17346   /* send it... */
17347   S (mp);
17348
17349   /* Wait for a reply... */
17350   W (ret);
17351   return ret;
17352 }
17353
17354 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17355
17356 /**
17357  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17358  * forwarding entries in data-plane accordingly.
17359  *
17360  * @param vam vpp API test context
17361  * @return return code
17362  */
17363 static int
17364 api_one_add_del_adjacency (vat_main_t * vam)
17365 {
17366   unformat_input_t *input = vam->input;
17367   vl_api_one_add_del_adjacency_t *mp;
17368   u32 vni = 0;
17369   ip4_address_t leid4, reid4;
17370   ip6_address_t leid6, reid6;
17371   u8 reid_mac[6] = { 0 };
17372   u8 leid_mac[6] = { 0 };
17373   u8 reid_type, leid_type;
17374   u32 leid_len = 0, reid_len = 0, len;
17375   u8 is_add = 1;
17376   int ret;
17377
17378   leid_type = reid_type = (u8) ~ 0;
17379
17380   /* Parse args required to build the message */
17381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17382     {
17383       if (unformat (input, "del"))
17384         {
17385           is_add = 0;
17386         }
17387       else if (unformat (input, "add"))
17388         {
17389           is_add = 1;
17390         }
17391       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17392                          &reid4, &len))
17393         {
17394           reid_type = 0;        /* ipv4 */
17395           reid_len = len;
17396         }
17397       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17398                          &reid6, &len))
17399         {
17400           reid_type = 1;        /* ipv6 */
17401           reid_len = len;
17402         }
17403       else if (unformat (input, "reid %U", unformat_ethernet_address,
17404                          reid_mac))
17405         {
17406           reid_type = 2;        /* mac */
17407         }
17408       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17409                          &leid4, &len))
17410         {
17411           leid_type = 0;        /* ipv4 */
17412           leid_len = len;
17413         }
17414       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17415                          &leid6, &len))
17416         {
17417           leid_type = 1;        /* ipv6 */
17418           leid_len = len;
17419         }
17420       else if (unformat (input, "leid %U", unformat_ethernet_address,
17421                          leid_mac))
17422         {
17423           leid_type = 2;        /* mac */
17424         }
17425       else if (unformat (input, "vni %d", &vni))
17426         {
17427           ;
17428         }
17429       else
17430         {
17431           errmsg ("parse error '%U'", format_unformat_error, input);
17432           return -99;
17433         }
17434     }
17435
17436   if ((u8) ~ 0 == reid_type)
17437     {
17438       errmsg ("missing params!");
17439       return -99;
17440     }
17441
17442   if (leid_type != reid_type)
17443     {
17444       errmsg ("remote and local EIDs are of different types!");
17445       return -99;
17446     }
17447
17448   M (ONE_ADD_DEL_ADJACENCY, mp);
17449   mp->is_add = is_add;
17450   mp->vni = htonl (vni);
17451   mp->leid_len = leid_len;
17452   mp->reid_len = reid_len;
17453   mp->eid_type = reid_type;
17454
17455   switch (mp->eid_type)
17456     {
17457     case 0:
17458       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17459       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17460       break;
17461     case 1:
17462       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17463       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17464       break;
17465     case 2:
17466       clib_memcpy (mp->leid, leid_mac, 6);
17467       clib_memcpy (mp->reid, reid_mac, 6);
17468       break;
17469     default:
17470       errmsg ("unknown EID type %d!", mp->eid_type);
17471       return 0;
17472     }
17473
17474   /* send it... */
17475   S (mp);
17476
17477   /* Wait for a reply... */
17478   W (ret);
17479   return ret;
17480 }
17481
17482 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17483
17484 uword
17485 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17486 {
17487   u32 *mode = va_arg (*args, u32 *);
17488
17489   if (unformat (input, "lisp"))
17490     *mode = 0;
17491   else if (unformat (input, "vxlan"))
17492     *mode = 1;
17493   else
17494     return 0;
17495
17496   return 1;
17497 }
17498
17499 static int
17500 api_gpe_get_encap_mode (vat_main_t * vam)
17501 {
17502   vl_api_gpe_get_encap_mode_t *mp;
17503   int ret;
17504
17505   /* Construct the API message */
17506   M (GPE_GET_ENCAP_MODE, mp);
17507
17508   /* send it... */
17509   S (mp);
17510
17511   /* Wait for a reply... */
17512   W (ret);
17513   return ret;
17514 }
17515
17516 static int
17517 api_gpe_set_encap_mode (vat_main_t * vam)
17518 {
17519   unformat_input_t *input = vam->input;
17520   vl_api_gpe_set_encap_mode_t *mp;
17521   int ret;
17522   u32 mode = 0;
17523
17524   /* Parse args required to build the message */
17525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17526     {
17527       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17528         ;
17529       else
17530         break;
17531     }
17532
17533   /* Construct the API message */
17534   M (GPE_SET_ENCAP_MODE, mp);
17535
17536   mp->mode = mode;
17537
17538   /* send it... */
17539   S (mp);
17540
17541   /* Wait for a reply... */
17542   W (ret);
17543   return ret;
17544 }
17545
17546 static int
17547 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17548 {
17549   unformat_input_t *input = vam->input;
17550   vl_api_gpe_add_del_iface_t *mp;
17551   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17552   u32 dp_table = 0, vni = 0;
17553   int ret;
17554
17555   /* Parse args required to build the message */
17556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17557     {
17558       if (unformat (input, "up"))
17559         {
17560           action_set = 1;
17561           is_add = 1;
17562         }
17563       else if (unformat (input, "down"))
17564         {
17565           action_set = 1;
17566           is_add = 0;
17567         }
17568       else if (unformat (input, "table_id %d", &dp_table))
17569         {
17570           dp_table_set = 1;
17571         }
17572       else if (unformat (input, "bd_id %d", &dp_table))
17573         {
17574           dp_table_set = 1;
17575           is_l2 = 1;
17576         }
17577       else if (unformat (input, "vni %d", &vni))
17578         {
17579           vni_set = 1;
17580         }
17581       else
17582         break;
17583     }
17584
17585   if (action_set == 0)
17586     {
17587       errmsg ("Action not set");
17588       return -99;
17589     }
17590   if (dp_table_set == 0 || vni_set == 0)
17591     {
17592       errmsg ("vni and dp_table must be set");
17593       return -99;
17594     }
17595
17596   /* Construct the API message */
17597   M (GPE_ADD_DEL_IFACE, mp);
17598
17599   mp->is_add = is_add;
17600   mp->dp_table = clib_host_to_net_u32 (dp_table);
17601   mp->is_l2 = is_l2;
17602   mp->vni = clib_host_to_net_u32 (vni);
17603
17604   /* send it... */
17605   S (mp);
17606
17607   /* Wait for a reply... */
17608   W (ret);
17609   return ret;
17610 }
17611
17612 static int
17613 api_one_map_register_fallback_threshold (vat_main_t * vam)
17614 {
17615   unformat_input_t *input = vam->input;
17616   vl_api_one_map_register_fallback_threshold_t *mp;
17617   u32 value = 0;
17618   u8 is_set = 0;
17619   int ret;
17620
17621   /* Parse args required to build the message */
17622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17623     {
17624       if (unformat (input, "%u", &value))
17625         is_set = 1;
17626       else
17627         {
17628           clib_warning ("parse error '%U'", format_unformat_error, input);
17629           return -99;
17630         }
17631     }
17632
17633   if (!is_set)
17634     {
17635       errmsg ("fallback threshold value is missing!");
17636       return -99;
17637     }
17638
17639   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17640   mp->value = clib_host_to_net_u32 (value);
17641
17642   /* send it... */
17643   S (mp);
17644
17645   /* Wait for a reply... */
17646   W (ret);
17647   return ret;
17648 }
17649
17650 static int
17651 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17652 {
17653   vl_api_show_one_map_register_fallback_threshold_t *mp;
17654   int ret;
17655
17656   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17657
17658   /* send it... */
17659   S (mp);
17660
17661   /* Wait for a reply... */
17662   W (ret);
17663   return ret;
17664 }
17665
17666 uword
17667 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17668 {
17669   u32 *proto = va_arg (*args, u32 *);
17670
17671   if (unformat (input, "udp"))
17672     *proto = 1;
17673   else if (unformat (input, "api"))
17674     *proto = 2;
17675   else
17676     return 0;
17677
17678   return 1;
17679 }
17680
17681 static int
17682 api_one_set_transport_protocol (vat_main_t * vam)
17683 {
17684   unformat_input_t *input = vam->input;
17685   vl_api_one_set_transport_protocol_t *mp;
17686   u8 is_set = 0;
17687   u32 protocol = 0;
17688   int ret;
17689
17690   /* Parse args required to build the message */
17691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17692     {
17693       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17694         is_set = 1;
17695       else
17696         {
17697           clib_warning ("parse error '%U'", format_unformat_error, input);
17698           return -99;
17699         }
17700     }
17701
17702   if (!is_set)
17703     {
17704       errmsg ("Transport protocol missing!");
17705       return -99;
17706     }
17707
17708   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17709   mp->protocol = (u8) protocol;
17710
17711   /* send it... */
17712   S (mp);
17713
17714   /* Wait for a reply... */
17715   W (ret);
17716   return ret;
17717 }
17718
17719 static int
17720 api_one_get_transport_protocol (vat_main_t * vam)
17721 {
17722   vl_api_one_get_transport_protocol_t *mp;
17723   int ret;
17724
17725   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17726
17727   /* send it... */
17728   S (mp);
17729
17730   /* Wait for a reply... */
17731   W (ret);
17732   return ret;
17733 }
17734
17735 static int
17736 api_one_map_register_set_ttl (vat_main_t * vam)
17737 {
17738   unformat_input_t *input = vam->input;
17739   vl_api_one_map_register_set_ttl_t *mp;
17740   u32 ttl = 0;
17741   u8 is_set = 0;
17742   int ret;
17743
17744   /* Parse args required to build the message */
17745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17746     {
17747       if (unformat (input, "%u", &ttl))
17748         is_set = 1;
17749       else
17750         {
17751           clib_warning ("parse error '%U'", format_unformat_error, input);
17752           return -99;
17753         }
17754     }
17755
17756   if (!is_set)
17757     {
17758       errmsg ("TTL value missing!");
17759       return -99;
17760     }
17761
17762   M (ONE_MAP_REGISTER_SET_TTL, mp);
17763   mp->ttl = clib_host_to_net_u32 (ttl);
17764
17765   /* send it... */
17766   S (mp);
17767
17768   /* Wait for a reply... */
17769   W (ret);
17770   return ret;
17771 }
17772
17773 static int
17774 api_show_one_map_register_ttl (vat_main_t * vam)
17775 {
17776   vl_api_show_one_map_register_ttl_t *mp;
17777   int ret;
17778
17779   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17780
17781   /* send it... */
17782   S (mp);
17783
17784   /* Wait for a reply... */
17785   W (ret);
17786   return ret;
17787 }
17788
17789 /**
17790  * Add/del map request itr rlocs from ONE control plane and updates
17791  *
17792  * @param vam vpp API test context
17793  * @return return code
17794  */
17795 static int
17796 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17797 {
17798   unformat_input_t *input = vam->input;
17799   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17800   u8 *locator_set_name = 0;
17801   u8 locator_set_name_set = 0;
17802   u8 is_add = 1;
17803   int ret;
17804
17805   /* Parse args required to build the message */
17806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17807     {
17808       if (unformat (input, "del"))
17809         {
17810           is_add = 0;
17811         }
17812       else if (unformat (input, "%_%v%_", &locator_set_name))
17813         {
17814           locator_set_name_set = 1;
17815         }
17816       else
17817         {
17818           clib_warning ("parse error '%U'", format_unformat_error, input);
17819           return -99;
17820         }
17821     }
17822
17823   if (is_add && !locator_set_name_set)
17824     {
17825       errmsg ("itr-rloc is not set!");
17826       return -99;
17827     }
17828
17829   if (is_add && vec_len (locator_set_name) > 64)
17830     {
17831       errmsg ("itr-rloc locator-set name too long");
17832       vec_free (locator_set_name);
17833       return -99;
17834     }
17835
17836   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17837   mp->is_add = is_add;
17838   if (is_add)
17839     {
17840       clib_memcpy (mp->locator_set_name, locator_set_name,
17841                    vec_len (locator_set_name));
17842     }
17843   else
17844     {
17845       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17846     }
17847   vec_free (locator_set_name);
17848
17849   /* send it... */
17850   S (mp);
17851
17852   /* Wait for a reply... */
17853   W (ret);
17854   return ret;
17855 }
17856
17857 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17858
17859 static int
17860 api_one_locator_dump (vat_main_t * vam)
17861 {
17862   unformat_input_t *input = vam->input;
17863   vl_api_one_locator_dump_t *mp;
17864   vl_api_control_ping_t *mp_ping;
17865   u8 is_index_set = 0, is_name_set = 0;
17866   u8 *ls_name = 0;
17867   u32 ls_index = ~0;
17868   int ret;
17869
17870   /* Parse args required to build the message */
17871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17872     {
17873       if (unformat (input, "ls_name %_%v%_", &ls_name))
17874         {
17875           is_name_set = 1;
17876         }
17877       else if (unformat (input, "ls_index %d", &ls_index))
17878         {
17879           is_index_set = 1;
17880         }
17881       else
17882         {
17883           errmsg ("parse error '%U'", format_unformat_error, input);
17884           return -99;
17885         }
17886     }
17887
17888   if (!is_index_set && !is_name_set)
17889     {
17890       errmsg ("error: expected one of index or name!");
17891       return -99;
17892     }
17893
17894   if (is_index_set && is_name_set)
17895     {
17896       errmsg ("error: only one param expected!");
17897       return -99;
17898     }
17899
17900   if (vec_len (ls_name) > 62)
17901     {
17902       errmsg ("error: locator set name too long!");
17903       return -99;
17904     }
17905
17906   if (!vam->json_output)
17907     {
17908       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17909     }
17910
17911   M (ONE_LOCATOR_DUMP, mp);
17912   mp->is_index_set = is_index_set;
17913
17914   if (is_index_set)
17915     mp->ls_index = clib_host_to_net_u32 (ls_index);
17916   else
17917     {
17918       vec_add1 (ls_name, 0);
17919       strncpy ((char *) mp->ls_name, (char *) ls_name,
17920                sizeof (mp->ls_name) - 1);
17921     }
17922
17923   /* send it... */
17924   S (mp);
17925
17926   /* Use a control ping for synchronization */
17927   MPING (CONTROL_PING, mp_ping);
17928   S (mp_ping);
17929
17930   /* Wait for a reply... */
17931   W (ret);
17932   return ret;
17933 }
17934
17935 #define api_lisp_locator_dump api_one_locator_dump
17936
17937 static int
17938 api_one_locator_set_dump (vat_main_t * vam)
17939 {
17940   vl_api_one_locator_set_dump_t *mp;
17941   vl_api_control_ping_t *mp_ping;
17942   unformat_input_t *input = vam->input;
17943   u8 filter = 0;
17944   int ret;
17945
17946   /* Parse args required to build the message */
17947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17948     {
17949       if (unformat (input, "local"))
17950         {
17951           filter = 1;
17952         }
17953       else if (unformat (input, "remote"))
17954         {
17955           filter = 2;
17956         }
17957       else
17958         {
17959           errmsg ("parse error '%U'", format_unformat_error, input);
17960           return -99;
17961         }
17962     }
17963
17964   if (!vam->json_output)
17965     {
17966       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17967     }
17968
17969   M (ONE_LOCATOR_SET_DUMP, mp);
17970
17971   mp->filter = filter;
17972
17973   /* send it... */
17974   S (mp);
17975
17976   /* Use a control ping for synchronization */
17977   MPING (CONTROL_PING, mp_ping);
17978   S (mp_ping);
17979
17980   /* Wait for a reply... */
17981   W (ret);
17982   return ret;
17983 }
17984
17985 #define api_lisp_locator_set_dump api_one_locator_set_dump
17986
17987 static int
17988 api_one_eid_table_map_dump (vat_main_t * vam)
17989 {
17990   u8 is_l2 = 0;
17991   u8 mode_set = 0;
17992   unformat_input_t *input = vam->input;
17993   vl_api_one_eid_table_map_dump_t *mp;
17994   vl_api_control_ping_t *mp_ping;
17995   int ret;
17996
17997   /* Parse args required to build the message */
17998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17999     {
18000       if (unformat (input, "l2"))
18001         {
18002           is_l2 = 1;
18003           mode_set = 1;
18004         }
18005       else if (unformat (input, "l3"))
18006         {
18007           is_l2 = 0;
18008           mode_set = 1;
18009         }
18010       else
18011         {
18012           errmsg ("parse error '%U'", format_unformat_error, input);
18013           return -99;
18014         }
18015     }
18016
18017   if (!mode_set)
18018     {
18019       errmsg ("expected one of 'l2' or 'l3' parameter!");
18020       return -99;
18021     }
18022
18023   if (!vam->json_output)
18024     {
18025       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18026     }
18027
18028   M (ONE_EID_TABLE_MAP_DUMP, mp);
18029   mp->is_l2 = is_l2;
18030
18031   /* send it... */
18032   S (mp);
18033
18034   /* Use a control ping for synchronization */
18035   MPING (CONTROL_PING, mp_ping);
18036   S (mp_ping);
18037
18038   /* Wait for a reply... */
18039   W (ret);
18040   return ret;
18041 }
18042
18043 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18044
18045 static int
18046 api_one_eid_table_vni_dump (vat_main_t * vam)
18047 {
18048   vl_api_one_eid_table_vni_dump_t *mp;
18049   vl_api_control_ping_t *mp_ping;
18050   int ret;
18051
18052   if (!vam->json_output)
18053     {
18054       print (vam->ofp, "VNI");
18055     }
18056
18057   M (ONE_EID_TABLE_VNI_DUMP, mp);
18058
18059   /* send it... */
18060   S (mp);
18061
18062   /* Use a control ping for synchronization */
18063   MPING (CONTROL_PING, mp_ping);
18064   S (mp_ping);
18065
18066   /* Wait for a reply... */
18067   W (ret);
18068   return ret;
18069 }
18070
18071 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18072
18073 static int
18074 api_one_eid_table_dump (vat_main_t * vam)
18075 {
18076   unformat_input_t *i = vam->input;
18077   vl_api_one_eid_table_dump_t *mp;
18078   vl_api_control_ping_t *mp_ping;
18079   struct in_addr ip4;
18080   struct in6_addr ip6;
18081   u8 mac[6];
18082   u8 eid_type = ~0, eid_set = 0;
18083   u32 prefix_length = ~0, t, vni = 0;
18084   u8 filter = 0;
18085   int ret;
18086   lisp_nsh_api_t nsh;
18087
18088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18089     {
18090       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18091         {
18092           eid_set = 1;
18093           eid_type = 0;
18094           prefix_length = t;
18095         }
18096       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18097         {
18098           eid_set = 1;
18099           eid_type = 1;
18100           prefix_length = t;
18101         }
18102       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18103         {
18104           eid_set = 1;
18105           eid_type = 2;
18106         }
18107       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18108         {
18109           eid_set = 1;
18110           eid_type = 3;
18111         }
18112       else if (unformat (i, "vni %d", &t))
18113         {
18114           vni = t;
18115         }
18116       else if (unformat (i, "local"))
18117         {
18118           filter = 1;
18119         }
18120       else if (unformat (i, "remote"))
18121         {
18122           filter = 2;
18123         }
18124       else
18125         {
18126           errmsg ("parse error '%U'", format_unformat_error, i);
18127           return -99;
18128         }
18129     }
18130
18131   if (!vam->json_output)
18132     {
18133       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18134              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18135     }
18136
18137   M (ONE_EID_TABLE_DUMP, mp);
18138
18139   mp->filter = filter;
18140   if (eid_set)
18141     {
18142       mp->eid_set = 1;
18143       mp->vni = htonl (vni);
18144       mp->eid_type = eid_type;
18145       switch (eid_type)
18146         {
18147         case 0:
18148           mp->prefix_length = prefix_length;
18149           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18150           break;
18151         case 1:
18152           mp->prefix_length = prefix_length;
18153           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18154           break;
18155         case 2:
18156           clib_memcpy (mp->eid, mac, sizeof (mac));
18157           break;
18158         case 3:
18159           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18160           break;
18161         default:
18162           errmsg ("unknown EID type %d!", eid_type);
18163           return -99;
18164         }
18165     }
18166
18167   /* send it... */
18168   S (mp);
18169
18170   /* Use a control ping for synchronization */
18171   MPING (CONTROL_PING, mp_ping);
18172   S (mp_ping);
18173
18174   /* Wait for a reply... */
18175   W (ret);
18176   return ret;
18177 }
18178
18179 #define api_lisp_eid_table_dump api_one_eid_table_dump
18180
18181 static int
18182 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18183 {
18184   unformat_input_t *i = vam->input;
18185   vl_api_gpe_fwd_entries_get_t *mp;
18186   u8 vni_set = 0;
18187   u32 vni = ~0;
18188   int ret;
18189
18190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18191     {
18192       if (unformat (i, "vni %d", &vni))
18193         {
18194           vni_set = 1;
18195         }
18196       else
18197         {
18198           errmsg ("parse error '%U'", format_unformat_error, i);
18199           return -99;
18200         }
18201     }
18202
18203   if (!vni_set)
18204     {
18205       errmsg ("vni not set!");
18206       return -99;
18207     }
18208
18209   if (!vam->json_output)
18210     {
18211       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18212              "leid", "reid");
18213     }
18214
18215   M (GPE_FWD_ENTRIES_GET, mp);
18216   mp->vni = clib_host_to_net_u32 (vni);
18217
18218   /* send it... */
18219   S (mp);
18220
18221   /* Wait for a reply... */
18222   W (ret);
18223   return ret;
18224 }
18225
18226 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18227 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18228 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18229 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18230 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18231 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18232 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18233 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18234
18235 static int
18236 api_one_adjacencies_get (vat_main_t * vam)
18237 {
18238   unformat_input_t *i = vam->input;
18239   vl_api_one_adjacencies_get_t *mp;
18240   u8 vni_set = 0;
18241   u32 vni = ~0;
18242   int ret;
18243
18244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18245     {
18246       if (unformat (i, "vni %d", &vni))
18247         {
18248           vni_set = 1;
18249         }
18250       else
18251         {
18252           errmsg ("parse error '%U'", format_unformat_error, i);
18253           return -99;
18254         }
18255     }
18256
18257   if (!vni_set)
18258     {
18259       errmsg ("vni not set!");
18260       return -99;
18261     }
18262
18263   if (!vam->json_output)
18264     {
18265       print (vam->ofp, "%s %40s", "leid", "reid");
18266     }
18267
18268   M (ONE_ADJACENCIES_GET, mp);
18269   mp->vni = clib_host_to_net_u32 (vni);
18270
18271   /* send it... */
18272   S (mp);
18273
18274   /* Wait for a reply... */
18275   W (ret);
18276   return ret;
18277 }
18278
18279 #define api_lisp_adjacencies_get api_one_adjacencies_get
18280
18281 static int
18282 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18283 {
18284   unformat_input_t *i = vam->input;
18285   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18286   int ret;
18287   u8 ip_family_set = 0, is_ip4 = 1;
18288
18289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18290     {
18291       if (unformat (i, "ip4"))
18292         {
18293           ip_family_set = 1;
18294           is_ip4 = 1;
18295         }
18296       else if (unformat (i, "ip6"))
18297         {
18298           ip_family_set = 1;
18299           is_ip4 = 0;
18300         }
18301       else
18302         {
18303           errmsg ("parse error '%U'", format_unformat_error, i);
18304           return -99;
18305         }
18306     }
18307
18308   if (!ip_family_set)
18309     {
18310       errmsg ("ip family not set!");
18311       return -99;
18312     }
18313
18314   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18315   mp->is_ip4 = is_ip4;
18316
18317   /* send it... */
18318   S (mp);
18319
18320   /* Wait for a reply... */
18321   W (ret);
18322   return ret;
18323 }
18324
18325 static int
18326 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18327 {
18328   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18329   int ret;
18330
18331   if (!vam->json_output)
18332     {
18333       print (vam->ofp, "VNIs");
18334     }
18335
18336   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18337
18338   /* send it... */
18339   S (mp);
18340
18341   /* Wait for a reply... */
18342   W (ret);
18343   return ret;
18344 }
18345
18346 static int
18347 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18348 {
18349   unformat_input_t *i = vam->input;
18350   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18351   int ret = 0;
18352   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18353   struct in_addr ip4;
18354   struct in6_addr ip6;
18355   u32 table_id = 0, nh_sw_if_index = ~0;
18356
18357   clib_memset (&ip4, 0, sizeof (ip4));
18358   clib_memset (&ip6, 0, sizeof (ip6));
18359
18360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18361     {
18362       if (unformat (i, "del"))
18363         is_add = 0;
18364       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18365                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18366         {
18367           ip_set = 1;
18368           is_ip4 = 1;
18369         }
18370       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18371                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18372         {
18373           ip_set = 1;
18374           is_ip4 = 0;
18375         }
18376       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18377         {
18378           ip_set = 1;
18379           is_ip4 = 1;
18380           nh_sw_if_index = ~0;
18381         }
18382       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18383         {
18384           ip_set = 1;
18385           is_ip4 = 0;
18386           nh_sw_if_index = ~0;
18387         }
18388       else if (unformat (i, "table %d", &table_id))
18389         ;
18390       else
18391         {
18392           errmsg ("parse error '%U'", format_unformat_error, i);
18393           return -99;
18394         }
18395     }
18396
18397   if (!ip_set)
18398     {
18399       errmsg ("nh addr not set!");
18400       return -99;
18401     }
18402
18403   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18404   mp->is_add = is_add;
18405   mp->table_id = clib_host_to_net_u32 (table_id);
18406   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18407   mp->is_ip4 = is_ip4;
18408   if (is_ip4)
18409     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18410   else
18411     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18412
18413   /* send it... */
18414   S (mp);
18415
18416   /* Wait for a reply... */
18417   W (ret);
18418   return ret;
18419 }
18420
18421 static int
18422 api_one_map_server_dump (vat_main_t * vam)
18423 {
18424   vl_api_one_map_server_dump_t *mp;
18425   vl_api_control_ping_t *mp_ping;
18426   int ret;
18427
18428   if (!vam->json_output)
18429     {
18430       print (vam->ofp, "%=20s", "Map server");
18431     }
18432
18433   M (ONE_MAP_SERVER_DUMP, mp);
18434   /* send it... */
18435   S (mp);
18436
18437   /* Use a control ping for synchronization */
18438   MPING (CONTROL_PING, mp_ping);
18439   S (mp_ping);
18440
18441   /* Wait for a reply... */
18442   W (ret);
18443   return ret;
18444 }
18445
18446 #define api_lisp_map_server_dump api_one_map_server_dump
18447
18448 static int
18449 api_one_map_resolver_dump (vat_main_t * vam)
18450 {
18451   vl_api_one_map_resolver_dump_t *mp;
18452   vl_api_control_ping_t *mp_ping;
18453   int ret;
18454
18455   if (!vam->json_output)
18456     {
18457       print (vam->ofp, "%=20s", "Map resolver");
18458     }
18459
18460   M (ONE_MAP_RESOLVER_DUMP, mp);
18461   /* send it... */
18462   S (mp);
18463
18464   /* Use a control ping for synchronization */
18465   MPING (CONTROL_PING, mp_ping);
18466   S (mp_ping);
18467
18468   /* Wait for a reply... */
18469   W (ret);
18470   return ret;
18471 }
18472
18473 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18474
18475 static int
18476 api_one_stats_flush (vat_main_t * vam)
18477 {
18478   vl_api_one_stats_flush_t *mp;
18479   int ret = 0;
18480
18481   M (ONE_STATS_FLUSH, mp);
18482   S (mp);
18483   W (ret);
18484   return ret;
18485 }
18486
18487 static int
18488 api_one_stats_dump (vat_main_t * vam)
18489 {
18490   vl_api_one_stats_dump_t *mp;
18491   vl_api_control_ping_t *mp_ping;
18492   int ret;
18493
18494   M (ONE_STATS_DUMP, mp);
18495   /* send it... */
18496   S (mp);
18497
18498   /* Use a control ping for synchronization */
18499   MPING (CONTROL_PING, mp_ping);
18500   S (mp_ping);
18501
18502   /* Wait for a reply... */
18503   W (ret);
18504   return ret;
18505 }
18506
18507 static int
18508 api_show_one_status (vat_main_t * vam)
18509 {
18510   vl_api_show_one_status_t *mp;
18511   int ret;
18512
18513   if (!vam->json_output)
18514     {
18515       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18516     }
18517
18518   M (SHOW_ONE_STATUS, mp);
18519   /* send it... */
18520   S (mp);
18521   /* Wait for a reply... */
18522   W (ret);
18523   return ret;
18524 }
18525
18526 #define api_show_lisp_status api_show_one_status
18527
18528 static int
18529 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18530 {
18531   vl_api_gpe_fwd_entry_path_dump_t *mp;
18532   vl_api_control_ping_t *mp_ping;
18533   unformat_input_t *i = vam->input;
18534   u32 fwd_entry_index = ~0;
18535   int ret;
18536
18537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18538     {
18539       if (unformat (i, "index %d", &fwd_entry_index))
18540         ;
18541       else
18542         break;
18543     }
18544
18545   if (~0 == fwd_entry_index)
18546     {
18547       errmsg ("no index specified!");
18548       return -99;
18549     }
18550
18551   if (!vam->json_output)
18552     {
18553       print (vam->ofp, "first line");
18554     }
18555
18556   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18557
18558   /* send it... */
18559   S (mp);
18560   /* Use a control ping for synchronization */
18561   MPING (CONTROL_PING, mp_ping);
18562   S (mp_ping);
18563
18564   /* Wait for a reply... */
18565   W (ret);
18566   return ret;
18567 }
18568
18569 static int
18570 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18571 {
18572   vl_api_one_get_map_request_itr_rlocs_t *mp;
18573   int ret;
18574
18575   if (!vam->json_output)
18576     {
18577       print (vam->ofp, "%=20s", "itr-rlocs:");
18578     }
18579
18580   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18581   /* send it... */
18582   S (mp);
18583   /* Wait for a reply... */
18584   W (ret);
18585   return ret;
18586 }
18587
18588 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18589
18590 static int
18591 api_af_packet_create (vat_main_t * vam)
18592 {
18593   unformat_input_t *i = vam->input;
18594   vl_api_af_packet_create_t *mp;
18595   u8 *host_if_name = 0;
18596   u8 hw_addr[6];
18597   u8 random_hw_addr = 1;
18598   int ret;
18599
18600   clib_memset (hw_addr, 0, sizeof (hw_addr));
18601
18602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18603     {
18604       if (unformat (i, "name %s", &host_if_name))
18605         vec_add1 (host_if_name, 0);
18606       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18607         random_hw_addr = 0;
18608       else
18609         break;
18610     }
18611
18612   if (!vec_len (host_if_name))
18613     {
18614       errmsg ("host-interface name must be specified");
18615       return -99;
18616     }
18617
18618   if (vec_len (host_if_name) > 64)
18619     {
18620       errmsg ("host-interface name too long");
18621       return -99;
18622     }
18623
18624   M (AF_PACKET_CREATE, mp);
18625
18626   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18627   clib_memcpy (mp->hw_addr, hw_addr, 6);
18628   mp->use_random_hw_addr = random_hw_addr;
18629   vec_free (host_if_name);
18630
18631   S (mp);
18632
18633   /* *INDENT-OFF* */
18634   W2 (ret,
18635       ({
18636         if (ret == 0)
18637           fprintf (vam->ofp ? vam->ofp : stderr,
18638                    " new sw_if_index = %d\n", vam->sw_if_index);
18639       }));
18640   /* *INDENT-ON* */
18641   return ret;
18642 }
18643
18644 static int
18645 api_af_packet_delete (vat_main_t * vam)
18646 {
18647   unformat_input_t *i = vam->input;
18648   vl_api_af_packet_delete_t *mp;
18649   u8 *host_if_name = 0;
18650   int ret;
18651
18652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18653     {
18654       if (unformat (i, "name %s", &host_if_name))
18655         vec_add1 (host_if_name, 0);
18656       else
18657         break;
18658     }
18659
18660   if (!vec_len (host_if_name))
18661     {
18662       errmsg ("host-interface name must be specified");
18663       return -99;
18664     }
18665
18666   if (vec_len (host_if_name) > 64)
18667     {
18668       errmsg ("host-interface name too long");
18669       return -99;
18670     }
18671
18672   M (AF_PACKET_DELETE, mp);
18673
18674   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18675   vec_free (host_if_name);
18676
18677   S (mp);
18678   W (ret);
18679   return ret;
18680 }
18681
18682 static void vl_api_af_packet_details_t_handler
18683   (vl_api_af_packet_details_t * mp)
18684 {
18685   vat_main_t *vam = &vat_main;
18686
18687   print (vam->ofp, "%-16s %d",
18688          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18689 }
18690
18691 static void vl_api_af_packet_details_t_handler_json
18692   (vl_api_af_packet_details_t * mp)
18693 {
18694   vat_main_t *vam = &vat_main;
18695   vat_json_node_t *node = NULL;
18696
18697   if (VAT_JSON_ARRAY != vam->json_tree.type)
18698     {
18699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18700       vat_json_init_array (&vam->json_tree);
18701     }
18702   node = vat_json_array_add (&vam->json_tree);
18703
18704   vat_json_init_object (node);
18705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18706   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18707 }
18708
18709 static int
18710 api_af_packet_dump (vat_main_t * vam)
18711 {
18712   vl_api_af_packet_dump_t *mp;
18713   vl_api_control_ping_t *mp_ping;
18714   int ret;
18715
18716   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18717   /* Get list of tap interfaces */
18718   M (AF_PACKET_DUMP, mp);
18719   S (mp);
18720
18721   /* Use a control ping for synchronization */
18722   MPING (CONTROL_PING, mp_ping);
18723   S (mp_ping);
18724
18725   W (ret);
18726   return ret;
18727 }
18728
18729 static int
18730 api_policer_add_del (vat_main_t * vam)
18731 {
18732   unformat_input_t *i = vam->input;
18733   vl_api_policer_add_del_t *mp;
18734   u8 is_add = 1;
18735   u8 *name = 0;
18736   u32 cir = 0;
18737   u32 eir = 0;
18738   u64 cb = 0;
18739   u64 eb = 0;
18740   u8 rate_type = 0;
18741   u8 round_type = 0;
18742   u8 type = 0;
18743   u8 color_aware = 0;
18744   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18745   int ret;
18746
18747   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18748   conform_action.dscp = 0;
18749   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18750   exceed_action.dscp = 0;
18751   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18752   violate_action.dscp = 0;
18753
18754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18755     {
18756       if (unformat (i, "del"))
18757         is_add = 0;
18758       else if (unformat (i, "name %s", &name))
18759         vec_add1 (name, 0);
18760       else if (unformat (i, "cir %u", &cir))
18761         ;
18762       else if (unformat (i, "eir %u", &eir))
18763         ;
18764       else if (unformat (i, "cb %u", &cb))
18765         ;
18766       else if (unformat (i, "eb %u", &eb))
18767         ;
18768       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18769                          &rate_type))
18770         ;
18771       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18772                          &round_type))
18773         ;
18774       else if (unformat (i, "type %U", unformat_policer_type, &type))
18775         ;
18776       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18777                          &conform_action))
18778         ;
18779       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18780                          &exceed_action))
18781         ;
18782       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18783                          &violate_action))
18784         ;
18785       else if (unformat (i, "color-aware"))
18786         color_aware = 1;
18787       else
18788         break;
18789     }
18790
18791   if (!vec_len (name))
18792     {
18793       errmsg ("policer name must be specified");
18794       return -99;
18795     }
18796
18797   if (vec_len (name) > 64)
18798     {
18799       errmsg ("policer name too long");
18800       return -99;
18801     }
18802
18803   M (POLICER_ADD_DEL, mp);
18804
18805   clib_memcpy (mp->name, name, vec_len (name));
18806   vec_free (name);
18807   mp->is_add = is_add;
18808   mp->cir = ntohl (cir);
18809   mp->eir = ntohl (eir);
18810   mp->cb = clib_net_to_host_u64 (cb);
18811   mp->eb = clib_net_to_host_u64 (eb);
18812   mp->rate_type = rate_type;
18813   mp->round_type = round_type;
18814   mp->type = type;
18815   mp->conform_action_type = conform_action.action_type;
18816   mp->conform_dscp = conform_action.dscp;
18817   mp->exceed_action_type = exceed_action.action_type;
18818   mp->exceed_dscp = exceed_action.dscp;
18819   mp->violate_action_type = violate_action.action_type;
18820   mp->violate_dscp = violate_action.dscp;
18821   mp->color_aware = color_aware;
18822
18823   S (mp);
18824   W (ret);
18825   return ret;
18826 }
18827
18828 static int
18829 api_policer_dump (vat_main_t * vam)
18830 {
18831   unformat_input_t *i = vam->input;
18832   vl_api_policer_dump_t *mp;
18833   vl_api_control_ping_t *mp_ping;
18834   u8 *match_name = 0;
18835   u8 match_name_valid = 0;
18836   int ret;
18837
18838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18839     {
18840       if (unformat (i, "name %s", &match_name))
18841         {
18842           vec_add1 (match_name, 0);
18843           match_name_valid = 1;
18844         }
18845       else
18846         break;
18847     }
18848
18849   M (POLICER_DUMP, mp);
18850   mp->match_name_valid = match_name_valid;
18851   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18852   vec_free (match_name);
18853   /* send it... */
18854   S (mp);
18855
18856   /* Use a control ping for synchronization */
18857   MPING (CONTROL_PING, mp_ping);
18858   S (mp_ping);
18859
18860   /* Wait for a reply... */
18861   W (ret);
18862   return ret;
18863 }
18864
18865 static int
18866 api_policer_classify_set_interface (vat_main_t * vam)
18867 {
18868   unformat_input_t *i = vam->input;
18869   vl_api_policer_classify_set_interface_t *mp;
18870   u32 sw_if_index;
18871   int sw_if_index_set;
18872   u32 ip4_table_index = ~0;
18873   u32 ip6_table_index = ~0;
18874   u32 l2_table_index = ~0;
18875   u8 is_add = 1;
18876   int ret;
18877
18878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18879     {
18880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18881         sw_if_index_set = 1;
18882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18883         sw_if_index_set = 1;
18884       else if (unformat (i, "del"))
18885         is_add = 0;
18886       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18887         ;
18888       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18889         ;
18890       else if (unformat (i, "l2-table %d", &l2_table_index))
18891         ;
18892       else
18893         {
18894           clib_warning ("parse error '%U'", format_unformat_error, i);
18895           return -99;
18896         }
18897     }
18898
18899   if (sw_if_index_set == 0)
18900     {
18901       errmsg ("missing interface name or sw_if_index");
18902       return -99;
18903     }
18904
18905   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18906
18907   mp->sw_if_index = ntohl (sw_if_index);
18908   mp->ip4_table_index = ntohl (ip4_table_index);
18909   mp->ip6_table_index = ntohl (ip6_table_index);
18910   mp->l2_table_index = ntohl (l2_table_index);
18911   mp->is_add = is_add;
18912
18913   S (mp);
18914   W (ret);
18915   return ret;
18916 }
18917
18918 static int
18919 api_policer_classify_dump (vat_main_t * vam)
18920 {
18921   unformat_input_t *i = vam->input;
18922   vl_api_policer_classify_dump_t *mp;
18923   vl_api_control_ping_t *mp_ping;
18924   u8 type = POLICER_CLASSIFY_N_TABLES;
18925   int ret;
18926
18927   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18928     ;
18929   else
18930     {
18931       errmsg ("classify table type must be specified");
18932       return -99;
18933     }
18934
18935   if (!vam->json_output)
18936     {
18937       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18938     }
18939
18940   M (POLICER_CLASSIFY_DUMP, mp);
18941   mp->type = type;
18942   /* send it... */
18943   S (mp);
18944
18945   /* Use a control ping for synchronization */
18946   MPING (CONTROL_PING, mp_ping);
18947   S (mp_ping);
18948
18949   /* Wait for a reply... */
18950   W (ret);
18951   return ret;
18952 }
18953
18954 static int
18955 api_netmap_create (vat_main_t * vam)
18956 {
18957   unformat_input_t *i = vam->input;
18958   vl_api_netmap_create_t *mp;
18959   u8 *if_name = 0;
18960   u8 hw_addr[6];
18961   u8 random_hw_addr = 1;
18962   u8 is_pipe = 0;
18963   u8 is_master = 0;
18964   int ret;
18965
18966   clib_memset (hw_addr, 0, sizeof (hw_addr));
18967
18968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18969     {
18970       if (unformat (i, "name %s", &if_name))
18971         vec_add1 (if_name, 0);
18972       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18973         random_hw_addr = 0;
18974       else if (unformat (i, "pipe"))
18975         is_pipe = 1;
18976       else if (unformat (i, "master"))
18977         is_master = 1;
18978       else if (unformat (i, "slave"))
18979         is_master = 0;
18980       else
18981         break;
18982     }
18983
18984   if (!vec_len (if_name))
18985     {
18986       errmsg ("interface name must be specified");
18987       return -99;
18988     }
18989
18990   if (vec_len (if_name) > 64)
18991     {
18992       errmsg ("interface name too long");
18993       return -99;
18994     }
18995
18996   M (NETMAP_CREATE, mp);
18997
18998   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18999   clib_memcpy (mp->hw_addr, hw_addr, 6);
19000   mp->use_random_hw_addr = random_hw_addr;
19001   mp->is_pipe = is_pipe;
19002   mp->is_master = is_master;
19003   vec_free (if_name);
19004
19005   S (mp);
19006   W (ret);
19007   return ret;
19008 }
19009
19010 static int
19011 api_netmap_delete (vat_main_t * vam)
19012 {
19013   unformat_input_t *i = vam->input;
19014   vl_api_netmap_delete_t *mp;
19015   u8 *if_name = 0;
19016   int ret;
19017
19018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19019     {
19020       if (unformat (i, "name %s", &if_name))
19021         vec_add1 (if_name, 0);
19022       else
19023         break;
19024     }
19025
19026   if (!vec_len (if_name))
19027     {
19028       errmsg ("interface name must be specified");
19029       return -99;
19030     }
19031
19032   if (vec_len (if_name) > 64)
19033     {
19034       errmsg ("interface name too long");
19035       return -99;
19036     }
19037
19038   M (NETMAP_DELETE, mp);
19039
19040   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19041   vec_free (if_name);
19042
19043   S (mp);
19044   W (ret);
19045   return ret;
19046 }
19047
19048 static void
19049 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19050 {
19051   if (fp->afi == IP46_TYPE_IP6)
19052     print (vam->ofp,
19053            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19054            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19055            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19056            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19057            format_ip6_address, fp->next_hop);
19058   else if (fp->afi == IP46_TYPE_IP4)
19059     print (vam->ofp,
19060            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19061            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19062            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19063            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19064            format_ip4_address, fp->next_hop);
19065 }
19066
19067 static void
19068 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19069                                  vl_api_fib_path_t * fp)
19070 {
19071   struct in_addr ip4;
19072   struct in6_addr ip6;
19073
19074   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19075   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19076   vat_json_object_add_uint (node, "is_local", fp->is_local);
19077   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19078   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19079   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19080   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19081   if (fp->afi == IP46_TYPE_IP4)
19082     {
19083       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19084       vat_json_object_add_ip4 (node, "next_hop", ip4);
19085     }
19086   else if (fp->afi == IP46_TYPE_IP6)
19087     {
19088       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19089       vat_json_object_add_ip6 (node, "next_hop", ip6);
19090     }
19091 }
19092
19093 static void
19094 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19095 {
19096   vat_main_t *vam = &vat_main;
19097   int count = ntohl (mp->mt_count);
19098   vl_api_fib_path_t *fp;
19099   i32 i;
19100
19101   print (vam->ofp, "[%d]: sw_if_index %d via:",
19102          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19103   fp = mp->mt_paths;
19104   for (i = 0; i < count; i++)
19105     {
19106       vl_api_mpls_fib_path_print (vam, fp);
19107       fp++;
19108     }
19109
19110   print (vam->ofp, "");
19111 }
19112
19113 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19114 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19115
19116 static void
19117 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19118 {
19119   vat_main_t *vam = &vat_main;
19120   vat_json_node_t *node = NULL;
19121   int count = ntohl (mp->mt_count);
19122   vl_api_fib_path_t *fp;
19123   i32 i;
19124
19125   if (VAT_JSON_ARRAY != vam->json_tree.type)
19126     {
19127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19128       vat_json_init_array (&vam->json_tree);
19129     }
19130   node = vat_json_array_add (&vam->json_tree);
19131
19132   vat_json_init_object (node);
19133   vat_json_object_add_uint (node, "tunnel_index",
19134                             ntohl (mp->mt_tunnel_index));
19135   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19136
19137   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19138
19139   fp = mp->mt_paths;
19140   for (i = 0; i < count; i++)
19141     {
19142       vl_api_mpls_fib_path_json_print (node, fp);
19143       fp++;
19144     }
19145 }
19146
19147 static int
19148 api_mpls_tunnel_dump (vat_main_t * vam)
19149 {
19150   vl_api_mpls_tunnel_dump_t *mp;
19151   vl_api_control_ping_t *mp_ping;
19152   u32 sw_if_index = ~0;
19153   int ret;
19154
19155   /* Parse args required to build the message */
19156   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19157     {
19158       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19159         ;
19160     }
19161
19162   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19163
19164   M (MPLS_TUNNEL_DUMP, mp);
19165   mp->sw_if_index = htonl (sw_if_index);
19166   S (mp);
19167
19168   /* Use a control ping for synchronization */
19169   MPING (CONTROL_PING, mp_ping);
19170   S (mp_ping);
19171
19172   W (ret);
19173   return ret;
19174 }
19175
19176 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19177 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19178
19179
19180 static void
19181 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19182 {
19183   vat_main_t *vam = &vat_main;
19184   int count = ntohl (mp->count);
19185   vl_api_fib_path_t *fp;
19186   int i;
19187
19188   print (vam->ofp,
19189          "table-id %d, label %u, ess_bit %u",
19190          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19191   fp = mp->path;
19192   for (i = 0; i < count; i++)
19193     {
19194       vl_api_mpls_fib_path_print (vam, fp);
19195       fp++;
19196     }
19197 }
19198
19199 static void vl_api_mpls_fib_details_t_handler_json
19200   (vl_api_mpls_fib_details_t * mp)
19201 {
19202   vat_main_t *vam = &vat_main;
19203   int count = ntohl (mp->count);
19204   vat_json_node_t *node = NULL;
19205   vl_api_fib_path_t *fp;
19206   int i;
19207
19208   if (VAT_JSON_ARRAY != vam->json_tree.type)
19209     {
19210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19211       vat_json_init_array (&vam->json_tree);
19212     }
19213   node = vat_json_array_add (&vam->json_tree);
19214
19215   vat_json_init_object (node);
19216   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19217   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19218   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19219   vat_json_object_add_uint (node, "path_count", count);
19220   fp = mp->path;
19221   for (i = 0; i < count; i++)
19222     {
19223       vl_api_mpls_fib_path_json_print (node, fp);
19224       fp++;
19225     }
19226 }
19227
19228 static int
19229 api_mpls_fib_dump (vat_main_t * vam)
19230 {
19231   vl_api_mpls_fib_dump_t *mp;
19232   vl_api_control_ping_t *mp_ping;
19233   int ret;
19234
19235   M (MPLS_FIB_DUMP, mp);
19236   S (mp);
19237
19238   /* Use a control ping for synchronization */
19239   MPING (CONTROL_PING, mp_ping);
19240   S (mp_ping);
19241
19242   W (ret);
19243   return ret;
19244 }
19245
19246 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19247 #define vl_api_ip_fib_details_t_print vl_noop_handler
19248
19249 static void
19250 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19251 {
19252   vat_main_t *vam = &vat_main;
19253   int count = ntohl (mp->count);
19254   vl_api_fib_path_t *fp;
19255   int i;
19256
19257   print (vam->ofp,
19258          "table-id %d, prefix %U/%d stats-index %d",
19259          ntohl (mp->table_id), format_ip4_address, mp->address,
19260          mp->address_length, ntohl (mp->stats_index));
19261   fp = mp->path;
19262   for (i = 0; i < count; i++)
19263     {
19264       if (fp->afi == IP46_TYPE_IP6)
19265         print (vam->ofp,
19266                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19267                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19268                "next_hop_table %d",
19269                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19270                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19271                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19272       else if (fp->afi == IP46_TYPE_IP4)
19273         print (vam->ofp,
19274                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19275                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19276                "next_hop_table %d",
19277                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19278                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19279                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19280       fp++;
19281     }
19282 }
19283
19284 static void vl_api_ip_fib_details_t_handler_json
19285   (vl_api_ip_fib_details_t * mp)
19286 {
19287   vat_main_t *vam = &vat_main;
19288   int count = ntohl (mp->count);
19289   vat_json_node_t *node = NULL;
19290   struct in_addr ip4;
19291   struct in6_addr ip6;
19292   vl_api_fib_path_t *fp;
19293   int i;
19294
19295   if (VAT_JSON_ARRAY != vam->json_tree.type)
19296     {
19297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19298       vat_json_init_array (&vam->json_tree);
19299     }
19300   node = vat_json_array_add (&vam->json_tree);
19301
19302   vat_json_init_object (node);
19303   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19304   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19305   vat_json_object_add_ip4 (node, "prefix", ip4);
19306   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19307   vat_json_object_add_uint (node, "path_count", count);
19308   fp = mp->path;
19309   for (i = 0; i < count; i++)
19310     {
19311       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19312       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19313       vat_json_object_add_uint (node, "is_local", fp->is_local);
19314       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19315       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19316       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19317       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19318       if (fp->afi == IP46_TYPE_IP4)
19319         {
19320           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19321           vat_json_object_add_ip4 (node, "next_hop", ip4);
19322         }
19323       else if (fp->afi == IP46_TYPE_IP6)
19324         {
19325           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19326           vat_json_object_add_ip6 (node, "next_hop", ip6);
19327         }
19328     }
19329 }
19330
19331 static int
19332 api_ip_fib_dump (vat_main_t * vam)
19333 {
19334   vl_api_ip_fib_dump_t *mp;
19335   vl_api_control_ping_t *mp_ping;
19336   int ret;
19337
19338   M (IP_FIB_DUMP, mp);
19339   S (mp);
19340
19341   /* Use a control ping for synchronization */
19342   MPING (CONTROL_PING, mp_ping);
19343   S (mp_ping);
19344
19345   W (ret);
19346   return ret;
19347 }
19348
19349 static int
19350 api_ip_mfib_dump (vat_main_t * vam)
19351 {
19352   vl_api_ip_mfib_dump_t *mp;
19353   vl_api_control_ping_t *mp_ping;
19354   int ret;
19355
19356   M (IP_MFIB_DUMP, mp);
19357   S (mp);
19358
19359   /* Use a control ping for synchronization */
19360   MPING (CONTROL_PING, mp_ping);
19361   S (mp_ping);
19362
19363   W (ret);
19364   return ret;
19365 }
19366
19367 static void vl_api_ip_neighbor_details_t_handler
19368   (vl_api_ip_neighbor_details_t * mp)
19369 {
19370   vat_main_t *vam = &vat_main;
19371
19372   print (vam->ofp, "%c %U %U",
19373          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19374          format_vl_api_mac_address, &mp->neighbor.mac_address,
19375          format_vl_api_address, &mp->neighbor.ip_address);
19376 }
19377
19378 static void vl_api_ip_neighbor_details_t_handler_json
19379   (vl_api_ip_neighbor_details_t * mp)
19380 {
19381
19382   vat_main_t *vam = &vat_main;
19383   vat_json_node_t *node;
19384
19385   if (VAT_JSON_ARRAY != vam->json_tree.type)
19386     {
19387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19388       vat_json_init_array (&vam->json_tree);
19389     }
19390   node = vat_json_array_add (&vam->json_tree);
19391
19392   vat_json_init_object (node);
19393   vat_json_object_add_string_copy
19394     (node, "flag",
19395      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19396       (u8 *) "static" : (u8 *) "dynamic"));
19397
19398   vat_json_object_add_string_copy (node, "link_layer",
19399                                    format (0, "%U", format_vl_api_mac_address,
19400                                            &mp->neighbor.mac_address));
19401   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19402 }
19403
19404 static int
19405 api_ip_neighbor_dump (vat_main_t * vam)
19406 {
19407   unformat_input_t *i = vam->input;
19408   vl_api_ip_neighbor_dump_t *mp;
19409   vl_api_control_ping_t *mp_ping;
19410   u8 is_ipv6 = 0;
19411   u32 sw_if_index = ~0;
19412   int ret;
19413
19414   /* Parse args required to build the message */
19415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19416     {
19417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19418         ;
19419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19420         ;
19421       else if (unformat (i, "ip6"))
19422         is_ipv6 = 1;
19423       else
19424         break;
19425     }
19426
19427   if (sw_if_index == ~0)
19428     {
19429       errmsg ("missing interface name or sw_if_index");
19430       return -99;
19431     }
19432
19433   M (IP_NEIGHBOR_DUMP, mp);
19434   mp->is_ipv6 = (u8) is_ipv6;
19435   mp->sw_if_index = ntohl (sw_if_index);
19436   S (mp);
19437
19438   /* Use a control ping for synchronization */
19439   MPING (CONTROL_PING, mp_ping);
19440   S (mp_ping);
19441
19442   W (ret);
19443   return ret;
19444 }
19445
19446 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19447 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19448
19449 static void
19450 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19451 {
19452   vat_main_t *vam = &vat_main;
19453   int count = ntohl (mp->count);
19454   vl_api_fib_path_t *fp;
19455   int i;
19456
19457   print (vam->ofp,
19458          "table-id %d, prefix %U/%d stats-index %d",
19459          ntohl (mp->table_id), format_ip6_address, mp->address,
19460          mp->address_length, ntohl (mp->stats_index));
19461   fp = mp->path;
19462   for (i = 0; i < count; i++)
19463     {
19464       if (fp->afi == IP46_TYPE_IP6)
19465         print (vam->ofp,
19466                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19467                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19468                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19469                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19470                format_ip6_address, fp->next_hop);
19471       else if (fp->afi == IP46_TYPE_IP4)
19472         print (vam->ofp,
19473                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19474                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19475                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19476                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19477                format_ip4_address, fp->next_hop);
19478       fp++;
19479     }
19480 }
19481
19482 static void vl_api_ip6_fib_details_t_handler_json
19483   (vl_api_ip6_fib_details_t * mp)
19484 {
19485   vat_main_t *vam = &vat_main;
19486   int count = ntohl (mp->count);
19487   vat_json_node_t *node = NULL;
19488   struct in_addr ip4;
19489   struct in6_addr ip6;
19490   vl_api_fib_path_t *fp;
19491   int i;
19492
19493   if (VAT_JSON_ARRAY != vam->json_tree.type)
19494     {
19495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19496       vat_json_init_array (&vam->json_tree);
19497     }
19498   node = vat_json_array_add (&vam->json_tree);
19499
19500   vat_json_init_object (node);
19501   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19502   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19503   vat_json_object_add_ip6 (node, "prefix", ip6);
19504   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19505   vat_json_object_add_uint (node, "path_count", count);
19506   fp = mp->path;
19507   for (i = 0; i < count; i++)
19508     {
19509       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19510       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19511       vat_json_object_add_uint (node, "is_local", fp->is_local);
19512       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19513       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19514       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19515       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19516       if (fp->afi == IP46_TYPE_IP4)
19517         {
19518           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19519           vat_json_object_add_ip4 (node, "next_hop", ip4);
19520         }
19521       else if (fp->afi == IP46_TYPE_IP6)
19522         {
19523           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19524           vat_json_object_add_ip6 (node, "next_hop", ip6);
19525         }
19526     }
19527 }
19528
19529 static int
19530 api_ip6_fib_dump (vat_main_t * vam)
19531 {
19532   vl_api_ip6_fib_dump_t *mp;
19533   vl_api_control_ping_t *mp_ping;
19534   int ret;
19535
19536   M (IP6_FIB_DUMP, mp);
19537   S (mp);
19538
19539   /* Use a control ping for synchronization */
19540   MPING (CONTROL_PING, mp_ping);
19541   S (mp_ping);
19542
19543   W (ret);
19544   return ret;
19545 }
19546
19547 static int
19548 api_ip6_mfib_dump (vat_main_t * vam)
19549 {
19550   vl_api_ip6_mfib_dump_t *mp;
19551   vl_api_control_ping_t *mp_ping;
19552   int ret;
19553
19554   M (IP6_MFIB_DUMP, mp);
19555   S (mp);
19556
19557   /* Use a control ping for synchronization */
19558   MPING (CONTROL_PING, mp_ping);
19559   S (mp_ping);
19560
19561   W (ret);
19562   return ret;
19563 }
19564
19565 int
19566 api_classify_table_ids (vat_main_t * vam)
19567 {
19568   vl_api_classify_table_ids_t *mp;
19569   int ret;
19570
19571   /* Construct the API message */
19572   M (CLASSIFY_TABLE_IDS, mp);
19573   mp->context = 0;
19574
19575   S (mp);
19576   W (ret);
19577   return ret;
19578 }
19579
19580 int
19581 api_classify_table_by_interface (vat_main_t * vam)
19582 {
19583   unformat_input_t *input = vam->input;
19584   vl_api_classify_table_by_interface_t *mp;
19585
19586   u32 sw_if_index = ~0;
19587   int ret;
19588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19589     {
19590       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19591         ;
19592       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19593         ;
19594       else
19595         break;
19596     }
19597   if (sw_if_index == ~0)
19598     {
19599       errmsg ("missing interface name or sw_if_index");
19600       return -99;
19601     }
19602
19603   /* Construct the API message */
19604   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19605   mp->context = 0;
19606   mp->sw_if_index = ntohl (sw_if_index);
19607
19608   S (mp);
19609   W (ret);
19610   return ret;
19611 }
19612
19613 int
19614 api_classify_table_info (vat_main_t * vam)
19615 {
19616   unformat_input_t *input = vam->input;
19617   vl_api_classify_table_info_t *mp;
19618
19619   u32 table_id = ~0;
19620   int ret;
19621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19622     {
19623       if (unformat (input, "table_id %d", &table_id))
19624         ;
19625       else
19626         break;
19627     }
19628   if (table_id == ~0)
19629     {
19630       errmsg ("missing table id");
19631       return -99;
19632     }
19633
19634   /* Construct the API message */
19635   M (CLASSIFY_TABLE_INFO, mp);
19636   mp->context = 0;
19637   mp->table_id = ntohl (table_id);
19638
19639   S (mp);
19640   W (ret);
19641   return ret;
19642 }
19643
19644 int
19645 api_classify_session_dump (vat_main_t * vam)
19646 {
19647   unformat_input_t *input = vam->input;
19648   vl_api_classify_session_dump_t *mp;
19649   vl_api_control_ping_t *mp_ping;
19650
19651   u32 table_id = ~0;
19652   int ret;
19653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19654     {
19655       if (unformat (input, "table_id %d", &table_id))
19656         ;
19657       else
19658         break;
19659     }
19660   if (table_id == ~0)
19661     {
19662       errmsg ("missing table id");
19663       return -99;
19664     }
19665
19666   /* Construct the API message */
19667   M (CLASSIFY_SESSION_DUMP, mp);
19668   mp->context = 0;
19669   mp->table_id = ntohl (table_id);
19670   S (mp);
19671
19672   /* Use a control ping for synchronization */
19673   MPING (CONTROL_PING, mp_ping);
19674   S (mp_ping);
19675
19676   W (ret);
19677   return ret;
19678 }
19679
19680 static void
19681 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19682 {
19683   vat_main_t *vam = &vat_main;
19684
19685   print (vam->ofp, "collector_address %U, collector_port %d, "
19686          "src_address %U, vrf_id %d, path_mtu %u, "
19687          "template_interval %u, udp_checksum %d",
19688          format_ip4_address, mp->collector_address,
19689          ntohs (mp->collector_port),
19690          format_ip4_address, mp->src_address,
19691          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19692          ntohl (mp->template_interval), mp->udp_checksum);
19693
19694   vam->retval = 0;
19695   vam->result_ready = 1;
19696 }
19697
19698 static void
19699   vl_api_ipfix_exporter_details_t_handler_json
19700   (vl_api_ipfix_exporter_details_t * mp)
19701 {
19702   vat_main_t *vam = &vat_main;
19703   vat_json_node_t node;
19704   struct in_addr collector_address;
19705   struct in_addr src_address;
19706
19707   vat_json_init_object (&node);
19708   clib_memcpy (&collector_address, &mp->collector_address,
19709                sizeof (collector_address));
19710   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19711   vat_json_object_add_uint (&node, "collector_port",
19712                             ntohs (mp->collector_port));
19713   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19714   vat_json_object_add_ip4 (&node, "src_address", src_address);
19715   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19716   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19717   vat_json_object_add_uint (&node, "template_interval",
19718                             ntohl (mp->template_interval));
19719   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19720
19721   vat_json_print (vam->ofp, &node);
19722   vat_json_free (&node);
19723   vam->retval = 0;
19724   vam->result_ready = 1;
19725 }
19726
19727 int
19728 api_ipfix_exporter_dump (vat_main_t * vam)
19729 {
19730   vl_api_ipfix_exporter_dump_t *mp;
19731   int ret;
19732
19733   /* Construct the API message */
19734   M (IPFIX_EXPORTER_DUMP, mp);
19735   mp->context = 0;
19736
19737   S (mp);
19738   W (ret);
19739   return ret;
19740 }
19741
19742 static int
19743 api_ipfix_classify_stream_dump (vat_main_t * vam)
19744 {
19745   vl_api_ipfix_classify_stream_dump_t *mp;
19746   int ret;
19747
19748   /* Construct the API message */
19749   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19750   mp->context = 0;
19751
19752   S (mp);
19753   W (ret);
19754   return ret;
19755   /* NOTREACHED */
19756   return 0;
19757 }
19758
19759 static void
19760   vl_api_ipfix_classify_stream_details_t_handler
19761   (vl_api_ipfix_classify_stream_details_t * mp)
19762 {
19763   vat_main_t *vam = &vat_main;
19764   print (vam->ofp, "domain_id %d, src_port %d",
19765          ntohl (mp->domain_id), ntohs (mp->src_port));
19766   vam->retval = 0;
19767   vam->result_ready = 1;
19768 }
19769
19770 static void
19771   vl_api_ipfix_classify_stream_details_t_handler_json
19772   (vl_api_ipfix_classify_stream_details_t * mp)
19773 {
19774   vat_main_t *vam = &vat_main;
19775   vat_json_node_t node;
19776
19777   vat_json_init_object (&node);
19778   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19779   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19780
19781   vat_json_print (vam->ofp, &node);
19782   vat_json_free (&node);
19783   vam->retval = 0;
19784   vam->result_ready = 1;
19785 }
19786
19787 static int
19788 api_ipfix_classify_table_dump (vat_main_t * vam)
19789 {
19790   vl_api_ipfix_classify_table_dump_t *mp;
19791   vl_api_control_ping_t *mp_ping;
19792   int ret;
19793
19794   if (!vam->json_output)
19795     {
19796       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19797              "transport_protocol");
19798     }
19799
19800   /* Construct the API message */
19801   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19802
19803   /* send it... */
19804   S (mp);
19805
19806   /* Use a control ping for synchronization */
19807   MPING (CONTROL_PING, mp_ping);
19808   S (mp_ping);
19809
19810   W (ret);
19811   return ret;
19812 }
19813
19814 static void
19815   vl_api_ipfix_classify_table_details_t_handler
19816   (vl_api_ipfix_classify_table_details_t * mp)
19817 {
19818   vat_main_t *vam = &vat_main;
19819   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19820          mp->transport_protocol);
19821 }
19822
19823 static void
19824   vl_api_ipfix_classify_table_details_t_handler_json
19825   (vl_api_ipfix_classify_table_details_t * mp)
19826 {
19827   vat_json_node_t *node = NULL;
19828   vat_main_t *vam = &vat_main;
19829
19830   if (VAT_JSON_ARRAY != vam->json_tree.type)
19831     {
19832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19833       vat_json_init_array (&vam->json_tree);
19834     }
19835
19836   node = vat_json_array_add (&vam->json_tree);
19837   vat_json_init_object (node);
19838
19839   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19840   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19841   vat_json_object_add_uint (node, "transport_protocol",
19842                             mp->transport_protocol);
19843 }
19844
19845 static int
19846 api_sw_interface_span_enable_disable (vat_main_t * vam)
19847 {
19848   unformat_input_t *i = vam->input;
19849   vl_api_sw_interface_span_enable_disable_t *mp;
19850   u32 src_sw_if_index = ~0;
19851   u32 dst_sw_if_index = ~0;
19852   u8 state = 3;
19853   int ret;
19854   u8 is_l2 = 0;
19855
19856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19857     {
19858       if (unformat
19859           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19860         ;
19861       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19862         ;
19863       else
19864         if (unformat
19865             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19866         ;
19867       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19868         ;
19869       else if (unformat (i, "disable"))
19870         state = 0;
19871       else if (unformat (i, "rx"))
19872         state = 1;
19873       else if (unformat (i, "tx"))
19874         state = 2;
19875       else if (unformat (i, "both"))
19876         state = 3;
19877       else if (unformat (i, "l2"))
19878         is_l2 = 1;
19879       else
19880         break;
19881     }
19882
19883   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19884
19885   mp->sw_if_index_from = htonl (src_sw_if_index);
19886   mp->sw_if_index_to = htonl (dst_sw_if_index);
19887   mp->state = state;
19888   mp->is_l2 = is_l2;
19889
19890   S (mp);
19891   W (ret);
19892   return ret;
19893 }
19894
19895 static void
19896 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19897                                             * mp)
19898 {
19899   vat_main_t *vam = &vat_main;
19900   u8 *sw_if_from_name = 0;
19901   u8 *sw_if_to_name = 0;
19902   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19903   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19904   char *states[] = { "none", "rx", "tx", "both" };
19905   hash_pair_t *p;
19906
19907   /* *INDENT-OFF* */
19908   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19909   ({
19910     if ((u32) p->value[0] == sw_if_index_from)
19911       {
19912         sw_if_from_name = (u8 *)(p->key);
19913         if (sw_if_to_name)
19914           break;
19915       }
19916     if ((u32) p->value[0] == sw_if_index_to)
19917       {
19918         sw_if_to_name = (u8 *)(p->key);
19919         if (sw_if_from_name)
19920           break;
19921       }
19922   }));
19923   /* *INDENT-ON* */
19924   print (vam->ofp, "%20s => %20s (%s) %s",
19925          sw_if_from_name, sw_if_to_name, states[mp->state],
19926          mp->is_l2 ? "l2" : "device");
19927 }
19928
19929 static void
19930   vl_api_sw_interface_span_details_t_handler_json
19931   (vl_api_sw_interface_span_details_t * mp)
19932 {
19933   vat_main_t *vam = &vat_main;
19934   vat_json_node_t *node = NULL;
19935   u8 *sw_if_from_name = 0;
19936   u8 *sw_if_to_name = 0;
19937   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19938   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19939   hash_pair_t *p;
19940
19941   /* *INDENT-OFF* */
19942   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19943   ({
19944     if ((u32) p->value[0] == sw_if_index_from)
19945       {
19946         sw_if_from_name = (u8 *)(p->key);
19947         if (sw_if_to_name)
19948           break;
19949       }
19950     if ((u32) p->value[0] == sw_if_index_to)
19951       {
19952         sw_if_to_name = (u8 *)(p->key);
19953         if (sw_if_from_name)
19954           break;
19955       }
19956   }));
19957   /* *INDENT-ON* */
19958
19959   if (VAT_JSON_ARRAY != vam->json_tree.type)
19960     {
19961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19962       vat_json_init_array (&vam->json_tree);
19963     }
19964   node = vat_json_array_add (&vam->json_tree);
19965
19966   vat_json_init_object (node);
19967   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19968   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19969   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19970   if (0 != sw_if_to_name)
19971     {
19972       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19973     }
19974   vat_json_object_add_uint (node, "state", mp->state);
19975   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19976 }
19977
19978 static int
19979 api_sw_interface_span_dump (vat_main_t * vam)
19980 {
19981   unformat_input_t *input = vam->input;
19982   vl_api_sw_interface_span_dump_t *mp;
19983   vl_api_control_ping_t *mp_ping;
19984   u8 is_l2 = 0;
19985   int ret;
19986
19987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19988     {
19989       if (unformat (input, "l2"))
19990         is_l2 = 1;
19991       else
19992         break;
19993     }
19994
19995   M (SW_INTERFACE_SPAN_DUMP, mp);
19996   mp->is_l2 = is_l2;
19997   S (mp);
19998
19999   /* Use a control ping for synchronization */
20000   MPING (CONTROL_PING, mp_ping);
20001   S (mp_ping);
20002
20003   W (ret);
20004   return ret;
20005 }
20006
20007 int
20008 api_pg_create_interface (vat_main_t * vam)
20009 {
20010   unformat_input_t *input = vam->input;
20011   vl_api_pg_create_interface_t *mp;
20012
20013   u32 if_id = ~0;
20014   int ret;
20015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20016     {
20017       if (unformat (input, "if_id %d", &if_id))
20018         ;
20019       else
20020         break;
20021     }
20022   if (if_id == ~0)
20023     {
20024       errmsg ("missing pg interface index");
20025       return -99;
20026     }
20027
20028   /* Construct the API message */
20029   M (PG_CREATE_INTERFACE, mp);
20030   mp->context = 0;
20031   mp->interface_id = ntohl (if_id);
20032
20033   S (mp);
20034   W (ret);
20035   return ret;
20036 }
20037
20038 int
20039 api_pg_capture (vat_main_t * vam)
20040 {
20041   unformat_input_t *input = vam->input;
20042   vl_api_pg_capture_t *mp;
20043
20044   u32 if_id = ~0;
20045   u8 enable = 1;
20046   u32 count = 1;
20047   u8 pcap_file_set = 0;
20048   u8 *pcap_file = 0;
20049   int ret;
20050   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20051     {
20052       if (unformat (input, "if_id %d", &if_id))
20053         ;
20054       else if (unformat (input, "pcap %s", &pcap_file))
20055         pcap_file_set = 1;
20056       else if (unformat (input, "count %d", &count))
20057         ;
20058       else if (unformat (input, "disable"))
20059         enable = 0;
20060       else
20061         break;
20062     }
20063   if (if_id == ~0)
20064     {
20065       errmsg ("missing pg interface index");
20066       return -99;
20067     }
20068   if (pcap_file_set > 0)
20069     {
20070       if (vec_len (pcap_file) > 255)
20071         {
20072           errmsg ("pcap file name is too long");
20073           return -99;
20074         }
20075     }
20076
20077   u32 name_len = vec_len (pcap_file);
20078   /* Construct the API message */
20079   M (PG_CAPTURE, mp);
20080   mp->context = 0;
20081   mp->interface_id = ntohl (if_id);
20082   mp->is_enabled = enable;
20083   mp->count = ntohl (count);
20084   mp->pcap_name_length = ntohl (name_len);
20085   if (pcap_file_set != 0)
20086     {
20087       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20088     }
20089   vec_free (pcap_file);
20090
20091   S (mp);
20092   W (ret);
20093   return ret;
20094 }
20095
20096 int
20097 api_pg_enable_disable (vat_main_t * vam)
20098 {
20099   unformat_input_t *input = vam->input;
20100   vl_api_pg_enable_disable_t *mp;
20101
20102   u8 enable = 1;
20103   u8 stream_name_set = 0;
20104   u8 *stream_name = 0;
20105   int ret;
20106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20107     {
20108       if (unformat (input, "stream %s", &stream_name))
20109         stream_name_set = 1;
20110       else if (unformat (input, "disable"))
20111         enable = 0;
20112       else
20113         break;
20114     }
20115
20116   if (stream_name_set > 0)
20117     {
20118       if (vec_len (stream_name) > 255)
20119         {
20120           errmsg ("stream name too long");
20121           return -99;
20122         }
20123     }
20124
20125   u32 name_len = vec_len (stream_name);
20126   /* Construct the API message */
20127   M (PG_ENABLE_DISABLE, mp);
20128   mp->context = 0;
20129   mp->is_enabled = enable;
20130   if (stream_name_set != 0)
20131     {
20132       mp->stream_name_length = ntohl (name_len);
20133       clib_memcpy (mp->stream_name, stream_name, name_len);
20134     }
20135   vec_free (stream_name);
20136
20137   S (mp);
20138   W (ret);
20139   return ret;
20140 }
20141
20142 int
20143 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20144 {
20145   unformat_input_t *input = vam->input;
20146   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20147
20148   u16 *low_ports = 0;
20149   u16 *high_ports = 0;
20150   u16 this_low;
20151   u16 this_hi;
20152   vl_api_prefix_t prefix;
20153   u32 tmp, tmp2;
20154   u8 prefix_set = 0;
20155   u32 vrf_id = ~0;
20156   u8 is_add = 1;
20157   u8 is_ipv6 = 0;
20158   int ret;
20159
20160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20161     {
20162       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20163         prefix_set = 1;
20164       else if (unformat (input, "vrf %d", &vrf_id))
20165         ;
20166       else if (unformat (input, "del"))
20167         is_add = 0;
20168       else if (unformat (input, "port %d", &tmp))
20169         {
20170           if (tmp == 0 || tmp > 65535)
20171             {
20172               errmsg ("port %d out of range", tmp);
20173               return -99;
20174             }
20175           this_low = tmp;
20176           this_hi = this_low + 1;
20177           vec_add1 (low_ports, this_low);
20178           vec_add1 (high_ports, this_hi);
20179         }
20180       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20181         {
20182           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20183             {
20184               errmsg ("incorrect range parameters");
20185               return -99;
20186             }
20187           this_low = tmp;
20188           /* Note: in debug CLI +1 is added to high before
20189              passing to real fn that does "the work"
20190              (ip_source_and_port_range_check_add_del).
20191              This fn is a wrapper around the binary API fn a
20192              control plane will call, which expects this increment
20193              to have occurred. Hence letting the binary API control
20194              plane fn do the increment for consistency between VAT
20195              and other control planes.
20196            */
20197           this_hi = tmp2;
20198           vec_add1 (low_ports, this_low);
20199           vec_add1 (high_ports, this_hi);
20200         }
20201       else
20202         break;
20203     }
20204
20205   if (prefix_set == 0)
20206     {
20207       errmsg ("<address>/<mask> not specified");
20208       return -99;
20209     }
20210
20211   if (vrf_id == ~0)
20212     {
20213       errmsg ("VRF ID required, not specified");
20214       return -99;
20215     }
20216
20217   if (vrf_id == 0)
20218     {
20219       errmsg
20220         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20221       return -99;
20222     }
20223
20224   if (vec_len (low_ports) == 0)
20225     {
20226       errmsg ("At least one port or port range required");
20227       return -99;
20228     }
20229
20230   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20231
20232   mp->is_add = is_add;
20233
20234   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20235
20236   mp->number_of_ranges = vec_len (low_ports);
20237
20238   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20239   vec_free (low_ports);
20240
20241   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20242   vec_free (high_ports);
20243
20244   mp->vrf_id = ntohl (vrf_id);
20245
20246   S (mp);
20247   W (ret);
20248   return ret;
20249 }
20250
20251 int
20252 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20253 {
20254   unformat_input_t *input = vam->input;
20255   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20256   u32 sw_if_index = ~0;
20257   int vrf_set = 0;
20258   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20259   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20260   u8 is_add = 1;
20261   int ret;
20262
20263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20264     {
20265       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20266         ;
20267       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20268         ;
20269       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20270         vrf_set = 1;
20271       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20272         vrf_set = 1;
20273       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20274         vrf_set = 1;
20275       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20276         vrf_set = 1;
20277       else if (unformat (input, "del"))
20278         is_add = 0;
20279       else
20280         break;
20281     }
20282
20283   if (sw_if_index == ~0)
20284     {
20285       errmsg ("Interface required but not specified");
20286       return -99;
20287     }
20288
20289   if (vrf_set == 0)
20290     {
20291       errmsg ("VRF ID required but not specified");
20292       return -99;
20293     }
20294
20295   if (tcp_out_vrf_id == 0
20296       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20297     {
20298       errmsg
20299         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20300       return -99;
20301     }
20302
20303   /* Construct the API message */
20304   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20305
20306   mp->sw_if_index = ntohl (sw_if_index);
20307   mp->is_add = is_add;
20308   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20309   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20310   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20311   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20312
20313   /* send it... */
20314   S (mp);
20315
20316   /* Wait for a reply... */
20317   W (ret);
20318   return ret;
20319 }
20320
20321 static int
20322 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20323 {
20324   unformat_input_t *i = vam->input;
20325   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20326   u32 local_sa_id = 0;
20327   u32 remote_sa_id = 0;
20328   vl_api_ip4_address_t src_address;
20329   vl_api_ip4_address_t dst_address;
20330   u8 is_add = 1;
20331   int ret;
20332
20333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20334     {
20335       if (unformat (i, "local_sa %d", &local_sa_id))
20336         ;
20337       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20338         ;
20339       else
20340         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20341         ;
20342       else
20343         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20344         ;
20345       else if (unformat (i, "del"))
20346         is_add = 0;
20347       else
20348         {
20349           clib_warning ("parse error '%U'", format_unformat_error, i);
20350           return -99;
20351         }
20352     }
20353
20354   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20355
20356   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20357   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20358   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20359   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20360   mp->is_add = is_add;
20361
20362   S (mp);
20363   W (ret);
20364   return ret;
20365 }
20366
20367 static int
20368 api_set_punt (vat_main_t * vam)
20369 {
20370   unformat_input_t *i = vam->input;
20371   vl_api_address_family_t af;
20372   vl_api_set_punt_t *mp;
20373   u32 ipv = ~0;
20374   u32 protocol = ~0;
20375   u32 port = ~0;
20376   int is_add = 1;
20377   u8 is_ip4 = 1;
20378   int ret;
20379
20380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20381     {
20382       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20383         ;
20384       else if (unformat (i, "protocol %d", &protocol))
20385         ;
20386       else if (unformat (i, "port %d", &port))
20387         ;
20388       else if (unformat (i, "del"))
20389         is_add = 0;
20390       else
20391         {
20392           clib_warning ("parse error '%U'", format_unformat_error, i);
20393           return -99;
20394         }
20395     }
20396
20397   M (SET_PUNT, mp);
20398
20399   mp->is_add = (u8) is_add;
20400   mp->punt.type = PUNT_API_TYPE_L4;
20401   mp->punt.punt.l4.af = af;
20402   mp->punt.punt.l4.protocol = (u8) protocol;
20403   mp->punt.punt.l4.port = htons ((u16) port);
20404
20405   S (mp);
20406   W (ret);
20407   return ret;
20408 }
20409
20410 static void vl_api_ipsec_gre_tunnel_details_t_handler
20411   (vl_api_ipsec_gre_tunnel_details_t * mp)
20412 {
20413   vat_main_t *vam = &vat_main;
20414
20415   print (vam->ofp, "%11d%15U%15U%14d%14d",
20416          ntohl (mp->tunnel.sw_if_index),
20417          format_vl_api_ip4_address, mp->tunnel.src,
20418          format_vl_api_ip4_address, mp->tunnel.dst,
20419          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20420 }
20421
20422 static void
20423 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20424                                 const char *name,
20425                                 const vl_api_ip4_address_t addr)
20426 {
20427   struct in_addr ip4;
20428
20429   clib_memcpy (&ip4, addr, sizeof (ip4));
20430   vat_json_object_add_ip4 (node, name, ip4);
20431 }
20432
20433 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20434   (vl_api_ipsec_gre_tunnel_details_t * mp)
20435 {
20436   vat_main_t *vam = &vat_main;
20437   vat_json_node_t *node = NULL;
20438   struct in_addr ip4;
20439
20440   if (VAT_JSON_ARRAY != vam->json_tree.type)
20441     {
20442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20443       vat_json_init_array (&vam->json_tree);
20444     }
20445   node = vat_json_array_add (&vam->json_tree);
20446
20447   vat_json_init_object (node);
20448   vat_json_object_add_uint (node, "sw_if_index",
20449                             ntohl (mp->tunnel.sw_if_index));
20450   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20451   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20452   vat_json_object_add_uint (node, "local_sa_id",
20453                             ntohl (mp->tunnel.local_sa_id));
20454   vat_json_object_add_uint (node, "remote_sa_id",
20455                             ntohl (mp->tunnel.remote_sa_id));
20456 }
20457
20458 static int
20459 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20460 {
20461   unformat_input_t *i = vam->input;
20462   vl_api_ipsec_gre_tunnel_dump_t *mp;
20463   vl_api_control_ping_t *mp_ping;
20464   u32 sw_if_index;
20465   u8 sw_if_index_set = 0;
20466   int ret;
20467
20468   /* Parse args required to build the message */
20469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20470     {
20471       if (unformat (i, "sw_if_index %d", &sw_if_index))
20472         sw_if_index_set = 1;
20473       else
20474         break;
20475     }
20476
20477   if (sw_if_index_set == 0)
20478     {
20479       sw_if_index = ~0;
20480     }
20481
20482   if (!vam->json_output)
20483     {
20484       print (vam->ofp, "%11s%15s%15s%14s%14s",
20485              "sw_if_index", "src_address", "dst_address",
20486              "local_sa_id", "remote_sa_id");
20487     }
20488
20489   /* Get list of gre-tunnel interfaces */
20490   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20491
20492   mp->sw_if_index = htonl (sw_if_index);
20493
20494   S (mp);
20495
20496   /* Use a control ping for synchronization */
20497   MPING (CONTROL_PING, mp_ping);
20498   S (mp_ping);
20499
20500   W (ret);
20501   return ret;
20502 }
20503
20504 static int
20505 api_delete_subif (vat_main_t * vam)
20506 {
20507   unformat_input_t *i = vam->input;
20508   vl_api_delete_subif_t *mp;
20509   u32 sw_if_index = ~0;
20510   int ret;
20511
20512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20513     {
20514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20515         ;
20516       if (unformat (i, "sw_if_index %d", &sw_if_index))
20517         ;
20518       else
20519         break;
20520     }
20521
20522   if (sw_if_index == ~0)
20523     {
20524       errmsg ("missing sw_if_index");
20525       return -99;
20526     }
20527
20528   /* Construct the API message */
20529   M (DELETE_SUBIF, mp);
20530   mp->sw_if_index = ntohl (sw_if_index);
20531
20532   S (mp);
20533   W (ret);
20534   return ret;
20535 }
20536
20537 #define foreach_pbb_vtr_op      \
20538 _("disable",  L2_VTR_DISABLED)  \
20539 _("pop",  L2_VTR_POP_2)         \
20540 _("push",  L2_VTR_PUSH_2)
20541
20542 static int
20543 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20544 {
20545   unformat_input_t *i = vam->input;
20546   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20547   u32 sw_if_index = ~0, vtr_op = ~0;
20548   u16 outer_tag = ~0;
20549   u8 dmac[6], smac[6];
20550   u8 dmac_set = 0, smac_set = 0;
20551   u16 vlanid = 0;
20552   u32 sid = ~0;
20553   u32 tmp;
20554   int ret;
20555
20556   /* Shut up coverity */
20557   clib_memset (dmac, 0, sizeof (dmac));
20558   clib_memset (smac, 0, sizeof (smac));
20559
20560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20561     {
20562       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20563         ;
20564       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20565         ;
20566       else if (unformat (i, "vtr_op %d", &vtr_op))
20567         ;
20568 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20569       foreach_pbb_vtr_op
20570 #undef _
20571         else if (unformat (i, "translate_pbb_stag"))
20572         {
20573           if (unformat (i, "%d", &tmp))
20574             {
20575               vtr_op = L2_VTR_TRANSLATE_2_1;
20576               outer_tag = tmp;
20577             }
20578           else
20579             {
20580               errmsg
20581                 ("translate_pbb_stag operation requires outer tag definition");
20582               return -99;
20583             }
20584         }
20585       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20586         dmac_set++;
20587       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20588         smac_set++;
20589       else if (unformat (i, "sid %d", &sid))
20590         ;
20591       else if (unformat (i, "vlanid %d", &tmp))
20592         vlanid = tmp;
20593       else
20594         {
20595           clib_warning ("parse error '%U'", format_unformat_error, i);
20596           return -99;
20597         }
20598     }
20599
20600   if ((sw_if_index == ~0) || (vtr_op == ~0))
20601     {
20602       errmsg ("missing sw_if_index or vtr operation");
20603       return -99;
20604     }
20605   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20606       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20607     {
20608       errmsg
20609         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20610       return -99;
20611     }
20612
20613   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20614   mp->sw_if_index = ntohl (sw_if_index);
20615   mp->vtr_op = ntohl (vtr_op);
20616   mp->outer_tag = ntohs (outer_tag);
20617   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20618   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20619   mp->b_vlanid = ntohs (vlanid);
20620   mp->i_sid = ntohl (sid);
20621
20622   S (mp);
20623   W (ret);
20624   return ret;
20625 }
20626
20627 static int
20628 api_flow_classify_set_interface (vat_main_t * vam)
20629 {
20630   unformat_input_t *i = vam->input;
20631   vl_api_flow_classify_set_interface_t *mp;
20632   u32 sw_if_index;
20633   int sw_if_index_set;
20634   u32 ip4_table_index = ~0;
20635   u32 ip6_table_index = ~0;
20636   u8 is_add = 1;
20637   int ret;
20638
20639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20640     {
20641       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20642         sw_if_index_set = 1;
20643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20644         sw_if_index_set = 1;
20645       else if (unformat (i, "del"))
20646         is_add = 0;
20647       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20648         ;
20649       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20650         ;
20651       else
20652         {
20653           clib_warning ("parse error '%U'", format_unformat_error, i);
20654           return -99;
20655         }
20656     }
20657
20658   if (sw_if_index_set == 0)
20659     {
20660       errmsg ("missing interface name or sw_if_index");
20661       return -99;
20662     }
20663
20664   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20665
20666   mp->sw_if_index = ntohl (sw_if_index);
20667   mp->ip4_table_index = ntohl (ip4_table_index);
20668   mp->ip6_table_index = ntohl (ip6_table_index);
20669   mp->is_add = is_add;
20670
20671   S (mp);
20672   W (ret);
20673   return ret;
20674 }
20675
20676 static int
20677 api_flow_classify_dump (vat_main_t * vam)
20678 {
20679   unformat_input_t *i = vam->input;
20680   vl_api_flow_classify_dump_t *mp;
20681   vl_api_control_ping_t *mp_ping;
20682   u8 type = FLOW_CLASSIFY_N_TABLES;
20683   int ret;
20684
20685   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20686     ;
20687   else
20688     {
20689       errmsg ("classify table type must be specified");
20690       return -99;
20691     }
20692
20693   if (!vam->json_output)
20694     {
20695       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20696     }
20697
20698   M (FLOW_CLASSIFY_DUMP, mp);
20699   mp->type = type;
20700   /* send it... */
20701   S (mp);
20702
20703   /* Use a control ping for synchronization */
20704   MPING (CONTROL_PING, mp_ping);
20705   S (mp_ping);
20706
20707   /* Wait for a reply... */
20708   W (ret);
20709   return ret;
20710 }
20711
20712 static int
20713 api_feature_enable_disable (vat_main_t * vam)
20714 {
20715   unformat_input_t *i = vam->input;
20716   vl_api_feature_enable_disable_t *mp;
20717   u8 *arc_name = 0;
20718   u8 *feature_name = 0;
20719   u32 sw_if_index = ~0;
20720   u8 enable = 1;
20721   int ret;
20722
20723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20724     {
20725       if (unformat (i, "arc_name %s", &arc_name))
20726         ;
20727       else if (unformat (i, "feature_name %s", &feature_name))
20728         ;
20729       else
20730         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20731         ;
20732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20733         ;
20734       else if (unformat (i, "disable"))
20735         enable = 0;
20736       else
20737         break;
20738     }
20739
20740   if (arc_name == 0)
20741     {
20742       errmsg ("missing arc name");
20743       return -99;
20744     }
20745   if (vec_len (arc_name) > 63)
20746     {
20747       errmsg ("arc name too long");
20748     }
20749
20750   if (feature_name == 0)
20751     {
20752       errmsg ("missing feature name");
20753       return -99;
20754     }
20755   if (vec_len (feature_name) > 63)
20756     {
20757       errmsg ("feature name too long");
20758     }
20759
20760   if (sw_if_index == ~0)
20761     {
20762       errmsg ("missing interface name or sw_if_index");
20763       return -99;
20764     }
20765
20766   /* Construct the API message */
20767   M (FEATURE_ENABLE_DISABLE, mp);
20768   mp->sw_if_index = ntohl (sw_if_index);
20769   mp->enable = enable;
20770   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20771   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20772   vec_free (arc_name);
20773   vec_free (feature_name);
20774
20775   S (mp);
20776   W (ret);
20777   return ret;
20778 }
20779
20780 static int
20781 api_sw_interface_tag_add_del (vat_main_t * vam)
20782 {
20783   unformat_input_t *i = vam->input;
20784   vl_api_sw_interface_tag_add_del_t *mp;
20785   u32 sw_if_index = ~0;
20786   u8 *tag = 0;
20787   u8 enable = 1;
20788   int ret;
20789
20790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20791     {
20792       if (unformat (i, "tag %s", &tag))
20793         ;
20794       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20795         ;
20796       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20797         ;
20798       else if (unformat (i, "del"))
20799         enable = 0;
20800       else
20801         break;
20802     }
20803
20804   if (sw_if_index == ~0)
20805     {
20806       errmsg ("missing interface name or sw_if_index");
20807       return -99;
20808     }
20809
20810   if (enable && (tag == 0))
20811     {
20812       errmsg ("no tag specified");
20813       return -99;
20814     }
20815
20816   /* Construct the API message */
20817   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20818   mp->sw_if_index = ntohl (sw_if_index);
20819   mp->is_add = enable;
20820   if (enable)
20821     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20822   vec_free (tag);
20823
20824   S (mp);
20825   W (ret);
20826   return ret;
20827 }
20828
20829 static void vl_api_l2_xconnect_details_t_handler
20830   (vl_api_l2_xconnect_details_t * mp)
20831 {
20832   vat_main_t *vam = &vat_main;
20833
20834   print (vam->ofp, "%15d%15d",
20835          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20836 }
20837
20838 static void vl_api_l2_xconnect_details_t_handler_json
20839   (vl_api_l2_xconnect_details_t * mp)
20840 {
20841   vat_main_t *vam = &vat_main;
20842   vat_json_node_t *node = NULL;
20843
20844   if (VAT_JSON_ARRAY != vam->json_tree.type)
20845     {
20846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20847       vat_json_init_array (&vam->json_tree);
20848     }
20849   node = vat_json_array_add (&vam->json_tree);
20850
20851   vat_json_init_object (node);
20852   vat_json_object_add_uint (node, "rx_sw_if_index",
20853                             ntohl (mp->rx_sw_if_index));
20854   vat_json_object_add_uint (node, "tx_sw_if_index",
20855                             ntohl (mp->tx_sw_if_index));
20856 }
20857
20858 static int
20859 api_l2_xconnect_dump (vat_main_t * vam)
20860 {
20861   vl_api_l2_xconnect_dump_t *mp;
20862   vl_api_control_ping_t *mp_ping;
20863   int ret;
20864
20865   if (!vam->json_output)
20866     {
20867       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20868     }
20869
20870   M (L2_XCONNECT_DUMP, mp);
20871
20872   S (mp);
20873
20874   /* Use a control ping for synchronization */
20875   MPING (CONTROL_PING, mp_ping);
20876   S (mp_ping);
20877
20878   W (ret);
20879   return ret;
20880 }
20881
20882 static int
20883 api_hw_interface_set_mtu (vat_main_t * vam)
20884 {
20885   unformat_input_t *i = vam->input;
20886   vl_api_hw_interface_set_mtu_t *mp;
20887   u32 sw_if_index = ~0;
20888   u32 mtu = 0;
20889   int ret;
20890
20891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20892     {
20893       if (unformat (i, "mtu %d", &mtu))
20894         ;
20895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20896         ;
20897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20898         ;
20899       else
20900         break;
20901     }
20902
20903   if (sw_if_index == ~0)
20904     {
20905       errmsg ("missing interface name or sw_if_index");
20906       return -99;
20907     }
20908
20909   if (mtu == 0)
20910     {
20911       errmsg ("no mtu specified");
20912       return -99;
20913     }
20914
20915   /* Construct the API message */
20916   M (HW_INTERFACE_SET_MTU, mp);
20917   mp->sw_if_index = ntohl (sw_if_index);
20918   mp->mtu = ntohs ((u16) mtu);
20919
20920   S (mp);
20921   W (ret);
20922   return ret;
20923 }
20924
20925 static int
20926 api_p2p_ethernet_add (vat_main_t * vam)
20927 {
20928   unformat_input_t *i = vam->input;
20929   vl_api_p2p_ethernet_add_t *mp;
20930   u32 parent_if_index = ~0;
20931   u32 sub_id = ~0;
20932   u8 remote_mac[6];
20933   u8 mac_set = 0;
20934   int ret;
20935
20936   clib_memset (remote_mac, 0, sizeof (remote_mac));
20937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20938     {
20939       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20940         ;
20941       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20942         ;
20943       else
20944         if (unformat
20945             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20946         mac_set++;
20947       else if (unformat (i, "sub_id %d", &sub_id))
20948         ;
20949       else
20950         {
20951           clib_warning ("parse error '%U'", format_unformat_error, i);
20952           return -99;
20953         }
20954     }
20955
20956   if (parent_if_index == ~0)
20957     {
20958       errmsg ("missing interface name or sw_if_index");
20959       return -99;
20960     }
20961   if (mac_set == 0)
20962     {
20963       errmsg ("missing remote mac address");
20964       return -99;
20965     }
20966   if (sub_id == ~0)
20967     {
20968       errmsg ("missing sub-interface id");
20969       return -99;
20970     }
20971
20972   M (P2P_ETHERNET_ADD, mp);
20973   mp->parent_if_index = ntohl (parent_if_index);
20974   mp->subif_id = ntohl (sub_id);
20975   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20976
20977   S (mp);
20978   W (ret);
20979   return ret;
20980 }
20981
20982 static int
20983 api_p2p_ethernet_del (vat_main_t * vam)
20984 {
20985   unformat_input_t *i = vam->input;
20986   vl_api_p2p_ethernet_del_t *mp;
20987   u32 parent_if_index = ~0;
20988   u8 remote_mac[6];
20989   u8 mac_set = 0;
20990   int ret;
20991
20992   clib_memset (remote_mac, 0, sizeof (remote_mac));
20993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20994     {
20995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20996         ;
20997       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20998         ;
20999       else
21000         if (unformat
21001             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21002         mac_set++;
21003       else
21004         {
21005           clib_warning ("parse error '%U'", format_unformat_error, i);
21006           return -99;
21007         }
21008     }
21009
21010   if (parent_if_index == ~0)
21011     {
21012       errmsg ("missing interface name or sw_if_index");
21013       return -99;
21014     }
21015   if (mac_set == 0)
21016     {
21017       errmsg ("missing remote mac address");
21018       return -99;
21019     }
21020
21021   M (P2P_ETHERNET_DEL, mp);
21022   mp->parent_if_index = ntohl (parent_if_index);
21023   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21024
21025   S (mp);
21026   W (ret);
21027   return ret;
21028 }
21029
21030 static int
21031 api_lldp_config (vat_main_t * vam)
21032 {
21033   unformat_input_t *i = vam->input;
21034   vl_api_lldp_config_t *mp;
21035   int tx_hold = 0;
21036   int tx_interval = 0;
21037   u8 *sys_name = NULL;
21038   int ret;
21039
21040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21041     {
21042       if (unformat (i, "system-name %s", &sys_name))
21043         ;
21044       else if (unformat (i, "tx-hold %d", &tx_hold))
21045         ;
21046       else if (unformat (i, "tx-interval %d", &tx_interval))
21047         ;
21048       else
21049         {
21050           clib_warning ("parse error '%U'", format_unformat_error, i);
21051           return -99;
21052         }
21053     }
21054
21055   vec_add1 (sys_name, 0);
21056
21057   M (LLDP_CONFIG, mp);
21058   mp->tx_hold = htonl (tx_hold);
21059   mp->tx_interval = htonl (tx_interval);
21060   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21061   vec_free (sys_name);
21062
21063   S (mp);
21064   W (ret);
21065   return ret;
21066 }
21067
21068 static int
21069 api_sw_interface_set_lldp (vat_main_t * vam)
21070 {
21071   unformat_input_t *i = vam->input;
21072   vl_api_sw_interface_set_lldp_t *mp;
21073   u32 sw_if_index = ~0;
21074   u32 enable = 1;
21075   u8 *port_desc = NULL, *mgmt_oid = NULL;
21076   ip4_address_t ip4_addr;
21077   ip6_address_t ip6_addr;
21078   int ret;
21079
21080   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21081   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21082
21083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21084     {
21085       if (unformat (i, "disable"))
21086         enable = 0;
21087       else
21088         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21089         ;
21090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21091         ;
21092       else if (unformat (i, "port-desc %s", &port_desc))
21093         ;
21094       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21095         ;
21096       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21097         ;
21098       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21099         ;
21100       else
21101         break;
21102     }
21103
21104   if (sw_if_index == ~0)
21105     {
21106       errmsg ("missing interface name or sw_if_index");
21107       return -99;
21108     }
21109
21110   /* Construct the API message */
21111   vec_add1 (port_desc, 0);
21112   vec_add1 (mgmt_oid, 0);
21113   M (SW_INTERFACE_SET_LLDP, mp);
21114   mp->sw_if_index = ntohl (sw_if_index);
21115   mp->enable = enable;
21116   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21117   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21118   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21119   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21120   vec_free (port_desc);
21121   vec_free (mgmt_oid);
21122
21123   S (mp);
21124   W (ret);
21125   return ret;
21126 }
21127
21128 static int
21129 api_tcp_configure_src_addresses (vat_main_t * vam)
21130 {
21131   vl_api_tcp_configure_src_addresses_t *mp;
21132   unformat_input_t *i = vam->input;
21133   ip4_address_t v4first, v4last;
21134   ip6_address_t v6first, v6last;
21135   u8 range_set = 0;
21136   u32 vrf_id = 0;
21137   int ret;
21138
21139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21140     {
21141       if (unformat (i, "%U - %U",
21142                     unformat_ip4_address, &v4first,
21143                     unformat_ip4_address, &v4last))
21144         {
21145           if (range_set)
21146             {
21147               errmsg ("one range per message (range already set)");
21148               return -99;
21149             }
21150           range_set = 1;
21151         }
21152       else if (unformat (i, "%U - %U",
21153                          unformat_ip6_address, &v6first,
21154                          unformat_ip6_address, &v6last))
21155         {
21156           if (range_set)
21157             {
21158               errmsg ("one range per message (range already set)");
21159               return -99;
21160             }
21161           range_set = 2;
21162         }
21163       else if (unformat (i, "vrf %d", &vrf_id))
21164         ;
21165       else
21166         break;
21167     }
21168
21169   if (range_set == 0)
21170     {
21171       errmsg ("address range not set");
21172       return -99;
21173     }
21174
21175   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21176   mp->vrf_id = ntohl (vrf_id);
21177   /* ipv6? */
21178   if (range_set == 2)
21179     {
21180       mp->is_ipv6 = 1;
21181       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21182       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21183     }
21184   else
21185     {
21186       mp->is_ipv6 = 0;
21187       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21188       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21189     }
21190   S (mp);
21191   W (ret);
21192   return ret;
21193 }
21194
21195 static void vl_api_app_namespace_add_del_reply_t_handler
21196   (vl_api_app_namespace_add_del_reply_t * mp)
21197 {
21198   vat_main_t *vam = &vat_main;
21199   i32 retval = ntohl (mp->retval);
21200   if (vam->async_mode)
21201     {
21202       vam->async_errors += (retval < 0);
21203     }
21204   else
21205     {
21206       vam->retval = retval;
21207       if (retval == 0)
21208         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21209       vam->result_ready = 1;
21210     }
21211 }
21212
21213 static void vl_api_app_namespace_add_del_reply_t_handler_json
21214   (vl_api_app_namespace_add_del_reply_t * mp)
21215 {
21216   vat_main_t *vam = &vat_main;
21217   vat_json_node_t node;
21218
21219   vat_json_init_object (&node);
21220   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21221   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21222
21223   vat_json_print (vam->ofp, &node);
21224   vat_json_free (&node);
21225
21226   vam->retval = ntohl (mp->retval);
21227   vam->result_ready = 1;
21228 }
21229
21230 static int
21231 api_app_namespace_add_del (vat_main_t * vam)
21232 {
21233   vl_api_app_namespace_add_del_t *mp;
21234   unformat_input_t *i = vam->input;
21235   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21236   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21237   u64 secret;
21238   int ret;
21239
21240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21241     {
21242       if (unformat (i, "id %_%v%_", &ns_id))
21243         ;
21244       else if (unformat (i, "secret %lu", &secret))
21245         secret_set = 1;
21246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21247         sw_if_index_set = 1;
21248       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21249         ;
21250       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21251         ;
21252       else
21253         break;
21254     }
21255   if (!ns_id || !secret_set || !sw_if_index_set)
21256     {
21257       errmsg ("namespace id, secret and sw_if_index must be set");
21258       return -99;
21259     }
21260   if (vec_len (ns_id) > 64)
21261     {
21262       errmsg ("namespace id too long");
21263       return -99;
21264     }
21265   M (APP_NAMESPACE_ADD_DEL, mp);
21266
21267   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21268   mp->namespace_id_len = vec_len (ns_id);
21269   mp->secret = clib_host_to_net_u64 (secret);
21270   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21271   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21272   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21273   vec_free (ns_id);
21274   S (mp);
21275   W (ret);
21276   return ret;
21277 }
21278
21279 static int
21280 api_sock_init_shm (vat_main_t * vam)
21281 {
21282 #if VPP_API_TEST_BUILTIN == 0
21283   unformat_input_t *i = vam->input;
21284   vl_api_shm_elem_config_t *config = 0;
21285   u64 size = 64 << 20;
21286   int rv;
21287
21288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21289     {
21290       if (unformat (i, "size %U", unformat_memory_size, &size))
21291         ;
21292       else
21293         break;
21294     }
21295
21296   /*
21297    * Canned custom ring allocator config.
21298    * Should probably parse all of this
21299    */
21300   vec_validate (config, 6);
21301   config[0].type = VL_API_VLIB_RING;
21302   config[0].size = 256;
21303   config[0].count = 32;
21304
21305   config[1].type = VL_API_VLIB_RING;
21306   config[1].size = 1024;
21307   config[1].count = 16;
21308
21309   config[2].type = VL_API_VLIB_RING;
21310   config[2].size = 4096;
21311   config[2].count = 2;
21312
21313   config[3].type = VL_API_CLIENT_RING;
21314   config[3].size = 256;
21315   config[3].count = 32;
21316
21317   config[4].type = VL_API_CLIENT_RING;
21318   config[4].size = 1024;
21319   config[4].count = 16;
21320
21321   config[5].type = VL_API_CLIENT_RING;
21322   config[5].size = 4096;
21323   config[5].count = 2;
21324
21325   config[6].type = VL_API_QUEUE;
21326   config[6].count = 128;
21327   config[6].size = sizeof (uword);
21328
21329   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21330   if (!rv)
21331     vam->client_index_invalid = 1;
21332   return rv;
21333 #else
21334   return -99;
21335 #endif
21336 }
21337
21338 static int
21339 api_dns_enable_disable (vat_main_t * vam)
21340 {
21341   unformat_input_t *line_input = vam->input;
21342   vl_api_dns_enable_disable_t *mp;
21343   u8 enable_disable = 1;
21344   int ret;
21345
21346   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21347     {
21348       if (unformat (line_input, "disable"))
21349         enable_disable = 0;
21350       if (unformat (line_input, "enable"))
21351         enable_disable = 1;
21352       else
21353         break;
21354     }
21355
21356   /* Construct the API message */
21357   M (DNS_ENABLE_DISABLE, mp);
21358   mp->enable = enable_disable;
21359
21360   /* send it... */
21361   S (mp);
21362   /* Wait for the reply */
21363   W (ret);
21364   return ret;
21365 }
21366
21367 static int
21368 api_dns_resolve_name (vat_main_t * vam)
21369 {
21370   unformat_input_t *line_input = vam->input;
21371   vl_api_dns_resolve_name_t *mp;
21372   u8 *name = 0;
21373   int ret;
21374
21375   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21376     {
21377       if (unformat (line_input, "%s", &name))
21378         ;
21379       else
21380         break;
21381     }
21382
21383   if (vec_len (name) > 127)
21384     {
21385       errmsg ("name too long");
21386       return -99;
21387     }
21388
21389   /* Construct the API message */
21390   M (DNS_RESOLVE_NAME, mp);
21391   memcpy (mp->name, name, vec_len (name));
21392   vec_free (name);
21393
21394   /* send it... */
21395   S (mp);
21396   /* Wait for the reply */
21397   W (ret);
21398   return ret;
21399 }
21400
21401 static int
21402 api_dns_resolve_ip (vat_main_t * vam)
21403 {
21404   unformat_input_t *line_input = vam->input;
21405   vl_api_dns_resolve_ip_t *mp;
21406   int is_ip6 = -1;
21407   ip4_address_t addr4;
21408   ip6_address_t addr6;
21409   int ret;
21410
21411   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21412     {
21413       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21414         is_ip6 = 1;
21415       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21416         is_ip6 = 0;
21417       else
21418         break;
21419     }
21420
21421   if (is_ip6 == -1)
21422     {
21423       errmsg ("missing address");
21424       return -99;
21425     }
21426
21427   /* Construct the API message */
21428   M (DNS_RESOLVE_IP, mp);
21429   mp->is_ip6 = is_ip6;
21430   if (is_ip6)
21431     memcpy (mp->address, &addr6, sizeof (addr6));
21432   else
21433     memcpy (mp->address, &addr4, sizeof (addr4));
21434
21435   /* send it... */
21436   S (mp);
21437   /* Wait for the reply */
21438   W (ret);
21439   return ret;
21440 }
21441
21442 static int
21443 api_dns_name_server_add_del (vat_main_t * vam)
21444 {
21445   unformat_input_t *i = vam->input;
21446   vl_api_dns_name_server_add_del_t *mp;
21447   u8 is_add = 1;
21448   ip6_address_t ip6_server;
21449   ip4_address_t ip4_server;
21450   int ip6_set = 0;
21451   int ip4_set = 0;
21452   int ret = 0;
21453
21454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21455     {
21456       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21457         ip6_set = 1;
21458       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21459         ip4_set = 1;
21460       else if (unformat (i, "del"))
21461         is_add = 0;
21462       else
21463         {
21464           clib_warning ("parse error '%U'", format_unformat_error, i);
21465           return -99;
21466         }
21467     }
21468
21469   if (ip4_set && ip6_set)
21470     {
21471       errmsg ("Only one server address allowed per message");
21472       return -99;
21473     }
21474   if ((ip4_set + ip6_set) == 0)
21475     {
21476       errmsg ("Server address required");
21477       return -99;
21478     }
21479
21480   /* Construct the API message */
21481   M (DNS_NAME_SERVER_ADD_DEL, mp);
21482
21483   if (ip6_set)
21484     {
21485       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21486       mp->is_ip6 = 1;
21487     }
21488   else
21489     {
21490       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21491       mp->is_ip6 = 0;
21492     }
21493
21494   mp->is_add = is_add;
21495
21496   /* send it... */
21497   S (mp);
21498
21499   /* Wait for a reply, return good/bad news  */
21500   W (ret);
21501   return ret;
21502 }
21503
21504 static void
21505 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21506 {
21507   vat_main_t *vam = &vat_main;
21508
21509   if (mp->is_ip4)
21510     {
21511       print (vam->ofp,
21512              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21513              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21514              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21515              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21516              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21517              clib_net_to_host_u32 (mp->action_index), mp->tag);
21518     }
21519   else
21520     {
21521       print (vam->ofp,
21522              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21523              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21524              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21525              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21526              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21527              clib_net_to_host_u32 (mp->action_index), mp->tag);
21528     }
21529 }
21530
21531 static void
21532 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21533                                              mp)
21534 {
21535   vat_main_t *vam = &vat_main;
21536   vat_json_node_t *node = NULL;
21537   struct in6_addr ip6;
21538   struct in_addr ip4;
21539
21540   if (VAT_JSON_ARRAY != vam->json_tree.type)
21541     {
21542       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21543       vat_json_init_array (&vam->json_tree);
21544     }
21545   node = vat_json_array_add (&vam->json_tree);
21546   vat_json_init_object (node);
21547
21548   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21549   vat_json_object_add_uint (node, "appns_index",
21550                             clib_net_to_host_u32 (mp->appns_index));
21551   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21552   vat_json_object_add_uint (node, "scope", mp->scope);
21553   vat_json_object_add_uint (node, "action_index",
21554                             clib_net_to_host_u32 (mp->action_index));
21555   vat_json_object_add_uint (node, "lcl_port",
21556                             clib_net_to_host_u16 (mp->lcl_port));
21557   vat_json_object_add_uint (node, "rmt_port",
21558                             clib_net_to_host_u16 (mp->rmt_port));
21559   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21560   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21561   vat_json_object_add_string_copy (node, "tag", mp->tag);
21562   if (mp->is_ip4)
21563     {
21564       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21565       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21566       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21567       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21568     }
21569   else
21570     {
21571       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21572       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21573       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21574       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21575     }
21576 }
21577
21578 static int
21579 api_session_rule_add_del (vat_main_t * vam)
21580 {
21581   vl_api_session_rule_add_del_t *mp;
21582   unformat_input_t *i = vam->input;
21583   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21584   u32 appns_index = 0, scope = 0;
21585   ip4_address_t lcl_ip4, rmt_ip4;
21586   ip6_address_t lcl_ip6, rmt_ip6;
21587   u8 is_ip4 = 1, conn_set = 0;
21588   u8 is_add = 1, *tag = 0;
21589   int ret;
21590
21591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21592     {
21593       if (unformat (i, "del"))
21594         is_add = 0;
21595       else if (unformat (i, "add"))
21596         ;
21597       else if (unformat (i, "proto tcp"))
21598         proto = 0;
21599       else if (unformat (i, "proto udp"))
21600         proto = 1;
21601       else if (unformat (i, "appns %d", &appns_index))
21602         ;
21603       else if (unformat (i, "scope %d", &scope))
21604         ;
21605       else if (unformat (i, "tag %_%v%_", &tag))
21606         ;
21607       else
21608         if (unformat
21609             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21610              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21611              &rmt_port))
21612         {
21613           is_ip4 = 1;
21614           conn_set = 1;
21615         }
21616       else
21617         if (unformat
21618             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21619              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21620              &rmt_port))
21621         {
21622           is_ip4 = 0;
21623           conn_set = 1;
21624         }
21625       else if (unformat (i, "action %d", &action))
21626         ;
21627       else
21628         break;
21629     }
21630   if (proto == ~0 || !conn_set || action == ~0)
21631     {
21632       errmsg ("transport proto, connection and action must be set");
21633       return -99;
21634     }
21635
21636   if (scope > 3)
21637     {
21638       errmsg ("scope should be 0-3");
21639       return -99;
21640     }
21641
21642   M (SESSION_RULE_ADD_DEL, mp);
21643
21644   mp->is_ip4 = is_ip4;
21645   mp->transport_proto = proto;
21646   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21647   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21648   mp->lcl_plen = lcl_plen;
21649   mp->rmt_plen = rmt_plen;
21650   mp->action_index = clib_host_to_net_u32 (action);
21651   mp->appns_index = clib_host_to_net_u32 (appns_index);
21652   mp->scope = scope;
21653   mp->is_add = is_add;
21654   if (is_ip4)
21655     {
21656       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21657       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21658     }
21659   else
21660     {
21661       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21662       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21663     }
21664   if (tag)
21665     {
21666       clib_memcpy (mp->tag, tag, vec_len (tag));
21667       vec_free (tag);
21668     }
21669
21670   S (mp);
21671   W (ret);
21672   return ret;
21673 }
21674
21675 static int
21676 api_session_rules_dump (vat_main_t * vam)
21677 {
21678   vl_api_session_rules_dump_t *mp;
21679   vl_api_control_ping_t *mp_ping;
21680   int ret;
21681
21682   if (!vam->json_output)
21683     {
21684       print (vam->ofp, "%=20s", "Session Rules");
21685     }
21686
21687   M (SESSION_RULES_DUMP, mp);
21688   /* send it... */
21689   S (mp);
21690
21691   /* Use a control ping for synchronization */
21692   MPING (CONTROL_PING, mp_ping);
21693   S (mp_ping);
21694
21695   /* Wait for a reply... */
21696   W (ret);
21697   return ret;
21698 }
21699
21700 static int
21701 api_ip_container_proxy_add_del (vat_main_t * vam)
21702 {
21703   vl_api_ip_container_proxy_add_del_t *mp;
21704   unformat_input_t *i = vam->input;
21705   u32 sw_if_index = ~0;
21706   vl_api_prefix_t pfx = { };
21707   u8 is_add = 1;
21708   int ret;
21709
21710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21711     {
21712       if (unformat (i, "del"))
21713         is_add = 0;
21714       else if (unformat (i, "add"))
21715         ;
21716       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21717         ;
21718       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21719         ;
21720       else
21721         break;
21722     }
21723   if (sw_if_index == ~0 || pfx.address_length == 0)
21724     {
21725       errmsg ("address and sw_if_index must be set");
21726       return -99;
21727     }
21728
21729   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21730
21731   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21732   mp->is_add = is_add;
21733   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21734
21735   S (mp);
21736   W (ret);
21737   return ret;
21738 }
21739
21740 static int
21741 api_qos_record_enable_disable (vat_main_t * vam)
21742 {
21743   unformat_input_t *i = vam->input;
21744   vl_api_qos_record_enable_disable_t *mp;
21745   u32 sw_if_index, qs = 0xff;
21746   u8 sw_if_index_set = 0;
21747   u8 enable = 1;
21748   int ret;
21749
21750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21751     {
21752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21753         sw_if_index_set = 1;
21754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21755         sw_if_index_set = 1;
21756       else if (unformat (i, "%U", unformat_qos_source, &qs))
21757         ;
21758       else if (unformat (i, "disable"))
21759         enable = 0;
21760       else
21761         {
21762           clib_warning ("parse error '%U'", format_unformat_error, i);
21763           return -99;
21764         }
21765     }
21766
21767   if (sw_if_index_set == 0)
21768     {
21769       errmsg ("missing interface name or sw_if_index");
21770       return -99;
21771     }
21772   if (qs == 0xff)
21773     {
21774       errmsg ("input location must be specified");
21775       return -99;
21776     }
21777
21778   M (QOS_RECORD_ENABLE_DISABLE, mp);
21779
21780   mp->sw_if_index = ntohl (sw_if_index);
21781   mp->input_source = qs;
21782   mp->enable = enable;
21783
21784   S (mp);
21785   W (ret);
21786   return ret;
21787 }
21788
21789
21790 static int
21791 q_or_quit (vat_main_t * vam)
21792 {
21793 #if VPP_API_TEST_BUILTIN == 0
21794   longjmp (vam->jump_buf, 1);
21795 #endif
21796   return 0;                     /* not so much */
21797 }
21798
21799 static int
21800 q (vat_main_t * vam)
21801 {
21802   return q_or_quit (vam);
21803 }
21804
21805 static int
21806 quit (vat_main_t * vam)
21807 {
21808   return q_or_quit (vam);
21809 }
21810
21811 static int
21812 comment (vat_main_t * vam)
21813 {
21814   return 0;
21815 }
21816
21817 static int
21818 statseg (vat_main_t * vam)
21819 {
21820   ssvm_private_t *ssvmp = &vam->stat_segment;
21821   ssvm_shared_header_t *shared_header = ssvmp->sh;
21822   vlib_counter_t **counters;
21823   u64 thread0_index1_packets;
21824   u64 thread0_index1_bytes;
21825   f64 vector_rate, input_rate;
21826   uword *p;
21827
21828   uword *counter_vector_by_name;
21829   if (vam->stat_segment_lockp == 0)
21830     {
21831       errmsg ("Stat segment not mapped...");
21832       return -99;
21833     }
21834
21835   /* look up "/if/rx for sw_if_index 1 as a test */
21836
21837   clib_spinlock_lock (vam->stat_segment_lockp);
21838
21839   counter_vector_by_name = (uword *) shared_header->opaque[1];
21840
21841   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21842   if (p == 0)
21843     {
21844       clib_spinlock_unlock (vam->stat_segment_lockp);
21845       errmsg ("/if/tx not found?");
21846       return -99;
21847     }
21848
21849   /* Fish per-thread vector of combined counters from shared memory */
21850   counters = (vlib_counter_t **) p[0];
21851
21852   if (vec_len (counters[0]) < 2)
21853     {
21854       clib_spinlock_unlock (vam->stat_segment_lockp);
21855       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21856       return -99;
21857     }
21858
21859   /* Read thread 0 sw_if_index 1 counter */
21860   thread0_index1_packets = counters[0][1].packets;
21861   thread0_index1_bytes = counters[0][1].bytes;
21862
21863   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21864   if (p == 0)
21865     {
21866       clib_spinlock_unlock (vam->stat_segment_lockp);
21867       errmsg ("vector_rate not found?");
21868       return -99;
21869     }
21870
21871   vector_rate = *(f64 *) (p[0]);
21872   p = hash_get_mem (counter_vector_by_name, "input_rate");
21873   if (p == 0)
21874     {
21875       clib_spinlock_unlock (vam->stat_segment_lockp);
21876       errmsg ("input_rate not found?");
21877       return -99;
21878     }
21879   input_rate = *(f64 *) (p[0]);
21880
21881   clib_spinlock_unlock (vam->stat_segment_lockp);
21882
21883   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21884          vector_rate, input_rate);
21885   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21886          thread0_index1_packets, thread0_index1_bytes);
21887
21888   return 0;
21889 }
21890
21891 static int
21892 cmd_cmp (void *a1, void *a2)
21893 {
21894   u8 **c1 = a1;
21895   u8 **c2 = a2;
21896
21897   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21898 }
21899
21900 static int
21901 help (vat_main_t * vam)
21902 {
21903   u8 **cmds = 0;
21904   u8 *name = 0;
21905   hash_pair_t *p;
21906   unformat_input_t *i = vam->input;
21907   int j;
21908
21909   if (unformat (i, "%s", &name))
21910     {
21911       uword *hs;
21912
21913       vec_add1 (name, 0);
21914
21915       hs = hash_get_mem (vam->help_by_name, name);
21916       if (hs)
21917         print (vam->ofp, "usage: %s %s", name, hs[0]);
21918       else
21919         print (vam->ofp, "No such msg / command '%s'", name);
21920       vec_free (name);
21921       return 0;
21922     }
21923
21924   print (vam->ofp, "Help is available for the following:");
21925
21926     /* *INDENT-OFF* */
21927     hash_foreach_pair (p, vam->function_by_name,
21928     ({
21929       vec_add1 (cmds, (u8 *)(p->key));
21930     }));
21931     /* *INDENT-ON* */
21932
21933   vec_sort_with_function (cmds, cmd_cmp);
21934
21935   for (j = 0; j < vec_len (cmds); j++)
21936     print (vam->ofp, "%s", cmds[j]);
21937
21938   vec_free (cmds);
21939   return 0;
21940 }
21941
21942 static int
21943 set (vat_main_t * vam)
21944 {
21945   u8 *name = 0, *value = 0;
21946   unformat_input_t *i = vam->input;
21947
21948   if (unformat (i, "%s", &name))
21949     {
21950       /* The input buffer is a vector, not a string. */
21951       value = vec_dup (i->buffer);
21952       vec_delete (value, i->index, 0);
21953       /* Almost certainly has a trailing newline */
21954       if (value[vec_len (value) - 1] == '\n')
21955         value[vec_len (value) - 1] = 0;
21956       /* Make sure it's a proper string, one way or the other */
21957       vec_add1 (value, 0);
21958       (void) clib_macro_set_value (&vam->macro_main,
21959                                    (char *) name, (char *) value);
21960     }
21961   else
21962     errmsg ("usage: set <name> <value>");
21963
21964   vec_free (name);
21965   vec_free (value);
21966   return 0;
21967 }
21968
21969 static int
21970 unset (vat_main_t * vam)
21971 {
21972   u8 *name = 0;
21973
21974   if (unformat (vam->input, "%s", &name))
21975     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21976       errmsg ("unset: %s wasn't set", name);
21977   vec_free (name);
21978   return 0;
21979 }
21980
21981 typedef struct
21982 {
21983   u8 *name;
21984   u8 *value;
21985 } macro_sort_t;
21986
21987
21988 static int
21989 macro_sort_cmp (void *a1, void *a2)
21990 {
21991   macro_sort_t *s1 = a1;
21992   macro_sort_t *s2 = a2;
21993
21994   return strcmp ((char *) (s1->name), (char *) (s2->name));
21995 }
21996
21997 static int
21998 dump_macro_table (vat_main_t * vam)
21999 {
22000   macro_sort_t *sort_me = 0, *sm;
22001   int i;
22002   hash_pair_t *p;
22003
22004     /* *INDENT-OFF* */
22005     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22006     ({
22007       vec_add2 (sort_me, sm, 1);
22008       sm->name = (u8 *)(p->key);
22009       sm->value = (u8 *) (p->value[0]);
22010     }));
22011     /* *INDENT-ON* */
22012
22013   vec_sort_with_function (sort_me, macro_sort_cmp);
22014
22015   if (vec_len (sort_me))
22016     print (vam->ofp, "%-15s%s", "Name", "Value");
22017   else
22018     print (vam->ofp, "The macro table is empty...");
22019
22020   for (i = 0; i < vec_len (sort_me); i++)
22021     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22022   return 0;
22023 }
22024
22025 static int
22026 dump_node_table (vat_main_t * vam)
22027 {
22028   int i, j;
22029   vlib_node_t *node, *next_node;
22030
22031   if (vec_len (vam->graph_nodes) == 0)
22032     {
22033       print (vam->ofp, "Node table empty, issue get_node_graph...");
22034       return 0;
22035     }
22036
22037   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22038     {
22039       node = vam->graph_nodes[0][i];
22040       print (vam->ofp, "[%d] %s", i, node->name);
22041       for (j = 0; j < vec_len (node->next_nodes); j++)
22042         {
22043           if (node->next_nodes[j] != ~0)
22044             {
22045               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22046               print (vam->ofp, "  [%d] %s", j, next_node->name);
22047             }
22048         }
22049     }
22050   return 0;
22051 }
22052
22053 static int
22054 value_sort_cmp (void *a1, void *a2)
22055 {
22056   name_sort_t *n1 = a1;
22057   name_sort_t *n2 = a2;
22058
22059   if (n1->value < n2->value)
22060     return -1;
22061   if (n1->value > n2->value)
22062     return 1;
22063   return 0;
22064 }
22065
22066
22067 static int
22068 dump_msg_api_table (vat_main_t * vam)
22069 {
22070   api_main_t *am = &api_main;
22071   name_sort_t *nses = 0, *ns;
22072   hash_pair_t *hp;
22073   int i;
22074
22075   /* *INDENT-OFF* */
22076   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22077   ({
22078     vec_add2 (nses, ns, 1);
22079     ns->name = (u8 *)(hp->key);
22080     ns->value = (u32) hp->value[0];
22081   }));
22082   /* *INDENT-ON* */
22083
22084   vec_sort_with_function (nses, value_sort_cmp);
22085
22086   for (i = 0; i < vec_len (nses); i++)
22087     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22088   vec_free (nses);
22089   return 0;
22090 }
22091
22092 static int
22093 get_msg_id (vat_main_t * vam)
22094 {
22095   u8 *name_and_crc;
22096   u32 message_index;
22097
22098   if (unformat (vam->input, "%s", &name_and_crc))
22099     {
22100       message_index = vl_msg_api_get_msg_index (name_and_crc);
22101       if (message_index == ~0)
22102         {
22103           print (vam->ofp, " '%s' not found", name_and_crc);
22104           return 0;
22105         }
22106       print (vam->ofp, " '%s' has message index %d",
22107              name_and_crc, message_index);
22108       return 0;
22109     }
22110   errmsg ("name_and_crc required...");
22111   return 0;
22112 }
22113
22114 static int
22115 search_node_table (vat_main_t * vam)
22116 {
22117   unformat_input_t *line_input = vam->input;
22118   u8 *node_to_find;
22119   int j;
22120   vlib_node_t *node, *next_node;
22121   uword *p;
22122
22123   if (vam->graph_node_index_by_name == 0)
22124     {
22125       print (vam->ofp, "Node table empty, issue get_node_graph...");
22126       return 0;
22127     }
22128
22129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22130     {
22131       if (unformat (line_input, "%s", &node_to_find))
22132         {
22133           vec_add1 (node_to_find, 0);
22134           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22135           if (p == 0)
22136             {
22137               print (vam->ofp, "%s not found...", node_to_find);
22138               goto out;
22139             }
22140           node = vam->graph_nodes[0][p[0]];
22141           print (vam->ofp, "[%d] %s", p[0], node->name);
22142           for (j = 0; j < vec_len (node->next_nodes); j++)
22143             {
22144               if (node->next_nodes[j] != ~0)
22145                 {
22146                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22147                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22148                 }
22149             }
22150         }
22151
22152       else
22153         {
22154           clib_warning ("parse error '%U'", format_unformat_error,
22155                         line_input);
22156           return -99;
22157         }
22158
22159     out:
22160       vec_free (node_to_find);
22161
22162     }
22163
22164   return 0;
22165 }
22166
22167
22168 static int
22169 script (vat_main_t * vam)
22170 {
22171 #if (VPP_API_TEST_BUILTIN==0)
22172   u8 *s = 0;
22173   char *save_current_file;
22174   unformat_input_t save_input;
22175   jmp_buf save_jump_buf;
22176   u32 save_line_number;
22177
22178   FILE *new_fp, *save_ifp;
22179
22180   if (unformat (vam->input, "%s", &s))
22181     {
22182       new_fp = fopen ((char *) s, "r");
22183       if (new_fp == 0)
22184         {
22185           errmsg ("Couldn't open script file %s", s);
22186           vec_free (s);
22187           return -99;
22188         }
22189     }
22190   else
22191     {
22192       errmsg ("Missing script name");
22193       return -99;
22194     }
22195
22196   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22197   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22198   save_ifp = vam->ifp;
22199   save_line_number = vam->input_line_number;
22200   save_current_file = (char *) vam->current_file;
22201
22202   vam->input_line_number = 0;
22203   vam->ifp = new_fp;
22204   vam->current_file = s;
22205   do_one_file (vam);
22206
22207   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22208   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22209   vam->ifp = save_ifp;
22210   vam->input_line_number = save_line_number;
22211   vam->current_file = (u8 *) save_current_file;
22212   vec_free (s);
22213
22214   return 0;
22215 #else
22216   clib_warning ("use the exec command...");
22217   return -99;
22218 #endif
22219 }
22220
22221 static int
22222 echo (vat_main_t * vam)
22223 {
22224   print (vam->ofp, "%v", vam->input->buffer);
22225   return 0;
22226 }
22227
22228 /* List of API message constructors, CLI names map to api_xxx */
22229 #define foreach_vpe_api_msg                                             \
22230 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22231 _(sw_interface_dump,"")                                                 \
22232 _(sw_interface_set_flags,                                               \
22233   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22234 _(sw_interface_add_del_address,                                         \
22235   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22236 _(sw_interface_set_rx_mode,                                             \
22237   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22238 _(sw_interface_set_rx_placement,                                        \
22239   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22240 _(sw_interface_rx_placement_dump,                                       \
22241   "[<intfc> | sw_if_index <id>]")                                         \
22242 _(sw_interface_set_table,                                               \
22243   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22244 _(sw_interface_set_mpls_enable,                                         \
22245   "<intfc> | sw_if_index [disable | dis]")                              \
22246 _(sw_interface_set_vpath,                                               \
22247   "<intfc> | sw_if_index <id> enable | disable")                        \
22248 _(sw_interface_set_vxlan_bypass,                                        \
22249   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22250 _(sw_interface_set_geneve_bypass,                                       \
22251   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22252 _(sw_interface_set_l2_xconnect,                                         \
22253   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22254   "enable | disable")                                                   \
22255 _(sw_interface_set_l2_bridge,                                           \
22256   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22257   "[shg <split-horizon-group>] [bvi]\n"                                 \
22258   "enable | disable")                                                   \
22259 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22260 _(bridge_domain_add_del,                                                \
22261   "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") \
22262 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22263 _(l2fib_add_del,                                                        \
22264   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22265 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22266 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22267 _(l2_flags,                                                             \
22268   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22269 _(bridge_flags,                                                         \
22270   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22271 _(tap_create_v2,                                                        \
22272   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22273 _(tap_delete_v2,                                                        \
22274   "<vpp-if-name> | sw_if_index <id>")                                   \
22275 _(sw_interface_tap_v2_dump, "")                                         \
22276 _(virtio_pci_create,                                                    \
22277   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
22278 _(virtio_pci_delete,                                                    \
22279   "<vpp-if-name> | sw_if_index <id>")                                   \
22280 _(sw_interface_virtio_pci_dump, "")                                     \
22281 _(bond_create,                                                          \
22282   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22283   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22284   "[id <if-id>]")                                                       \
22285 _(bond_delete,                                                          \
22286   "<vpp-if-name> | sw_if_index <id>")                                   \
22287 _(bond_enslave,                                                         \
22288   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22289 _(bond_detach_slave,                                                    \
22290   "sw_if_index <n>")                                                    \
22291 _(sw_interface_bond_dump, "")                                           \
22292 _(sw_interface_slave_dump,                                              \
22293   "<vpp-if-name> | sw_if_index <id>")                                   \
22294 _(ip_table_add_del,                                                     \
22295   "table <n> [ipv6] [add | del]\n")                                     \
22296 _(ip_add_del_route,                                                     \
22297   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22298   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22299   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22300   "[multipath] [count <n>] [del]")                                      \
22301 _(ip_mroute_add_del,                                                    \
22302   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22303   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22304 _(mpls_table_add_del,                                                   \
22305   "table <n> [add | del]\n")                                            \
22306 _(mpls_route_add_del,                                                   \
22307   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22308   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22309   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22310   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22311   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22312   "[count <n>] [del]")                                                  \
22313 _(mpls_ip_bind_unbind,                                                  \
22314   "<label> <addr/len>")                                                 \
22315 _(mpls_tunnel_add_del,                                                  \
22316   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22317   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22318   "[l2-only]  [out-label <n>]")                                         \
22319 _(sr_mpls_policy_add,                                                   \
22320   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22321 _(sr_mpls_policy_del,                                                   \
22322   "bsid <id>")                                                          \
22323 _(bier_table_add_del,                                                   \
22324   "<label> <sub-domain> <set> <bsl> [del]")                             \
22325 _(bier_route_add_del,                                                   \
22326   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22327   "[<intfc> | sw_if_index <id>]"                                        \
22328   "[weight <n>] [del] [multipath]")                                     \
22329 _(proxy_arp_add_del,                                                    \
22330   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22331 _(proxy_arp_intfc_enable_disable,                                       \
22332   "<intfc> | sw_if_index <id> enable | disable")                        \
22333 _(sw_interface_set_unnumbered,                                          \
22334   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22335 _(ip_neighbor_add_del,                                                  \
22336   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22337   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22338 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22339 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22340   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22341   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22342   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22343 _(reset_fib, "vrf <n> [ipv6]")                                          \
22344 _(dhcp_proxy_config,                                                    \
22345   "svr <v46-address> src <v46-address>\n"                               \
22346    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22347 _(dhcp_proxy_set_vss,                                                   \
22348   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22349 _(dhcp_proxy_dump, "ip6")                                               \
22350 _(dhcp_client_config,                                                   \
22351   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22352 _(set_ip_flow_hash,                                                     \
22353   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22354 _(sw_interface_ip6_enable_disable,                                      \
22355   "<intfc> | sw_if_index <id> enable | disable")                        \
22356 _(ip6nd_proxy_add_del,                                                  \
22357   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22358 _(ip6nd_proxy_dump, "")                                                 \
22359 _(sw_interface_ip6nd_ra_prefix,                                         \
22360   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22361   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22362   "[nolink] [isno]")                                                    \
22363 _(sw_interface_ip6nd_ra_config,                                         \
22364   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22365   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22366   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22367 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22368 _(l2_patch_add_del,                                                     \
22369   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22370   "enable | disable")                                                   \
22371 _(sr_localsid_add_del,                                                  \
22372   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22373   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22374 _(classify_add_del_table,                                               \
22375   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22376   " [del] [del-chain] mask <mask-value>\n"                              \
22377   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22378   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22379 _(classify_add_del_session,                                             \
22380   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22381   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22382   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22383   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22384 _(classify_set_interface_ip_table,                                      \
22385   "<intfc> | sw_if_index <nn> table <nn>")                              \
22386 _(classify_set_interface_l2_tables,                                     \
22387   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22388   "  [other-table <nn>]")                                               \
22389 _(get_node_index, "node <node-name")                                    \
22390 _(add_node_next, "node <node-name> next <next-node-name>")              \
22391 _(l2tpv3_create_tunnel,                                                 \
22392   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22393   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22394   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22395 _(l2tpv3_set_tunnel_cookies,                                            \
22396   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22397   "[new_remote_cookie <nn>]\n")                                         \
22398 _(l2tpv3_interface_enable_disable,                                      \
22399   "<intfc> | sw_if_index <nn> enable | disable")                        \
22400 _(l2tpv3_set_lookup_key,                                                \
22401   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22402 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22403 _(vxlan_offload_rx,                                                     \
22404   "hw { <interface name> | hw_if_index <nn>} "                          \
22405   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22406 _(vxlan_add_del_tunnel,                                                 \
22407   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22408   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22409   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22410 _(geneve_add_del_tunnel,                                                \
22411   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22412   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22413   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22414 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22415 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22416 _(gre_tunnel_add_del,                                                   \
22417   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22418   "[teb | erspan <session-id>] [del]")                                  \
22419 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22420 _(l2_fib_clear_table, "")                                               \
22421 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22422 _(l2_interface_vlan_tag_rewrite,                                        \
22423   "<intfc> | sw_if_index <nn> \n"                                       \
22424   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22425   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22426 _(create_vhost_user_if,                                                 \
22427         "socket <filename> [server] [renumber <dev_instance>] "         \
22428         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22429         "[mac <mac_address>]")                                          \
22430 _(modify_vhost_user_if,                                                 \
22431         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22432         "[server] [renumber <dev_instance>]")                           \
22433 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22434 _(sw_interface_vhost_user_dump, "")                                     \
22435 _(show_version, "")                                                     \
22436 _(show_threads, "")                                                     \
22437 _(vxlan_gpe_add_del_tunnel,                                             \
22438   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22439   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22440   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22441   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22442 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22443 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22444 _(interface_name_renumber,                                              \
22445   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22446 _(input_acl_set_interface,                                              \
22447   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22448   "  [l2-table <nn>] [del]")                                            \
22449 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22450 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22451   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22452 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22453 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22454 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22455 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22456 _(ip_dump, "ipv4 | ipv6")                                               \
22457 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22458 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22459   "  spid_id <n> ")                                                     \
22460 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22461   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22462   "  integ_alg <alg> integ_key <hex>")                                  \
22463 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22464   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22465   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22466   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22467 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22468 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22469   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22470   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22471   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22472   "  [instance <n>]")     \
22473 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22474 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22475   "  <alg> <hex>\n")                                                    \
22476 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22477 _(delete_loopback,"sw_if_index <nn>")                                   \
22478 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22479 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22480 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22481 _(want_interface_events,  "enable|disable")                             \
22482 _(get_first_msg_id, "client <name>")                                    \
22483 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22484 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22485   "fib-id <nn> [ip4][ip6][default]")                                    \
22486 _(get_node_graph, " ")                                                  \
22487 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22488 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22489 _(ioam_disable, "")                                                     \
22490 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22491                             " sw_if_index <sw_if_index> p <priority> "  \
22492                             "w <weight>] [del]")                        \
22493 _(one_add_del_locator, "locator-set <locator_name> "                    \
22494                         "iface <intf> | sw_if_index <sw_if_index> "     \
22495                         "p <priority> w <weight> [del]")                \
22496 _(one_add_del_local_eid,"vni <vni> eid "                                \
22497                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22498                          "locator-set <locator_name> [del]"             \
22499                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22500 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22501 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22502 _(one_enable_disable, "enable|disable")                                 \
22503 _(one_map_register_enable_disable, "enable|disable")                    \
22504 _(one_map_register_fallback_threshold, "<value>")                       \
22505 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22506 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22507                                "[seid <seid>] "                         \
22508                                "rloc <locator> p <prio> "               \
22509                                "w <weight> [rloc <loc> ... ] "          \
22510                                "action <action> [del-all]")             \
22511 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22512                           "<local-eid>")                                \
22513 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22514 _(one_use_petr, "ip-address> | disable")                                \
22515 _(one_map_request_mode, "src-dst|dst-only")                             \
22516 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22517 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22518 _(one_locator_set_dump, "[local | remote]")                             \
22519 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22520 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22521                        "[local] | [remote]")                            \
22522 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22523 _(one_ndp_bd_get, "")                                                   \
22524 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22525 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22526 _(one_l2_arp_bd_get, "")                                                \
22527 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22528 _(one_stats_enable_disable, "enable|disable")                           \
22529 _(show_one_stats_enable_disable, "")                                    \
22530 _(one_eid_table_vni_dump, "")                                           \
22531 _(one_eid_table_map_dump, "l2|l3")                                      \
22532 _(one_map_resolver_dump, "")                                            \
22533 _(one_map_server_dump, "")                                              \
22534 _(one_adjacencies_get, "vni <vni>")                                     \
22535 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22536 _(show_one_rloc_probe_state, "")                                        \
22537 _(show_one_map_register_state, "")                                      \
22538 _(show_one_status, "")                                                  \
22539 _(one_stats_dump, "")                                                   \
22540 _(one_stats_flush, "")                                                  \
22541 _(one_get_map_request_itr_rlocs, "")                                    \
22542 _(one_map_register_set_ttl, "<ttl>")                                    \
22543 _(one_set_transport_protocol, "udp|api")                                \
22544 _(one_get_transport_protocol, "")                                       \
22545 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22546 _(one_show_xtr_mode, "")                                                \
22547 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22548 _(one_show_pitr_mode, "")                                               \
22549 _(one_enable_disable_petr_mode, "enable|disable")                       \
22550 _(one_show_petr_mode, "")                                               \
22551 _(show_one_nsh_mapping, "")                                             \
22552 _(show_one_pitr, "")                                                    \
22553 _(show_one_use_petr, "")                                                \
22554 _(show_one_map_request_mode, "")                                        \
22555 _(show_one_map_register_ttl, "")                                        \
22556 _(show_one_map_register_fallback_threshold, "")                         \
22557 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22558                             " sw_if_index <sw_if_index> p <priority> "  \
22559                             "w <weight>] [del]")                        \
22560 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22561                         "iface <intf> | sw_if_index <sw_if_index> "     \
22562                         "p <priority> w <weight> [del]")                \
22563 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22564                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22565                          "locator-set <locator_name> [del]"             \
22566                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22567 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22568 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22569 _(lisp_enable_disable, "enable|disable")                                \
22570 _(lisp_map_register_enable_disable, "enable|disable")                   \
22571 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22572 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22573                                "[seid <seid>] "                         \
22574                                "rloc <locator> p <prio> "               \
22575                                "w <weight> [rloc <loc> ... ] "          \
22576                                "action <action> [del-all]")             \
22577 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22578                           "<local-eid>")                                \
22579 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22580 _(lisp_use_petr, "<ip-address> | disable")                              \
22581 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22582 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22583 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22584 _(lisp_locator_set_dump, "[local | remote]")                            \
22585 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22586 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22587                        "[local] | [remote]")                            \
22588 _(lisp_eid_table_vni_dump, "")                                          \
22589 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22590 _(lisp_map_resolver_dump, "")                                           \
22591 _(lisp_map_server_dump, "")                                             \
22592 _(lisp_adjacencies_get, "vni <vni>")                                    \
22593 _(gpe_fwd_entry_vnis_get, "")                                           \
22594 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22595 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22596                                 "[table <table-id>]")                   \
22597 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22598 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22599 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22600 _(gpe_get_encap_mode, "")                                               \
22601 _(lisp_gpe_add_del_iface, "up|down")                                    \
22602 _(lisp_gpe_enable_disable, "enable|disable")                            \
22603 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22604   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22605 _(show_lisp_rloc_probe_state, "")                                       \
22606 _(show_lisp_map_register_state, "")                                     \
22607 _(show_lisp_status, "")                                                 \
22608 _(lisp_get_map_request_itr_rlocs, "")                                   \
22609 _(show_lisp_pitr, "")                                                   \
22610 _(show_lisp_use_petr, "")                                               \
22611 _(show_lisp_map_request_mode, "")                                       \
22612 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22613 _(af_packet_delete, "name <host interface name>")                       \
22614 _(af_packet_dump, "")                                                   \
22615 _(policer_add_del, "name <policer name> <params> [del]")                \
22616 _(policer_dump, "[name <policer name>]")                                \
22617 _(policer_classify_set_interface,                                       \
22618   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22619   "  [l2-table <nn>] [del]")                                            \
22620 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22621 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22622     "[master|slave]")                                                   \
22623 _(netmap_delete, "name <interface name>")                               \
22624 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22625 _(mpls_fib_dump, "")                                                    \
22626 _(classify_table_ids, "")                                               \
22627 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22628 _(classify_table_info, "table_id <nn>")                                 \
22629 _(classify_session_dump, "table_id <nn>")                               \
22630 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22631     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22632     "[template_interval <nn>] [udp_checksum]")                          \
22633 _(ipfix_exporter_dump, "")                                              \
22634 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22635 _(ipfix_classify_stream_dump, "")                                       \
22636 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22637 _(ipfix_classify_table_dump, "")                                        \
22638 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22639 _(sw_interface_span_dump, "[l2]")                                           \
22640 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22641 _(pg_create_interface, "if_id <nn>")                                    \
22642 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22643 _(pg_enable_disable, "[stream <id>] disable")                           \
22644 _(ip_source_and_port_range_check_add_del,                               \
22645   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22646 _(ip_source_and_port_range_check_interface_add_del,                     \
22647   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22648   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22649 _(ipsec_gre_tunnel_add_del,                                             \
22650   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22651 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22652 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22653 _(l2_interface_pbb_tag_rewrite,                                         \
22654   "<intfc> | sw_if_index <nn> \n"                                       \
22655   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22656   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22657 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22658 _(flow_classify_set_interface,                                          \
22659   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22660 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22661 _(ip_fib_dump, "")                                                      \
22662 _(ip_mfib_dump, "")                                                     \
22663 _(ip6_fib_dump, "")                                                     \
22664 _(ip6_mfib_dump, "")                                                    \
22665 _(feature_enable_disable, "arc_name <arc_name> "                        \
22666   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22667 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22668 "[disable]")                                                            \
22669 _(l2_xconnect_dump, "")                                                 \
22670 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22671 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22672 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22673 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22674 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22675 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22676 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22677   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22678 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22679 _(sock_init_shm, "size <nnn>")                                          \
22680 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22681 _(dns_enable_disable, "[enable][disable]")                              \
22682 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22683 _(dns_resolve_name, "<hostname>")                                       \
22684 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22685 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22686 _(dns_resolve_name, "<hostname>")                                       \
22687 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22688   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22689 _(session_rules_dump, "")                                               \
22690 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22691 _(output_acl_set_interface,                                             \
22692   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22693   "  [l2-table <nn>] [del]")                                            \
22694 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22695
22696 /* List of command functions, CLI names map directly to functions */
22697 #define foreach_cli_function                                    \
22698 _(comment, "usage: comment <ignore-rest-of-line>")              \
22699 _(dump_interface_table, "usage: dump_interface_table")          \
22700 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22701 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22702 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22703 _(dump_macro_table, "usage: dump_macro_table ")                 \
22704 _(dump_node_table, "usage: dump_node_table")                    \
22705 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22706 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22707 _(echo, "usage: echo <message>")                                \
22708 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22709 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22710 _(help, "usage: help")                                          \
22711 _(q, "usage: quit")                                             \
22712 _(quit, "usage: quit")                                          \
22713 _(search_node_table, "usage: search_node_table <name>...")      \
22714 _(set, "usage: set <variable-name> <value>")                    \
22715 _(script, "usage: script <file-name>")                          \
22716 _(statseg, "usage: statseg");                                   \
22717 _(unset, "usage: unset <variable-name>")
22718
22719 #define _(N,n)                                  \
22720     static void vl_api_##n##_t_handler_uni      \
22721     (vl_api_##n##_t * mp)                       \
22722     {                                           \
22723         vat_main_t * vam = &vat_main;           \
22724         if (vam->json_output) {                 \
22725             vl_api_##n##_t_handler_json(mp);    \
22726         } else {                                \
22727             vl_api_##n##_t_handler(mp);         \
22728         }                                       \
22729     }
22730 foreach_vpe_api_reply_msg;
22731 #if VPP_API_TEST_BUILTIN == 0
22732 foreach_standalone_reply_msg;
22733 #endif
22734 #undef _
22735
22736 void
22737 vat_api_hookup (vat_main_t * vam)
22738 {
22739 #define _(N,n)                                                  \
22740     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22741                            vl_api_##n##_t_handler_uni,          \
22742                            vl_noop_handler,                     \
22743                            vl_api_##n##_t_endian,               \
22744                            vl_api_##n##_t_print,                \
22745                            sizeof(vl_api_##n##_t), 1);
22746   foreach_vpe_api_reply_msg;
22747 #if VPP_API_TEST_BUILTIN == 0
22748   foreach_standalone_reply_msg;
22749 #endif
22750 #undef _
22751
22752 #if (VPP_API_TEST_BUILTIN==0)
22753   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22754
22755   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22756
22757   vam->function_by_name = hash_create_string (0, sizeof (uword));
22758
22759   vam->help_by_name = hash_create_string (0, sizeof (uword));
22760 #endif
22761
22762   /* API messages we can send */
22763 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22764   foreach_vpe_api_msg;
22765 #undef _
22766
22767   /* Help strings */
22768 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22769   foreach_vpe_api_msg;
22770 #undef _
22771
22772   /* CLI functions */
22773 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22774   foreach_cli_function;
22775 #undef _
22776
22777   /* Help strings */
22778 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22779   foreach_cli_function;
22780 #undef _
22781 }
22782
22783 #if VPP_API_TEST_BUILTIN
22784 static clib_error_t *
22785 vat_api_hookup_shim (vlib_main_t * vm)
22786 {
22787   vat_api_hookup (&vat_main);
22788   return 0;
22789 }
22790
22791 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22792 #endif
22793
22794 /*
22795  * fd.io coding-style-patch-verification: ON
22796  *
22797  * Local Variables:
22798  * eval: (c-set-style "gnu")
22799  * End:
22800  */