ipsec: remove the set_key API
[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_tunnel_if_add_del_reply)                        \
5214 _(ipsec_tunnel_if_set_sa_reply)                         \
5215 _(delete_loopback_reply)                                \
5216 _(bd_ip_mac_add_del_reply)                              \
5217 _(bd_ip_mac_flush_reply)                                \
5218 _(want_interface_events_reply)                          \
5219 _(cop_interface_enable_disable_reply)                   \
5220 _(cop_whitelist_enable_disable_reply)                   \
5221 _(sw_interface_clear_stats_reply)                       \
5222 _(ioam_enable_reply)                                    \
5223 _(ioam_disable_reply)                                   \
5224 _(one_add_del_locator_reply)                            \
5225 _(one_add_del_local_eid_reply)                          \
5226 _(one_add_del_remote_mapping_reply)                     \
5227 _(one_add_del_adjacency_reply)                          \
5228 _(one_add_del_map_resolver_reply)                       \
5229 _(one_add_del_map_server_reply)                         \
5230 _(one_enable_disable_reply)                             \
5231 _(one_rloc_probe_enable_disable_reply)                  \
5232 _(one_map_register_enable_disable_reply)                \
5233 _(one_map_register_set_ttl_reply)                       \
5234 _(one_set_transport_protocol_reply)                     \
5235 _(one_map_register_fallback_threshold_reply)            \
5236 _(one_pitr_set_locator_set_reply)                       \
5237 _(one_map_request_mode_reply)                           \
5238 _(one_add_del_map_request_itr_rlocs_reply)              \
5239 _(one_eid_table_add_del_map_reply)                      \
5240 _(one_use_petr_reply)                                   \
5241 _(one_stats_enable_disable_reply)                       \
5242 _(one_add_del_l2_arp_entry_reply)                       \
5243 _(one_add_del_ndp_entry_reply)                          \
5244 _(one_stats_flush_reply)                                \
5245 _(one_enable_disable_xtr_mode_reply)                    \
5246 _(one_enable_disable_pitr_mode_reply)                   \
5247 _(one_enable_disable_petr_mode_reply)                   \
5248 _(gpe_enable_disable_reply)                             \
5249 _(gpe_set_encap_mode_reply)                             \
5250 _(gpe_add_del_iface_reply)                              \
5251 _(gpe_add_del_native_fwd_rpath_reply)                   \
5252 _(af_packet_delete_reply)                               \
5253 _(policer_classify_set_interface_reply)                 \
5254 _(netmap_create_reply)                                  \
5255 _(netmap_delete_reply)                                  \
5256 _(set_ipfix_exporter_reply)                             \
5257 _(set_ipfix_classify_stream_reply)                      \
5258 _(ipfix_classify_table_add_del_reply)                   \
5259 _(flow_classify_set_interface_reply)                    \
5260 _(sw_interface_span_enable_disable_reply)               \
5261 _(pg_capture_reply)                                     \
5262 _(pg_enable_disable_reply)                              \
5263 _(ip_source_and_port_range_check_add_del_reply)         \
5264 _(ip_source_and_port_range_check_interface_add_del_reply)\
5265 _(delete_subif_reply)                                   \
5266 _(l2_interface_pbb_tag_rewrite_reply)                   \
5267 _(set_punt_reply)                                       \
5268 _(feature_enable_disable_reply)                         \
5269 _(sw_interface_tag_add_del_reply)                       \
5270 _(hw_interface_set_mtu_reply)                           \
5271 _(p2p_ethernet_add_reply)                               \
5272 _(p2p_ethernet_del_reply)                               \
5273 _(lldp_config_reply)                                    \
5274 _(sw_interface_set_lldp_reply)                          \
5275 _(tcp_configure_src_addresses_reply)                    \
5276 _(dns_enable_disable_reply)                             \
5277 _(dns_name_server_add_del_reply)                        \
5278 _(session_rule_add_del_reply)                           \
5279 _(ip_container_proxy_add_del_reply)                     \
5280 _(output_acl_set_interface_reply)                       \
5281 _(qos_record_enable_disable_reply)
5282
5283 #define _(n)                                    \
5284     static void vl_api_##n##_t_handler          \
5285     (vl_api_##n##_t * mp)                       \
5286     {                                           \
5287         vat_main_t * vam = &vat_main;           \
5288         i32 retval = ntohl(mp->retval);         \
5289         if (vam->async_mode) {                  \
5290             vam->async_errors += (retval < 0);  \
5291         } else {                                \
5292             vam->retval = retval;               \
5293             vam->result_ready = 1;              \
5294         }                                       \
5295     }
5296 foreach_standard_reply_retval_handler;
5297 #undef _
5298
5299 #define _(n)                                    \
5300     static void vl_api_##n##_t_handler_json     \
5301     (vl_api_##n##_t * mp)                       \
5302     {                                           \
5303         vat_main_t * vam = &vat_main;           \
5304         vat_json_node_t node;                   \
5305         vat_json_init_object(&node);            \
5306         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5307         vat_json_print(vam->ofp, &node);        \
5308         vam->retval = ntohl(mp->retval);        \
5309         vam->result_ready = 1;                  \
5310     }
5311 foreach_standard_reply_retval_handler;
5312 #undef _
5313
5314 /*
5315  * Table of message reply handlers, must include boilerplate handlers
5316  * we just generated
5317  */
5318
5319 #define foreach_vpe_api_reply_msg                                       \
5320 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5321 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5322 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5323 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5324 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5325 _(CLI_REPLY, cli_reply)                                                 \
5326 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5327 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5328   sw_interface_add_del_address_reply)                                   \
5329 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5330 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5331 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5332 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5333 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5334 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5335 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5336 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5337 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5338 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5339   sw_interface_set_l2_xconnect_reply)                                   \
5340 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5341   sw_interface_set_l2_bridge_reply)                                     \
5342 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5343 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5344 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5345 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5346 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5347 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5348 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5349 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5350 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5351 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5352 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5353 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5354 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5355 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5356 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5357 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5358 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5359 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5360 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5361 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5362 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5363 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5364 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5365 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5366 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5367 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5368 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5369 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5370 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5371 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5372   proxy_arp_intfc_enable_disable_reply)                                 \
5373 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5374 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5375   sw_interface_set_unnumbered_reply)                                    \
5376 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5377 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5378 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5379 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5380 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5381 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5382 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5383 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5384 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5385 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5386   sw_interface_ip6_enable_disable_reply)                                \
5387 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5388 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5389 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5390   sw_interface_ip6nd_ra_prefix_reply)                                   \
5391 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5392   sw_interface_ip6nd_ra_config_reply)                                   \
5393 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5394 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5395 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5396 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5397 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5398 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5399 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5400 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5401 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5402 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5403 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5404 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5405 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5406 classify_set_interface_ip_table_reply)                                  \
5407 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5408   classify_set_interface_l2_tables_reply)                               \
5409 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5410 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5411 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5412 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5413 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5414   l2tpv3_interface_enable_disable_reply)                                \
5415 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5416 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5417 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5418 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5419 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5420 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5421 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5422 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5423 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5424 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5425 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5426 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5427 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5428 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5429 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5430 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5431 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5432 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5433 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5434 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5435 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5436 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5437 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5438 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5439 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5440 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5441 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5442 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5443 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5444 _(L2_MACS_EVENT, l2_macs_event)                                         \
5445 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5446 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5447 _(IP_DETAILS, ip_details)                                               \
5448 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5449 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5450 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5451 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5452 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5453 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5454 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5455 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5456 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5457 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5458 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5459 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5460 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5461 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5462 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5463 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5464 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5465 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5466 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5467 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5468 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5469 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5470 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5471 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5472 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5473 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5474 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5475 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5476 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5477   one_map_register_enable_disable_reply)                                \
5478 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5479 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5480 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5481 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5482   one_map_register_fallback_threshold_reply)                            \
5483 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5484   one_rloc_probe_enable_disable_reply)                                  \
5485 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5486 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5487 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5488 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5489 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5490 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5491 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5492 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5493 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5494 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5495 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5496 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5497 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5498 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5499 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5500 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5501   show_one_stats_enable_disable_reply)                                  \
5502 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5503 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5504 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5505 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5506 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5507 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5508 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5509 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5510   one_enable_disable_pitr_mode_reply)                                   \
5511 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5512   one_enable_disable_petr_mode_reply)                                   \
5513 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5514 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5515 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5516 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5517 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5518 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5519 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5520 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5521 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5522 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5523 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5524 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5525   gpe_add_del_native_fwd_rpath_reply)                                   \
5526 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5527   gpe_fwd_entry_path_details)                                           \
5528 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5529 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5530   one_add_del_map_request_itr_rlocs_reply)                              \
5531 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5532   one_get_map_request_itr_rlocs_reply)                                  \
5533 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5534 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5535 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5536 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5537 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5538 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5539   show_one_map_register_state_reply)                                    \
5540 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5541 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5542   show_one_map_register_fallback_threshold_reply)                       \
5543 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5544 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5545 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5546 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5547 _(POLICER_DETAILS, policer_details)                                     \
5548 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5549 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5550 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5551 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5552 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5553 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5554 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5555 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5556 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5557 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5558 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5559 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5560 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5561 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5562 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5563 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5564 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5565 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5566 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5567 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5568 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5569 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5570 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5571 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5572 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5573  ip_source_and_port_range_check_add_del_reply)                          \
5574 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5575  ip_source_and_port_range_check_interface_add_del_reply)                \
5576 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5577 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5578 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5579 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5580 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5581 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5582 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5583 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5584 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5585 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5586 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5587 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5588 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5589 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5590 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5591 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5592 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5593 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5594 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5595 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5596 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5597 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5598 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5599 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5600 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5601 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5602 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5603 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5604
5605 #define foreach_standalone_reply_msg                                    \
5606 _(SW_INTERFACE_EVENT, sw_interface_event)
5607
5608 typedef struct
5609 {
5610   u8 *name;
5611   u32 value;
5612 } name_sort_t;
5613
5614 #define STR_VTR_OP_CASE(op)     \
5615     case L2_VTR_ ## op:         \
5616         return "" # op;
5617
5618 static const char *
5619 str_vtr_op (u32 vtr_op)
5620 {
5621   switch (vtr_op)
5622     {
5623       STR_VTR_OP_CASE (DISABLED);
5624       STR_VTR_OP_CASE (PUSH_1);
5625       STR_VTR_OP_CASE (PUSH_2);
5626       STR_VTR_OP_CASE (POP_1);
5627       STR_VTR_OP_CASE (POP_2);
5628       STR_VTR_OP_CASE (TRANSLATE_1_1);
5629       STR_VTR_OP_CASE (TRANSLATE_1_2);
5630       STR_VTR_OP_CASE (TRANSLATE_2_1);
5631       STR_VTR_OP_CASE (TRANSLATE_2_2);
5632     }
5633
5634   return "UNKNOWN";
5635 }
5636
5637 static int
5638 dump_sub_interface_table (vat_main_t * vam)
5639 {
5640   const sw_interface_subif_t *sub = NULL;
5641
5642   if (vam->json_output)
5643     {
5644       clib_warning
5645         ("JSON output supported only for VPE API calls and dump_stats_table");
5646       return -99;
5647     }
5648
5649   print (vam->ofp,
5650          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5651          "Interface", "sw_if_index",
5652          "sub id", "dot1ad", "tags", "outer id",
5653          "inner id", "exact", "default", "outer any", "inner any");
5654
5655   vec_foreach (sub, vam->sw_if_subif_table)
5656   {
5657     print (vam->ofp,
5658            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5659            sub->interface_name,
5660            sub->sw_if_index,
5661            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5662            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5663            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5664            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5665     if (sub->vtr_op != L2_VTR_DISABLED)
5666       {
5667         print (vam->ofp,
5668                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5669                "tag1: %d tag2: %d ]",
5670                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5671                sub->vtr_tag1, sub->vtr_tag2);
5672       }
5673   }
5674
5675   return 0;
5676 }
5677
5678 static int
5679 name_sort_cmp (void *a1, void *a2)
5680 {
5681   name_sort_t *n1 = a1;
5682   name_sort_t *n2 = a2;
5683
5684   return strcmp ((char *) n1->name, (char *) n2->name);
5685 }
5686
5687 static int
5688 dump_interface_table (vat_main_t * vam)
5689 {
5690   hash_pair_t *p;
5691   name_sort_t *nses = 0, *ns;
5692
5693   if (vam->json_output)
5694     {
5695       clib_warning
5696         ("JSON output supported only for VPE API calls and dump_stats_table");
5697       return -99;
5698     }
5699
5700   /* *INDENT-OFF* */
5701   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5702   ({
5703     vec_add2 (nses, ns, 1);
5704     ns->name = (u8 *)(p->key);
5705     ns->value = (u32) p->value[0];
5706   }));
5707   /* *INDENT-ON* */
5708
5709   vec_sort_with_function (nses, name_sort_cmp);
5710
5711   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5712   vec_foreach (ns, nses)
5713   {
5714     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5715   }
5716   vec_free (nses);
5717   return 0;
5718 }
5719
5720 static int
5721 dump_ip_table (vat_main_t * vam, int is_ipv6)
5722 {
5723   const ip_details_t *det = NULL;
5724   const ip_address_details_t *address = NULL;
5725   u32 i = ~0;
5726
5727   print (vam->ofp, "%-12s", "sw_if_index");
5728
5729   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5730   {
5731     i++;
5732     if (!det->present)
5733       {
5734         continue;
5735       }
5736     print (vam->ofp, "%-12d", i);
5737     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5738     if (!det->addr)
5739       {
5740         continue;
5741       }
5742     vec_foreach (address, det->addr)
5743     {
5744       print (vam->ofp,
5745              "            %-30U%-13d",
5746              is_ipv6 ? format_ip6_address : format_ip4_address,
5747              address->ip, address->prefix_length);
5748     }
5749   }
5750
5751   return 0;
5752 }
5753
5754 static int
5755 dump_ipv4_table (vat_main_t * vam)
5756 {
5757   if (vam->json_output)
5758     {
5759       clib_warning
5760         ("JSON output supported only for VPE API calls and dump_stats_table");
5761       return -99;
5762     }
5763
5764   return dump_ip_table (vam, 0);
5765 }
5766
5767 static int
5768 dump_ipv6_table (vat_main_t * vam)
5769 {
5770   if (vam->json_output)
5771     {
5772       clib_warning
5773         ("JSON output supported only for VPE API calls and dump_stats_table");
5774       return -99;
5775     }
5776
5777   return dump_ip_table (vam, 1);
5778 }
5779
5780 /*
5781  * Pass CLI buffers directly in the CLI_INBAND API message,
5782  * instead of an additional shared memory area.
5783  */
5784 static int
5785 exec_inband (vat_main_t * vam)
5786 {
5787   vl_api_cli_inband_t *mp;
5788   unformat_input_t *i = vam->input;
5789   int ret;
5790
5791   if (vec_len (i->buffer) == 0)
5792     return -1;
5793
5794   if (vam->exec_mode == 0 && unformat (i, "mode"))
5795     {
5796       vam->exec_mode = 1;
5797       return 0;
5798     }
5799   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5800     {
5801       vam->exec_mode = 0;
5802       return 0;
5803     }
5804
5805   /*
5806    * In order for the CLI command to work, it
5807    * must be a vector ending in \n, not a C-string ending
5808    * in \n\0.
5809    */
5810   u32 len = vec_len (vam->input->buffer);
5811   M2 (CLI_INBAND, mp, len);
5812   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5813
5814   S (mp);
5815   W (ret);
5816   /* json responses may or may not include a useful reply... */
5817   if (vec_len (vam->cmd_reply))
5818     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5819   return ret;
5820 }
5821
5822 int
5823 exec (vat_main_t * vam)
5824 {
5825   return exec_inband (vam);
5826 }
5827
5828 static int
5829 api_create_loopback (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_create_loopback_t *mp;
5833   vl_api_create_loopback_instance_t *mp_lbi;
5834   u8 mac_address[6];
5835   u8 mac_set = 0;
5836   u8 is_specified = 0;
5837   u32 user_instance = 0;
5838   int ret;
5839
5840   clib_memset (mac_address, 0, sizeof (mac_address));
5841
5842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5843     {
5844       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5845         mac_set = 1;
5846       if (unformat (i, "instance %d", &user_instance))
5847         is_specified = 1;
5848       else
5849         break;
5850     }
5851
5852   if (is_specified)
5853     {
5854       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5855       mp_lbi->is_specified = is_specified;
5856       if (is_specified)
5857         mp_lbi->user_instance = htonl (user_instance);
5858       if (mac_set)
5859         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5860       S (mp_lbi);
5861     }
5862   else
5863     {
5864       /* Construct the API message */
5865       M (CREATE_LOOPBACK, mp);
5866       if (mac_set)
5867         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5868       S (mp);
5869     }
5870
5871   W (ret);
5872   return ret;
5873 }
5874
5875 static int
5876 api_delete_loopback (vat_main_t * vam)
5877 {
5878   unformat_input_t *i = vam->input;
5879   vl_api_delete_loopback_t *mp;
5880   u32 sw_if_index = ~0;
5881   int ret;
5882
5883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5884     {
5885       if (unformat (i, "sw_if_index %d", &sw_if_index))
5886         ;
5887       else
5888         break;
5889     }
5890
5891   if (sw_if_index == ~0)
5892     {
5893       errmsg ("missing sw_if_index");
5894       return -99;
5895     }
5896
5897   /* Construct the API message */
5898   M (DELETE_LOOPBACK, mp);
5899   mp->sw_if_index = ntohl (sw_if_index);
5900
5901   S (mp);
5902   W (ret);
5903   return ret;
5904 }
5905
5906 static int
5907 api_want_interface_events (vat_main_t * vam)
5908 {
5909   unformat_input_t *i = vam->input;
5910   vl_api_want_interface_events_t *mp;
5911   int enable = -1;
5912   int ret;
5913
5914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5915     {
5916       if (unformat (i, "enable"))
5917         enable = 1;
5918       else if (unformat (i, "disable"))
5919         enable = 0;
5920       else
5921         break;
5922     }
5923
5924   if (enable == -1)
5925     {
5926       errmsg ("missing enable|disable");
5927       return -99;
5928     }
5929
5930   M (WANT_INTERFACE_EVENTS, mp);
5931   mp->enable_disable = enable;
5932
5933   vam->interface_event_display = enable;
5934
5935   S (mp);
5936   W (ret);
5937   return ret;
5938 }
5939
5940
5941 /* Note: non-static, called once to set up the initial intfc table */
5942 int
5943 api_sw_interface_dump (vat_main_t * vam)
5944 {
5945   vl_api_sw_interface_dump_t *mp;
5946   vl_api_control_ping_t *mp_ping;
5947   hash_pair_t *p;
5948   name_sort_t *nses = 0, *ns;
5949   sw_interface_subif_t *sub = NULL;
5950   int ret;
5951
5952   /* Toss the old name table */
5953   /* *INDENT-OFF* */
5954   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5955   ({
5956     vec_add2 (nses, ns, 1);
5957     ns->name = (u8 *)(p->key);
5958     ns->value = (u32) p->value[0];
5959   }));
5960   /* *INDENT-ON* */
5961
5962   hash_free (vam->sw_if_index_by_interface_name);
5963
5964   vec_foreach (ns, nses) vec_free (ns->name);
5965
5966   vec_free (nses);
5967
5968   vec_foreach (sub, vam->sw_if_subif_table)
5969   {
5970     vec_free (sub->interface_name);
5971   }
5972   vec_free (vam->sw_if_subif_table);
5973
5974   /* recreate the interface name hash table */
5975   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5976
5977   /*
5978    * Ask for all interface names. Otherwise, the epic catalog of
5979    * name filters becomes ridiculously long, and vat ends up needing
5980    * to be taught about new interface types.
5981    */
5982   M (SW_INTERFACE_DUMP, mp);
5983   S (mp);
5984
5985   /* Use a control ping for synchronization */
5986   MPING (CONTROL_PING, mp_ping);
5987   S (mp_ping);
5988
5989   W (ret);
5990   return ret;
5991 }
5992
5993 static int
5994 api_sw_interface_set_flags (vat_main_t * vam)
5995 {
5996   unformat_input_t *i = vam->input;
5997   vl_api_sw_interface_set_flags_t *mp;
5998   u32 sw_if_index;
5999   u8 sw_if_index_set = 0;
6000   u8 admin_up = 0;
6001   int ret;
6002
6003   /* Parse args required to build the message */
6004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6005     {
6006       if (unformat (i, "admin-up"))
6007         admin_up = 1;
6008       else if (unformat (i, "admin-down"))
6009         admin_up = 0;
6010       else
6011         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6012         sw_if_index_set = 1;
6013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6014         sw_if_index_set = 1;
6015       else
6016         break;
6017     }
6018
6019   if (sw_if_index_set == 0)
6020     {
6021       errmsg ("missing interface name or sw_if_index");
6022       return -99;
6023     }
6024
6025   /* Construct the API message */
6026   M (SW_INTERFACE_SET_FLAGS, mp);
6027   mp->sw_if_index = ntohl (sw_if_index);
6028   mp->admin_up_down = admin_up;
6029
6030   /* send it... */
6031   S (mp);
6032
6033   /* Wait for a reply, return the good/bad news... */
6034   W (ret);
6035   return ret;
6036 }
6037
6038 static int
6039 api_sw_interface_set_rx_mode (vat_main_t * vam)
6040 {
6041   unformat_input_t *i = vam->input;
6042   vl_api_sw_interface_set_rx_mode_t *mp;
6043   u32 sw_if_index;
6044   u8 sw_if_index_set = 0;
6045   int ret;
6046   u8 queue_id_valid = 0;
6047   u32 queue_id;
6048   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6049
6050   /* Parse args required to build the message */
6051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6052     {
6053       if (unformat (i, "queue %d", &queue_id))
6054         queue_id_valid = 1;
6055       else if (unformat (i, "polling"))
6056         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6057       else if (unformat (i, "interrupt"))
6058         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6059       else if (unformat (i, "adaptive"))
6060         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6061       else
6062         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6063         sw_if_index_set = 1;
6064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6065         sw_if_index_set = 1;
6066       else
6067         break;
6068     }
6069
6070   if (sw_if_index_set == 0)
6071     {
6072       errmsg ("missing interface name or sw_if_index");
6073       return -99;
6074     }
6075   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6076     {
6077       errmsg ("missing rx-mode");
6078       return -99;
6079     }
6080
6081   /* Construct the API message */
6082   M (SW_INTERFACE_SET_RX_MODE, mp);
6083   mp->sw_if_index = ntohl (sw_if_index);
6084   mp->mode = mode;
6085   mp->queue_id_valid = queue_id_valid;
6086   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6087
6088   /* send it... */
6089   S (mp);
6090
6091   /* Wait for a reply, return the good/bad news... */
6092   W (ret);
6093   return ret;
6094 }
6095
6096 static int
6097 api_sw_interface_set_rx_placement (vat_main_t * vam)
6098 {
6099   unformat_input_t *i = vam->input;
6100   vl_api_sw_interface_set_rx_placement_t *mp;
6101   u32 sw_if_index;
6102   u8 sw_if_index_set = 0;
6103   int ret;
6104   u8 is_main = 0;
6105   u32 queue_id, thread_index;
6106
6107   /* Parse args required to build the message */
6108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6109     {
6110       if (unformat (i, "queue %d", &queue_id))
6111         ;
6112       else if (unformat (i, "main"))
6113         is_main = 1;
6114       else if (unformat (i, "worker %d", &thread_index))
6115         ;
6116       else
6117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6118         sw_if_index_set = 1;
6119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         sw_if_index_set = 1;
6121       else
6122         break;
6123     }
6124
6125   if (sw_if_index_set == 0)
6126     {
6127       errmsg ("missing interface name or sw_if_index");
6128       return -99;
6129     }
6130
6131   if (is_main)
6132     thread_index = 0;
6133   /* Construct the API message */
6134   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6135   mp->sw_if_index = ntohl (sw_if_index);
6136   mp->worker_id = ntohl (thread_index);
6137   mp->queue_id = ntohl (queue_id);
6138   mp->is_main = is_main;
6139
6140   /* send it... */
6141   S (mp);
6142   /* Wait for a reply, return the good/bad news... */
6143   W (ret);
6144   return ret;
6145 }
6146
6147 static void vl_api_sw_interface_rx_placement_details_t_handler
6148   (vl_api_sw_interface_rx_placement_details_t * mp)
6149 {
6150   vat_main_t *vam = &vat_main;
6151   u32 worker_id = ntohl (mp->worker_id);
6152
6153   print (vam->ofp,
6154          "\n%-11d %-11s %-6d %-5d %-9s",
6155          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6156          worker_id, ntohl (mp->queue_id),
6157          (mp->mode ==
6158           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6159 }
6160
6161 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6162   (vl_api_sw_interface_rx_placement_details_t * mp)
6163 {
6164   vat_main_t *vam = &vat_main;
6165   vat_json_node_t *node = NULL;
6166
6167   if (VAT_JSON_ARRAY != vam->json_tree.type)
6168     {
6169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6170       vat_json_init_array (&vam->json_tree);
6171     }
6172   node = vat_json_array_add (&vam->json_tree);
6173
6174   vat_json_init_object (node);
6175   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6176   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6177   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6178   vat_json_object_add_uint (node, "mode", mp->mode);
6179 }
6180
6181 static int
6182 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6183 {
6184   unformat_input_t *i = vam->input;
6185   vl_api_sw_interface_rx_placement_dump_t *mp;
6186   vl_api_control_ping_t *mp_ping;
6187   int ret;
6188   u32 sw_if_index;
6189   u8 sw_if_index_set = 0;
6190
6191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6192     {
6193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6194         sw_if_index_set++;
6195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6196         sw_if_index_set++;
6197       else
6198         break;
6199     }
6200
6201   print (vam->ofp,
6202          "\n%-11s %-11s %-6s %-5s %-4s",
6203          "sw_if_index", "main/worker", "thread", "queue", "mode");
6204
6205   /* Dump Interface rx placement */
6206   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6207
6208   if (sw_if_index_set)
6209     mp->sw_if_index = htonl (sw_if_index);
6210   else
6211     mp->sw_if_index = ~0;
6212
6213   S (mp);
6214
6215   /* Use a control ping for synchronization */
6216   MPING (CONTROL_PING, mp_ping);
6217   S (mp_ping);
6218
6219   W (ret);
6220   return ret;
6221 }
6222
6223 static int
6224 api_sw_interface_clear_stats (vat_main_t * vam)
6225 {
6226   unformat_input_t *i = vam->input;
6227   vl_api_sw_interface_clear_stats_t *mp;
6228   u32 sw_if_index;
6229   u8 sw_if_index_set = 0;
6230   int ret;
6231
6232   /* Parse args required to build the message */
6233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6234     {
6235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6236         sw_if_index_set = 1;
6237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6238         sw_if_index_set = 1;
6239       else
6240         break;
6241     }
6242
6243   /* Construct the API message */
6244   M (SW_INTERFACE_CLEAR_STATS, mp);
6245
6246   if (sw_if_index_set == 1)
6247     mp->sw_if_index = ntohl (sw_if_index);
6248   else
6249     mp->sw_if_index = ~0;
6250
6251   /* send it... */
6252   S (mp);
6253
6254   /* Wait for a reply, return the good/bad news... */
6255   W (ret);
6256   return ret;
6257 }
6258
6259 static int
6260 api_sw_interface_add_del_address (vat_main_t * vam)
6261 {
6262   unformat_input_t *i = vam->input;
6263   vl_api_sw_interface_add_del_address_t *mp;
6264   u32 sw_if_index;
6265   u8 sw_if_index_set = 0;
6266   u8 is_add = 1, del_all = 0;
6267   u32 address_length = 0;
6268   u8 v4_address_set = 0;
6269   u8 v6_address_set = 0;
6270   ip4_address_t v4address;
6271   ip6_address_t v6address;
6272   int ret;
6273
6274   /* Parse args required to build the message */
6275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6276     {
6277       if (unformat (i, "del-all"))
6278         del_all = 1;
6279       else if (unformat (i, "del"))
6280         is_add = 0;
6281       else
6282         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6283         sw_if_index_set = 1;
6284       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6285         sw_if_index_set = 1;
6286       else if (unformat (i, "%U/%d",
6287                          unformat_ip4_address, &v4address, &address_length))
6288         v4_address_set = 1;
6289       else if (unformat (i, "%U/%d",
6290                          unformat_ip6_address, &v6address, &address_length))
6291         v6_address_set = 1;
6292       else
6293         break;
6294     }
6295
6296   if (sw_if_index_set == 0)
6297     {
6298       errmsg ("missing interface name or sw_if_index");
6299       return -99;
6300     }
6301   if (v4_address_set && v6_address_set)
6302     {
6303       errmsg ("both v4 and v6 addresses set");
6304       return -99;
6305     }
6306   if (!v4_address_set && !v6_address_set && !del_all)
6307     {
6308       errmsg ("no addresses set");
6309       return -99;
6310     }
6311
6312   /* Construct the API message */
6313   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6314
6315   mp->sw_if_index = ntohl (sw_if_index);
6316   mp->is_add = is_add;
6317   mp->del_all = del_all;
6318   if (v6_address_set)
6319     {
6320       mp->is_ipv6 = 1;
6321       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6322     }
6323   else
6324     {
6325       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6326     }
6327   mp->address_length = address_length;
6328
6329   /* send it... */
6330   S (mp);
6331
6332   /* Wait for a reply, return good/bad news  */
6333   W (ret);
6334   return ret;
6335 }
6336
6337 static int
6338 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6339 {
6340   unformat_input_t *i = vam->input;
6341   vl_api_sw_interface_set_mpls_enable_t *mp;
6342   u32 sw_if_index;
6343   u8 sw_if_index_set = 0;
6344   u8 enable = 1;
6345   int ret;
6346
6347   /* Parse args required to build the message */
6348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6349     {
6350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6351         sw_if_index_set = 1;
6352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6353         sw_if_index_set = 1;
6354       else if (unformat (i, "disable"))
6355         enable = 0;
6356       else if (unformat (i, "dis"))
6357         enable = 0;
6358       else
6359         break;
6360     }
6361
6362   if (sw_if_index_set == 0)
6363     {
6364       errmsg ("missing interface name or sw_if_index");
6365       return -99;
6366     }
6367
6368   /* Construct the API message */
6369   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6370
6371   mp->sw_if_index = ntohl (sw_if_index);
6372   mp->enable = enable;
6373
6374   /* send it... */
6375   S (mp);
6376
6377   /* Wait for a reply... */
6378   W (ret);
6379   return ret;
6380 }
6381
6382 static int
6383 api_sw_interface_set_table (vat_main_t * vam)
6384 {
6385   unformat_input_t *i = vam->input;
6386   vl_api_sw_interface_set_table_t *mp;
6387   u32 sw_if_index, vrf_id = 0;
6388   u8 sw_if_index_set = 0;
6389   u8 is_ipv6 = 0;
6390   int ret;
6391
6392   /* Parse args required to build the message */
6393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6394     {
6395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6396         sw_if_index_set = 1;
6397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6398         sw_if_index_set = 1;
6399       else if (unformat (i, "vrf %d", &vrf_id))
6400         ;
6401       else if (unformat (i, "ipv6"))
6402         is_ipv6 = 1;
6403       else
6404         break;
6405     }
6406
6407   if (sw_if_index_set == 0)
6408     {
6409       errmsg ("missing interface name or sw_if_index");
6410       return -99;
6411     }
6412
6413   /* Construct the API message */
6414   M (SW_INTERFACE_SET_TABLE, mp);
6415
6416   mp->sw_if_index = ntohl (sw_if_index);
6417   mp->is_ipv6 = is_ipv6;
6418   mp->vrf_id = ntohl (vrf_id);
6419
6420   /* send it... */
6421   S (mp);
6422
6423   /* Wait for a reply... */
6424   W (ret);
6425   return ret;
6426 }
6427
6428 static void vl_api_sw_interface_get_table_reply_t_handler
6429   (vl_api_sw_interface_get_table_reply_t * mp)
6430 {
6431   vat_main_t *vam = &vat_main;
6432
6433   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6434
6435   vam->retval = ntohl (mp->retval);
6436   vam->result_ready = 1;
6437
6438 }
6439
6440 static void vl_api_sw_interface_get_table_reply_t_handler_json
6441   (vl_api_sw_interface_get_table_reply_t * mp)
6442 {
6443   vat_main_t *vam = &vat_main;
6444   vat_json_node_t node;
6445
6446   vat_json_init_object (&node);
6447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6448   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6449
6450   vat_json_print (vam->ofp, &node);
6451   vat_json_free (&node);
6452
6453   vam->retval = ntohl (mp->retval);
6454   vam->result_ready = 1;
6455 }
6456
6457 static int
6458 api_sw_interface_get_table (vat_main_t * vam)
6459 {
6460   unformat_input_t *i = vam->input;
6461   vl_api_sw_interface_get_table_t *mp;
6462   u32 sw_if_index;
6463   u8 sw_if_index_set = 0;
6464   u8 is_ipv6 = 0;
6465   int ret;
6466
6467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6468     {
6469       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6470         sw_if_index_set = 1;
6471       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6472         sw_if_index_set = 1;
6473       else if (unformat (i, "ipv6"))
6474         is_ipv6 = 1;
6475       else
6476         break;
6477     }
6478
6479   if (sw_if_index_set == 0)
6480     {
6481       errmsg ("missing interface name or sw_if_index");
6482       return -99;
6483     }
6484
6485   M (SW_INTERFACE_GET_TABLE, mp);
6486   mp->sw_if_index = htonl (sw_if_index);
6487   mp->is_ipv6 = is_ipv6;
6488
6489   S (mp);
6490   W (ret);
6491   return ret;
6492 }
6493
6494 static int
6495 api_sw_interface_set_vpath (vat_main_t * vam)
6496 {
6497   unformat_input_t *i = vam->input;
6498   vl_api_sw_interface_set_vpath_t *mp;
6499   u32 sw_if_index = 0;
6500   u8 sw_if_index_set = 0;
6501   u8 is_enable = 0;
6502   int ret;
6503
6504   /* Parse args required to build the message */
6505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506     {
6507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6508         sw_if_index_set = 1;
6509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6510         sw_if_index_set = 1;
6511       else if (unformat (i, "enable"))
6512         is_enable = 1;
6513       else if (unformat (i, "disable"))
6514         is_enable = 0;
6515       else
6516         break;
6517     }
6518
6519   if (sw_if_index_set == 0)
6520     {
6521       errmsg ("missing interface name or sw_if_index");
6522       return -99;
6523     }
6524
6525   /* Construct the API message */
6526   M (SW_INTERFACE_SET_VPATH, mp);
6527
6528   mp->sw_if_index = ntohl (sw_if_index);
6529   mp->enable = is_enable;
6530
6531   /* send it... */
6532   S (mp);
6533
6534   /* Wait for a reply... */
6535   W (ret);
6536   return ret;
6537 }
6538
6539 static int
6540 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6541 {
6542   unformat_input_t *i = vam->input;
6543   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6544   u32 sw_if_index = 0;
6545   u8 sw_if_index_set = 0;
6546   u8 is_enable = 1;
6547   u8 is_ipv6 = 0;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6554         sw_if_index_set = 1;
6555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6556         sw_if_index_set = 1;
6557       else if (unformat (i, "enable"))
6558         is_enable = 1;
6559       else if (unformat (i, "disable"))
6560         is_enable = 0;
6561       else if (unformat (i, "ip4"))
6562         is_ipv6 = 0;
6563       else if (unformat (i, "ip6"))
6564         is_ipv6 = 1;
6565       else
6566         break;
6567     }
6568
6569   if (sw_if_index_set == 0)
6570     {
6571       errmsg ("missing interface name or sw_if_index");
6572       return -99;
6573     }
6574
6575   /* Construct the API message */
6576   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6577
6578   mp->sw_if_index = ntohl (sw_if_index);
6579   mp->enable = is_enable;
6580   mp->is_ipv6 = is_ipv6;
6581
6582   /* send it... */
6583   S (mp);
6584
6585   /* Wait for a reply... */
6586   W (ret);
6587   return ret;
6588 }
6589
6590 static int
6591 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6592 {
6593   unformat_input_t *i = vam->input;
6594   vl_api_sw_interface_set_geneve_bypass_t *mp;
6595   u32 sw_if_index = 0;
6596   u8 sw_if_index_set = 0;
6597   u8 is_enable = 1;
6598   u8 is_ipv6 = 0;
6599   int ret;
6600
6601   /* Parse args required to build the message */
6602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6603     {
6604       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6605         sw_if_index_set = 1;
6606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6607         sw_if_index_set = 1;
6608       else if (unformat (i, "enable"))
6609         is_enable = 1;
6610       else if (unformat (i, "disable"))
6611         is_enable = 0;
6612       else if (unformat (i, "ip4"))
6613         is_ipv6 = 0;
6614       else if (unformat (i, "ip6"))
6615         is_ipv6 = 1;
6616       else
6617         break;
6618     }
6619
6620   if (sw_if_index_set == 0)
6621     {
6622       errmsg ("missing interface name or sw_if_index");
6623       return -99;
6624     }
6625
6626   /* Construct the API message */
6627   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6628
6629   mp->sw_if_index = ntohl (sw_if_index);
6630   mp->enable = is_enable;
6631   mp->is_ipv6 = is_ipv6;
6632
6633   /* send it... */
6634   S (mp);
6635
6636   /* Wait for a reply... */
6637   W (ret);
6638   return ret;
6639 }
6640
6641 static int
6642 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6643 {
6644   unformat_input_t *i = vam->input;
6645   vl_api_sw_interface_set_l2_xconnect_t *mp;
6646   u32 rx_sw_if_index;
6647   u8 rx_sw_if_index_set = 0;
6648   u32 tx_sw_if_index;
6649   u8 tx_sw_if_index_set = 0;
6650   u8 enable = 1;
6651   int ret;
6652
6653   /* Parse args required to build the message */
6654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6655     {
6656       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6657         rx_sw_if_index_set = 1;
6658       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6659         tx_sw_if_index_set = 1;
6660       else if (unformat (i, "rx"))
6661         {
6662           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663             {
6664               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6665                             &rx_sw_if_index))
6666                 rx_sw_if_index_set = 1;
6667             }
6668           else
6669             break;
6670         }
6671       else if (unformat (i, "tx"))
6672         {
6673           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6674             {
6675               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6676                             &tx_sw_if_index))
6677                 tx_sw_if_index_set = 1;
6678             }
6679           else
6680             break;
6681         }
6682       else if (unformat (i, "enable"))
6683         enable = 1;
6684       else if (unformat (i, "disable"))
6685         enable = 0;
6686       else
6687         break;
6688     }
6689
6690   if (rx_sw_if_index_set == 0)
6691     {
6692       errmsg ("missing rx interface name or rx_sw_if_index");
6693       return -99;
6694     }
6695
6696   if (enable && (tx_sw_if_index_set == 0))
6697     {
6698       errmsg ("missing tx interface name or tx_sw_if_index");
6699       return -99;
6700     }
6701
6702   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6703
6704   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6705   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6706   mp->enable = enable;
6707
6708   S (mp);
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static int
6714 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6715 {
6716   unformat_input_t *i = vam->input;
6717   vl_api_sw_interface_set_l2_bridge_t *mp;
6718   vl_api_l2_port_type_t port_type;
6719   u32 rx_sw_if_index;
6720   u8 rx_sw_if_index_set = 0;
6721   u32 bd_id;
6722   u8 bd_id_set = 0;
6723   u32 shg = 0;
6724   u8 enable = 1;
6725   int ret;
6726
6727   port_type = L2_API_PORT_TYPE_NORMAL;
6728
6729   /* Parse args required to build the message */
6730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6731     {
6732       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6733         rx_sw_if_index_set = 1;
6734       else if (unformat (i, "bd_id %d", &bd_id))
6735         bd_id_set = 1;
6736       else
6737         if (unformat
6738             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6739         rx_sw_if_index_set = 1;
6740       else if (unformat (i, "shg %d", &shg))
6741         ;
6742       else if (unformat (i, "bvi"))
6743         port_type = L2_API_PORT_TYPE_BVI;
6744       else if (unformat (i, "uu-fwd"))
6745         port_type = L2_API_PORT_TYPE_UU_FWD;
6746       else if (unformat (i, "enable"))
6747         enable = 1;
6748       else if (unformat (i, "disable"))
6749         enable = 0;
6750       else
6751         break;
6752     }
6753
6754   if (rx_sw_if_index_set == 0)
6755     {
6756       errmsg ("missing rx interface name or sw_if_index");
6757       return -99;
6758     }
6759
6760   if (enable && (bd_id_set == 0))
6761     {
6762       errmsg ("missing bridge domain");
6763       return -99;
6764     }
6765
6766   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6767
6768   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6769   mp->bd_id = ntohl (bd_id);
6770   mp->shg = (u8) shg;
6771   mp->port_type = ntohl (port_type);
6772   mp->enable = enable;
6773
6774   S (mp);
6775   W (ret);
6776   return ret;
6777 }
6778
6779 static int
6780 api_bridge_domain_dump (vat_main_t * vam)
6781 {
6782   unformat_input_t *i = vam->input;
6783   vl_api_bridge_domain_dump_t *mp;
6784   vl_api_control_ping_t *mp_ping;
6785   u32 bd_id = ~0;
6786   int ret;
6787
6788   /* Parse args required to build the message */
6789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6790     {
6791       if (unformat (i, "bd_id %d", &bd_id))
6792         ;
6793       else
6794         break;
6795     }
6796
6797   M (BRIDGE_DOMAIN_DUMP, mp);
6798   mp->bd_id = ntohl (bd_id);
6799   S (mp);
6800
6801   /* Use a control ping for synchronization */
6802   MPING (CONTROL_PING, mp_ping);
6803   S (mp_ping);
6804
6805   W (ret);
6806   return ret;
6807 }
6808
6809 static int
6810 api_bridge_domain_add_del (vat_main_t * vam)
6811 {
6812   unformat_input_t *i = vam->input;
6813   vl_api_bridge_domain_add_del_t *mp;
6814   u32 bd_id = ~0;
6815   u8 is_add = 1;
6816   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6817   u8 *bd_tag = NULL;
6818   u32 mac_age = 0;
6819   int ret;
6820
6821   /* Parse args required to build the message */
6822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6823     {
6824       if (unformat (i, "bd_id %d", &bd_id))
6825         ;
6826       else if (unformat (i, "flood %d", &flood))
6827         ;
6828       else if (unformat (i, "uu-flood %d", &uu_flood))
6829         ;
6830       else if (unformat (i, "forward %d", &forward))
6831         ;
6832       else if (unformat (i, "learn %d", &learn))
6833         ;
6834       else if (unformat (i, "arp-term %d", &arp_term))
6835         ;
6836       else if (unformat (i, "mac-age %d", &mac_age))
6837         ;
6838       else if (unformat (i, "bd-tag %s", &bd_tag))
6839         ;
6840       else if (unformat (i, "del"))
6841         {
6842           is_add = 0;
6843           flood = uu_flood = forward = learn = 0;
6844         }
6845       else
6846         break;
6847     }
6848
6849   if (bd_id == ~0)
6850     {
6851       errmsg ("missing bridge domain");
6852       ret = -99;
6853       goto done;
6854     }
6855
6856   if (mac_age > 255)
6857     {
6858       errmsg ("mac age must be less than 256 ");
6859       ret = -99;
6860       goto done;
6861     }
6862
6863   if ((bd_tag) && (vec_len (bd_tag) > 63))
6864     {
6865       errmsg ("bd-tag cannot be longer than 63");
6866       ret = -99;
6867       goto done;
6868     }
6869
6870   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6871
6872   mp->bd_id = ntohl (bd_id);
6873   mp->flood = flood;
6874   mp->uu_flood = uu_flood;
6875   mp->forward = forward;
6876   mp->learn = learn;
6877   mp->arp_term = arp_term;
6878   mp->is_add = is_add;
6879   mp->mac_age = (u8) mac_age;
6880   if (bd_tag)
6881     {
6882       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6883       mp->bd_tag[vec_len (bd_tag)] = 0;
6884     }
6885   S (mp);
6886   W (ret);
6887
6888 done:
6889   vec_free (bd_tag);
6890   return ret;
6891 }
6892
6893 static int
6894 api_l2fib_flush_bd (vat_main_t * vam)
6895 {
6896   unformat_input_t *i = vam->input;
6897   vl_api_l2fib_flush_bd_t *mp;
6898   u32 bd_id = ~0;
6899   int ret;
6900
6901   /* Parse args required to build the message */
6902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6903     {
6904       if (unformat (i, "bd_id %d", &bd_id));
6905       else
6906         break;
6907     }
6908
6909   if (bd_id == ~0)
6910     {
6911       errmsg ("missing bridge domain");
6912       return -99;
6913     }
6914
6915   M (L2FIB_FLUSH_BD, mp);
6916
6917   mp->bd_id = htonl (bd_id);
6918
6919   S (mp);
6920   W (ret);
6921   return ret;
6922 }
6923
6924 static int
6925 api_l2fib_flush_int (vat_main_t * vam)
6926 {
6927   unformat_input_t *i = vam->input;
6928   vl_api_l2fib_flush_int_t *mp;
6929   u32 sw_if_index = ~0;
6930   int ret;
6931
6932   /* Parse args required to build the message */
6933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6934     {
6935       if (unformat (i, "sw_if_index %d", &sw_if_index));
6936       else
6937         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6938       else
6939         break;
6940     }
6941
6942   if (sw_if_index == ~0)
6943     {
6944       errmsg ("missing interface name or sw_if_index");
6945       return -99;
6946     }
6947
6948   M (L2FIB_FLUSH_INT, mp);
6949
6950   mp->sw_if_index = ntohl (sw_if_index);
6951
6952   S (mp);
6953   W (ret);
6954   return ret;
6955 }
6956
6957 static int
6958 api_l2fib_add_del (vat_main_t * vam)
6959 {
6960   unformat_input_t *i = vam->input;
6961   vl_api_l2fib_add_del_t *mp;
6962   f64 timeout;
6963   u8 mac[6] = { 0 };
6964   u8 mac_set = 0;
6965   u32 bd_id;
6966   u8 bd_id_set = 0;
6967   u32 sw_if_index = 0;
6968   u8 sw_if_index_set = 0;
6969   u8 is_add = 1;
6970   u8 static_mac = 0;
6971   u8 filter_mac = 0;
6972   u8 bvi_mac = 0;
6973   int count = 1;
6974   f64 before = 0;
6975   int j;
6976
6977   /* Parse args required to build the message */
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6981         mac_set = 1;
6982       else if (unformat (i, "bd_id %d", &bd_id))
6983         bd_id_set = 1;
6984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6985         sw_if_index_set = 1;
6986       else if (unformat (i, "sw_if"))
6987         {
6988           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6989             {
6990               if (unformat
6991                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6992                 sw_if_index_set = 1;
6993             }
6994           else
6995             break;
6996         }
6997       else if (unformat (i, "static"))
6998         static_mac = 1;
6999       else if (unformat (i, "filter"))
7000         {
7001           filter_mac = 1;
7002           static_mac = 1;
7003         }
7004       else if (unformat (i, "bvi"))
7005         {
7006           bvi_mac = 1;
7007           static_mac = 1;
7008         }
7009       else if (unformat (i, "del"))
7010         is_add = 0;
7011       else if (unformat (i, "count %d", &count))
7012         ;
7013       else
7014         break;
7015     }
7016
7017   if (mac_set == 0)
7018     {
7019       errmsg ("missing mac address");
7020       return -99;
7021     }
7022
7023   if (bd_id_set == 0)
7024     {
7025       errmsg ("missing bridge domain");
7026       return -99;
7027     }
7028
7029   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7030     {
7031       errmsg ("missing interface name or sw_if_index");
7032       return -99;
7033     }
7034
7035   if (count > 1)
7036     {
7037       /* Turn on async mode */
7038       vam->async_mode = 1;
7039       vam->async_errors = 0;
7040       before = vat_time_now (vam);
7041     }
7042
7043   for (j = 0; j < count; j++)
7044     {
7045       M (L2FIB_ADD_DEL, mp);
7046
7047       clib_memcpy (mp->mac, mac, 6);
7048       mp->bd_id = ntohl (bd_id);
7049       mp->is_add = is_add;
7050       mp->sw_if_index = ntohl (sw_if_index);
7051
7052       if (is_add)
7053         {
7054           mp->static_mac = static_mac;
7055           mp->filter_mac = filter_mac;
7056           mp->bvi_mac = bvi_mac;
7057         }
7058       increment_mac_address (mac);
7059       /* send it... */
7060       S (mp);
7061     }
7062
7063   if (count > 1)
7064     {
7065       vl_api_control_ping_t *mp_ping;
7066       f64 after;
7067
7068       /* Shut off async mode */
7069       vam->async_mode = 0;
7070
7071       MPING (CONTROL_PING, mp_ping);
7072       S (mp_ping);
7073
7074       timeout = vat_time_now (vam) + 1.0;
7075       while (vat_time_now (vam) < timeout)
7076         if (vam->result_ready == 1)
7077           goto out;
7078       vam->retval = -99;
7079
7080     out:
7081       if (vam->retval == -99)
7082         errmsg ("timeout");
7083
7084       if (vam->async_errors > 0)
7085         {
7086           errmsg ("%d asynchronous errors", vam->async_errors);
7087           vam->retval = -98;
7088         }
7089       vam->async_errors = 0;
7090       after = vat_time_now (vam);
7091
7092       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7093              count, after - before, count / (after - before));
7094     }
7095   else
7096     {
7097       int ret;
7098
7099       /* Wait for a reply... */
7100       W (ret);
7101       return ret;
7102     }
7103   /* Return the good/bad news */
7104   return (vam->retval);
7105 }
7106
7107 static int
7108 api_bridge_domain_set_mac_age (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_bridge_domain_set_mac_age_t *mp;
7112   u32 bd_id = ~0;
7113   u32 mac_age = 0;
7114   int ret;
7115
7116   /* Parse args required to build the message */
7117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7118     {
7119       if (unformat (i, "bd_id %d", &bd_id));
7120       else if (unformat (i, "mac-age %d", &mac_age));
7121       else
7122         break;
7123     }
7124
7125   if (bd_id == ~0)
7126     {
7127       errmsg ("missing bridge domain");
7128       return -99;
7129     }
7130
7131   if (mac_age > 255)
7132     {
7133       errmsg ("mac age must be less than 256 ");
7134       return -99;
7135     }
7136
7137   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7138
7139   mp->bd_id = htonl (bd_id);
7140   mp->mac_age = (u8) mac_age;
7141
7142   S (mp);
7143   W (ret);
7144   return ret;
7145 }
7146
7147 static int
7148 api_l2_flags (vat_main_t * vam)
7149 {
7150   unformat_input_t *i = vam->input;
7151   vl_api_l2_flags_t *mp;
7152   u32 sw_if_index;
7153   u32 flags = 0;
7154   u8 sw_if_index_set = 0;
7155   u8 is_set = 0;
7156   int ret;
7157
7158   /* Parse args required to build the message */
7159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7160     {
7161       if (unformat (i, "sw_if_index %d", &sw_if_index))
7162         sw_if_index_set = 1;
7163       else if (unformat (i, "sw_if"))
7164         {
7165           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7166             {
7167               if (unformat
7168                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7169                 sw_if_index_set = 1;
7170             }
7171           else
7172             break;
7173         }
7174       else if (unformat (i, "learn"))
7175         flags |= L2_LEARN;
7176       else if (unformat (i, "forward"))
7177         flags |= L2_FWD;
7178       else if (unformat (i, "flood"))
7179         flags |= L2_FLOOD;
7180       else if (unformat (i, "uu-flood"))
7181         flags |= L2_UU_FLOOD;
7182       else if (unformat (i, "arp-term"))
7183         flags |= L2_ARP_TERM;
7184       else if (unformat (i, "off"))
7185         is_set = 0;
7186       else if (unformat (i, "disable"))
7187         is_set = 0;
7188       else
7189         break;
7190     }
7191
7192   if (sw_if_index_set == 0)
7193     {
7194       errmsg ("missing interface name or sw_if_index");
7195       return -99;
7196     }
7197
7198   M (L2_FLAGS, mp);
7199
7200   mp->sw_if_index = ntohl (sw_if_index);
7201   mp->feature_bitmap = ntohl (flags);
7202   mp->is_set = is_set;
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static int
7210 api_bridge_flags (vat_main_t * vam)
7211 {
7212   unformat_input_t *i = vam->input;
7213   vl_api_bridge_flags_t *mp;
7214   u32 bd_id;
7215   u8 bd_id_set = 0;
7216   u8 is_set = 1;
7217   bd_flags_t flags = 0;
7218   int ret;
7219
7220   /* Parse args required to build the message */
7221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222     {
7223       if (unformat (i, "bd_id %d", &bd_id))
7224         bd_id_set = 1;
7225       else if (unformat (i, "learn"))
7226         flags |= BRIDGE_API_FLAG_LEARN;
7227       else if (unformat (i, "forward"))
7228         flags |= BRIDGE_API_FLAG_FWD;
7229       else if (unformat (i, "flood"))
7230         flags |= BRIDGE_API_FLAG_FLOOD;
7231       else if (unformat (i, "uu-flood"))
7232         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7233       else if (unformat (i, "arp-term"))
7234         flags |= BRIDGE_API_FLAG_ARP_TERM;
7235       else if (unformat (i, "off"))
7236         is_set = 0;
7237       else if (unformat (i, "disable"))
7238         is_set = 0;
7239       else
7240         break;
7241     }
7242
7243   if (bd_id_set == 0)
7244     {
7245       errmsg ("missing bridge domain");
7246       return -99;
7247     }
7248
7249   M (BRIDGE_FLAGS, mp);
7250
7251   mp->bd_id = ntohl (bd_id);
7252   mp->flags = ntohl (flags);
7253   mp->is_set = is_set;
7254
7255   S (mp);
7256   W (ret);
7257   return ret;
7258 }
7259
7260 static int
7261 api_bd_ip_mac_add_del (vat_main_t * vam)
7262 {
7263   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7264   vl_api_mac_address_t mac = { 0 };
7265   unformat_input_t *i = vam->input;
7266   vl_api_bd_ip_mac_add_del_t *mp;
7267   ip46_type_t type;
7268   u32 bd_id;
7269   u8 is_ipv6 = 0;
7270   u8 is_add = 1;
7271   u8 bd_id_set = 0;
7272   u8 ip_set = 0;
7273   u8 mac_set = 0;
7274   u8 macaddr[6];
7275   int ret;
7276
7277
7278   /* Parse args required to build the message */
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "bd_id %d", &bd_id))
7282         {
7283           bd_id_set++;
7284         }
7285       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7286         {
7287           ip_set++;
7288         }
7289       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7290         {
7291           mac_set++;
7292         }
7293       else if (unformat (i, "del"))
7294         is_add = 0;
7295       else
7296         break;
7297     }
7298
7299   if (bd_id_set == 0)
7300     {
7301       errmsg ("missing bridge domain");
7302       return -99;
7303     }
7304   else if (ip_set == 0)
7305     {
7306       errmsg ("missing IP address");
7307       return -99;
7308     }
7309   else if (mac_set == 0)
7310     {
7311       errmsg ("missing MAC address");
7312       return -99;
7313     }
7314
7315   M (BD_IP_MAC_ADD_DEL, mp);
7316
7317   mp->bd_id = ntohl (bd_id);
7318   mp->is_add = is_add;
7319
7320   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7321   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7322
7323   S (mp);
7324   W (ret);
7325   return ret;
7326 }
7327
7328 static int
7329 api_bd_ip_mac_flush (vat_main_t * vam)
7330 {
7331   unformat_input_t *i = vam->input;
7332   vl_api_bd_ip_mac_flush_t *mp;
7333   u32 bd_id;
7334   u8 bd_id_set = 0;
7335   int ret;
7336
7337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7338     {
7339       if (unformat (i, "bd_id %d", &bd_id))
7340         {
7341           bd_id_set++;
7342         }
7343       else
7344         break;
7345     }
7346
7347   if (bd_id_set == 0)
7348     {
7349       errmsg ("missing bridge domain");
7350       return -99;
7351     }
7352
7353   M (BD_IP_MAC_FLUSH, mp);
7354
7355   mp->bd_id = ntohl (bd_id);
7356
7357   S (mp);
7358   W (ret);
7359   return ret;
7360 }
7361
7362 static void vl_api_bd_ip_mac_details_t_handler
7363   (vl_api_bd_ip_mac_details_t * mp)
7364 {
7365   vat_main_t *vam = &vat_main;
7366   u8 *ip = 0;
7367
7368   if (!mp->is_ipv6)
7369     ip =
7370       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7371   else
7372     ip =
7373       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7374
7375   print (vam->ofp,
7376          "\n%-5d %-7s %-20U %-30s",
7377          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7378          format_ethernet_address, mp->mac_address, ip);
7379
7380   vec_free (ip);
7381 }
7382
7383 static void vl_api_bd_ip_mac_details_t_handler_json
7384   (vl_api_bd_ip_mac_details_t * mp)
7385 {
7386   vat_main_t *vam = &vat_main;
7387   vat_json_node_t *node = NULL;
7388
7389   if (VAT_JSON_ARRAY != vam->json_tree.type)
7390     {
7391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7392       vat_json_init_array (&vam->json_tree);
7393     }
7394   node = vat_json_array_add (&vam->json_tree);
7395
7396   vat_json_init_object (node);
7397   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7398   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7399   vat_json_object_add_string_copy (node, "mac_address",
7400                                    format (0, "%U", format_ethernet_address,
7401                                            &mp->mac_address));
7402   u8 *ip = 0;
7403
7404   if (!mp->is_ipv6)
7405     ip =
7406       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7407   else
7408     ip =
7409       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7410   vat_json_object_add_string_copy (node, "ip_address", ip);
7411   vec_free (ip);
7412 }
7413
7414 static int
7415 api_bd_ip_mac_dump (vat_main_t * vam)
7416 {
7417   unformat_input_t *i = vam->input;
7418   vl_api_bd_ip_mac_dump_t *mp;
7419   vl_api_control_ping_t *mp_ping;
7420   int ret;
7421   u32 bd_id;
7422   u8 bd_id_set = 0;
7423
7424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7425     {
7426       if (unformat (i, "bd_id %d", &bd_id))
7427         {
7428           bd_id_set++;
7429         }
7430       else
7431         break;
7432     }
7433
7434   print (vam->ofp,
7435          "\n%-5s %-7s %-20s %-30s",
7436          "bd_id", "is_ipv6", "mac_address", "ip_address");
7437
7438   /* Dump Bridge Domain Ip to Mac entries */
7439   M (BD_IP_MAC_DUMP, mp);
7440
7441   if (bd_id_set)
7442     mp->bd_id = htonl (bd_id);
7443   else
7444     mp->bd_id = ~0;
7445
7446   S (mp);
7447
7448   /* Use a control ping for synchronization */
7449   MPING (CONTROL_PING, mp_ping);
7450   S (mp_ping);
7451
7452   W (ret);
7453   return ret;
7454 }
7455
7456 static int
7457 api_tap_create_v2 (vat_main_t * vam)
7458 {
7459   unformat_input_t *i = vam->input;
7460   vl_api_tap_create_v2_t *mp;
7461   u8 mac_address[6];
7462   u8 random_mac = 1;
7463   u32 id = ~0;
7464   u8 *host_if_name = 0;
7465   u8 *host_ns = 0;
7466   u8 host_mac_addr[6];
7467   u8 host_mac_addr_set = 0;
7468   u8 *host_bridge = 0;
7469   ip4_address_t host_ip4_addr;
7470   ip4_address_t host_ip4_gw;
7471   u8 host_ip4_gw_set = 0;
7472   u32 host_ip4_prefix_len = 0;
7473   ip6_address_t host_ip6_addr;
7474   ip6_address_t host_ip6_gw;
7475   u8 host_ip6_gw_set = 0;
7476   u32 host_ip6_prefix_len = 0;
7477   int ret;
7478   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7479
7480   clib_memset (mac_address, 0, sizeof (mac_address));
7481
7482   /* Parse args required to build the message */
7483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7484     {
7485       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7486         {
7487           random_mac = 0;
7488         }
7489       else if (unformat (i, "id %u", &id))
7490         ;
7491       else if (unformat (i, "host-if-name %s", &host_if_name))
7492         ;
7493       else if (unformat (i, "host-ns %s", &host_ns))
7494         ;
7495       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7496                          host_mac_addr))
7497         host_mac_addr_set = 1;
7498       else if (unformat (i, "host-bridge %s", &host_bridge))
7499         ;
7500       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7501                          &host_ip4_addr, &host_ip4_prefix_len))
7502         ;
7503       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7504                          &host_ip6_addr, &host_ip6_prefix_len))
7505         ;
7506       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7507                          &host_ip4_gw))
7508         host_ip4_gw_set = 1;
7509       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7510                          &host_ip6_gw))
7511         host_ip6_gw_set = 1;
7512       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7513         ;
7514       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7515         ;
7516       else
7517         break;
7518     }
7519
7520   if (vec_len (host_if_name) > 63)
7521     {
7522       errmsg ("tap name too long. ");
7523       return -99;
7524     }
7525   if (vec_len (host_ns) > 63)
7526     {
7527       errmsg ("host name space too long. ");
7528       return -99;
7529     }
7530   if (vec_len (host_bridge) > 63)
7531     {
7532       errmsg ("host bridge name too long. ");
7533       return -99;
7534     }
7535   if (host_ip4_prefix_len > 32)
7536     {
7537       errmsg ("host ip4 prefix length not valid. ");
7538       return -99;
7539     }
7540   if (host_ip6_prefix_len > 128)
7541     {
7542       errmsg ("host ip6 prefix length not valid. ");
7543       return -99;
7544     }
7545   if (!is_pow2 (rx_ring_sz))
7546     {
7547       errmsg ("rx ring size must be power of 2. ");
7548       return -99;
7549     }
7550   if (rx_ring_sz > 32768)
7551     {
7552       errmsg ("rx ring size must be 32768 or lower. ");
7553       return -99;
7554     }
7555   if (!is_pow2 (tx_ring_sz))
7556     {
7557       errmsg ("tx ring size must be power of 2. ");
7558       return -99;
7559     }
7560   if (tx_ring_sz > 32768)
7561     {
7562       errmsg ("tx ring size must be 32768 or lower. ");
7563       return -99;
7564     }
7565
7566   /* Construct the API message */
7567   M (TAP_CREATE_V2, mp);
7568
7569   mp->use_random_mac = random_mac;
7570
7571   mp->id = ntohl (id);
7572   mp->host_namespace_set = host_ns != 0;
7573   mp->host_bridge_set = host_bridge != 0;
7574   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7575   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7576   mp->rx_ring_sz = ntohs (rx_ring_sz);
7577   mp->tx_ring_sz = ntohs (tx_ring_sz);
7578
7579   if (random_mac == 0)
7580     clib_memcpy (mp->mac_address, mac_address, 6);
7581   if (host_mac_addr_set)
7582     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7583   if (host_if_name)
7584     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7585   if (host_ns)
7586     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7587   if (host_bridge)
7588     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7589   if (host_ip4_prefix_len)
7590     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7591   if (host_ip6_prefix_len)
7592     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7593   if (host_ip4_gw_set)
7594     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7595   if (host_ip6_gw_set)
7596     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7597
7598   vec_free (host_ns);
7599   vec_free (host_if_name);
7600   vec_free (host_bridge);
7601
7602   /* send it... */
7603   S (mp);
7604
7605   /* Wait for a reply... */
7606   W (ret);
7607   return ret;
7608 }
7609
7610 static int
7611 api_tap_delete_v2 (vat_main_t * vam)
7612 {
7613   unformat_input_t *i = vam->input;
7614   vl_api_tap_delete_v2_t *mp;
7615   u32 sw_if_index = ~0;
7616   u8 sw_if_index_set = 0;
7617   int ret;
7618
7619   /* Parse args required to build the message */
7620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7621     {
7622       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7623         sw_if_index_set = 1;
7624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7625         sw_if_index_set = 1;
7626       else
7627         break;
7628     }
7629
7630   if (sw_if_index_set == 0)
7631     {
7632       errmsg ("missing vpp interface name. ");
7633       return -99;
7634     }
7635
7636   /* Construct the API message */
7637   M (TAP_DELETE_V2, mp);
7638
7639   mp->sw_if_index = ntohl (sw_if_index);
7640
7641   /* send it... */
7642   S (mp);
7643
7644   /* Wait for a reply... */
7645   W (ret);
7646   return ret;
7647 }
7648
7649 uword
7650 unformat_pci_addr (unformat_input_t * input, va_list * args)
7651 {
7652   struct pci_addr_t
7653   {
7654     u16 domain;
7655     u8 bus;
7656     u8 slot:5;
7657     u8 function:3;
7658   } *addr;
7659   addr = va_arg (*args, struct pci_addr_t *);
7660   u32 x[4];
7661
7662   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7663     return 0;
7664
7665   addr->domain = x[0];
7666   addr->bus = x[1];
7667   addr->slot = x[2];
7668   addr->function = x[3];
7669
7670   return 1;
7671 }
7672
7673 static int
7674 api_virtio_pci_create (vat_main_t * vam)
7675 {
7676   unformat_input_t *i = vam->input;
7677   vl_api_virtio_pci_create_t *mp;
7678   u8 mac_address[6];
7679   u8 random_mac = 1;
7680   u8 gso_enabled = 0;
7681   u32 pci_addr = 0;
7682   u64 features = (u64) ~ (0ULL);
7683   int ret;
7684
7685   clib_memset (mac_address, 0, sizeof (mac_address));
7686
7687   /* Parse args required to build the message */
7688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7689     {
7690       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7691         {
7692           random_mac = 0;
7693         }
7694       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7695         ;
7696       else if (unformat (i, "features 0x%llx", &features))
7697         ;
7698       else if (unformat (i, "gso-enabled"))
7699         gso_enabled = 1;
7700       else
7701         break;
7702     }
7703
7704   if (pci_addr == 0)
7705     {
7706       errmsg ("pci address must be non zero. ");
7707       return -99;
7708     }
7709
7710   /* Construct the API message */
7711   M (VIRTIO_PCI_CREATE, mp);
7712
7713   mp->use_random_mac = random_mac;
7714
7715   mp->pci_addr = htonl (pci_addr);
7716   mp->features = clib_host_to_net_u64 (features);
7717
7718   if (random_mac == 0)
7719     clib_memcpy (mp->mac_address, mac_address, 6);
7720
7721   /* send it... */
7722   S (mp);
7723
7724   /* Wait for a reply... */
7725   W (ret);
7726   return ret;
7727 }
7728
7729 static int
7730 api_virtio_pci_delete (vat_main_t * vam)
7731 {
7732   unformat_input_t *i = vam->input;
7733   vl_api_virtio_pci_delete_t *mp;
7734   u32 sw_if_index = ~0;
7735   u8 sw_if_index_set = 0;
7736   int ret;
7737
7738   /* Parse args required to build the message */
7739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7742         sw_if_index_set = 1;
7743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7744         sw_if_index_set = 1;
7745       else
7746         break;
7747     }
7748
7749   if (sw_if_index_set == 0)
7750     {
7751       errmsg ("missing vpp interface name. ");
7752       return -99;
7753     }
7754
7755   /* Construct the API message */
7756   M (VIRTIO_PCI_DELETE, mp);
7757
7758   mp->sw_if_index = htonl (sw_if_index);
7759
7760   /* send it... */
7761   S (mp);
7762
7763   /* Wait for a reply... */
7764   W (ret);
7765   return ret;
7766 }
7767
7768 static int
7769 api_bond_create (vat_main_t * vam)
7770 {
7771   unformat_input_t *i = vam->input;
7772   vl_api_bond_create_t *mp;
7773   u8 mac_address[6];
7774   u8 custom_mac = 0;
7775   int ret;
7776   u8 mode;
7777   u8 lb;
7778   u8 mode_is_set = 0;
7779   u32 id = ~0;
7780
7781   clib_memset (mac_address, 0, sizeof (mac_address));
7782   lb = BOND_LB_L2;
7783
7784   /* Parse args required to build the message */
7785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7786     {
7787       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7788         mode_is_set = 1;
7789       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7790                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7791         ;
7792       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7793                          mac_address))
7794         custom_mac = 1;
7795       else if (unformat (i, "id %u", &id))
7796         ;
7797       else
7798         break;
7799     }
7800
7801   if (mode_is_set == 0)
7802     {
7803       errmsg ("Missing bond mode. ");
7804       return -99;
7805     }
7806
7807   /* Construct the API message */
7808   M (BOND_CREATE, mp);
7809
7810   mp->use_custom_mac = custom_mac;
7811
7812   mp->mode = mode;
7813   mp->lb = lb;
7814   mp->id = htonl (id);
7815
7816   if (custom_mac)
7817     clib_memcpy (mp->mac_address, mac_address, 6);
7818
7819   /* send it... */
7820   S (mp);
7821
7822   /* Wait for a reply... */
7823   W (ret);
7824   return ret;
7825 }
7826
7827 static int
7828 api_bond_delete (vat_main_t * vam)
7829 {
7830   unformat_input_t *i = vam->input;
7831   vl_api_bond_delete_t *mp;
7832   u32 sw_if_index = ~0;
7833   u8 sw_if_index_set = 0;
7834   int ret;
7835
7836   /* Parse args required to build the message */
7837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7838     {
7839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7840         sw_if_index_set = 1;
7841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7842         sw_if_index_set = 1;
7843       else
7844         break;
7845     }
7846
7847   if (sw_if_index_set == 0)
7848     {
7849       errmsg ("missing vpp interface name. ");
7850       return -99;
7851     }
7852
7853   /* Construct the API message */
7854   M (BOND_DELETE, mp);
7855
7856   mp->sw_if_index = ntohl (sw_if_index);
7857
7858   /* send it... */
7859   S (mp);
7860
7861   /* Wait for a reply... */
7862   W (ret);
7863   return ret;
7864 }
7865
7866 static int
7867 api_bond_enslave (vat_main_t * vam)
7868 {
7869   unformat_input_t *i = vam->input;
7870   vl_api_bond_enslave_t *mp;
7871   u32 bond_sw_if_index;
7872   int ret;
7873   u8 is_passive;
7874   u8 is_long_timeout;
7875   u32 bond_sw_if_index_is_set = 0;
7876   u32 sw_if_index;
7877   u8 sw_if_index_is_set = 0;
7878
7879   /* Parse args required to build the message */
7880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7881     {
7882       if (unformat (i, "sw_if_index %d", &sw_if_index))
7883         sw_if_index_is_set = 1;
7884       else if (unformat (i, "bond %u", &bond_sw_if_index))
7885         bond_sw_if_index_is_set = 1;
7886       else if (unformat (i, "passive %d", &is_passive))
7887         ;
7888       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7889         ;
7890       else
7891         break;
7892     }
7893
7894   if (bond_sw_if_index_is_set == 0)
7895     {
7896       errmsg ("Missing bond sw_if_index. ");
7897       return -99;
7898     }
7899   if (sw_if_index_is_set == 0)
7900     {
7901       errmsg ("Missing slave sw_if_index. ");
7902       return -99;
7903     }
7904
7905   /* Construct the API message */
7906   M (BOND_ENSLAVE, mp);
7907
7908   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7909   mp->sw_if_index = ntohl (sw_if_index);
7910   mp->is_long_timeout = is_long_timeout;
7911   mp->is_passive = is_passive;
7912
7913   /* send it... */
7914   S (mp);
7915
7916   /* Wait for a reply... */
7917   W (ret);
7918   return ret;
7919 }
7920
7921 static int
7922 api_bond_detach_slave (vat_main_t * vam)
7923 {
7924   unformat_input_t *i = vam->input;
7925   vl_api_bond_detach_slave_t *mp;
7926   u32 sw_if_index = ~0;
7927   u8 sw_if_index_set = 0;
7928   int ret;
7929
7930   /* Parse args required to build the message */
7931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7932     {
7933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7934         sw_if_index_set = 1;
7935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7936         sw_if_index_set = 1;
7937       else
7938         break;
7939     }
7940
7941   if (sw_if_index_set == 0)
7942     {
7943       errmsg ("missing vpp interface name. ");
7944       return -99;
7945     }
7946
7947   /* Construct the API message */
7948   M (BOND_DETACH_SLAVE, mp);
7949
7950   mp->sw_if_index = ntohl (sw_if_index);
7951
7952   /* send it... */
7953   S (mp);
7954
7955   /* Wait for a reply... */
7956   W (ret);
7957   return ret;
7958 }
7959
7960 static int
7961 api_ip_table_add_del (vat_main_t * vam)
7962 {
7963   unformat_input_t *i = vam->input;
7964   vl_api_ip_table_add_del_t *mp;
7965   u32 table_id = ~0;
7966   u8 is_ipv6 = 0;
7967   u8 is_add = 1;
7968   int ret = 0;
7969
7970   /* Parse args required to build the message */
7971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7972     {
7973       if (unformat (i, "ipv6"))
7974         is_ipv6 = 1;
7975       else if (unformat (i, "del"))
7976         is_add = 0;
7977       else if (unformat (i, "add"))
7978         is_add = 1;
7979       else if (unformat (i, "table %d", &table_id))
7980         ;
7981       else
7982         {
7983           clib_warning ("parse error '%U'", format_unformat_error, i);
7984           return -99;
7985         }
7986     }
7987
7988   if (~0 == table_id)
7989     {
7990       errmsg ("missing table-ID");
7991       return -99;
7992     }
7993
7994   /* Construct the API message */
7995   M (IP_TABLE_ADD_DEL, mp);
7996
7997   mp->table_id = ntohl (table_id);
7998   mp->is_ipv6 = is_ipv6;
7999   mp->is_add = is_add;
8000
8001   /* send it... */
8002   S (mp);
8003
8004   /* Wait for a reply... */
8005   W (ret);
8006
8007   return ret;
8008 }
8009
8010 static int
8011 api_ip_add_del_route (vat_main_t * vam)
8012 {
8013   unformat_input_t *i = vam->input;
8014   vl_api_ip_add_del_route_t *mp;
8015   u32 sw_if_index = ~0, vrf_id = 0;
8016   u8 is_ipv6 = 0;
8017   u8 is_local = 0, is_drop = 0;
8018   u8 is_unreach = 0, is_prohibit = 0;
8019   u8 is_add = 1;
8020   u32 next_hop_weight = 1;
8021   u8 is_multipath = 0;
8022   u8 address_set = 0;
8023   u8 address_length_set = 0;
8024   u32 next_hop_table_id = 0;
8025   u32 resolve_attempts = 0;
8026   u32 dst_address_length = 0;
8027   u8 next_hop_set = 0;
8028   ip4_address_t v4_dst_address, v4_next_hop_address;
8029   ip6_address_t v6_dst_address, v6_next_hop_address;
8030   int count = 1;
8031   int j;
8032   f64 before = 0;
8033   u32 random_add_del = 0;
8034   u32 *random_vector = 0;
8035   uword *random_hash;
8036   u32 random_seed = 0xdeaddabe;
8037   u32 classify_table_index = ~0;
8038   u8 is_classify = 0;
8039   u8 resolve_host = 0, resolve_attached = 0;
8040   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8041   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8042   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8043
8044   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8045   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8046   /* Parse args required to build the message */
8047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8048     {
8049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8050         ;
8051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8052         ;
8053       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8054         {
8055           address_set = 1;
8056           is_ipv6 = 0;
8057         }
8058       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8059         {
8060           address_set = 1;
8061           is_ipv6 = 1;
8062         }
8063       else if (unformat (i, "/%d", &dst_address_length))
8064         {
8065           address_length_set = 1;
8066         }
8067
8068       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8069                                          &v4_next_hop_address))
8070         {
8071           next_hop_set = 1;
8072         }
8073       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8074                                          &v6_next_hop_address))
8075         {
8076           next_hop_set = 1;
8077         }
8078       else
8079         if (unformat
8080             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8081         {
8082           next_hop_set = 1;
8083         }
8084       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8085         {
8086           next_hop_set = 1;
8087         }
8088       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8089         ;
8090       else if (unformat (i, "weight %d", &next_hop_weight))
8091         ;
8092       else if (unformat (i, "drop"))
8093         {
8094           is_drop = 1;
8095         }
8096       else if (unformat (i, "null-send-unreach"))
8097         {
8098           is_unreach = 1;
8099         }
8100       else if (unformat (i, "null-send-prohibit"))
8101         {
8102           is_prohibit = 1;
8103         }
8104       else if (unformat (i, "local"))
8105         {
8106           is_local = 1;
8107         }
8108       else if (unformat (i, "classify %d", &classify_table_index))
8109         {
8110           is_classify = 1;
8111         }
8112       else if (unformat (i, "del"))
8113         is_add = 0;
8114       else if (unformat (i, "add"))
8115         is_add = 1;
8116       else if (unformat (i, "resolve-via-host"))
8117         resolve_host = 1;
8118       else if (unformat (i, "resolve-via-attached"))
8119         resolve_attached = 1;
8120       else if (unformat (i, "multipath"))
8121         is_multipath = 1;
8122       else if (unformat (i, "vrf %d", &vrf_id))
8123         ;
8124       else if (unformat (i, "count %d", &count))
8125         ;
8126       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8127         ;
8128       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8129         ;
8130       else if (unformat (i, "out-label %d", &next_hop_out_label))
8131         {
8132           vl_api_fib_mpls_label_t fib_label = {
8133             .label = ntohl (next_hop_out_label),
8134             .ttl = 64,
8135             .exp = 0,
8136           };
8137           vec_add1 (next_hop_out_label_stack, fib_label);
8138         }
8139       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8140         ;
8141       else if (unformat (i, "random"))
8142         random_add_del = 1;
8143       else if (unformat (i, "seed %d", &random_seed))
8144         ;
8145       else
8146         {
8147           clib_warning ("parse error '%U'", format_unformat_error, i);
8148           return -99;
8149         }
8150     }
8151
8152   if (!next_hop_set && !is_drop && !is_local &&
8153       !is_classify && !is_unreach && !is_prohibit &&
8154       MPLS_LABEL_INVALID == next_hop_via_label)
8155     {
8156       errmsg
8157         ("next hop / local / drop / unreach / prohibit / classify not set");
8158       return -99;
8159     }
8160
8161   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8162     {
8163       errmsg ("next hop and next-hop via label set");
8164       return -99;
8165     }
8166   if (address_set == 0)
8167     {
8168       errmsg ("missing addresses");
8169       return -99;
8170     }
8171
8172   if (address_length_set == 0)
8173     {
8174       errmsg ("missing address length");
8175       return -99;
8176     }
8177
8178   /* Generate a pile of unique, random routes */
8179   if (random_add_del)
8180     {
8181       u32 this_random_address;
8182       random_hash = hash_create (count, sizeof (uword));
8183
8184       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8185       for (j = 0; j <= count; j++)
8186         {
8187           do
8188             {
8189               this_random_address = random_u32 (&random_seed);
8190               this_random_address =
8191                 clib_host_to_net_u32 (this_random_address);
8192             }
8193           while (hash_get (random_hash, this_random_address));
8194           vec_add1 (random_vector, this_random_address);
8195           hash_set (random_hash, this_random_address, 1);
8196         }
8197       hash_free (random_hash);
8198       v4_dst_address.as_u32 = random_vector[0];
8199     }
8200
8201   if (count > 1)
8202     {
8203       /* Turn on async mode */
8204       vam->async_mode = 1;
8205       vam->async_errors = 0;
8206       before = vat_time_now (vam);
8207     }
8208
8209   for (j = 0; j < count; j++)
8210     {
8211       /* Construct the API message */
8212       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8213           vec_len (next_hop_out_label_stack));
8214
8215       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8216       mp->table_id = ntohl (vrf_id);
8217
8218       mp->is_add = is_add;
8219       mp->is_drop = is_drop;
8220       mp->is_unreach = is_unreach;
8221       mp->is_prohibit = is_prohibit;
8222       mp->is_ipv6 = is_ipv6;
8223       mp->is_local = is_local;
8224       mp->is_classify = is_classify;
8225       mp->is_multipath = is_multipath;
8226       mp->is_resolve_host = resolve_host;
8227       mp->is_resolve_attached = resolve_attached;
8228       mp->next_hop_weight = next_hop_weight;
8229       mp->next_hop_preference = 0;
8230       mp->dst_address_length = dst_address_length;
8231       mp->next_hop_table_id = ntohl (next_hop_table_id);
8232       mp->classify_table_index = ntohl (classify_table_index);
8233       mp->next_hop_via_label = ntohl (next_hop_via_label);
8234       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8235       if (0 != mp->next_hop_n_out_labels)
8236         {
8237           memcpy (mp->next_hop_out_label_stack,
8238                   next_hop_out_label_stack,
8239                   (vec_len (next_hop_out_label_stack) *
8240                    sizeof (vl_api_fib_mpls_label_t)));
8241           vec_free (next_hop_out_label_stack);
8242         }
8243
8244       if (is_ipv6)
8245         {
8246           clib_memcpy (mp->dst_address, &v6_dst_address,
8247                        sizeof (v6_dst_address));
8248           if (next_hop_set)
8249             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8250                          sizeof (v6_next_hop_address));
8251           increment_v6_address (&v6_dst_address);
8252         }
8253       else
8254         {
8255           clib_memcpy (mp->dst_address, &v4_dst_address,
8256                        sizeof (v4_dst_address));
8257           if (next_hop_set)
8258             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8259                          sizeof (v4_next_hop_address));
8260           if (random_add_del)
8261             v4_dst_address.as_u32 = random_vector[j + 1];
8262           else
8263             increment_v4_address (&v4_dst_address);
8264         }
8265       /* send it... */
8266       S (mp);
8267       /* If we receive SIGTERM, stop now... */
8268       if (vam->do_exit)
8269         break;
8270     }
8271
8272   /* When testing multiple add/del ops, use a control-ping to sync */
8273   if (count > 1)
8274     {
8275       vl_api_control_ping_t *mp_ping;
8276       f64 after;
8277       f64 timeout;
8278
8279       /* Shut off async mode */
8280       vam->async_mode = 0;
8281
8282       MPING (CONTROL_PING, mp_ping);
8283       S (mp_ping);
8284
8285       timeout = vat_time_now (vam) + 1.0;
8286       while (vat_time_now (vam) < timeout)
8287         if (vam->result_ready == 1)
8288           goto out;
8289       vam->retval = -99;
8290
8291     out:
8292       if (vam->retval == -99)
8293         errmsg ("timeout");
8294
8295       if (vam->async_errors > 0)
8296         {
8297           errmsg ("%d asynchronous errors", vam->async_errors);
8298           vam->retval = -98;
8299         }
8300       vam->async_errors = 0;
8301       after = vat_time_now (vam);
8302
8303       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8304       if (j > 0)
8305         count = j;
8306
8307       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8308              count, after - before, count / (after - before));
8309     }
8310   else
8311     {
8312       int ret;
8313
8314       /* Wait for a reply... */
8315       W (ret);
8316       return ret;
8317     }
8318
8319   /* Return the good/bad news */
8320   return (vam->retval);
8321 }
8322
8323 static int
8324 api_ip_mroute_add_del (vat_main_t * vam)
8325 {
8326   unformat_input_t *i = vam->input;
8327   vl_api_ip_mroute_add_del_t *mp;
8328   u32 sw_if_index = ~0, vrf_id = 0;
8329   u8 is_ipv6 = 0;
8330   u8 is_local = 0;
8331   u8 is_add = 1;
8332   u8 address_set = 0;
8333   u32 grp_address_length = 0;
8334   ip4_address_t v4_grp_address, v4_src_address;
8335   ip6_address_t v6_grp_address, v6_src_address;
8336   mfib_itf_flags_t iflags = 0;
8337   mfib_entry_flags_t eflags = 0;
8338   int ret;
8339
8340   /* Parse args required to build the message */
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "sw_if_index %d", &sw_if_index))
8344         ;
8345       else if (unformat (i, "%U %U",
8346                          unformat_ip4_address, &v4_src_address,
8347                          unformat_ip4_address, &v4_grp_address))
8348         {
8349           grp_address_length = 64;
8350           address_set = 1;
8351           is_ipv6 = 0;
8352         }
8353       else if (unformat (i, "%U %U",
8354                          unformat_ip6_address, &v6_src_address,
8355                          unformat_ip6_address, &v6_grp_address))
8356         {
8357           grp_address_length = 256;
8358           address_set = 1;
8359           is_ipv6 = 1;
8360         }
8361       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8362         {
8363           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8364           grp_address_length = 32;
8365           address_set = 1;
8366           is_ipv6 = 0;
8367         }
8368       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8369         {
8370           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8371           grp_address_length = 128;
8372           address_set = 1;
8373           is_ipv6 = 1;
8374         }
8375       else if (unformat (i, "/%d", &grp_address_length))
8376         ;
8377       else if (unformat (i, "local"))
8378         {
8379           is_local = 1;
8380         }
8381       else if (unformat (i, "del"))
8382         is_add = 0;
8383       else if (unformat (i, "add"))
8384         is_add = 1;
8385       else if (unformat (i, "vrf %d", &vrf_id))
8386         ;
8387       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8388         ;
8389       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8390         ;
8391       else
8392         {
8393           clib_warning ("parse error '%U'", format_unformat_error, i);
8394           return -99;
8395         }
8396     }
8397
8398   if (address_set == 0)
8399     {
8400       errmsg ("missing addresses\n");
8401       return -99;
8402     }
8403
8404   /* Construct the API message */
8405   M (IP_MROUTE_ADD_DEL, mp);
8406
8407   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8408   mp->table_id = ntohl (vrf_id);
8409
8410   mp->is_add = is_add;
8411   mp->is_ipv6 = is_ipv6;
8412   mp->is_local = is_local;
8413   mp->itf_flags = ntohl (iflags);
8414   mp->entry_flags = ntohl (eflags);
8415   mp->grp_address_length = grp_address_length;
8416   mp->grp_address_length = ntohs (mp->grp_address_length);
8417
8418   if (is_ipv6)
8419     {
8420       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8421       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8422     }
8423   else
8424     {
8425       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8426       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8427
8428     }
8429
8430   /* send it... */
8431   S (mp);
8432   /* Wait for a reply... */
8433   W (ret);
8434   return ret;
8435 }
8436
8437 static int
8438 api_mpls_table_add_del (vat_main_t * vam)
8439 {
8440   unformat_input_t *i = vam->input;
8441   vl_api_mpls_table_add_del_t *mp;
8442   u32 table_id = ~0;
8443   u8 is_add = 1;
8444   int ret = 0;
8445
8446   /* Parse args required to build the message */
8447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8448     {
8449       if (unformat (i, "table %d", &table_id))
8450         ;
8451       else if (unformat (i, "del"))
8452         is_add = 0;
8453       else if (unformat (i, "add"))
8454         is_add = 1;
8455       else
8456         {
8457           clib_warning ("parse error '%U'", format_unformat_error, i);
8458           return -99;
8459         }
8460     }
8461
8462   if (~0 == table_id)
8463     {
8464       errmsg ("missing table-ID");
8465       return -99;
8466     }
8467
8468   /* Construct the API message */
8469   M (MPLS_TABLE_ADD_DEL, mp);
8470
8471   mp->mt_table_id = ntohl (table_id);
8472   mp->mt_is_add = is_add;
8473
8474   /* send it... */
8475   S (mp);
8476
8477   /* Wait for a reply... */
8478   W (ret);
8479
8480   return ret;
8481 }
8482
8483 static int
8484 api_mpls_route_add_del (vat_main_t * vam)
8485 {
8486   unformat_input_t *i = vam->input;
8487   vl_api_mpls_route_add_del_t *mp;
8488   u32 sw_if_index = ~0, table_id = 0;
8489   u8 is_add = 1;
8490   u32 next_hop_weight = 1;
8491   u8 is_multipath = 0;
8492   u32 next_hop_table_id = 0;
8493   u8 next_hop_set = 0;
8494   ip4_address_t v4_next_hop_address = {
8495     .as_u32 = 0,
8496   };
8497   ip6_address_t v6_next_hop_address = { {0} };
8498   int count = 1;
8499   int j;
8500   f64 before = 0;
8501   u32 classify_table_index = ~0;
8502   u8 is_classify = 0;
8503   u8 resolve_host = 0, resolve_attached = 0;
8504   u8 is_interface_rx = 0;
8505   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8506   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8507   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8508   mpls_label_t local_label = MPLS_LABEL_INVALID;
8509   u8 is_eos = 0;
8510   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8511
8512   /* Parse args required to build the message */
8513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8514     {
8515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8516         ;
8517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8518         ;
8519       else if (unformat (i, "%d", &local_label))
8520         ;
8521       else if (unformat (i, "eos"))
8522         is_eos = 1;
8523       else if (unformat (i, "non-eos"))
8524         is_eos = 0;
8525       else if (unformat (i, "via %U", unformat_ip4_address,
8526                          &v4_next_hop_address))
8527         {
8528           next_hop_set = 1;
8529           next_hop_proto = DPO_PROTO_IP4;
8530         }
8531       else if (unformat (i, "via %U", unformat_ip6_address,
8532                          &v6_next_hop_address))
8533         {
8534           next_hop_set = 1;
8535           next_hop_proto = DPO_PROTO_IP6;
8536         }
8537       else if (unformat (i, "weight %d", &next_hop_weight))
8538         ;
8539       else if (unformat (i, "classify %d", &classify_table_index))
8540         {
8541           is_classify = 1;
8542         }
8543       else if (unformat (i, "del"))
8544         is_add = 0;
8545       else if (unformat (i, "add"))
8546         is_add = 1;
8547       else if (unformat (i, "resolve-via-host"))
8548         resolve_host = 1;
8549       else if (unformat (i, "resolve-via-attached"))
8550         resolve_attached = 1;
8551       else if (unformat (i, "multipath"))
8552         is_multipath = 1;
8553       else if (unformat (i, "count %d", &count))
8554         ;
8555       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8556         {
8557           next_hop_set = 1;
8558           next_hop_proto = DPO_PROTO_IP4;
8559         }
8560       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8561         {
8562           next_hop_set = 1;
8563           next_hop_proto = DPO_PROTO_IP6;
8564         }
8565       else
8566         if (unformat
8567             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8568              &sw_if_index))
8569         {
8570           next_hop_set = 1;
8571           next_hop_proto = DPO_PROTO_ETHERNET;
8572           is_interface_rx = 1;
8573         }
8574       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8575         {
8576           next_hop_set = 1;
8577           next_hop_proto = DPO_PROTO_ETHERNET;
8578           is_interface_rx = 1;
8579         }
8580       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8581         next_hop_set = 1;
8582       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8583         next_hop_set = 1;
8584       else if (unformat (i, "out-label %d", &next_hop_out_label))
8585         {
8586           vl_api_fib_mpls_label_t fib_label = {
8587             .label = ntohl (next_hop_out_label),
8588             .ttl = 64,
8589             .exp = 0,
8590           };
8591           vec_add1 (next_hop_out_label_stack, fib_label);
8592         }
8593       else
8594         {
8595           clib_warning ("parse error '%U'", format_unformat_error, i);
8596           return -99;
8597         }
8598     }
8599
8600   if (!next_hop_set && !is_classify)
8601     {
8602       errmsg ("next hop / classify not set");
8603       return -99;
8604     }
8605
8606   if (MPLS_LABEL_INVALID == local_label)
8607     {
8608       errmsg ("missing label");
8609       return -99;
8610     }
8611
8612   if (count > 1)
8613     {
8614       /* Turn on async mode */
8615       vam->async_mode = 1;
8616       vam->async_errors = 0;
8617       before = vat_time_now (vam);
8618     }
8619
8620   for (j = 0; j < count; j++)
8621     {
8622       /* Construct the API message */
8623       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8624           vec_len (next_hop_out_label_stack));
8625
8626       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8627       mp->mr_table_id = ntohl (table_id);
8628
8629       mp->mr_is_add = is_add;
8630       mp->mr_next_hop_proto = next_hop_proto;
8631       mp->mr_is_classify = is_classify;
8632       mp->mr_is_multipath = is_multipath;
8633       mp->mr_is_resolve_host = resolve_host;
8634       mp->mr_is_resolve_attached = resolve_attached;
8635       mp->mr_is_interface_rx = is_interface_rx;
8636       mp->mr_next_hop_weight = next_hop_weight;
8637       mp->mr_next_hop_preference = 0;
8638       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8639       mp->mr_classify_table_index = ntohl (classify_table_index);
8640       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8641       mp->mr_label = ntohl (local_label);
8642       mp->mr_eos = is_eos;
8643
8644       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8645       if (0 != mp->mr_next_hop_n_out_labels)
8646         {
8647           memcpy (mp->mr_next_hop_out_label_stack,
8648                   next_hop_out_label_stack,
8649                   vec_len (next_hop_out_label_stack) *
8650                   sizeof (vl_api_fib_mpls_label_t));
8651           vec_free (next_hop_out_label_stack);
8652         }
8653
8654       if (next_hop_set)
8655         {
8656           if (DPO_PROTO_IP4 == next_hop_proto)
8657             {
8658               clib_memcpy (mp->mr_next_hop,
8659                            &v4_next_hop_address,
8660                            sizeof (v4_next_hop_address));
8661             }
8662           else if (DPO_PROTO_IP6 == next_hop_proto)
8663
8664             {
8665               clib_memcpy (mp->mr_next_hop,
8666                            &v6_next_hop_address,
8667                            sizeof (v6_next_hop_address));
8668             }
8669         }
8670       local_label++;
8671
8672       /* send it... */
8673       S (mp);
8674       /* If we receive SIGTERM, stop now... */
8675       if (vam->do_exit)
8676         break;
8677     }
8678
8679   /* When testing multiple add/del ops, use a control-ping to sync */
8680   if (count > 1)
8681     {
8682       vl_api_control_ping_t *mp_ping;
8683       f64 after;
8684       f64 timeout;
8685
8686       /* Shut off async mode */
8687       vam->async_mode = 0;
8688
8689       MPING (CONTROL_PING, mp_ping);
8690       S (mp_ping);
8691
8692       timeout = vat_time_now (vam) + 1.0;
8693       while (vat_time_now (vam) < timeout)
8694         if (vam->result_ready == 1)
8695           goto out;
8696       vam->retval = -99;
8697
8698     out:
8699       if (vam->retval == -99)
8700         errmsg ("timeout");
8701
8702       if (vam->async_errors > 0)
8703         {
8704           errmsg ("%d asynchronous errors", vam->async_errors);
8705           vam->retval = -98;
8706         }
8707       vam->async_errors = 0;
8708       after = vat_time_now (vam);
8709
8710       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8711       if (j > 0)
8712         count = j;
8713
8714       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8715              count, after - before, count / (after - before));
8716     }
8717   else
8718     {
8719       int ret;
8720
8721       /* Wait for a reply... */
8722       W (ret);
8723       return ret;
8724     }
8725
8726   /* Return the good/bad news */
8727   return (vam->retval);
8728 }
8729
8730 static int
8731 api_mpls_ip_bind_unbind (vat_main_t * vam)
8732 {
8733   unformat_input_t *i = vam->input;
8734   vl_api_mpls_ip_bind_unbind_t *mp;
8735   u32 ip_table_id = 0;
8736   u8 is_bind = 1;
8737   u8 is_ip4 = 1;
8738   ip4_address_t v4_address;
8739   ip6_address_t v6_address;
8740   u32 address_length;
8741   u8 address_set = 0;
8742   mpls_label_t local_label = MPLS_LABEL_INVALID;
8743   int ret;
8744
8745   /* Parse args required to build the message */
8746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8747     {
8748       if (unformat (i, "%U/%d", unformat_ip4_address,
8749                     &v4_address, &address_length))
8750         {
8751           is_ip4 = 1;
8752           address_set = 1;
8753         }
8754       else if (unformat (i, "%U/%d", unformat_ip6_address,
8755                          &v6_address, &address_length))
8756         {
8757           is_ip4 = 0;
8758           address_set = 1;
8759         }
8760       else if (unformat (i, "%d", &local_label))
8761         ;
8762       else if (unformat (i, "table-id %d", &ip_table_id))
8763         ;
8764       else if (unformat (i, "unbind"))
8765         is_bind = 0;
8766       else if (unformat (i, "bind"))
8767         is_bind = 1;
8768       else
8769         {
8770           clib_warning ("parse error '%U'", format_unformat_error, i);
8771           return -99;
8772         }
8773     }
8774
8775   if (!address_set)
8776     {
8777       errmsg ("IP address not set");
8778       return -99;
8779     }
8780
8781   if (MPLS_LABEL_INVALID == local_label)
8782     {
8783       errmsg ("missing label");
8784       return -99;
8785     }
8786
8787   /* Construct the API message */
8788   M (MPLS_IP_BIND_UNBIND, mp);
8789
8790   mp->mb_is_bind = is_bind;
8791   mp->mb_is_ip4 = is_ip4;
8792   mp->mb_ip_table_id = ntohl (ip_table_id);
8793   mp->mb_mpls_table_id = 0;
8794   mp->mb_label = ntohl (local_label);
8795   mp->mb_address_length = address_length;
8796
8797   if (is_ip4)
8798     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8799   else
8800     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8801
8802   /* send it... */
8803   S (mp);
8804
8805   /* Wait for a reply... */
8806   W (ret);
8807   return ret;
8808 }
8809
8810 static int
8811 api_sr_mpls_policy_add (vat_main_t * vam)
8812 {
8813   unformat_input_t *i = vam->input;
8814   vl_api_sr_mpls_policy_add_t *mp;
8815   u32 bsid = 0;
8816   u32 weight = 1;
8817   u8 type = 0;
8818   u8 n_segments = 0;
8819   u32 sid;
8820   u32 *segments = NULL;
8821   int ret;
8822
8823   /* Parse args required to build the message */
8824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8825     {
8826       if (unformat (i, "bsid %d", &bsid))
8827         ;
8828       else if (unformat (i, "weight %d", &weight))
8829         ;
8830       else if (unformat (i, "spray"))
8831         type = 1;
8832       else if (unformat (i, "next %d", &sid))
8833         {
8834           n_segments += 1;
8835           vec_add1 (segments, htonl (sid));
8836         }
8837       else
8838         {
8839           clib_warning ("parse error '%U'", format_unformat_error, i);
8840           return -99;
8841         }
8842     }
8843
8844   if (bsid == 0)
8845     {
8846       errmsg ("bsid not set");
8847       return -99;
8848     }
8849
8850   if (n_segments == 0)
8851     {
8852       errmsg ("no sid in segment stack");
8853       return -99;
8854     }
8855
8856   /* Construct the API message */
8857   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8858
8859   mp->bsid = htonl (bsid);
8860   mp->weight = htonl (weight);
8861   mp->type = type;
8862   mp->n_segments = n_segments;
8863   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8864   vec_free (segments);
8865
8866   /* send it... */
8867   S (mp);
8868
8869   /* Wait for a reply... */
8870   W (ret);
8871   return ret;
8872 }
8873
8874 static int
8875 api_sr_mpls_policy_del (vat_main_t * vam)
8876 {
8877   unformat_input_t *i = vam->input;
8878   vl_api_sr_mpls_policy_del_t *mp;
8879   u32 bsid = 0;
8880   int ret;
8881
8882   /* Parse args required to build the message */
8883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8884     {
8885       if (unformat (i, "bsid %d", &bsid))
8886         ;
8887       else
8888         {
8889           clib_warning ("parse error '%U'", format_unformat_error, i);
8890           return -99;
8891         }
8892     }
8893
8894   if (bsid == 0)
8895     {
8896       errmsg ("bsid not set");
8897       return -99;
8898     }
8899
8900   /* Construct the API message */
8901   M (SR_MPLS_POLICY_DEL, mp);
8902
8903   mp->bsid = htonl (bsid);
8904
8905   /* send it... */
8906   S (mp);
8907
8908   /* Wait for a reply... */
8909   W (ret);
8910   return ret;
8911 }
8912
8913 static int
8914 api_bier_table_add_del (vat_main_t * vam)
8915 {
8916   unformat_input_t *i = vam->input;
8917   vl_api_bier_table_add_del_t *mp;
8918   u8 is_add = 1;
8919   u32 set = 0, sub_domain = 0, hdr_len = 3;
8920   mpls_label_t local_label = MPLS_LABEL_INVALID;
8921   int ret;
8922
8923   /* Parse args required to build the message */
8924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8925     {
8926       if (unformat (i, "sub-domain %d", &sub_domain))
8927         ;
8928       else if (unformat (i, "set %d", &set))
8929         ;
8930       else if (unformat (i, "label %d", &local_label))
8931         ;
8932       else if (unformat (i, "hdr-len %d", &hdr_len))
8933         ;
8934       else if (unformat (i, "add"))
8935         is_add = 1;
8936       else if (unformat (i, "del"))
8937         is_add = 0;
8938       else
8939         {
8940           clib_warning ("parse error '%U'", format_unformat_error, i);
8941           return -99;
8942         }
8943     }
8944
8945   if (MPLS_LABEL_INVALID == local_label)
8946     {
8947       errmsg ("missing label\n");
8948       return -99;
8949     }
8950
8951   /* Construct the API message */
8952   M (BIER_TABLE_ADD_DEL, mp);
8953
8954   mp->bt_is_add = is_add;
8955   mp->bt_label = ntohl (local_label);
8956   mp->bt_tbl_id.bt_set = set;
8957   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8958   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8959
8960   /* send it... */
8961   S (mp);
8962
8963   /* Wait for a reply... */
8964   W (ret);
8965
8966   return (ret);
8967 }
8968
8969 static int
8970 api_bier_route_add_del (vat_main_t * vam)
8971 {
8972   unformat_input_t *i = vam->input;
8973   vl_api_bier_route_add_del_t *mp;
8974   u8 is_add = 1;
8975   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8976   ip4_address_t v4_next_hop_address;
8977   ip6_address_t v6_next_hop_address;
8978   u8 next_hop_set = 0;
8979   u8 next_hop_proto_is_ip4 = 1;
8980   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8981   int ret;
8982
8983   /* Parse args required to build the message */
8984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8985     {
8986       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8987         {
8988           next_hop_proto_is_ip4 = 1;
8989           next_hop_set = 1;
8990         }
8991       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8992         {
8993           next_hop_proto_is_ip4 = 0;
8994           next_hop_set = 1;
8995         }
8996       if (unformat (i, "sub-domain %d", &sub_domain))
8997         ;
8998       else if (unformat (i, "set %d", &set))
8999         ;
9000       else if (unformat (i, "hdr-len %d", &hdr_len))
9001         ;
9002       else if (unformat (i, "bp %d", &bp))
9003         ;
9004       else if (unformat (i, "add"))
9005         is_add = 1;
9006       else if (unformat (i, "del"))
9007         is_add = 0;
9008       else if (unformat (i, "out-label %d", &next_hop_out_label))
9009         ;
9010       else
9011         {
9012           clib_warning ("parse error '%U'", format_unformat_error, i);
9013           return -99;
9014         }
9015     }
9016
9017   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9018     {
9019       errmsg ("next hop / label set\n");
9020       return -99;
9021     }
9022   if (0 == bp)
9023     {
9024       errmsg ("bit=position not set\n");
9025       return -99;
9026     }
9027
9028   /* Construct the API message */
9029   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9030
9031   mp->br_is_add = is_add;
9032   mp->br_tbl_id.bt_set = set;
9033   mp->br_tbl_id.bt_sub_domain = sub_domain;
9034   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9035   mp->br_bp = ntohs (bp);
9036   mp->br_n_paths = 1;
9037   mp->br_paths[0].n_labels = 1;
9038   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9039   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9040
9041   if (next_hop_proto_is_ip4)
9042     {
9043       clib_memcpy (mp->br_paths[0].next_hop,
9044                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9045     }
9046   else
9047     {
9048       clib_memcpy (mp->br_paths[0].next_hop,
9049                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9050     }
9051
9052   /* send it... */
9053   S (mp);
9054
9055   /* Wait for a reply... */
9056   W (ret);
9057
9058   return (ret);
9059 }
9060
9061 static int
9062 api_proxy_arp_add_del (vat_main_t * vam)
9063 {
9064   unformat_input_t *i = vam->input;
9065   vl_api_proxy_arp_add_del_t *mp;
9066   u32 vrf_id = 0;
9067   u8 is_add = 1;
9068   vl_api_ip4_address_t lo, hi;
9069   u8 range_set = 0;
9070   int ret;
9071
9072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9073     {
9074       if (unformat (i, "vrf %d", &vrf_id))
9075         ;
9076       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9077                          unformat_vl_api_ip4_address, &hi))
9078         range_set = 1;
9079       else if (unformat (i, "del"))
9080         is_add = 0;
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   if (range_set == 0)
9089     {
9090       errmsg ("address range not set");
9091       return -99;
9092     }
9093
9094   M (PROXY_ARP_ADD_DEL, mp);
9095
9096   mp->proxy.table_id = ntohl (vrf_id);
9097   mp->is_add = is_add;
9098   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9099   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9100
9101   S (mp);
9102   W (ret);
9103   return ret;
9104 }
9105
9106 static int
9107 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9108 {
9109   unformat_input_t *i = vam->input;
9110   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9111   u32 sw_if_index;
9112   u8 enable = 1;
9113   u8 sw_if_index_set = 0;
9114   int ret;
9115
9116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9117     {
9118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9119         sw_if_index_set = 1;
9120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9121         sw_if_index_set = 1;
9122       else if (unformat (i, "enable"))
9123         enable = 1;
9124       else if (unformat (i, "disable"))
9125         enable = 0;
9126       else
9127         {
9128           clib_warning ("parse error '%U'", format_unformat_error, i);
9129           return -99;
9130         }
9131     }
9132
9133   if (sw_if_index_set == 0)
9134     {
9135       errmsg ("missing interface name or sw_if_index");
9136       return -99;
9137     }
9138
9139   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9140
9141   mp->sw_if_index = ntohl (sw_if_index);
9142   mp->enable_disable = enable;
9143
9144   S (mp);
9145   W (ret);
9146   return ret;
9147 }
9148
9149 static int
9150 api_mpls_tunnel_add_del (vat_main_t * vam)
9151 {
9152   unformat_input_t *i = vam->input;
9153   vl_api_mpls_tunnel_add_del_t *mp;
9154
9155   u8 is_add = 1;
9156   u8 l2_only = 0;
9157   u32 sw_if_index = ~0;
9158   u32 next_hop_sw_if_index = ~0;
9159   u32 next_hop_proto_is_ip4 = 1;
9160
9161   u32 next_hop_table_id = 0;
9162   ip4_address_t v4_next_hop_address = {
9163     .as_u32 = 0,
9164   };
9165   ip6_address_t v6_next_hop_address = { {0} };
9166   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9167   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9168   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9169   int ret;
9170
9171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9172     {
9173       if (unformat (i, "add"))
9174         is_add = 1;
9175       else
9176         if (unformat
9177             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9178         is_add = 0;
9179       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9180         is_add = 0;
9181       else if (unformat (i, "via %U",
9182                          unformat_ip4_address, &v4_next_hop_address))
9183         {
9184           next_hop_proto_is_ip4 = 1;
9185         }
9186       else if (unformat (i, "via %U",
9187                          unformat_ip6_address, &v6_next_hop_address))
9188         {
9189           next_hop_proto_is_ip4 = 0;
9190         }
9191       else if (unformat (i, "via-label %d", &next_hop_via_label))
9192         ;
9193       else
9194         if (unformat
9195             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9196         ;
9197       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9198         ;
9199       else if (unformat (i, "l2-only"))
9200         l2_only = 1;
9201       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9202         ;
9203       else if (unformat (i, "out-label %d", &next_hop_out_label))
9204         {
9205           vl_api_fib_mpls_label_t fib_label = {
9206             .label = ntohl (next_hop_out_label),
9207             .ttl = 64,
9208             .exp = 0,
9209           };
9210           vec_add1 (next_hop_out_label_stack, fib_label);
9211         }
9212       else
9213         {
9214           clib_warning ("parse error '%U'", format_unformat_error, i);
9215           return -99;
9216         }
9217     }
9218
9219   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9220       vec_len (next_hop_out_label_stack));
9221
9222   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9223   mp->mt_sw_if_index = ntohl (sw_if_index);
9224   mp->mt_is_add = is_add;
9225   mp->mt_l2_only = l2_only;
9226   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9227   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9228   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9229   mp->mt_next_hop_weight = 1;
9230   mp->mt_next_hop_preference = 0;
9231
9232   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9233
9234   if (0 != mp->mt_next_hop_n_out_labels)
9235     {
9236       clib_memcpy (mp->mt_next_hop_out_label_stack,
9237                    next_hop_out_label_stack,
9238                    (vec_len (next_hop_out_label_stack) *
9239                     sizeof (vl_api_fib_mpls_label_t)));
9240       vec_free (next_hop_out_label_stack);
9241     }
9242
9243   if (next_hop_proto_is_ip4)
9244     {
9245       clib_memcpy (mp->mt_next_hop,
9246                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9247     }
9248   else
9249     {
9250       clib_memcpy (mp->mt_next_hop,
9251                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9252     }
9253
9254   S (mp);
9255   W (ret);
9256   return ret;
9257 }
9258
9259 static int
9260 api_sw_interface_set_unnumbered (vat_main_t * vam)
9261 {
9262   unformat_input_t *i = vam->input;
9263   vl_api_sw_interface_set_unnumbered_t *mp;
9264   u32 sw_if_index;
9265   u32 unnum_sw_index = ~0;
9266   u8 is_add = 1;
9267   u8 sw_if_index_set = 0;
9268   int ret;
9269
9270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9271     {
9272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9273         sw_if_index_set = 1;
9274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9275         sw_if_index_set = 1;
9276       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9277         ;
9278       else if (unformat (i, "del"))
9279         is_add = 0;
9280       else
9281         {
9282           clib_warning ("parse error '%U'", format_unformat_error, i);
9283           return -99;
9284         }
9285     }
9286
9287   if (sw_if_index_set == 0)
9288     {
9289       errmsg ("missing interface name or sw_if_index");
9290       return -99;
9291     }
9292
9293   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9294
9295   mp->sw_if_index = ntohl (sw_if_index);
9296   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9297   mp->is_add = is_add;
9298
9299   S (mp);
9300   W (ret);
9301   return ret;
9302 }
9303
9304 static int
9305 api_ip_neighbor_add_del (vat_main_t * vam)
9306 {
9307   vl_api_mac_address_t mac_address;
9308   unformat_input_t *i = vam->input;
9309   vl_api_ip_neighbor_add_del_t *mp;
9310   vl_api_address_t ip_address;
9311   u32 sw_if_index;
9312   u8 sw_if_index_set = 0;
9313   u8 is_add = 1;
9314   u8 mac_set = 0;
9315   u8 address_set = 0;
9316   int ret;
9317   ip_neighbor_flags_t flags;
9318
9319   flags = IP_NEIGHBOR_FLAG_NONE;
9320   clib_memset (&ip_address, 0, sizeof (ip_address));
9321   clib_memset (&mac_address, 0, sizeof (mac_address));
9322   /* Parse args required to build the message */
9323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9324     {
9325       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9326         {
9327           mac_set = 1;
9328         }
9329       else if (unformat (i, "del"))
9330         is_add = 0;
9331       else
9332         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9333         sw_if_index_set = 1;
9334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9335         sw_if_index_set = 1;
9336       else if (unformat (i, "static"))
9337         flags |= IP_NEIGHBOR_FLAG_STATIC;
9338       else if (unformat (i, "no-fib-entry"))
9339         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9340       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9341         address_set = 1;
9342       else
9343         {
9344           clib_warning ("parse error '%U'", format_unformat_error, i);
9345           return -99;
9346         }
9347     }
9348
9349   if (sw_if_index_set == 0)
9350     {
9351       errmsg ("missing interface name or sw_if_index");
9352       return -99;
9353     }
9354   if (!address_set)
9355     {
9356       errmsg ("no address set");
9357       return -99;
9358     }
9359
9360   /* Construct the API message */
9361   M (IP_NEIGHBOR_ADD_DEL, mp);
9362
9363   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9364   mp->is_add = is_add;
9365   mp->neighbor.flags = htonl (flags);
9366   if (mac_set)
9367     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9368                  sizeof (mac_address));
9369   if (address_set)
9370     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9371
9372   /* send it... */
9373   S (mp);
9374
9375   /* Wait for a reply, return good/bad news  */
9376   W (ret);
9377   return ret;
9378 }
9379
9380 static int
9381 api_create_vlan_subif (vat_main_t * vam)
9382 {
9383   unformat_input_t *i = vam->input;
9384   vl_api_create_vlan_subif_t *mp;
9385   u32 sw_if_index;
9386   u8 sw_if_index_set = 0;
9387   u32 vlan_id;
9388   u8 vlan_id_set = 0;
9389   int ret;
9390
9391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9392     {
9393       if (unformat (i, "sw_if_index %d", &sw_if_index))
9394         sw_if_index_set = 1;
9395       else
9396         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9397         sw_if_index_set = 1;
9398       else if (unformat (i, "vlan %d", &vlan_id))
9399         vlan_id_set = 1;
9400       else
9401         {
9402           clib_warning ("parse error '%U'", format_unformat_error, i);
9403           return -99;
9404         }
9405     }
9406
9407   if (sw_if_index_set == 0)
9408     {
9409       errmsg ("missing interface name or sw_if_index");
9410       return -99;
9411     }
9412
9413   if (vlan_id_set == 0)
9414     {
9415       errmsg ("missing vlan_id");
9416       return -99;
9417     }
9418   M (CREATE_VLAN_SUBIF, mp);
9419
9420   mp->sw_if_index = ntohl (sw_if_index);
9421   mp->vlan_id = ntohl (vlan_id);
9422
9423   S (mp);
9424   W (ret);
9425   return ret;
9426 }
9427
9428 #define foreach_create_subif_bit                \
9429 _(no_tags)                                      \
9430 _(one_tag)                                      \
9431 _(two_tags)                                     \
9432 _(dot1ad)                                       \
9433 _(exact_match)                                  \
9434 _(default_sub)                                  \
9435 _(outer_vlan_id_any)                            \
9436 _(inner_vlan_id_any)
9437
9438 static int
9439 api_create_subif (vat_main_t * vam)
9440 {
9441   unformat_input_t *i = vam->input;
9442   vl_api_create_subif_t *mp;
9443   u32 sw_if_index;
9444   u8 sw_if_index_set = 0;
9445   u32 sub_id;
9446   u8 sub_id_set = 0;
9447   u32 no_tags = 0;
9448   u32 one_tag = 0;
9449   u32 two_tags = 0;
9450   u32 dot1ad = 0;
9451   u32 exact_match = 0;
9452   u32 default_sub = 0;
9453   u32 outer_vlan_id_any = 0;
9454   u32 inner_vlan_id_any = 0;
9455   u32 tmp;
9456   u16 outer_vlan_id = 0;
9457   u16 inner_vlan_id = 0;
9458   int ret;
9459
9460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (unformat (i, "sw_if_index %d", &sw_if_index))
9463         sw_if_index_set = 1;
9464       else
9465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9466         sw_if_index_set = 1;
9467       else if (unformat (i, "sub_id %d", &sub_id))
9468         sub_id_set = 1;
9469       else if (unformat (i, "outer_vlan_id %d", &tmp))
9470         outer_vlan_id = tmp;
9471       else if (unformat (i, "inner_vlan_id %d", &tmp))
9472         inner_vlan_id = tmp;
9473
9474 #define _(a) else if (unformat (i, #a)) a = 1 ;
9475       foreach_create_subif_bit
9476 #undef _
9477         else
9478         {
9479           clib_warning ("parse error '%U'", format_unformat_error, i);
9480           return -99;
9481         }
9482     }
9483
9484   if (sw_if_index_set == 0)
9485     {
9486       errmsg ("missing interface name or sw_if_index");
9487       return -99;
9488     }
9489
9490   if (sub_id_set == 0)
9491     {
9492       errmsg ("missing sub_id");
9493       return -99;
9494     }
9495   M (CREATE_SUBIF, mp);
9496
9497   mp->sw_if_index = ntohl (sw_if_index);
9498   mp->sub_id = ntohl (sub_id);
9499
9500 #define _(a) mp->a = a;
9501   foreach_create_subif_bit;
9502 #undef _
9503
9504   mp->outer_vlan_id = ntohs (outer_vlan_id);
9505   mp->inner_vlan_id = ntohs (inner_vlan_id);
9506
9507   S (mp);
9508   W (ret);
9509   return ret;
9510 }
9511
9512 static int
9513 api_reset_fib (vat_main_t * vam)
9514 {
9515   unformat_input_t *i = vam->input;
9516   vl_api_reset_fib_t *mp;
9517   u32 vrf_id = 0;
9518   u8 is_ipv6 = 0;
9519   u8 vrf_id_set = 0;
9520
9521   int ret;
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "vrf %d", &vrf_id))
9525         vrf_id_set = 1;
9526       else if (unformat (i, "ipv6"))
9527         is_ipv6 = 1;
9528       else
9529         {
9530           clib_warning ("parse error '%U'", format_unformat_error, i);
9531           return -99;
9532         }
9533     }
9534
9535   if (vrf_id_set == 0)
9536     {
9537       errmsg ("missing vrf id");
9538       return -99;
9539     }
9540
9541   M (RESET_FIB, mp);
9542
9543   mp->vrf_id = ntohl (vrf_id);
9544   mp->is_ipv6 = is_ipv6;
9545
9546   S (mp);
9547   W (ret);
9548   return ret;
9549 }
9550
9551 static int
9552 api_dhcp_proxy_config (vat_main_t * vam)
9553 {
9554   unformat_input_t *i = vam->input;
9555   vl_api_dhcp_proxy_config_t *mp;
9556   u32 rx_vrf_id = 0;
9557   u32 server_vrf_id = 0;
9558   u8 is_add = 1;
9559   u8 v4_address_set = 0;
9560   u8 v6_address_set = 0;
9561   ip4_address_t v4address;
9562   ip6_address_t v6address;
9563   u8 v4_src_address_set = 0;
9564   u8 v6_src_address_set = 0;
9565   ip4_address_t v4srcaddress;
9566   ip6_address_t v6srcaddress;
9567   int ret;
9568
9569   /* Parse args required to build the message */
9570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9571     {
9572       if (unformat (i, "del"))
9573         is_add = 0;
9574       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9575         ;
9576       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9577         ;
9578       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9579         v4_address_set = 1;
9580       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9581         v6_address_set = 1;
9582       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9583         v4_src_address_set = 1;
9584       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9585         v6_src_address_set = 1;
9586       else
9587         break;
9588     }
9589
9590   if (v4_address_set && v6_address_set)
9591     {
9592       errmsg ("both v4 and v6 server addresses set");
9593       return -99;
9594     }
9595   if (!v4_address_set && !v6_address_set)
9596     {
9597       errmsg ("no server addresses set");
9598       return -99;
9599     }
9600
9601   if (v4_src_address_set && v6_src_address_set)
9602     {
9603       errmsg ("both v4 and v6  src addresses set");
9604       return -99;
9605     }
9606   if (!v4_src_address_set && !v6_src_address_set)
9607     {
9608       errmsg ("no src addresses set");
9609       return -99;
9610     }
9611
9612   if (!(v4_src_address_set && v4_address_set) &&
9613       !(v6_src_address_set && v6_address_set))
9614     {
9615       errmsg ("no matching server and src addresses set");
9616       return -99;
9617     }
9618
9619   /* Construct the API message */
9620   M (DHCP_PROXY_CONFIG, mp);
9621
9622   mp->is_add = is_add;
9623   mp->rx_vrf_id = ntohl (rx_vrf_id);
9624   mp->server_vrf_id = ntohl (server_vrf_id);
9625   if (v6_address_set)
9626     {
9627       mp->is_ipv6 = 1;
9628       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9629       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9630     }
9631   else
9632     {
9633       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9634       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9635     }
9636
9637   /* send it... */
9638   S (mp);
9639
9640   /* Wait for a reply, return good/bad news  */
9641   W (ret);
9642   return ret;
9643 }
9644
9645 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9646 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9647
9648 static void
9649 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9650 {
9651   vat_main_t *vam = &vat_main;
9652   u32 i, count = mp->count;
9653   vl_api_dhcp_server_t *s;
9654
9655   if (mp->is_ipv6)
9656     print (vam->ofp,
9657            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9658            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9659            ntohl (mp->rx_vrf_id),
9660            format_ip6_address, mp->dhcp_src_address,
9661            mp->vss_type, mp->vss_vpn_ascii_id,
9662            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9663   else
9664     print (vam->ofp,
9665            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9666            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9667            ntohl (mp->rx_vrf_id),
9668            format_ip4_address, mp->dhcp_src_address,
9669            mp->vss_type, mp->vss_vpn_ascii_id,
9670            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9671
9672   for (i = 0; i < count; i++)
9673     {
9674       s = &mp->servers[i];
9675
9676       if (mp->is_ipv6)
9677         print (vam->ofp,
9678                " Server Table-ID %d, Server Address %U",
9679                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9680       else
9681         print (vam->ofp,
9682                " Server Table-ID %d, Server Address %U",
9683                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9684     }
9685 }
9686
9687 static void vl_api_dhcp_proxy_details_t_handler_json
9688   (vl_api_dhcp_proxy_details_t * mp)
9689 {
9690   vat_main_t *vam = &vat_main;
9691   vat_json_node_t *node = NULL;
9692   u32 i, count = mp->count;
9693   struct in_addr ip4;
9694   struct in6_addr ip6;
9695   vl_api_dhcp_server_t *s;
9696
9697   if (VAT_JSON_ARRAY != vam->json_tree.type)
9698     {
9699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9700       vat_json_init_array (&vam->json_tree);
9701     }
9702   node = vat_json_array_add (&vam->json_tree);
9703
9704   vat_json_init_object (node);
9705   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9706   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9707                              sizeof (mp->vss_type));
9708   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9709                                    mp->vss_vpn_ascii_id);
9710   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9711   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9712
9713   if (mp->is_ipv6)
9714     {
9715       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9716       vat_json_object_add_ip6 (node, "src_address", ip6);
9717     }
9718   else
9719     {
9720       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9721       vat_json_object_add_ip4 (node, "src_address", ip4);
9722     }
9723
9724   for (i = 0; i < count; i++)
9725     {
9726       s = &mp->servers[i];
9727
9728       vat_json_object_add_uint (node, "server-table-id",
9729                                 ntohl (s->server_vrf_id));
9730
9731       if (mp->is_ipv6)
9732         {
9733           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9734           vat_json_object_add_ip4 (node, "src_address", ip4);
9735         }
9736       else
9737         {
9738           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9739           vat_json_object_add_ip6 (node, "server_address", ip6);
9740         }
9741     }
9742 }
9743
9744 static int
9745 api_dhcp_proxy_dump (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_control_ping_t *mp_ping;
9749   vl_api_dhcp_proxy_dump_t *mp;
9750   u8 is_ipv6 = 0;
9751   int ret;
9752
9753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9754     {
9755       if (unformat (i, "ipv6"))
9756         is_ipv6 = 1;
9757       else
9758         {
9759           clib_warning ("parse error '%U'", format_unformat_error, i);
9760           return -99;
9761         }
9762     }
9763
9764   M (DHCP_PROXY_DUMP, mp);
9765
9766   mp->is_ip6 = is_ipv6;
9767   S (mp);
9768
9769   /* Use a control ping for synchronization */
9770   MPING (CONTROL_PING, mp_ping);
9771   S (mp_ping);
9772
9773   W (ret);
9774   return ret;
9775 }
9776
9777 static int
9778 api_dhcp_proxy_set_vss (vat_main_t * vam)
9779 {
9780   unformat_input_t *i = vam->input;
9781   vl_api_dhcp_proxy_set_vss_t *mp;
9782   u8 is_ipv6 = 0;
9783   u8 is_add = 1;
9784   u32 tbl_id = ~0;
9785   u8 vss_type = VSS_TYPE_DEFAULT;
9786   u8 *vpn_ascii_id = 0;
9787   u32 oui = 0;
9788   u32 fib_id = 0;
9789   int ret;
9790
9791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9792     {
9793       if (unformat (i, "tbl_id %d", &tbl_id))
9794         ;
9795       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9796         vss_type = VSS_TYPE_ASCII;
9797       else if (unformat (i, "fib_id %d", &fib_id))
9798         vss_type = VSS_TYPE_VPN_ID;
9799       else if (unformat (i, "oui %d", &oui))
9800         vss_type = VSS_TYPE_VPN_ID;
9801       else if (unformat (i, "ipv6"))
9802         is_ipv6 = 1;
9803       else if (unformat (i, "del"))
9804         is_add = 0;
9805       else
9806         break;
9807     }
9808
9809   if (tbl_id == ~0)
9810     {
9811       errmsg ("missing tbl_id ");
9812       vec_free (vpn_ascii_id);
9813       return -99;
9814     }
9815
9816   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9817     {
9818       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9819       vec_free (vpn_ascii_id);
9820       return -99;
9821     }
9822
9823   M (DHCP_PROXY_SET_VSS, mp);
9824   mp->tbl_id = ntohl (tbl_id);
9825   mp->vss_type = vss_type;
9826   if (vpn_ascii_id)
9827     {
9828       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9829       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9830     }
9831   mp->vpn_index = ntohl (fib_id);
9832   mp->oui = ntohl (oui);
9833   mp->is_ipv6 = is_ipv6;
9834   mp->is_add = is_add;
9835
9836   S (mp);
9837   W (ret);
9838
9839   vec_free (vpn_ascii_id);
9840   return ret;
9841 }
9842
9843 static int
9844 api_dhcp_client_config (vat_main_t * vam)
9845 {
9846   unformat_input_t *i = vam->input;
9847   vl_api_dhcp_client_config_t *mp;
9848   u32 sw_if_index;
9849   u8 sw_if_index_set = 0;
9850   u8 is_add = 1;
9851   u8 *hostname = 0;
9852   u8 disable_event = 0;
9853   int ret;
9854
9855   /* Parse args required to build the message */
9856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (i, "del"))
9859         is_add = 0;
9860       else
9861         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9862         sw_if_index_set = 1;
9863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9864         sw_if_index_set = 1;
9865       else if (unformat (i, "hostname %s", &hostname))
9866         ;
9867       else if (unformat (i, "disable_event"))
9868         disable_event = 1;
9869       else
9870         break;
9871     }
9872
9873   if (sw_if_index_set == 0)
9874     {
9875       errmsg ("missing interface name or sw_if_index");
9876       return -99;
9877     }
9878
9879   if (vec_len (hostname) > 63)
9880     {
9881       errmsg ("hostname too long");
9882     }
9883   vec_add1 (hostname, 0);
9884
9885   /* Construct the API message */
9886   M (DHCP_CLIENT_CONFIG, mp);
9887
9888   mp->is_add = is_add;
9889   mp->client.sw_if_index = htonl (sw_if_index);
9890   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9891   vec_free (hostname);
9892   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9893   mp->client.pid = htonl (getpid ());
9894
9895   /* send it... */
9896   S (mp);
9897
9898   /* Wait for a reply, return good/bad news  */
9899   W (ret);
9900   return ret;
9901 }
9902
9903 static int
9904 api_set_ip_flow_hash (vat_main_t * vam)
9905 {
9906   unformat_input_t *i = vam->input;
9907   vl_api_set_ip_flow_hash_t *mp;
9908   u32 vrf_id = 0;
9909   u8 is_ipv6 = 0;
9910   u8 vrf_id_set = 0;
9911   u8 src = 0;
9912   u8 dst = 0;
9913   u8 sport = 0;
9914   u8 dport = 0;
9915   u8 proto = 0;
9916   u8 reverse = 0;
9917   int ret;
9918
9919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9920     {
9921       if (unformat (i, "vrf %d", &vrf_id))
9922         vrf_id_set = 1;
9923       else if (unformat (i, "ipv6"))
9924         is_ipv6 = 1;
9925       else if (unformat (i, "src"))
9926         src = 1;
9927       else if (unformat (i, "dst"))
9928         dst = 1;
9929       else if (unformat (i, "sport"))
9930         sport = 1;
9931       else if (unformat (i, "dport"))
9932         dport = 1;
9933       else if (unformat (i, "proto"))
9934         proto = 1;
9935       else if (unformat (i, "reverse"))
9936         reverse = 1;
9937
9938       else
9939         {
9940           clib_warning ("parse error '%U'", format_unformat_error, i);
9941           return -99;
9942         }
9943     }
9944
9945   if (vrf_id_set == 0)
9946     {
9947       errmsg ("missing vrf id");
9948       return -99;
9949     }
9950
9951   M (SET_IP_FLOW_HASH, mp);
9952   mp->src = src;
9953   mp->dst = dst;
9954   mp->sport = sport;
9955   mp->dport = dport;
9956   mp->proto = proto;
9957   mp->reverse = reverse;
9958   mp->vrf_id = ntohl (vrf_id);
9959   mp->is_ipv6 = is_ipv6;
9960
9961   S (mp);
9962   W (ret);
9963   return ret;
9964 }
9965
9966 static int
9967 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9968 {
9969   unformat_input_t *i = vam->input;
9970   vl_api_sw_interface_ip6_enable_disable_t *mp;
9971   u32 sw_if_index;
9972   u8 sw_if_index_set = 0;
9973   u8 enable = 0;
9974   int ret;
9975
9976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9977     {
9978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9979         sw_if_index_set = 1;
9980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9981         sw_if_index_set = 1;
9982       else if (unformat (i, "enable"))
9983         enable = 1;
9984       else if (unformat (i, "disable"))
9985         enable = 0;
9986       else
9987         {
9988           clib_warning ("parse error '%U'", format_unformat_error, i);
9989           return -99;
9990         }
9991     }
9992
9993   if (sw_if_index_set == 0)
9994     {
9995       errmsg ("missing interface name or sw_if_index");
9996       return -99;
9997     }
9998
9999   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10000
10001   mp->sw_if_index = ntohl (sw_if_index);
10002   mp->enable = enable;
10003
10004   S (mp);
10005   W (ret);
10006   return ret;
10007 }
10008
10009 static int
10010 api_ip6nd_proxy_add_del (vat_main_t * vam)
10011 {
10012   unformat_input_t *i = vam->input;
10013   vl_api_ip6nd_proxy_add_del_t *mp;
10014   u32 sw_if_index = ~0;
10015   u8 v6_address_set = 0;
10016   vl_api_ip6_address_t v6address;
10017   u8 is_del = 0;
10018   int ret;
10019
10020   /* Parse args required to build the message */
10021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10022     {
10023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10024         ;
10025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10026         ;
10027       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10028         v6_address_set = 1;
10029       if (unformat (i, "del"))
10030         is_del = 1;
10031       else
10032         {
10033           clib_warning ("parse error '%U'", format_unformat_error, i);
10034           return -99;
10035         }
10036     }
10037
10038   if (sw_if_index == ~0)
10039     {
10040       errmsg ("missing interface name or sw_if_index");
10041       return -99;
10042     }
10043   if (!v6_address_set)
10044     {
10045       errmsg ("no address set");
10046       return -99;
10047     }
10048
10049   /* Construct the API message */
10050   M (IP6ND_PROXY_ADD_DEL, mp);
10051
10052   mp->is_del = is_del;
10053   mp->sw_if_index = ntohl (sw_if_index);
10054   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10055
10056   /* send it... */
10057   S (mp);
10058
10059   /* Wait for a reply, return good/bad news  */
10060   W (ret);
10061   return ret;
10062 }
10063
10064 static int
10065 api_ip6nd_proxy_dump (vat_main_t * vam)
10066 {
10067   vl_api_ip6nd_proxy_dump_t *mp;
10068   vl_api_control_ping_t *mp_ping;
10069   int ret;
10070
10071   M (IP6ND_PROXY_DUMP, mp);
10072
10073   S (mp);
10074
10075   /* Use a control ping for synchronization */
10076   MPING (CONTROL_PING, mp_ping);
10077   S (mp_ping);
10078
10079   W (ret);
10080   return ret;
10081 }
10082
10083 static void vl_api_ip6nd_proxy_details_t_handler
10084   (vl_api_ip6nd_proxy_details_t * mp)
10085 {
10086   vat_main_t *vam = &vat_main;
10087
10088   print (vam->ofp, "host %U sw_if_index %d",
10089          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10090 }
10091
10092 static void vl_api_ip6nd_proxy_details_t_handler_json
10093   (vl_api_ip6nd_proxy_details_t * mp)
10094 {
10095   vat_main_t *vam = &vat_main;
10096   struct in6_addr ip6;
10097   vat_json_node_t *node = NULL;
10098
10099   if (VAT_JSON_ARRAY != vam->json_tree.type)
10100     {
10101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10102       vat_json_init_array (&vam->json_tree);
10103     }
10104   node = vat_json_array_add (&vam->json_tree);
10105
10106   vat_json_init_object (node);
10107   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10108
10109   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10110   vat_json_object_add_ip6 (node, "host", ip6);
10111 }
10112
10113 static int
10114 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10115 {
10116   unformat_input_t *i = vam->input;
10117   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10118   u32 sw_if_index;
10119   u8 sw_if_index_set = 0;
10120   u32 address_length = 0;
10121   u8 v6_address_set = 0;
10122   vl_api_prefix_t pfx;
10123   u8 use_default = 0;
10124   u8 no_advertise = 0;
10125   u8 off_link = 0;
10126   u8 no_autoconfig = 0;
10127   u8 no_onlink = 0;
10128   u8 is_no = 0;
10129   u32 val_lifetime = 0;
10130   u32 pref_lifetime = 0;
10131   int ret;
10132
10133   /* Parse args required to build the message */
10134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10135     {
10136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10137         sw_if_index_set = 1;
10138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10139         sw_if_index_set = 1;
10140       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10141         v6_address_set = 1;
10142       else if (unformat (i, "val_life %d", &val_lifetime))
10143         ;
10144       else if (unformat (i, "pref_life %d", &pref_lifetime))
10145         ;
10146       else if (unformat (i, "def"))
10147         use_default = 1;
10148       else if (unformat (i, "noadv"))
10149         no_advertise = 1;
10150       else if (unformat (i, "offl"))
10151         off_link = 1;
10152       else if (unformat (i, "noauto"))
10153         no_autoconfig = 1;
10154       else if (unformat (i, "nolink"))
10155         no_onlink = 1;
10156       else if (unformat (i, "isno"))
10157         is_no = 1;
10158       else
10159         {
10160           clib_warning ("parse error '%U'", format_unformat_error, i);
10161           return -99;
10162         }
10163     }
10164
10165   if (sw_if_index_set == 0)
10166     {
10167       errmsg ("missing interface name or sw_if_index");
10168       return -99;
10169     }
10170   if (!v6_address_set)
10171     {
10172       errmsg ("no address set");
10173       return -99;
10174     }
10175
10176   /* Construct the API message */
10177   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10178
10179   mp->sw_if_index = ntohl (sw_if_index);
10180   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10181   mp->use_default = use_default;
10182   mp->no_advertise = no_advertise;
10183   mp->off_link = off_link;
10184   mp->no_autoconfig = no_autoconfig;
10185   mp->no_onlink = no_onlink;
10186   mp->is_no = is_no;
10187   mp->val_lifetime = ntohl (val_lifetime);
10188   mp->pref_lifetime = ntohl (pref_lifetime);
10189
10190   /* send it... */
10191   S (mp);
10192
10193   /* Wait for a reply, return good/bad news  */
10194   W (ret);
10195   return ret;
10196 }
10197
10198 static int
10199 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10200 {
10201   unformat_input_t *i = vam->input;
10202   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10203   u32 sw_if_index;
10204   u8 sw_if_index_set = 0;
10205   u8 suppress = 0;
10206   u8 managed = 0;
10207   u8 other = 0;
10208   u8 ll_option = 0;
10209   u8 send_unicast = 0;
10210   u8 cease = 0;
10211   u8 is_no = 0;
10212   u8 default_router = 0;
10213   u32 max_interval = 0;
10214   u32 min_interval = 0;
10215   u32 lifetime = 0;
10216   u32 initial_count = 0;
10217   u32 initial_interval = 0;
10218   int ret;
10219
10220
10221   /* Parse args required to build the message */
10222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10223     {
10224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10225         sw_if_index_set = 1;
10226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10227         sw_if_index_set = 1;
10228       else if (unformat (i, "maxint %d", &max_interval))
10229         ;
10230       else if (unformat (i, "minint %d", &min_interval))
10231         ;
10232       else if (unformat (i, "life %d", &lifetime))
10233         ;
10234       else if (unformat (i, "count %d", &initial_count))
10235         ;
10236       else if (unformat (i, "interval %d", &initial_interval))
10237         ;
10238       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10239         suppress = 1;
10240       else if (unformat (i, "managed"))
10241         managed = 1;
10242       else if (unformat (i, "other"))
10243         other = 1;
10244       else if (unformat (i, "ll"))
10245         ll_option = 1;
10246       else if (unformat (i, "send"))
10247         send_unicast = 1;
10248       else if (unformat (i, "cease"))
10249         cease = 1;
10250       else if (unformat (i, "isno"))
10251         is_no = 1;
10252       else if (unformat (i, "def"))
10253         default_router = 1;
10254       else
10255         {
10256           clib_warning ("parse error '%U'", format_unformat_error, i);
10257           return -99;
10258         }
10259     }
10260
10261   if (sw_if_index_set == 0)
10262     {
10263       errmsg ("missing interface name or sw_if_index");
10264       return -99;
10265     }
10266
10267   /* Construct the API message */
10268   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10269
10270   mp->sw_if_index = ntohl (sw_if_index);
10271   mp->max_interval = ntohl (max_interval);
10272   mp->min_interval = ntohl (min_interval);
10273   mp->lifetime = ntohl (lifetime);
10274   mp->initial_count = ntohl (initial_count);
10275   mp->initial_interval = ntohl (initial_interval);
10276   mp->suppress = suppress;
10277   mp->managed = managed;
10278   mp->other = other;
10279   mp->ll_option = ll_option;
10280   mp->send_unicast = send_unicast;
10281   mp->cease = cease;
10282   mp->is_no = is_no;
10283   mp->default_router = default_router;
10284
10285   /* send it... */
10286   S (mp);
10287
10288   /* Wait for a reply, return good/bad news  */
10289   W (ret);
10290   return ret;
10291 }
10292
10293 static int
10294 api_set_arp_neighbor_limit (vat_main_t * vam)
10295 {
10296   unformat_input_t *i = vam->input;
10297   vl_api_set_arp_neighbor_limit_t *mp;
10298   u32 arp_nbr_limit;
10299   u8 limit_set = 0;
10300   u8 is_ipv6 = 0;
10301   int ret;
10302
10303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10304     {
10305       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10306         limit_set = 1;
10307       else if (unformat (i, "ipv6"))
10308         is_ipv6 = 1;
10309       else
10310         {
10311           clib_warning ("parse error '%U'", format_unformat_error, i);
10312           return -99;
10313         }
10314     }
10315
10316   if (limit_set == 0)
10317     {
10318       errmsg ("missing limit value");
10319       return -99;
10320     }
10321
10322   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10323
10324   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10325   mp->is_ipv6 = is_ipv6;
10326
10327   S (mp);
10328   W (ret);
10329   return ret;
10330 }
10331
10332 static int
10333 api_l2_patch_add_del (vat_main_t * vam)
10334 {
10335   unformat_input_t *i = vam->input;
10336   vl_api_l2_patch_add_del_t *mp;
10337   u32 rx_sw_if_index;
10338   u8 rx_sw_if_index_set = 0;
10339   u32 tx_sw_if_index;
10340   u8 tx_sw_if_index_set = 0;
10341   u8 is_add = 1;
10342   int ret;
10343
10344   /* Parse args required to build the message */
10345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10346     {
10347       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10348         rx_sw_if_index_set = 1;
10349       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10350         tx_sw_if_index_set = 1;
10351       else if (unformat (i, "rx"))
10352         {
10353           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10354             {
10355               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10356                             &rx_sw_if_index))
10357                 rx_sw_if_index_set = 1;
10358             }
10359           else
10360             break;
10361         }
10362       else if (unformat (i, "tx"))
10363         {
10364           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10365             {
10366               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10367                             &tx_sw_if_index))
10368                 tx_sw_if_index_set = 1;
10369             }
10370           else
10371             break;
10372         }
10373       else if (unformat (i, "del"))
10374         is_add = 0;
10375       else
10376         break;
10377     }
10378
10379   if (rx_sw_if_index_set == 0)
10380     {
10381       errmsg ("missing rx interface name or rx_sw_if_index");
10382       return -99;
10383     }
10384
10385   if (tx_sw_if_index_set == 0)
10386     {
10387       errmsg ("missing tx interface name or tx_sw_if_index");
10388       return -99;
10389     }
10390
10391   M (L2_PATCH_ADD_DEL, mp);
10392
10393   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10394   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10395   mp->is_add = is_add;
10396
10397   S (mp);
10398   W (ret);
10399   return ret;
10400 }
10401
10402 u8 is_del;
10403 u8 localsid_addr[16];
10404 u8 end_psp;
10405 u8 behavior;
10406 u32 sw_if_index;
10407 u32 vlan_index;
10408 u32 fib_table;
10409 u8 nh_addr[16];
10410
10411 static int
10412 api_sr_localsid_add_del (vat_main_t * vam)
10413 {
10414   unformat_input_t *i = vam->input;
10415   vl_api_sr_localsid_add_del_t *mp;
10416
10417   u8 is_del;
10418   ip6_address_t localsid;
10419   u8 end_psp = 0;
10420   u8 behavior = ~0;
10421   u32 sw_if_index;
10422   u32 fib_table = ~(u32) 0;
10423   ip6_address_t nh_addr6;
10424   ip4_address_t nh_addr4;
10425   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10426   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10427
10428   bool nexthop_set = 0;
10429
10430   int ret;
10431
10432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10433     {
10434       if (unformat (i, "del"))
10435         is_del = 1;
10436       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10437       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10438         nexthop_set = 1;
10439       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10440         nexthop_set = 1;
10441       else if (unformat (i, "behavior %u", &behavior));
10442       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10443       else if (unformat (i, "fib-table %u", &fib_table));
10444       else if (unformat (i, "end.psp %u", &behavior));
10445       else
10446         break;
10447     }
10448
10449   M (SR_LOCALSID_ADD_DEL, mp);
10450
10451   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10452   if (nexthop_set)
10453     {
10454       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10455       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10456     }
10457   mp->behavior = behavior;
10458   mp->sw_if_index = ntohl (sw_if_index);
10459   mp->fib_table = ntohl (fib_table);
10460   mp->end_psp = end_psp;
10461   mp->is_del = is_del;
10462
10463   S (mp);
10464   W (ret);
10465   return ret;
10466 }
10467
10468 static int
10469 api_ioam_enable (vat_main_t * vam)
10470 {
10471   unformat_input_t *input = vam->input;
10472   vl_api_ioam_enable_t *mp;
10473   u32 id = 0;
10474   int has_trace_option = 0;
10475   int has_pot_option = 0;
10476   int has_seqno_option = 0;
10477   int has_analyse_option = 0;
10478   int ret;
10479
10480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10481     {
10482       if (unformat (input, "trace"))
10483         has_trace_option = 1;
10484       else if (unformat (input, "pot"))
10485         has_pot_option = 1;
10486       else if (unformat (input, "seqno"))
10487         has_seqno_option = 1;
10488       else if (unformat (input, "analyse"))
10489         has_analyse_option = 1;
10490       else
10491         break;
10492     }
10493   M (IOAM_ENABLE, mp);
10494   mp->id = htons (id);
10495   mp->seqno = has_seqno_option;
10496   mp->analyse = has_analyse_option;
10497   mp->pot_enable = has_pot_option;
10498   mp->trace_enable = has_trace_option;
10499
10500   S (mp);
10501   W (ret);
10502   return ret;
10503 }
10504
10505
10506 static int
10507 api_ioam_disable (vat_main_t * vam)
10508 {
10509   vl_api_ioam_disable_t *mp;
10510   int ret;
10511
10512   M (IOAM_DISABLE, mp);
10513   S (mp);
10514   W (ret);
10515   return ret;
10516 }
10517
10518 #define foreach_tcp_proto_field                 \
10519 _(src_port)                                     \
10520 _(dst_port)
10521
10522 #define foreach_udp_proto_field                 \
10523 _(src_port)                                     \
10524 _(dst_port)
10525
10526 #define foreach_ip4_proto_field                 \
10527 _(src_address)                                  \
10528 _(dst_address)                                  \
10529 _(tos)                                          \
10530 _(length)                                       \
10531 _(fragment_id)                                  \
10532 _(ttl)                                          \
10533 _(protocol)                                     \
10534 _(checksum)
10535
10536 typedef struct
10537 {
10538   u16 src_port, dst_port;
10539 } tcpudp_header_t;
10540
10541 #if VPP_API_TEST_BUILTIN == 0
10542 uword
10543 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10544 {
10545   u8 **maskp = va_arg (*args, u8 **);
10546   u8 *mask = 0;
10547   u8 found_something = 0;
10548   tcp_header_t *tcp;
10549
10550 #define _(a) u8 a=0;
10551   foreach_tcp_proto_field;
10552 #undef _
10553
10554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10555     {
10556       if (0);
10557 #define _(a) else if (unformat (input, #a)) a=1;
10558       foreach_tcp_proto_field
10559 #undef _
10560         else
10561         break;
10562     }
10563
10564 #define _(a) found_something += a;
10565   foreach_tcp_proto_field;
10566 #undef _
10567
10568   if (found_something == 0)
10569     return 0;
10570
10571   vec_validate (mask, sizeof (*tcp) - 1);
10572
10573   tcp = (tcp_header_t *) mask;
10574
10575 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10576   foreach_tcp_proto_field;
10577 #undef _
10578
10579   *maskp = mask;
10580   return 1;
10581 }
10582
10583 uword
10584 unformat_udp_mask (unformat_input_t * input, va_list * args)
10585 {
10586   u8 **maskp = va_arg (*args, u8 **);
10587   u8 *mask = 0;
10588   u8 found_something = 0;
10589   udp_header_t *udp;
10590
10591 #define _(a) u8 a=0;
10592   foreach_udp_proto_field;
10593 #undef _
10594
10595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (0);
10598 #define _(a) else if (unformat (input, #a)) a=1;
10599       foreach_udp_proto_field
10600 #undef _
10601         else
10602         break;
10603     }
10604
10605 #define _(a) found_something += a;
10606   foreach_udp_proto_field;
10607 #undef _
10608
10609   if (found_something == 0)
10610     return 0;
10611
10612   vec_validate (mask, sizeof (*udp) - 1);
10613
10614   udp = (udp_header_t *) mask;
10615
10616 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10617   foreach_udp_proto_field;
10618 #undef _
10619
10620   *maskp = mask;
10621   return 1;
10622 }
10623
10624 uword
10625 unformat_l4_mask (unformat_input_t * input, va_list * args)
10626 {
10627   u8 **maskp = va_arg (*args, u8 **);
10628   u16 src_port = 0, dst_port = 0;
10629   tcpudp_header_t *tcpudp;
10630
10631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10632     {
10633       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10634         return 1;
10635       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10636         return 1;
10637       else if (unformat (input, "src_port"))
10638         src_port = 0xFFFF;
10639       else if (unformat (input, "dst_port"))
10640         dst_port = 0xFFFF;
10641       else
10642         return 0;
10643     }
10644
10645   if (!src_port && !dst_port)
10646     return 0;
10647
10648   u8 *mask = 0;
10649   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10650
10651   tcpudp = (tcpudp_header_t *) mask;
10652   tcpudp->src_port = src_port;
10653   tcpudp->dst_port = dst_port;
10654
10655   *maskp = mask;
10656
10657   return 1;
10658 }
10659
10660 uword
10661 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10662 {
10663   u8 **maskp = va_arg (*args, u8 **);
10664   u8 *mask = 0;
10665   u8 found_something = 0;
10666   ip4_header_t *ip;
10667
10668 #define _(a) u8 a=0;
10669   foreach_ip4_proto_field;
10670 #undef _
10671   u8 version = 0;
10672   u8 hdr_length = 0;
10673
10674
10675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (unformat (input, "version"))
10678         version = 1;
10679       else if (unformat (input, "hdr_length"))
10680         hdr_length = 1;
10681       else if (unformat (input, "src"))
10682         src_address = 1;
10683       else if (unformat (input, "dst"))
10684         dst_address = 1;
10685       else if (unformat (input, "proto"))
10686         protocol = 1;
10687
10688 #define _(a) else if (unformat (input, #a)) a=1;
10689       foreach_ip4_proto_field
10690 #undef _
10691         else
10692         break;
10693     }
10694
10695 #define _(a) found_something += a;
10696   foreach_ip4_proto_field;
10697 #undef _
10698
10699   if (found_something == 0)
10700     return 0;
10701
10702   vec_validate (mask, sizeof (*ip) - 1);
10703
10704   ip = (ip4_header_t *) mask;
10705
10706 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10707   foreach_ip4_proto_field;
10708 #undef _
10709
10710   ip->ip_version_and_header_length = 0;
10711
10712   if (version)
10713     ip->ip_version_and_header_length |= 0xF0;
10714
10715   if (hdr_length)
10716     ip->ip_version_and_header_length |= 0x0F;
10717
10718   *maskp = mask;
10719   return 1;
10720 }
10721
10722 #define foreach_ip6_proto_field                 \
10723 _(src_address)                                  \
10724 _(dst_address)                                  \
10725 _(payload_length)                               \
10726 _(hop_limit)                                    \
10727 _(protocol)
10728
10729 uword
10730 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10731 {
10732   u8 **maskp = va_arg (*args, u8 **);
10733   u8 *mask = 0;
10734   u8 found_something = 0;
10735   ip6_header_t *ip;
10736   u32 ip_version_traffic_class_and_flow_label;
10737
10738 #define _(a) u8 a=0;
10739   foreach_ip6_proto_field;
10740 #undef _
10741   u8 version = 0;
10742   u8 traffic_class = 0;
10743   u8 flow_label = 0;
10744
10745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10746     {
10747       if (unformat (input, "version"))
10748         version = 1;
10749       else if (unformat (input, "traffic-class"))
10750         traffic_class = 1;
10751       else if (unformat (input, "flow-label"))
10752         flow_label = 1;
10753       else if (unformat (input, "src"))
10754         src_address = 1;
10755       else if (unformat (input, "dst"))
10756         dst_address = 1;
10757       else if (unformat (input, "proto"))
10758         protocol = 1;
10759
10760 #define _(a) else if (unformat (input, #a)) a=1;
10761       foreach_ip6_proto_field
10762 #undef _
10763         else
10764         break;
10765     }
10766
10767 #define _(a) found_something += a;
10768   foreach_ip6_proto_field;
10769 #undef _
10770
10771   if (found_something == 0)
10772     return 0;
10773
10774   vec_validate (mask, sizeof (*ip) - 1);
10775
10776   ip = (ip6_header_t *) mask;
10777
10778 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10779   foreach_ip6_proto_field;
10780 #undef _
10781
10782   ip_version_traffic_class_and_flow_label = 0;
10783
10784   if (version)
10785     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10786
10787   if (traffic_class)
10788     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10789
10790   if (flow_label)
10791     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10792
10793   ip->ip_version_traffic_class_and_flow_label =
10794     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10795
10796   *maskp = mask;
10797   return 1;
10798 }
10799
10800 uword
10801 unformat_l3_mask (unformat_input_t * input, va_list * args)
10802 {
10803   u8 **maskp = va_arg (*args, u8 **);
10804
10805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10806     {
10807       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10808         return 1;
10809       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10810         return 1;
10811       else
10812         break;
10813     }
10814   return 0;
10815 }
10816
10817 uword
10818 unformat_l2_mask (unformat_input_t * input, va_list * args)
10819 {
10820   u8 **maskp = va_arg (*args, u8 **);
10821   u8 *mask = 0;
10822   u8 src = 0;
10823   u8 dst = 0;
10824   u8 proto = 0;
10825   u8 tag1 = 0;
10826   u8 tag2 = 0;
10827   u8 ignore_tag1 = 0;
10828   u8 ignore_tag2 = 0;
10829   u8 cos1 = 0;
10830   u8 cos2 = 0;
10831   u8 dot1q = 0;
10832   u8 dot1ad = 0;
10833   int len = 14;
10834
10835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10836     {
10837       if (unformat (input, "src"))
10838         src = 1;
10839       else if (unformat (input, "dst"))
10840         dst = 1;
10841       else if (unformat (input, "proto"))
10842         proto = 1;
10843       else if (unformat (input, "tag1"))
10844         tag1 = 1;
10845       else if (unformat (input, "tag2"))
10846         tag2 = 1;
10847       else if (unformat (input, "ignore-tag1"))
10848         ignore_tag1 = 1;
10849       else if (unformat (input, "ignore-tag2"))
10850         ignore_tag2 = 1;
10851       else if (unformat (input, "cos1"))
10852         cos1 = 1;
10853       else if (unformat (input, "cos2"))
10854         cos2 = 1;
10855       else if (unformat (input, "dot1q"))
10856         dot1q = 1;
10857       else if (unformat (input, "dot1ad"))
10858         dot1ad = 1;
10859       else
10860         break;
10861     }
10862   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10863        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10864     return 0;
10865
10866   if (tag1 || ignore_tag1 || cos1 || dot1q)
10867     len = 18;
10868   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10869     len = 22;
10870
10871   vec_validate (mask, len - 1);
10872
10873   if (dst)
10874     clib_memset (mask, 0xff, 6);
10875
10876   if (src)
10877     clib_memset (mask + 6, 0xff, 6);
10878
10879   if (tag2 || dot1ad)
10880     {
10881       /* inner vlan tag */
10882       if (tag2)
10883         {
10884           mask[19] = 0xff;
10885           mask[18] = 0x0f;
10886         }
10887       if (cos2)
10888         mask[18] |= 0xe0;
10889       if (proto)
10890         mask[21] = mask[20] = 0xff;
10891       if (tag1)
10892         {
10893           mask[15] = 0xff;
10894           mask[14] = 0x0f;
10895         }
10896       if (cos1)
10897         mask[14] |= 0xe0;
10898       *maskp = mask;
10899       return 1;
10900     }
10901   if (tag1 | dot1q)
10902     {
10903       if (tag1)
10904         {
10905           mask[15] = 0xff;
10906           mask[14] = 0x0f;
10907         }
10908       if (cos1)
10909         mask[14] |= 0xe0;
10910       if (proto)
10911         mask[16] = mask[17] = 0xff;
10912
10913       *maskp = mask;
10914       return 1;
10915     }
10916   if (cos2)
10917     mask[18] |= 0xe0;
10918   if (cos1)
10919     mask[14] |= 0xe0;
10920   if (proto)
10921     mask[12] = mask[13] = 0xff;
10922
10923   *maskp = mask;
10924   return 1;
10925 }
10926
10927 uword
10928 unformat_classify_mask (unformat_input_t * input, va_list * args)
10929 {
10930   u8 **maskp = va_arg (*args, u8 **);
10931   u32 *skipp = va_arg (*args, u32 *);
10932   u32 *matchp = va_arg (*args, u32 *);
10933   u32 match;
10934   u8 *mask = 0;
10935   u8 *l2 = 0;
10936   u8 *l3 = 0;
10937   u8 *l4 = 0;
10938   int i;
10939
10940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10941     {
10942       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10943         ;
10944       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10945         ;
10946       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10947         ;
10948       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10949         ;
10950       else
10951         break;
10952     }
10953
10954   if (l4 && !l3)
10955     {
10956       vec_free (mask);
10957       vec_free (l2);
10958       vec_free (l4);
10959       return 0;
10960     }
10961
10962   if (mask || l2 || l3 || l4)
10963     {
10964       if (l2 || l3 || l4)
10965         {
10966           /* "With a free Ethernet header in every package" */
10967           if (l2 == 0)
10968             vec_validate (l2, 13);
10969           mask = l2;
10970           if (vec_len (l3))
10971             {
10972               vec_append (mask, l3);
10973               vec_free (l3);
10974             }
10975           if (vec_len (l4))
10976             {
10977               vec_append (mask, l4);
10978               vec_free (l4);
10979             }
10980         }
10981
10982       /* Scan forward looking for the first significant mask octet */
10983       for (i = 0; i < vec_len (mask); i++)
10984         if (mask[i])
10985           break;
10986
10987       /* compute (skip, match) params */
10988       *skipp = i / sizeof (u32x4);
10989       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10990
10991       /* Pad mask to an even multiple of the vector size */
10992       while (vec_len (mask) % sizeof (u32x4))
10993         vec_add1 (mask, 0);
10994
10995       match = vec_len (mask) / sizeof (u32x4);
10996
10997       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10998         {
10999           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11000           if (*tmp || *(tmp + 1))
11001             break;
11002           match--;
11003         }
11004       if (match == 0)
11005         clib_warning ("BUG: match 0");
11006
11007       _vec_len (mask) = match * sizeof (u32x4);
11008
11009       *matchp = match;
11010       *maskp = mask;
11011
11012       return 1;
11013     }
11014
11015   return 0;
11016 }
11017 #endif /* VPP_API_TEST_BUILTIN */
11018
11019 #define foreach_l2_next                         \
11020 _(drop, DROP)                                   \
11021 _(ethernet, ETHERNET_INPUT)                     \
11022 _(ip4, IP4_INPUT)                               \
11023 _(ip6, IP6_INPUT)
11024
11025 uword
11026 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11027 {
11028   u32 *miss_next_indexp = va_arg (*args, u32 *);
11029   u32 next_index = 0;
11030   u32 tmp;
11031
11032 #define _(n,N) \
11033   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11034   foreach_l2_next;
11035 #undef _
11036
11037   if (unformat (input, "%d", &tmp))
11038     {
11039       next_index = tmp;
11040       goto out;
11041     }
11042
11043   return 0;
11044
11045 out:
11046   *miss_next_indexp = next_index;
11047   return 1;
11048 }
11049
11050 #define foreach_ip_next                         \
11051 _(drop, DROP)                                   \
11052 _(local, LOCAL)                                 \
11053 _(rewrite, REWRITE)
11054
11055 uword
11056 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11057 {
11058   u32 *miss_next_indexp = va_arg (*args, u32 *);
11059   u32 next_index = 0;
11060   u32 tmp;
11061
11062 #define _(n,N) \
11063   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11064   foreach_ip_next;
11065 #undef _
11066
11067   if (unformat (input, "%d", &tmp))
11068     {
11069       next_index = tmp;
11070       goto out;
11071     }
11072
11073   return 0;
11074
11075 out:
11076   *miss_next_indexp = next_index;
11077   return 1;
11078 }
11079
11080 #define foreach_acl_next                        \
11081 _(deny, DENY)
11082
11083 uword
11084 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11085 {
11086   u32 *miss_next_indexp = va_arg (*args, u32 *);
11087   u32 next_index = 0;
11088   u32 tmp;
11089
11090 #define _(n,N) \
11091   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11092   foreach_acl_next;
11093 #undef _
11094
11095   if (unformat (input, "permit"))
11096     {
11097       next_index = ~0;
11098       goto out;
11099     }
11100   else if (unformat (input, "%d", &tmp))
11101     {
11102       next_index = tmp;
11103       goto out;
11104     }
11105
11106   return 0;
11107
11108 out:
11109   *miss_next_indexp = next_index;
11110   return 1;
11111 }
11112
11113 uword
11114 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11115 {
11116   u32 *r = va_arg (*args, u32 *);
11117
11118   if (unformat (input, "conform-color"))
11119     *r = POLICE_CONFORM;
11120   else if (unformat (input, "exceed-color"))
11121     *r = POLICE_EXCEED;
11122   else
11123     return 0;
11124
11125   return 1;
11126 }
11127
11128 static int
11129 api_classify_add_del_table (vat_main_t * vam)
11130 {
11131   unformat_input_t *i = vam->input;
11132   vl_api_classify_add_del_table_t *mp;
11133
11134   u32 nbuckets = 2;
11135   u32 skip = ~0;
11136   u32 match = ~0;
11137   int is_add = 1;
11138   int del_chain = 0;
11139   u32 table_index = ~0;
11140   u32 next_table_index = ~0;
11141   u32 miss_next_index = ~0;
11142   u32 memory_size = 32 << 20;
11143   u8 *mask = 0;
11144   u32 current_data_flag = 0;
11145   int current_data_offset = 0;
11146   int ret;
11147
11148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11149     {
11150       if (unformat (i, "del"))
11151         is_add = 0;
11152       else if (unformat (i, "del-chain"))
11153         {
11154           is_add = 0;
11155           del_chain = 1;
11156         }
11157       else if (unformat (i, "buckets %d", &nbuckets))
11158         ;
11159       else if (unformat (i, "memory_size %d", &memory_size))
11160         ;
11161       else if (unformat (i, "skip %d", &skip))
11162         ;
11163       else if (unformat (i, "match %d", &match))
11164         ;
11165       else if (unformat (i, "table %d", &table_index))
11166         ;
11167       else if (unformat (i, "mask %U", unformat_classify_mask,
11168                          &mask, &skip, &match))
11169         ;
11170       else if (unformat (i, "next-table %d", &next_table_index))
11171         ;
11172       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11173                          &miss_next_index))
11174         ;
11175       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11176                          &miss_next_index))
11177         ;
11178       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11179                          &miss_next_index))
11180         ;
11181       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11182         ;
11183       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11184         ;
11185       else
11186         break;
11187     }
11188
11189   if (is_add && mask == 0)
11190     {
11191       errmsg ("Mask required");
11192       return -99;
11193     }
11194
11195   if (is_add && skip == ~0)
11196     {
11197       errmsg ("skip count required");
11198       return -99;
11199     }
11200
11201   if (is_add && match == ~0)
11202     {
11203       errmsg ("match count required");
11204       return -99;
11205     }
11206
11207   if (!is_add && table_index == ~0)
11208     {
11209       errmsg ("table index required for delete");
11210       return -99;
11211     }
11212
11213   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11214
11215   mp->is_add = is_add;
11216   mp->del_chain = del_chain;
11217   mp->table_index = ntohl (table_index);
11218   mp->nbuckets = ntohl (nbuckets);
11219   mp->memory_size = ntohl (memory_size);
11220   mp->skip_n_vectors = ntohl (skip);
11221   mp->match_n_vectors = ntohl (match);
11222   mp->next_table_index = ntohl (next_table_index);
11223   mp->miss_next_index = ntohl (miss_next_index);
11224   mp->current_data_flag = ntohl (current_data_flag);
11225   mp->current_data_offset = ntohl (current_data_offset);
11226   mp->mask_len = ntohl (vec_len (mask));
11227   clib_memcpy (mp->mask, mask, vec_len (mask));
11228
11229   vec_free (mask);
11230
11231   S (mp);
11232   W (ret);
11233   return ret;
11234 }
11235
11236 #if VPP_API_TEST_BUILTIN == 0
11237 uword
11238 unformat_l4_match (unformat_input_t * input, va_list * args)
11239 {
11240   u8 **matchp = va_arg (*args, u8 **);
11241
11242   u8 *proto_header = 0;
11243   int src_port = 0;
11244   int dst_port = 0;
11245
11246   tcpudp_header_t h;
11247
11248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11249     {
11250       if (unformat (input, "src_port %d", &src_port))
11251         ;
11252       else if (unformat (input, "dst_port %d", &dst_port))
11253         ;
11254       else
11255         return 0;
11256     }
11257
11258   h.src_port = clib_host_to_net_u16 (src_port);
11259   h.dst_port = clib_host_to_net_u16 (dst_port);
11260   vec_validate (proto_header, sizeof (h) - 1);
11261   memcpy (proto_header, &h, sizeof (h));
11262
11263   *matchp = proto_header;
11264
11265   return 1;
11266 }
11267
11268 uword
11269 unformat_ip4_match (unformat_input_t * input, va_list * args)
11270 {
11271   u8 **matchp = va_arg (*args, u8 **);
11272   u8 *match = 0;
11273   ip4_header_t *ip;
11274   int version = 0;
11275   u32 version_val;
11276   int hdr_length = 0;
11277   u32 hdr_length_val;
11278   int src = 0, dst = 0;
11279   ip4_address_t src_val, dst_val;
11280   int proto = 0;
11281   u32 proto_val;
11282   int tos = 0;
11283   u32 tos_val;
11284   int length = 0;
11285   u32 length_val;
11286   int fragment_id = 0;
11287   u32 fragment_id_val;
11288   int ttl = 0;
11289   int ttl_val;
11290   int checksum = 0;
11291   u32 checksum_val;
11292
11293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11294     {
11295       if (unformat (input, "version %d", &version_val))
11296         version = 1;
11297       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11298         hdr_length = 1;
11299       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11300         src = 1;
11301       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11302         dst = 1;
11303       else if (unformat (input, "proto %d", &proto_val))
11304         proto = 1;
11305       else if (unformat (input, "tos %d", &tos_val))
11306         tos = 1;
11307       else if (unformat (input, "length %d", &length_val))
11308         length = 1;
11309       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11310         fragment_id = 1;
11311       else if (unformat (input, "ttl %d", &ttl_val))
11312         ttl = 1;
11313       else if (unformat (input, "checksum %d", &checksum_val))
11314         checksum = 1;
11315       else
11316         break;
11317     }
11318
11319   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11320       + ttl + checksum == 0)
11321     return 0;
11322
11323   /*
11324    * Aligned because we use the real comparison functions
11325    */
11326   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11327
11328   ip = (ip4_header_t *) match;
11329
11330   /* These are realistically matched in practice */
11331   if (src)
11332     ip->src_address.as_u32 = src_val.as_u32;
11333
11334   if (dst)
11335     ip->dst_address.as_u32 = dst_val.as_u32;
11336
11337   if (proto)
11338     ip->protocol = proto_val;
11339
11340
11341   /* These are not, but they're included for completeness */
11342   if (version)
11343     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11344
11345   if (hdr_length)
11346     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11347
11348   if (tos)
11349     ip->tos = tos_val;
11350
11351   if (length)
11352     ip->length = clib_host_to_net_u16 (length_val);
11353
11354   if (ttl)
11355     ip->ttl = ttl_val;
11356
11357   if (checksum)
11358     ip->checksum = clib_host_to_net_u16 (checksum_val);
11359
11360   *matchp = match;
11361   return 1;
11362 }
11363
11364 uword
11365 unformat_ip6_match (unformat_input_t * input, va_list * args)
11366 {
11367   u8 **matchp = va_arg (*args, u8 **);
11368   u8 *match = 0;
11369   ip6_header_t *ip;
11370   int version = 0;
11371   u32 version_val;
11372   u8 traffic_class = 0;
11373   u32 traffic_class_val = 0;
11374   u8 flow_label = 0;
11375   u8 flow_label_val;
11376   int src = 0, dst = 0;
11377   ip6_address_t src_val, dst_val;
11378   int proto = 0;
11379   u32 proto_val;
11380   int payload_length = 0;
11381   u32 payload_length_val;
11382   int hop_limit = 0;
11383   int hop_limit_val;
11384   u32 ip_version_traffic_class_and_flow_label;
11385
11386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11387     {
11388       if (unformat (input, "version %d", &version_val))
11389         version = 1;
11390       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11391         traffic_class = 1;
11392       else if (unformat (input, "flow_label %d", &flow_label_val))
11393         flow_label = 1;
11394       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11395         src = 1;
11396       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11397         dst = 1;
11398       else if (unformat (input, "proto %d", &proto_val))
11399         proto = 1;
11400       else if (unformat (input, "payload_length %d", &payload_length_val))
11401         payload_length = 1;
11402       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11403         hop_limit = 1;
11404       else
11405         break;
11406     }
11407
11408   if (version + traffic_class + flow_label + src + dst + proto +
11409       payload_length + hop_limit == 0)
11410     return 0;
11411
11412   /*
11413    * Aligned because we use the real comparison functions
11414    */
11415   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11416
11417   ip = (ip6_header_t *) match;
11418
11419   if (src)
11420     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11421
11422   if (dst)
11423     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11424
11425   if (proto)
11426     ip->protocol = proto_val;
11427
11428   ip_version_traffic_class_and_flow_label = 0;
11429
11430   if (version)
11431     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11432
11433   if (traffic_class)
11434     ip_version_traffic_class_and_flow_label |=
11435       (traffic_class_val & 0xFF) << 20;
11436
11437   if (flow_label)
11438     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11439
11440   ip->ip_version_traffic_class_and_flow_label =
11441     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11442
11443   if (payload_length)
11444     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11445
11446   if (hop_limit)
11447     ip->hop_limit = hop_limit_val;
11448
11449   *matchp = match;
11450   return 1;
11451 }
11452
11453 uword
11454 unformat_l3_match (unformat_input_t * input, va_list * args)
11455 {
11456   u8 **matchp = va_arg (*args, u8 **);
11457
11458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11459     {
11460       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11461         return 1;
11462       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11463         return 1;
11464       else
11465         break;
11466     }
11467   return 0;
11468 }
11469
11470 uword
11471 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11472 {
11473   u8 *tagp = va_arg (*args, u8 *);
11474   u32 tag;
11475
11476   if (unformat (input, "%d", &tag))
11477     {
11478       tagp[0] = (tag >> 8) & 0x0F;
11479       tagp[1] = tag & 0xFF;
11480       return 1;
11481     }
11482
11483   return 0;
11484 }
11485
11486 uword
11487 unformat_l2_match (unformat_input_t * input, va_list * args)
11488 {
11489   u8 **matchp = va_arg (*args, u8 **);
11490   u8 *match = 0;
11491   u8 src = 0;
11492   u8 src_val[6];
11493   u8 dst = 0;
11494   u8 dst_val[6];
11495   u8 proto = 0;
11496   u16 proto_val;
11497   u8 tag1 = 0;
11498   u8 tag1_val[2];
11499   u8 tag2 = 0;
11500   u8 tag2_val[2];
11501   int len = 14;
11502   u8 ignore_tag1 = 0;
11503   u8 ignore_tag2 = 0;
11504   u8 cos1 = 0;
11505   u8 cos2 = 0;
11506   u32 cos1_val = 0;
11507   u32 cos2_val = 0;
11508
11509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11510     {
11511       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11512         src = 1;
11513       else
11514         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11515         dst = 1;
11516       else if (unformat (input, "proto %U",
11517                          unformat_ethernet_type_host_byte_order, &proto_val))
11518         proto = 1;
11519       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11520         tag1 = 1;
11521       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11522         tag2 = 1;
11523       else if (unformat (input, "ignore-tag1"))
11524         ignore_tag1 = 1;
11525       else if (unformat (input, "ignore-tag2"))
11526         ignore_tag2 = 1;
11527       else if (unformat (input, "cos1 %d", &cos1_val))
11528         cos1 = 1;
11529       else if (unformat (input, "cos2 %d", &cos2_val))
11530         cos2 = 1;
11531       else
11532         break;
11533     }
11534   if ((src + dst + proto + tag1 + tag2 +
11535        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11536     return 0;
11537
11538   if (tag1 || ignore_tag1 || cos1)
11539     len = 18;
11540   if (tag2 || ignore_tag2 || cos2)
11541     len = 22;
11542
11543   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11544
11545   if (dst)
11546     clib_memcpy (match, dst_val, 6);
11547
11548   if (src)
11549     clib_memcpy (match + 6, src_val, 6);
11550
11551   if (tag2)
11552     {
11553       /* inner vlan tag */
11554       match[19] = tag2_val[1];
11555       match[18] = tag2_val[0];
11556       if (cos2)
11557         match[18] |= (cos2_val & 0x7) << 5;
11558       if (proto)
11559         {
11560           match[21] = proto_val & 0xff;
11561           match[20] = proto_val >> 8;
11562         }
11563       if (tag1)
11564         {
11565           match[15] = tag1_val[1];
11566           match[14] = tag1_val[0];
11567         }
11568       if (cos1)
11569         match[14] |= (cos1_val & 0x7) << 5;
11570       *matchp = match;
11571       return 1;
11572     }
11573   if (tag1)
11574     {
11575       match[15] = tag1_val[1];
11576       match[14] = tag1_val[0];
11577       if (proto)
11578         {
11579           match[17] = proto_val & 0xff;
11580           match[16] = proto_val >> 8;
11581         }
11582       if (cos1)
11583         match[14] |= (cos1_val & 0x7) << 5;
11584
11585       *matchp = match;
11586       return 1;
11587     }
11588   if (cos2)
11589     match[18] |= (cos2_val & 0x7) << 5;
11590   if (cos1)
11591     match[14] |= (cos1_val & 0x7) << 5;
11592   if (proto)
11593     {
11594       match[13] = proto_val & 0xff;
11595       match[12] = proto_val >> 8;
11596     }
11597
11598   *matchp = match;
11599   return 1;
11600 }
11601
11602 uword
11603 unformat_qos_source (unformat_input_t * input, va_list * args)
11604 {
11605   int *qs = va_arg (*args, int *);
11606
11607   if (unformat (input, "ip"))
11608     *qs = QOS_SOURCE_IP;
11609   else if (unformat (input, "mpls"))
11610     *qs = QOS_SOURCE_MPLS;
11611   else if (unformat (input, "ext"))
11612     *qs = QOS_SOURCE_EXT;
11613   else if (unformat (input, "vlan"))
11614     *qs = QOS_SOURCE_VLAN;
11615   else
11616     return 0;
11617
11618   return 1;
11619 }
11620 #endif
11621
11622 uword
11623 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11624 {
11625   u8 **matchp = va_arg (*args, u8 **);
11626   u32 skip_n_vectors = va_arg (*args, u32);
11627   u32 match_n_vectors = va_arg (*args, u32);
11628
11629   u8 *match = 0;
11630   u8 *l2 = 0;
11631   u8 *l3 = 0;
11632   u8 *l4 = 0;
11633
11634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11635     {
11636       if (unformat (input, "hex %U", unformat_hex_string, &match))
11637         ;
11638       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11639         ;
11640       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11641         ;
11642       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11643         ;
11644       else
11645         break;
11646     }
11647
11648   if (l4 && !l3)
11649     {
11650       vec_free (match);
11651       vec_free (l2);
11652       vec_free (l4);
11653       return 0;
11654     }
11655
11656   if (match || l2 || l3 || l4)
11657     {
11658       if (l2 || l3 || l4)
11659         {
11660           /* "Win a free Ethernet header in every packet" */
11661           if (l2 == 0)
11662             vec_validate_aligned (l2, 13, sizeof (u32x4));
11663           match = l2;
11664           if (vec_len (l3))
11665             {
11666               vec_append_aligned (match, l3, sizeof (u32x4));
11667               vec_free (l3);
11668             }
11669           if (vec_len (l4))
11670             {
11671               vec_append_aligned (match, l4, sizeof (u32x4));
11672               vec_free (l4);
11673             }
11674         }
11675
11676       /* Make sure the vector is big enough even if key is all 0's */
11677       vec_validate_aligned
11678         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11679          sizeof (u32x4));
11680
11681       /* Set size, include skipped vectors */
11682       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11683
11684       *matchp = match;
11685
11686       return 1;
11687     }
11688
11689   return 0;
11690 }
11691
11692 static int
11693 api_classify_add_del_session (vat_main_t * vam)
11694 {
11695   unformat_input_t *i = vam->input;
11696   vl_api_classify_add_del_session_t *mp;
11697   int is_add = 1;
11698   u32 table_index = ~0;
11699   u32 hit_next_index = ~0;
11700   u32 opaque_index = ~0;
11701   u8 *match = 0;
11702   i32 advance = 0;
11703   u32 skip_n_vectors = 0;
11704   u32 match_n_vectors = 0;
11705   u32 action = 0;
11706   u32 metadata = 0;
11707   int ret;
11708
11709   /*
11710    * Warning: you have to supply skip_n and match_n
11711    * because the API client cant simply look at the classify
11712    * table object.
11713    */
11714
11715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11716     {
11717       if (unformat (i, "del"))
11718         is_add = 0;
11719       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11720                          &hit_next_index))
11721         ;
11722       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11723                          &hit_next_index))
11724         ;
11725       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11726                          &hit_next_index))
11727         ;
11728       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11729         ;
11730       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11731         ;
11732       else if (unformat (i, "opaque-index %d", &opaque_index))
11733         ;
11734       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11735         ;
11736       else if (unformat (i, "match_n %d", &match_n_vectors))
11737         ;
11738       else if (unformat (i, "match %U", api_unformat_classify_match,
11739                          &match, skip_n_vectors, match_n_vectors))
11740         ;
11741       else if (unformat (i, "advance %d", &advance))
11742         ;
11743       else if (unformat (i, "table-index %d", &table_index))
11744         ;
11745       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11746         action = 1;
11747       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11748         action = 2;
11749       else if (unformat (i, "action %d", &action))
11750         ;
11751       else if (unformat (i, "metadata %d", &metadata))
11752         ;
11753       else
11754         break;
11755     }
11756
11757   if (table_index == ~0)
11758     {
11759       errmsg ("Table index required");
11760       return -99;
11761     }
11762
11763   if (is_add && match == 0)
11764     {
11765       errmsg ("Match value required");
11766       return -99;
11767     }
11768
11769   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11770
11771   mp->is_add = is_add;
11772   mp->table_index = ntohl (table_index);
11773   mp->hit_next_index = ntohl (hit_next_index);
11774   mp->opaque_index = ntohl (opaque_index);
11775   mp->advance = ntohl (advance);
11776   mp->action = action;
11777   mp->metadata = ntohl (metadata);
11778   mp->match_len = ntohl (vec_len (match));
11779   clib_memcpy (mp->match, match, vec_len (match));
11780   vec_free (match);
11781
11782   S (mp);
11783   W (ret);
11784   return ret;
11785 }
11786
11787 static int
11788 api_classify_set_interface_ip_table (vat_main_t * vam)
11789 {
11790   unformat_input_t *i = vam->input;
11791   vl_api_classify_set_interface_ip_table_t *mp;
11792   u32 sw_if_index;
11793   int sw_if_index_set;
11794   u32 table_index = ~0;
11795   u8 is_ipv6 = 0;
11796   int ret;
11797
11798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11799     {
11800       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11801         sw_if_index_set = 1;
11802       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11803         sw_if_index_set = 1;
11804       else if (unformat (i, "table %d", &table_index))
11805         ;
11806       else
11807         {
11808           clib_warning ("parse error '%U'", format_unformat_error, i);
11809           return -99;
11810         }
11811     }
11812
11813   if (sw_if_index_set == 0)
11814     {
11815       errmsg ("missing interface name or sw_if_index");
11816       return -99;
11817     }
11818
11819
11820   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11821
11822   mp->sw_if_index = ntohl (sw_if_index);
11823   mp->table_index = ntohl (table_index);
11824   mp->is_ipv6 = is_ipv6;
11825
11826   S (mp);
11827   W (ret);
11828   return ret;
11829 }
11830
11831 static int
11832 api_classify_set_interface_l2_tables (vat_main_t * vam)
11833 {
11834   unformat_input_t *i = vam->input;
11835   vl_api_classify_set_interface_l2_tables_t *mp;
11836   u32 sw_if_index;
11837   int sw_if_index_set;
11838   u32 ip4_table_index = ~0;
11839   u32 ip6_table_index = ~0;
11840   u32 other_table_index = ~0;
11841   u32 is_input = 1;
11842   int ret;
11843
11844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11845     {
11846       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11847         sw_if_index_set = 1;
11848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11849         sw_if_index_set = 1;
11850       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11851         ;
11852       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11853         ;
11854       else if (unformat (i, "other-table %d", &other_table_index))
11855         ;
11856       else if (unformat (i, "is-input %d", &is_input))
11857         ;
11858       else
11859         {
11860           clib_warning ("parse error '%U'", format_unformat_error, i);
11861           return -99;
11862         }
11863     }
11864
11865   if (sw_if_index_set == 0)
11866     {
11867       errmsg ("missing interface name or sw_if_index");
11868       return -99;
11869     }
11870
11871
11872   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11873
11874   mp->sw_if_index = ntohl (sw_if_index);
11875   mp->ip4_table_index = ntohl (ip4_table_index);
11876   mp->ip6_table_index = ntohl (ip6_table_index);
11877   mp->other_table_index = ntohl (other_table_index);
11878   mp->is_input = (u8) is_input;
11879
11880   S (mp);
11881   W (ret);
11882   return ret;
11883 }
11884
11885 static int
11886 api_set_ipfix_exporter (vat_main_t * vam)
11887 {
11888   unformat_input_t *i = vam->input;
11889   vl_api_set_ipfix_exporter_t *mp;
11890   ip4_address_t collector_address;
11891   u8 collector_address_set = 0;
11892   u32 collector_port = ~0;
11893   ip4_address_t src_address;
11894   u8 src_address_set = 0;
11895   u32 vrf_id = ~0;
11896   u32 path_mtu = ~0;
11897   u32 template_interval = ~0;
11898   u8 udp_checksum = 0;
11899   int ret;
11900
11901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11902     {
11903       if (unformat (i, "collector_address %U", unformat_ip4_address,
11904                     &collector_address))
11905         collector_address_set = 1;
11906       else if (unformat (i, "collector_port %d", &collector_port))
11907         ;
11908       else if (unformat (i, "src_address %U", unformat_ip4_address,
11909                          &src_address))
11910         src_address_set = 1;
11911       else if (unformat (i, "vrf_id %d", &vrf_id))
11912         ;
11913       else if (unformat (i, "path_mtu %d", &path_mtu))
11914         ;
11915       else if (unformat (i, "template_interval %d", &template_interval))
11916         ;
11917       else if (unformat (i, "udp_checksum"))
11918         udp_checksum = 1;
11919       else
11920         break;
11921     }
11922
11923   if (collector_address_set == 0)
11924     {
11925       errmsg ("collector_address required");
11926       return -99;
11927     }
11928
11929   if (src_address_set == 0)
11930     {
11931       errmsg ("src_address required");
11932       return -99;
11933     }
11934
11935   M (SET_IPFIX_EXPORTER, mp);
11936
11937   memcpy (mp->collector_address, collector_address.data,
11938           sizeof (collector_address.data));
11939   mp->collector_port = htons ((u16) collector_port);
11940   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11941   mp->vrf_id = htonl (vrf_id);
11942   mp->path_mtu = htonl (path_mtu);
11943   mp->template_interval = htonl (template_interval);
11944   mp->udp_checksum = udp_checksum;
11945
11946   S (mp);
11947   W (ret);
11948   return ret;
11949 }
11950
11951 static int
11952 api_set_ipfix_classify_stream (vat_main_t * vam)
11953 {
11954   unformat_input_t *i = vam->input;
11955   vl_api_set_ipfix_classify_stream_t *mp;
11956   u32 domain_id = 0;
11957   u32 src_port = UDP_DST_PORT_ipfix;
11958   int ret;
11959
11960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11961     {
11962       if (unformat (i, "domain %d", &domain_id))
11963         ;
11964       else if (unformat (i, "src_port %d", &src_port))
11965         ;
11966       else
11967         {
11968           errmsg ("unknown input `%U'", format_unformat_error, i);
11969           return -99;
11970         }
11971     }
11972
11973   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11974
11975   mp->domain_id = htonl (domain_id);
11976   mp->src_port = htons ((u16) src_port);
11977
11978   S (mp);
11979   W (ret);
11980   return ret;
11981 }
11982
11983 static int
11984 api_ipfix_classify_table_add_del (vat_main_t * vam)
11985 {
11986   unformat_input_t *i = vam->input;
11987   vl_api_ipfix_classify_table_add_del_t *mp;
11988   int is_add = -1;
11989   u32 classify_table_index = ~0;
11990   u8 ip_version = 0;
11991   u8 transport_protocol = 255;
11992   int ret;
11993
11994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11995     {
11996       if (unformat (i, "add"))
11997         is_add = 1;
11998       else if (unformat (i, "del"))
11999         is_add = 0;
12000       else if (unformat (i, "table %d", &classify_table_index))
12001         ;
12002       else if (unformat (i, "ip4"))
12003         ip_version = 4;
12004       else if (unformat (i, "ip6"))
12005         ip_version = 6;
12006       else if (unformat (i, "tcp"))
12007         transport_protocol = 6;
12008       else if (unformat (i, "udp"))
12009         transport_protocol = 17;
12010       else
12011         {
12012           errmsg ("unknown input `%U'", format_unformat_error, i);
12013           return -99;
12014         }
12015     }
12016
12017   if (is_add == -1)
12018     {
12019       errmsg ("expecting: add|del");
12020       return -99;
12021     }
12022   if (classify_table_index == ~0)
12023     {
12024       errmsg ("classifier table not specified");
12025       return -99;
12026     }
12027   if (ip_version == 0)
12028     {
12029       errmsg ("IP version not specified");
12030       return -99;
12031     }
12032
12033   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12034
12035   mp->is_add = is_add;
12036   mp->table_id = htonl (classify_table_index);
12037   mp->ip_version = ip_version;
12038   mp->transport_protocol = transport_protocol;
12039
12040   S (mp);
12041   W (ret);
12042   return ret;
12043 }
12044
12045 static int
12046 api_get_node_index (vat_main_t * vam)
12047 {
12048   unformat_input_t *i = vam->input;
12049   vl_api_get_node_index_t *mp;
12050   u8 *name = 0;
12051   int ret;
12052
12053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12054     {
12055       if (unformat (i, "node %s", &name))
12056         ;
12057       else
12058         break;
12059     }
12060   if (name == 0)
12061     {
12062       errmsg ("node name required");
12063       return -99;
12064     }
12065   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12066     {
12067       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12068       return -99;
12069     }
12070
12071   M (GET_NODE_INDEX, mp);
12072   clib_memcpy (mp->node_name, name, vec_len (name));
12073   vec_free (name);
12074
12075   S (mp);
12076   W (ret);
12077   return ret;
12078 }
12079
12080 static int
12081 api_get_next_index (vat_main_t * vam)
12082 {
12083   unformat_input_t *i = vam->input;
12084   vl_api_get_next_index_t *mp;
12085   u8 *node_name = 0, *next_node_name = 0;
12086   int ret;
12087
12088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12089     {
12090       if (unformat (i, "node-name %s", &node_name))
12091         ;
12092       else if (unformat (i, "next-node-name %s", &next_node_name))
12093         break;
12094     }
12095
12096   if (node_name == 0)
12097     {
12098       errmsg ("node name required");
12099       return -99;
12100     }
12101   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12102     {
12103       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12104       return -99;
12105     }
12106
12107   if (next_node_name == 0)
12108     {
12109       errmsg ("next node name required");
12110       return -99;
12111     }
12112   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12113     {
12114       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12115       return -99;
12116     }
12117
12118   M (GET_NEXT_INDEX, mp);
12119   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12120   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12121   vec_free (node_name);
12122   vec_free (next_node_name);
12123
12124   S (mp);
12125   W (ret);
12126   return ret;
12127 }
12128
12129 static int
12130 api_add_node_next (vat_main_t * vam)
12131 {
12132   unformat_input_t *i = vam->input;
12133   vl_api_add_node_next_t *mp;
12134   u8 *name = 0;
12135   u8 *next = 0;
12136   int ret;
12137
12138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12139     {
12140       if (unformat (i, "node %s", &name))
12141         ;
12142       else if (unformat (i, "next %s", &next))
12143         ;
12144       else
12145         break;
12146     }
12147   if (name == 0)
12148     {
12149       errmsg ("node name required");
12150       return -99;
12151     }
12152   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12153     {
12154       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12155       return -99;
12156     }
12157   if (next == 0)
12158     {
12159       errmsg ("next node required");
12160       return -99;
12161     }
12162   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12163     {
12164       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12165       return -99;
12166     }
12167
12168   M (ADD_NODE_NEXT, mp);
12169   clib_memcpy (mp->node_name, name, vec_len (name));
12170   clib_memcpy (mp->next_name, next, vec_len (next));
12171   vec_free (name);
12172   vec_free (next);
12173
12174   S (mp);
12175   W (ret);
12176   return ret;
12177 }
12178
12179 static int
12180 api_l2tpv3_create_tunnel (vat_main_t * vam)
12181 {
12182   unformat_input_t *i = vam->input;
12183   ip6_address_t client_address, our_address;
12184   int client_address_set = 0;
12185   int our_address_set = 0;
12186   u32 local_session_id = 0;
12187   u32 remote_session_id = 0;
12188   u64 local_cookie = 0;
12189   u64 remote_cookie = 0;
12190   u8 l2_sublayer_present = 0;
12191   vl_api_l2tpv3_create_tunnel_t *mp;
12192   int ret;
12193
12194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12195     {
12196       if (unformat (i, "client_address %U", unformat_ip6_address,
12197                     &client_address))
12198         client_address_set = 1;
12199       else if (unformat (i, "our_address %U", unformat_ip6_address,
12200                          &our_address))
12201         our_address_set = 1;
12202       else if (unformat (i, "local_session_id %d", &local_session_id))
12203         ;
12204       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12205         ;
12206       else if (unformat (i, "local_cookie %lld", &local_cookie))
12207         ;
12208       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12209         ;
12210       else if (unformat (i, "l2-sublayer-present"))
12211         l2_sublayer_present = 1;
12212       else
12213         break;
12214     }
12215
12216   if (client_address_set == 0)
12217     {
12218       errmsg ("client_address required");
12219       return -99;
12220     }
12221
12222   if (our_address_set == 0)
12223     {
12224       errmsg ("our_address required");
12225       return -99;
12226     }
12227
12228   M (L2TPV3_CREATE_TUNNEL, mp);
12229
12230   clib_memcpy (mp->client_address, client_address.as_u8,
12231                sizeof (mp->client_address));
12232
12233   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12234
12235   mp->local_session_id = ntohl (local_session_id);
12236   mp->remote_session_id = ntohl (remote_session_id);
12237   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12238   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12239   mp->l2_sublayer_present = l2_sublayer_present;
12240   mp->is_ipv6 = 1;
12241
12242   S (mp);
12243   W (ret);
12244   return ret;
12245 }
12246
12247 static int
12248 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12249 {
12250   unformat_input_t *i = vam->input;
12251   u32 sw_if_index;
12252   u8 sw_if_index_set = 0;
12253   u64 new_local_cookie = 0;
12254   u64 new_remote_cookie = 0;
12255   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12256   int ret;
12257
12258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12261         sw_if_index_set = 1;
12262       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12263         sw_if_index_set = 1;
12264       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12265         ;
12266       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12267         ;
12268       else
12269         break;
12270     }
12271
12272   if (sw_if_index_set == 0)
12273     {
12274       errmsg ("missing interface name or sw_if_index");
12275       return -99;
12276     }
12277
12278   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12279
12280   mp->sw_if_index = ntohl (sw_if_index);
12281   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12282   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12283
12284   S (mp);
12285   W (ret);
12286   return ret;
12287 }
12288
12289 static int
12290 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12291 {
12292   unformat_input_t *i = vam->input;
12293   vl_api_l2tpv3_interface_enable_disable_t *mp;
12294   u32 sw_if_index;
12295   u8 sw_if_index_set = 0;
12296   u8 enable_disable = 1;
12297   int ret;
12298
12299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12300     {
12301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12302         sw_if_index_set = 1;
12303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12304         sw_if_index_set = 1;
12305       else if (unformat (i, "enable"))
12306         enable_disable = 1;
12307       else if (unformat (i, "disable"))
12308         enable_disable = 0;
12309       else
12310         break;
12311     }
12312
12313   if (sw_if_index_set == 0)
12314     {
12315       errmsg ("missing interface name or sw_if_index");
12316       return -99;
12317     }
12318
12319   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12320
12321   mp->sw_if_index = ntohl (sw_if_index);
12322   mp->enable_disable = enable_disable;
12323
12324   S (mp);
12325   W (ret);
12326   return ret;
12327 }
12328
12329 static int
12330 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12331 {
12332   unformat_input_t *i = vam->input;
12333   vl_api_l2tpv3_set_lookup_key_t *mp;
12334   u8 key = ~0;
12335   int ret;
12336
12337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12338     {
12339       if (unformat (i, "lookup_v6_src"))
12340         key = L2T_LOOKUP_SRC_ADDRESS;
12341       else if (unformat (i, "lookup_v6_dst"))
12342         key = L2T_LOOKUP_DST_ADDRESS;
12343       else if (unformat (i, "lookup_session_id"))
12344         key = L2T_LOOKUP_SESSION_ID;
12345       else
12346         break;
12347     }
12348
12349   if (key == (u8) ~ 0)
12350     {
12351       errmsg ("l2tp session lookup key unset");
12352       return -99;
12353     }
12354
12355   M (L2TPV3_SET_LOOKUP_KEY, mp);
12356
12357   mp->key = key;
12358
12359   S (mp);
12360   W (ret);
12361   return ret;
12362 }
12363
12364 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12365   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12366 {
12367   vat_main_t *vam = &vat_main;
12368
12369   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12370          format_ip6_address, mp->our_address,
12371          format_ip6_address, mp->client_address,
12372          clib_net_to_host_u32 (mp->sw_if_index));
12373
12374   print (vam->ofp,
12375          "   local cookies %016llx %016llx remote cookie %016llx",
12376          clib_net_to_host_u64 (mp->local_cookie[0]),
12377          clib_net_to_host_u64 (mp->local_cookie[1]),
12378          clib_net_to_host_u64 (mp->remote_cookie));
12379
12380   print (vam->ofp, "   local session-id %d remote session-id %d",
12381          clib_net_to_host_u32 (mp->local_session_id),
12382          clib_net_to_host_u32 (mp->remote_session_id));
12383
12384   print (vam->ofp, "   l2 specific sublayer %s\n",
12385          mp->l2_sublayer_present ? "preset" : "absent");
12386
12387 }
12388
12389 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12390   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12391 {
12392   vat_main_t *vam = &vat_main;
12393   vat_json_node_t *node = NULL;
12394   struct in6_addr addr;
12395
12396   if (VAT_JSON_ARRAY != vam->json_tree.type)
12397     {
12398       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12399       vat_json_init_array (&vam->json_tree);
12400     }
12401   node = vat_json_array_add (&vam->json_tree);
12402
12403   vat_json_init_object (node);
12404
12405   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12406   vat_json_object_add_ip6 (node, "our_address", addr);
12407   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12408   vat_json_object_add_ip6 (node, "client_address", addr);
12409
12410   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12411   vat_json_init_array (lc);
12412   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12413   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12414   vat_json_object_add_uint (node, "remote_cookie",
12415                             clib_net_to_host_u64 (mp->remote_cookie));
12416
12417   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12418   vat_json_object_add_uint (node, "local_session_id",
12419                             clib_net_to_host_u32 (mp->local_session_id));
12420   vat_json_object_add_uint (node, "remote_session_id",
12421                             clib_net_to_host_u32 (mp->remote_session_id));
12422   vat_json_object_add_string_copy (node, "l2_sublayer",
12423                                    mp->l2_sublayer_present ? (u8 *) "present"
12424                                    : (u8 *) "absent");
12425 }
12426
12427 static int
12428 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12429 {
12430   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12431   vl_api_control_ping_t *mp_ping;
12432   int ret;
12433
12434   /* Get list of l2tpv3-tunnel interfaces */
12435   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12436   S (mp);
12437
12438   /* Use a control ping for synchronization */
12439   MPING (CONTROL_PING, mp_ping);
12440   S (mp_ping);
12441
12442   W (ret);
12443   return ret;
12444 }
12445
12446
12447 static void vl_api_sw_interface_tap_v2_details_t_handler
12448   (vl_api_sw_interface_tap_v2_details_t * mp)
12449 {
12450   vat_main_t *vam = &vat_main;
12451
12452   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12453                     mp->host_ip4_prefix_len);
12454   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12455                     mp->host_ip6_prefix_len);
12456
12457   print (vam->ofp,
12458          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12459          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12460          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12461          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12462          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12463
12464   vec_free (ip4);
12465   vec_free (ip6);
12466 }
12467
12468 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12469   (vl_api_sw_interface_tap_v2_details_t * mp)
12470 {
12471   vat_main_t *vam = &vat_main;
12472   vat_json_node_t *node = NULL;
12473
12474   if (VAT_JSON_ARRAY != vam->json_tree.type)
12475     {
12476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12477       vat_json_init_array (&vam->json_tree);
12478     }
12479   node = vat_json_array_add (&vam->json_tree);
12480
12481   vat_json_init_object (node);
12482   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12483   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12484   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12485   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12486   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12487   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12488   vat_json_object_add_string_copy (node, "host_mac_addr",
12489                                    format (0, "%U", format_ethernet_address,
12490                                            &mp->host_mac_addr));
12491   vat_json_object_add_string_copy (node, "host_namespace",
12492                                    mp->host_namespace);
12493   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12494   vat_json_object_add_string_copy (node, "host_ip4_addr",
12495                                    format (0, "%U/%d", format_ip4_address,
12496                                            mp->host_ip4_addr,
12497                                            mp->host_ip4_prefix_len));
12498   vat_json_object_add_string_copy (node, "host_ip6_addr",
12499                                    format (0, "%U/%d", format_ip6_address,
12500                                            mp->host_ip6_addr,
12501                                            mp->host_ip6_prefix_len));
12502
12503 }
12504
12505 static int
12506 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12507 {
12508   vl_api_sw_interface_tap_v2_dump_t *mp;
12509   vl_api_control_ping_t *mp_ping;
12510   int ret;
12511
12512   print (vam->ofp,
12513          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12514          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12515          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12516          "host_ip6_addr");
12517
12518   /* Get list of tap interfaces */
12519   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12520   S (mp);
12521
12522   /* Use a control ping for synchronization */
12523   MPING (CONTROL_PING, mp_ping);
12524   S (mp_ping);
12525
12526   W (ret);
12527   return ret;
12528 }
12529
12530 static void vl_api_sw_interface_virtio_pci_details_t_handler
12531   (vl_api_sw_interface_virtio_pci_details_t * mp)
12532 {
12533   vat_main_t *vam = &vat_main;
12534
12535   typedef union
12536   {
12537     struct
12538     {
12539       u16 domain;
12540       u8 bus;
12541       u8 slot:5;
12542       u8 function:3;
12543     };
12544     u32 as_u32;
12545   } pci_addr_t;
12546   pci_addr_t addr;
12547   addr.as_u32 = ntohl (mp->pci_addr);
12548   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12549                          addr.slot, addr.function);
12550
12551   print (vam->ofp,
12552          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12553          pci_addr, ntohl (mp->sw_if_index),
12554          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12555          format_ethernet_address, mp->mac_addr,
12556          clib_net_to_host_u64 (mp->features));
12557   vec_free (pci_addr);
12558 }
12559
12560 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12561   (vl_api_sw_interface_virtio_pci_details_t * mp)
12562 {
12563   vat_main_t *vam = &vat_main;
12564   vat_json_node_t *node = NULL;
12565
12566   if (VAT_JSON_ARRAY != vam->json_tree.type)
12567     {
12568       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12569       vat_json_init_array (&vam->json_tree);
12570     }
12571   node = vat_json_array_add (&vam->json_tree);
12572
12573   vat_json_init_object (node);
12574   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12575   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12576   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12577   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12578   vat_json_object_add_uint (node, "features",
12579                             clib_net_to_host_u64 (mp->features));
12580   vat_json_object_add_string_copy (node, "mac_addr",
12581                                    format (0, "%U", format_ethernet_address,
12582                                            &mp->mac_addr));
12583 }
12584
12585 static int
12586 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12587 {
12588   vl_api_sw_interface_virtio_pci_dump_t *mp;
12589   vl_api_control_ping_t *mp_ping;
12590   int ret;
12591
12592   print (vam->ofp,
12593          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12594          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12595          "mac_addr", "features");
12596
12597   /* Get list of tap interfaces */
12598   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12599   S (mp);
12600
12601   /* Use a control ping for synchronization */
12602   MPING (CONTROL_PING, mp_ping);
12603   S (mp_ping);
12604
12605   W (ret);
12606   return ret;
12607 }
12608
12609 static int
12610 api_vxlan_offload_rx (vat_main_t * vam)
12611 {
12612   unformat_input_t *line_input = vam->input;
12613   vl_api_vxlan_offload_rx_t *mp;
12614   u32 hw_if_index = ~0, rx_if_index = ~0;
12615   u8 is_add = 1;
12616   int ret;
12617
12618   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12619     {
12620       if (unformat (line_input, "del"))
12621         is_add = 0;
12622       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12623                          &hw_if_index))
12624         ;
12625       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12626         ;
12627       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12628                          &rx_if_index))
12629         ;
12630       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12631         ;
12632       else
12633         {
12634           errmsg ("parse error '%U'", format_unformat_error, line_input);
12635           return -99;
12636         }
12637     }
12638
12639   if (hw_if_index == ~0)
12640     {
12641       errmsg ("no hw interface");
12642       return -99;
12643     }
12644
12645   if (rx_if_index == ~0)
12646     {
12647       errmsg ("no rx tunnel");
12648       return -99;
12649     }
12650
12651   M (VXLAN_OFFLOAD_RX, mp);
12652
12653   mp->hw_if_index = ntohl (hw_if_index);
12654   mp->sw_if_index = ntohl (rx_if_index);
12655   mp->enable = is_add;
12656
12657   S (mp);
12658   W (ret);
12659   return ret;
12660 }
12661
12662 static uword unformat_vxlan_decap_next
12663   (unformat_input_t * input, va_list * args)
12664 {
12665   u32 *result = va_arg (*args, u32 *);
12666   u32 tmp;
12667
12668   if (unformat (input, "l2"))
12669     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12670   else if (unformat (input, "%d", &tmp))
12671     *result = tmp;
12672   else
12673     return 0;
12674   return 1;
12675 }
12676
12677 static int
12678 api_vxlan_add_del_tunnel (vat_main_t * vam)
12679 {
12680   unformat_input_t *line_input = vam->input;
12681   vl_api_vxlan_add_del_tunnel_t *mp;
12682   ip46_address_t src, dst;
12683   u8 is_add = 1;
12684   u8 ipv4_set = 0, ipv6_set = 0;
12685   u8 src_set = 0;
12686   u8 dst_set = 0;
12687   u8 grp_set = 0;
12688   u32 instance = ~0;
12689   u32 mcast_sw_if_index = ~0;
12690   u32 encap_vrf_id = 0;
12691   u32 decap_next_index = ~0;
12692   u32 vni = 0;
12693   int ret;
12694
12695   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12696   clib_memset (&src, 0, sizeof src);
12697   clib_memset (&dst, 0, sizeof dst);
12698
12699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12700     {
12701       if (unformat (line_input, "del"))
12702         is_add = 0;
12703       else if (unformat (line_input, "instance %d", &instance))
12704         ;
12705       else
12706         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12707         {
12708           ipv4_set = 1;
12709           src_set = 1;
12710         }
12711       else
12712         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12713         {
12714           ipv4_set = 1;
12715           dst_set = 1;
12716         }
12717       else
12718         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12719         {
12720           ipv6_set = 1;
12721           src_set = 1;
12722         }
12723       else
12724         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12725         {
12726           ipv6_set = 1;
12727           dst_set = 1;
12728         }
12729       else if (unformat (line_input, "group %U %U",
12730                          unformat_ip4_address, &dst.ip4,
12731                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12732         {
12733           grp_set = dst_set = 1;
12734           ipv4_set = 1;
12735         }
12736       else if (unformat (line_input, "group %U",
12737                          unformat_ip4_address, &dst.ip4))
12738         {
12739           grp_set = dst_set = 1;
12740           ipv4_set = 1;
12741         }
12742       else if (unformat (line_input, "group %U %U",
12743                          unformat_ip6_address, &dst.ip6,
12744                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12745         {
12746           grp_set = dst_set = 1;
12747           ipv6_set = 1;
12748         }
12749       else if (unformat (line_input, "group %U",
12750                          unformat_ip6_address, &dst.ip6))
12751         {
12752           grp_set = dst_set = 1;
12753           ipv6_set = 1;
12754         }
12755       else
12756         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12757         ;
12758       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12759         ;
12760       else if (unformat (line_input, "decap-next %U",
12761                          unformat_vxlan_decap_next, &decap_next_index))
12762         ;
12763       else if (unformat (line_input, "vni %d", &vni))
12764         ;
12765       else
12766         {
12767           errmsg ("parse error '%U'", format_unformat_error, line_input);
12768           return -99;
12769         }
12770     }
12771
12772   if (src_set == 0)
12773     {
12774       errmsg ("tunnel src address not specified");
12775       return -99;
12776     }
12777   if (dst_set == 0)
12778     {
12779       errmsg ("tunnel dst address not specified");
12780       return -99;
12781     }
12782
12783   if (grp_set && !ip46_address_is_multicast (&dst))
12784     {
12785       errmsg ("tunnel group address not multicast");
12786       return -99;
12787     }
12788   if (grp_set && mcast_sw_if_index == ~0)
12789     {
12790       errmsg ("tunnel nonexistent multicast device");
12791       return -99;
12792     }
12793   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12794     {
12795       errmsg ("tunnel dst address must be unicast");
12796       return -99;
12797     }
12798
12799
12800   if (ipv4_set && ipv6_set)
12801     {
12802       errmsg ("both IPv4 and IPv6 addresses specified");
12803       return -99;
12804     }
12805
12806   if ((vni == 0) || (vni >> 24))
12807     {
12808       errmsg ("vni not specified or out of range");
12809       return -99;
12810     }
12811
12812   M (VXLAN_ADD_DEL_TUNNEL, mp);
12813
12814   if (ipv6_set)
12815     {
12816       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12817       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12818     }
12819   else
12820     {
12821       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12822       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12823     }
12824
12825   mp->instance = htonl (instance);
12826   mp->encap_vrf_id = ntohl (encap_vrf_id);
12827   mp->decap_next_index = ntohl (decap_next_index);
12828   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12829   mp->vni = ntohl (vni);
12830   mp->is_add = is_add;
12831   mp->is_ipv6 = ipv6_set;
12832
12833   S (mp);
12834   W (ret);
12835   return ret;
12836 }
12837
12838 static void vl_api_vxlan_tunnel_details_t_handler
12839   (vl_api_vxlan_tunnel_details_t * mp)
12840 {
12841   vat_main_t *vam = &vat_main;
12842   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12843   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12844
12845   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12846          ntohl (mp->sw_if_index),
12847          ntohl (mp->instance),
12848          format_ip46_address, &src, IP46_TYPE_ANY,
12849          format_ip46_address, &dst, IP46_TYPE_ANY,
12850          ntohl (mp->encap_vrf_id),
12851          ntohl (mp->decap_next_index), ntohl (mp->vni),
12852          ntohl (mp->mcast_sw_if_index));
12853 }
12854
12855 static void vl_api_vxlan_tunnel_details_t_handler_json
12856   (vl_api_vxlan_tunnel_details_t * mp)
12857 {
12858   vat_main_t *vam = &vat_main;
12859   vat_json_node_t *node = NULL;
12860
12861   if (VAT_JSON_ARRAY != vam->json_tree.type)
12862     {
12863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12864       vat_json_init_array (&vam->json_tree);
12865     }
12866   node = vat_json_array_add (&vam->json_tree);
12867
12868   vat_json_init_object (node);
12869   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12870
12871   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12872
12873   if (mp->is_ipv6)
12874     {
12875       struct in6_addr ip6;
12876
12877       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12878       vat_json_object_add_ip6 (node, "src_address", ip6);
12879       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12880       vat_json_object_add_ip6 (node, "dst_address", ip6);
12881     }
12882   else
12883     {
12884       struct in_addr ip4;
12885
12886       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12887       vat_json_object_add_ip4 (node, "src_address", ip4);
12888       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12889       vat_json_object_add_ip4 (node, "dst_address", ip4);
12890     }
12891   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12892   vat_json_object_add_uint (node, "decap_next_index",
12893                             ntohl (mp->decap_next_index));
12894   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12895   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12896   vat_json_object_add_uint (node, "mcast_sw_if_index",
12897                             ntohl (mp->mcast_sw_if_index));
12898 }
12899
12900 static int
12901 api_vxlan_tunnel_dump (vat_main_t * vam)
12902 {
12903   unformat_input_t *i = vam->input;
12904   vl_api_vxlan_tunnel_dump_t *mp;
12905   vl_api_control_ping_t *mp_ping;
12906   u32 sw_if_index;
12907   u8 sw_if_index_set = 0;
12908   int ret;
12909
12910   /* Parse args required to build the message */
12911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12912     {
12913       if (unformat (i, "sw_if_index %d", &sw_if_index))
12914         sw_if_index_set = 1;
12915       else
12916         break;
12917     }
12918
12919   if (sw_if_index_set == 0)
12920     {
12921       sw_if_index = ~0;
12922     }
12923
12924   if (!vam->json_output)
12925     {
12926       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12927              "sw_if_index", "instance", "src_address", "dst_address",
12928              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12929     }
12930
12931   /* Get list of vxlan-tunnel interfaces */
12932   M (VXLAN_TUNNEL_DUMP, mp);
12933
12934   mp->sw_if_index = htonl (sw_if_index);
12935
12936   S (mp);
12937
12938   /* Use a control ping for synchronization */
12939   MPING (CONTROL_PING, mp_ping);
12940   S (mp_ping);
12941
12942   W (ret);
12943   return ret;
12944 }
12945
12946 static uword unformat_geneve_decap_next
12947   (unformat_input_t * input, va_list * args)
12948 {
12949   u32 *result = va_arg (*args, u32 *);
12950   u32 tmp;
12951
12952   if (unformat (input, "l2"))
12953     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12954   else if (unformat (input, "%d", &tmp))
12955     *result = tmp;
12956   else
12957     return 0;
12958   return 1;
12959 }
12960
12961 static int
12962 api_geneve_add_del_tunnel (vat_main_t * vam)
12963 {
12964   unformat_input_t *line_input = vam->input;
12965   vl_api_geneve_add_del_tunnel_t *mp;
12966   ip46_address_t src, dst;
12967   u8 is_add = 1;
12968   u8 ipv4_set = 0, ipv6_set = 0;
12969   u8 src_set = 0;
12970   u8 dst_set = 0;
12971   u8 grp_set = 0;
12972   u32 mcast_sw_if_index = ~0;
12973   u32 encap_vrf_id = 0;
12974   u32 decap_next_index = ~0;
12975   u32 vni = 0;
12976   int ret;
12977
12978   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12979   clib_memset (&src, 0, sizeof src);
12980   clib_memset (&dst, 0, sizeof dst);
12981
12982   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12983     {
12984       if (unformat (line_input, "del"))
12985         is_add = 0;
12986       else
12987         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12988         {
12989           ipv4_set = 1;
12990           src_set = 1;
12991         }
12992       else
12993         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12994         {
12995           ipv4_set = 1;
12996           dst_set = 1;
12997         }
12998       else
12999         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13000         {
13001           ipv6_set = 1;
13002           src_set = 1;
13003         }
13004       else
13005         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13006         {
13007           ipv6_set = 1;
13008           dst_set = 1;
13009         }
13010       else if (unformat (line_input, "group %U %U",
13011                          unformat_ip4_address, &dst.ip4,
13012                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13013         {
13014           grp_set = dst_set = 1;
13015           ipv4_set = 1;
13016         }
13017       else if (unformat (line_input, "group %U",
13018                          unformat_ip4_address, &dst.ip4))
13019         {
13020           grp_set = dst_set = 1;
13021           ipv4_set = 1;
13022         }
13023       else if (unformat (line_input, "group %U %U",
13024                          unformat_ip6_address, &dst.ip6,
13025                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13026         {
13027           grp_set = dst_set = 1;
13028           ipv6_set = 1;
13029         }
13030       else if (unformat (line_input, "group %U",
13031                          unformat_ip6_address, &dst.ip6))
13032         {
13033           grp_set = dst_set = 1;
13034           ipv6_set = 1;
13035         }
13036       else
13037         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13038         ;
13039       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13040         ;
13041       else if (unformat (line_input, "decap-next %U",
13042                          unformat_geneve_decap_next, &decap_next_index))
13043         ;
13044       else if (unformat (line_input, "vni %d", &vni))
13045         ;
13046       else
13047         {
13048           errmsg ("parse error '%U'", format_unformat_error, line_input);
13049           return -99;
13050         }
13051     }
13052
13053   if (src_set == 0)
13054     {
13055       errmsg ("tunnel src address not specified");
13056       return -99;
13057     }
13058   if (dst_set == 0)
13059     {
13060       errmsg ("tunnel dst address not specified");
13061       return -99;
13062     }
13063
13064   if (grp_set && !ip46_address_is_multicast (&dst))
13065     {
13066       errmsg ("tunnel group address not multicast");
13067       return -99;
13068     }
13069   if (grp_set && mcast_sw_if_index == ~0)
13070     {
13071       errmsg ("tunnel nonexistent multicast device");
13072       return -99;
13073     }
13074   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13075     {
13076       errmsg ("tunnel dst address must be unicast");
13077       return -99;
13078     }
13079
13080
13081   if (ipv4_set && ipv6_set)
13082     {
13083       errmsg ("both IPv4 and IPv6 addresses specified");
13084       return -99;
13085     }
13086
13087   if ((vni == 0) || (vni >> 24))
13088     {
13089       errmsg ("vni not specified or out of range");
13090       return -99;
13091     }
13092
13093   M (GENEVE_ADD_DEL_TUNNEL, mp);
13094
13095   if (ipv6_set)
13096     {
13097       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13098       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13099     }
13100   else
13101     {
13102       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13103       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13104     }
13105   mp->encap_vrf_id = ntohl (encap_vrf_id);
13106   mp->decap_next_index = ntohl (decap_next_index);
13107   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13108   mp->vni = ntohl (vni);
13109   mp->is_add = is_add;
13110   mp->is_ipv6 = ipv6_set;
13111
13112   S (mp);
13113   W (ret);
13114   return ret;
13115 }
13116
13117 static void vl_api_geneve_tunnel_details_t_handler
13118   (vl_api_geneve_tunnel_details_t * mp)
13119 {
13120   vat_main_t *vam = &vat_main;
13121   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13122   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13123
13124   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13125          ntohl (mp->sw_if_index),
13126          format_ip46_address, &src, IP46_TYPE_ANY,
13127          format_ip46_address, &dst, IP46_TYPE_ANY,
13128          ntohl (mp->encap_vrf_id),
13129          ntohl (mp->decap_next_index), ntohl (mp->vni),
13130          ntohl (mp->mcast_sw_if_index));
13131 }
13132
13133 static void vl_api_geneve_tunnel_details_t_handler_json
13134   (vl_api_geneve_tunnel_details_t * mp)
13135 {
13136   vat_main_t *vam = &vat_main;
13137   vat_json_node_t *node = NULL;
13138
13139   if (VAT_JSON_ARRAY != vam->json_tree.type)
13140     {
13141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13142       vat_json_init_array (&vam->json_tree);
13143     }
13144   node = vat_json_array_add (&vam->json_tree);
13145
13146   vat_json_init_object (node);
13147   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13148   if (mp->is_ipv6)
13149     {
13150       struct in6_addr ip6;
13151
13152       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13153       vat_json_object_add_ip6 (node, "src_address", ip6);
13154       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13155       vat_json_object_add_ip6 (node, "dst_address", ip6);
13156     }
13157   else
13158     {
13159       struct in_addr ip4;
13160
13161       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13162       vat_json_object_add_ip4 (node, "src_address", ip4);
13163       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13164       vat_json_object_add_ip4 (node, "dst_address", ip4);
13165     }
13166   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13167   vat_json_object_add_uint (node, "decap_next_index",
13168                             ntohl (mp->decap_next_index));
13169   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13170   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13171   vat_json_object_add_uint (node, "mcast_sw_if_index",
13172                             ntohl (mp->mcast_sw_if_index));
13173 }
13174
13175 static int
13176 api_geneve_tunnel_dump (vat_main_t * vam)
13177 {
13178   unformat_input_t *i = vam->input;
13179   vl_api_geneve_tunnel_dump_t *mp;
13180   vl_api_control_ping_t *mp_ping;
13181   u32 sw_if_index;
13182   u8 sw_if_index_set = 0;
13183   int ret;
13184
13185   /* Parse args required to build the message */
13186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (i, "sw_if_index %d", &sw_if_index))
13189         sw_if_index_set = 1;
13190       else
13191         break;
13192     }
13193
13194   if (sw_if_index_set == 0)
13195     {
13196       sw_if_index = ~0;
13197     }
13198
13199   if (!vam->json_output)
13200     {
13201       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13202              "sw_if_index", "local_address", "remote_address",
13203              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13204     }
13205
13206   /* Get list of geneve-tunnel interfaces */
13207   M (GENEVE_TUNNEL_DUMP, mp);
13208
13209   mp->sw_if_index = htonl (sw_if_index);
13210
13211   S (mp);
13212
13213   /* Use a control ping for synchronization */
13214   M (CONTROL_PING, mp_ping);
13215   S (mp_ping);
13216
13217   W (ret);
13218   return ret;
13219 }
13220
13221 static int
13222 api_gre_tunnel_add_del (vat_main_t * vam)
13223 {
13224   unformat_input_t *line_input = vam->input;
13225   vl_api_address_t src = { }, dst =
13226   {
13227   };
13228   vl_api_gre_tunnel_add_del_t *mp;
13229   vl_api_gre_tunnel_type_t t_type;
13230   u8 is_add = 1;
13231   u8 ipv4_set = 0;
13232   u8 ipv6_set = 0;
13233   u8 src_set = 0;
13234   u8 dst_set = 0;
13235   u32 outer_fib_id = 0;
13236   u32 session_id = 0;
13237   u32 instance = ~0;
13238   int ret;
13239
13240   t_type = GRE_API_TUNNEL_TYPE_L3;
13241
13242   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13243     {
13244       if (unformat (line_input, "del"))
13245         is_add = 0;
13246       else if (unformat (line_input, "instance %d", &instance))
13247         ;
13248       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13249         {
13250           src_set = 1;
13251         }
13252       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13253         {
13254           dst_set = 1;
13255         }
13256       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13257         ;
13258       else if (unformat (line_input, "teb"))
13259         t_type = GRE_API_TUNNEL_TYPE_TEB;
13260       else if (unformat (line_input, "erspan %d", &session_id))
13261         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13262       else
13263         {
13264           errmsg ("parse error '%U'", format_unformat_error, line_input);
13265           return -99;
13266         }
13267     }
13268
13269   if (src_set == 0)
13270     {
13271       errmsg ("tunnel src address not specified");
13272       return -99;
13273     }
13274   if (dst_set == 0)
13275     {
13276       errmsg ("tunnel dst address not specified");
13277       return -99;
13278     }
13279
13280   M (GRE_TUNNEL_ADD_DEL, mp);
13281
13282   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13283   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13284
13285   mp->tunnel.instance = htonl (instance);
13286   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13287   mp->is_add = is_add;
13288   mp->tunnel.session_id = htons ((u16) session_id);
13289   mp->tunnel.type = htonl (t_type);
13290
13291   S (mp);
13292   W (ret);
13293   return ret;
13294 }
13295
13296 static void vl_api_gre_tunnel_details_t_handler
13297   (vl_api_gre_tunnel_details_t * mp)
13298 {
13299   vat_main_t *vam = &vat_main;
13300
13301   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13302          ntohl (mp->tunnel.sw_if_index),
13303          ntohl (mp->tunnel.instance),
13304          format_vl_api_address, &mp->tunnel.src,
13305          format_vl_api_address, &mp->tunnel.dst,
13306          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13307          ntohl (mp->tunnel.session_id));
13308 }
13309
13310 static void
13311 vat_json_object_add_address (vat_json_node_t * node,
13312                              const char *str, const vl_api_address_t * addr)
13313 {
13314   if (ADDRESS_IP6 == addr->af)
13315     {
13316       struct in6_addr ip6;
13317
13318       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13319       vat_json_object_add_ip6 (node, str, ip6);
13320     }
13321   else
13322     {
13323       struct in_addr ip4;
13324
13325       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13326       vat_json_object_add_ip4 (node, str, ip4);
13327     }
13328 }
13329
13330 static void vl_api_gre_tunnel_details_t_handler_json
13331   (vl_api_gre_tunnel_details_t * mp)
13332 {
13333   vat_main_t *vam = &vat_main;
13334   vat_json_node_t *node = NULL;
13335   struct in_addr ip4;
13336   struct in6_addr ip6;
13337
13338   if (VAT_JSON_ARRAY != vam->json_tree.type)
13339     {
13340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13341       vat_json_init_array (&vam->json_tree);
13342     }
13343   node = vat_json_array_add (&vam->json_tree);
13344
13345   vat_json_init_object (node);
13346   vat_json_object_add_uint (node, "sw_if_index",
13347                             ntohl (mp->tunnel.sw_if_index));
13348   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13349
13350   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13351   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13352   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13353   vat_json_object_add_uint (node, "outer_fib_id",
13354                             ntohl (mp->tunnel.outer_fib_id));
13355   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13356 }
13357
13358 static int
13359 api_gre_tunnel_dump (vat_main_t * vam)
13360 {
13361   unformat_input_t *i = vam->input;
13362   vl_api_gre_tunnel_dump_t *mp;
13363   vl_api_control_ping_t *mp_ping;
13364   u32 sw_if_index;
13365   u8 sw_if_index_set = 0;
13366   int ret;
13367
13368   /* Parse args required to build the message */
13369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (i, "sw_if_index %d", &sw_if_index))
13372         sw_if_index_set = 1;
13373       else
13374         break;
13375     }
13376
13377   if (sw_if_index_set == 0)
13378     {
13379       sw_if_index = ~0;
13380     }
13381
13382   if (!vam->json_output)
13383     {
13384       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13385              "sw_if_index", "instance", "src_address", "dst_address",
13386              "tunnel_type", "outer_fib_id", "session_id");
13387     }
13388
13389   /* Get list of gre-tunnel interfaces */
13390   M (GRE_TUNNEL_DUMP, mp);
13391
13392   mp->sw_if_index = htonl (sw_if_index);
13393
13394   S (mp);
13395
13396   /* Use a control ping for synchronization */
13397   MPING (CONTROL_PING, mp_ping);
13398   S (mp_ping);
13399
13400   W (ret);
13401   return ret;
13402 }
13403
13404 static int
13405 api_l2_fib_clear_table (vat_main_t * vam)
13406 {
13407 //  unformat_input_t * i = vam->input;
13408   vl_api_l2_fib_clear_table_t *mp;
13409   int ret;
13410
13411   M (L2_FIB_CLEAR_TABLE, mp);
13412
13413   S (mp);
13414   W (ret);
13415   return ret;
13416 }
13417
13418 static int
13419 api_l2_interface_efp_filter (vat_main_t * vam)
13420 {
13421   unformat_input_t *i = vam->input;
13422   vl_api_l2_interface_efp_filter_t *mp;
13423   u32 sw_if_index;
13424   u8 enable = 1;
13425   u8 sw_if_index_set = 0;
13426   int ret;
13427
13428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13429     {
13430       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13431         sw_if_index_set = 1;
13432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13433         sw_if_index_set = 1;
13434       else if (unformat (i, "enable"))
13435         enable = 1;
13436       else if (unformat (i, "disable"))
13437         enable = 0;
13438       else
13439         {
13440           clib_warning ("parse error '%U'", format_unformat_error, i);
13441           return -99;
13442         }
13443     }
13444
13445   if (sw_if_index_set == 0)
13446     {
13447       errmsg ("missing sw_if_index");
13448       return -99;
13449     }
13450
13451   M (L2_INTERFACE_EFP_FILTER, mp);
13452
13453   mp->sw_if_index = ntohl (sw_if_index);
13454   mp->enable_disable = enable;
13455
13456   S (mp);
13457   W (ret);
13458   return ret;
13459 }
13460
13461 #define foreach_vtr_op                          \
13462 _("disable",  L2_VTR_DISABLED)                  \
13463 _("push-1",  L2_VTR_PUSH_1)                     \
13464 _("push-2",  L2_VTR_PUSH_2)                     \
13465 _("pop-1",  L2_VTR_POP_1)                       \
13466 _("pop-2",  L2_VTR_POP_2)                       \
13467 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13468 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13469 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13470 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13471
13472 static int
13473 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13474 {
13475   unformat_input_t *i = vam->input;
13476   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13477   u32 sw_if_index;
13478   u8 sw_if_index_set = 0;
13479   u8 vtr_op_set = 0;
13480   u32 vtr_op = 0;
13481   u32 push_dot1q = 1;
13482   u32 tag1 = ~0;
13483   u32 tag2 = ~0;
13484   int ret;
13485
13486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13487     {
13488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13489         sw_if_index_set = 1;
13490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13491         sw_if_index_set = 1;
13492       else if (unformat (i, "vtr_op %d", &vtr_op))
13493         vtr_op_set = 1;
13494 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13495       foreach_vtr_op
13496 #undef _
13497         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13498         ;
13499       else if (unformat (i, "tag1 %d", &tag1))
13500         ;
13501       else if (unformat (i, "tag2 %d", &tag2))
13502         ;
13503       else
13504         {
13505           clib_warning ("parse error '%U'", format_unformat_error, i);
13506           return -99;
13507         }
13508     }
13509
13510   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13511     {
13512       errmsg ("missing vtr operation or sw_if_index");
13513       return -99;
13514     }
13515
13516   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13517   mp->sw_if_index = ntohl (sw_if_index);
13518   mp->vtr_op = ntohl (vtr_op);
13519   mp->push_dot1q = ntohl (push_dot1q);
13520   mp->tag1 = ntohl (tag1);
13521   mp->tag2 = ntohl (tag2);
13522
13523   S (mp);
13524   W (ret);
13525   return ret;
13526 }
13527
13528 static int
13529 api_create_vhost_user_if (vat_main_t * vam)
13530 {
13531   unformat_input_t *i = vam->input;
13532   vl_api_create_vhost_user_if_t *mp;
13533   u8 *file_name;
13534   u8 is_server = 0;
13535   u8 file_name_set = 0;
13536   u32 custom_dev_instance = ~0;
13537   u8 hwaddr[6];
13538   u8 use_custom_mac = 0;
13539   u8 disable_mrg_rxbuf = 0;
13540   u8 disable_indirect_desc = 0;
13541   u8 *tag = 0;
13542   int ret;
13543
13544   /* Shut up coverity */
13545   clib_memset (hwaddr, 0, sizeof (hwaddr));
13546
13547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13548     {
13549       if (unformat (i, "socket %s", &file_name))
13550         {
13551           file_name_set = 1;
13552         }
13553       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13554         ;
13555       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13556         use_custom_mac = 1;
13557       else if (unformat (i, "server"))
13558         is_server = 1;
13559       else if (unformat (i, "disable_mrg_rxbuf"))
13560         disable_mrg_rxbuf = 1;
13561       else if (unformat (i, "disable_indirect_desc"))
13562         disable_indirect_desc = 1;
13563       else if (unformat (i, "tag %s", &tag))
13564         ;
13565       else
13566         break;
13567     }
13568
13569   if (file_name_set == 0)
13570     {
13571       errmsg ("missing socket file name");
13572       return -99;
13573     }
13574
13575   if (vec_len (file_name) > 255)
13576     {
13577       errmsg ("socket file name too long");
13578       return -99;
13579     }
13580   vec_add1 (file_name, 0);
13581
13582   M (CREATE_VHOST_USER_IF, mp);
13583
13584   mp->is_server = is_server;
13585   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13586   mp->disable_indirect_desc = disable_indirect_desc;
13587   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13588   vec_free (file_name);
13589   if (custom_dev_instance != ~0)
13590     {
13591       mp->renumber = 1;
13592       mp->custom_dev_instance = ntohl (custom_dev_instance);
13593     }
13594
13595   mp->use_custom_mac = use_custom_mac;
13596   clib_memcpy (mp->mac_address, hwaddr, 6);
13597   if (tag)
13598     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13599   vec_free (tag);
13600
13601   S (mp);
13602   W (ret);
13603   return ret;
13604 }
13605
13606 static int
13607 api_modify_vhost_user_if (vat_main_t * vam)
13608 {
13609   unformat_input_t *i = vam->input;
13610   vl_api_modify_vhost_user_if_t *mp;
13611   u8 *file_name;
13612   u8 is_server = 0;
13613   u8 file_name_set = 0;
13614   u32 custom_dev_instance = ~0;
13615   u8 sw_if_index_set = 0;
13616   u32 sw_if_index = (u32) ~ 0;
13617   int ret;
13618
13619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13620     {
13621       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13622         sw_if_index_set = 1;
13623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13624         sw_if_index_set = 1;
13625       else if (unformat (i, "socket %s", &file_name))
13626         {
13627           file_name_set = 1;
13628         }
13629       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13630         ;
13631       else if (unformat (i, "server"))
13632         is_server = 1;
13633       else
13634         break;
13635     }
13636
13637   if (sw_if_index_set == 0)
13638     {
13639       errmsg ("missing sw_if_index or interface name");
13640       return -99;
13641     }
13642
13643   if (file_name_set == 0)
13644     {
13645       errmsg ("missing socket file name");
13646       return -99;
13647     }
13648
13649   if (vec_len (file_name) > 255)
13650     {
13651       errmsg ("socket file name too long");
13652       return -99;
13653     }
13654   vec_add1 (file_name, 0);
13655
13656   M (MODIFY_VHOST_USER_IF, mp);
13657
13658   mp->sw_if_index = ntohl (sw_if_index);
13659   mp->is_server = is_server;
13660   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13661   vec_free (file_name);
13662   if (custom_dev_instance != ~0)
13663     {
13664       mp->renumber = 1;
13665       mp->custom_dev_instance = ntohl (custom_dev_instance);
13666     }
13667
13668   S (mp);
13669   W (ret);
13670   return ret;
13671 }
13672
13673 static int
13674 api_delete_vhost_user_if (vat_main_t * vam)
13675 {
13676   unformat_input_t *i = vam->input;
13677   vl_api_delete_vhost_user_if_t *mp;
13678   u32 sw_if_index = ~0;
13679   u8 sw_if_index_set = 0;
13680   int ret;
13681
13682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13683     {
13684       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13685         sw_if_index_set = 1;
13686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13687         sw_if_index_set = 1;
13688       else
13689         break;
13690     }
13691
13692   if (sw_if_index_set == 0)
13693     {
13694       errmsg ("missing sw_if_index or interface name");
13695       return -99;
13696     }
13697
13698
13699   M (DELETE_VHOST_USER_IF, mp);
13700
13701   mp->sw_if_index = ntohl (sw_if_index);
13702
13703   S (mp);
13704   W (ret);
13705   return ret;
13706 }
13707
13708 static void vl_api_sw_interface_vhost_user_details_t_handler
13709   (vl_api_sw_interface_vhost_user_details_t * mp)
13710 {
13711   vat_main_t *vam = &vat_main;
13712
13713   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13714          (char *) mp->interface_name,
13715          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13716          clib_net_to_host_u64 (mp->features), mp->is_server,
13717          ntohl (mp->num_regions), (char *) mp->sock_filename);
13718   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13719 }
13720
13721 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13722   (vl_api_sw_interface_vhost_user_details_t * mp)
13723 {
13724   vat_main_t *vam = &vat_main;
13725   vat_json_node_t *node = NULL;
13726
13727   if (VAT_JSON_ARRAY != vam->json_tree.type)
13728     {
13729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13730       vat_json_init_array (&vam->json_tree);
13731     }
13732   node = vat_json_array_add (&vam->json_tree);
13733
13734   vat_json_init_object (node);
13735   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13736   vat_json_object_add_string_copy (node, "interface_name",
13737                                    mp->interface_name);
13738   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13739                             ntohl (mp->virtio_net_hdr_sz));
13740   vat_json_object_add_uint (node, "features",
13741                             clib_net_to_host_u64 (mp->features));
13742   vat_json_object_add_uint (node, "is_server", mp->is_server);
13743   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13744   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13745   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13746 }
13747
13748 static int
13749 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13750 {
13751   vl_api_sw_interface_vhost_user_dump_t *mp;
13752   vl_api_control_ping_t *mp_ping;
13753   int ret;
13754   print (vam->ofp,
13755          "Interface name            idx hdr_sz features server regions filename");
13756
13757   /* Get list of vhost-user interfaces */
13758   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13759   S (mp);
13760
13761   /* Use a control ping for synchronization */
13762   MPING (CONTROL_PING, mp_ping);
13763   S (mp_ping);
13764
13765   W (ret);
13766   return ret;
13767 }
13768
13769 static int
13770 api_show_version (vat_main_t * vam)
13771 {
13772   vl_api_show_version_t *mp;
13773   int ret;
13774
13775   M (SHOW_VERSION, mp);
13776
13777   S (mp);
13778   W (ret);
13779   return ret;
13780 }
13781
13782
13783 static int
13784 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13785 {
13786   unformat_input_t *line_input = vam->input;
13787   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13788   ip4_address_t local4, remote4;
13789   ip6_address_t local6, remote6;
13790   u8 is_add = 1;
13791   u8 ipv4_set = 0, ipv6_set = 0;
13792   u8 local_set = 0;
13793   u8 remote_set = 0;
13794   u8 grp_set = 0;
13795   u32 mcast_sw_if_index = ~0;
13796   u32 encap_vrf_id = 0;
13797   u32 decap_vrf_id = 0;
13798   u8 protocol = ~0;
13799   u32 vni;
13800   u8 vni_set = 0;
13801   int ret;
13802
13803   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13804   clib_memset (&local4, 0, sizeof local4);
13805   clib_memset (&remote4, 0, sizeof remote4);
13806   clib_memset (&local6, 0, sizeof local6);
13807   clib_memset (&remote6, 0, sizeof remote6);
13808
13809   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (line_input, "del"))
13812         is_add = 0;
13813       else if (unformat (line_input, "local %U",
13814                          unformat_ip4_address, &local4))
13815         {
13816           local_set = 1;
13817           ipv4_set = 1;
13818         }
13819       else if (unformat (line_input, "remote %U",
13820                          unformat_ip4_address, &remote4))
13821         {
13822           remote_set = 1;
13823           ipv4_set = 1;
13824         }
13825       else if (unformat (line_input, "local %U",
13826                          unformat_ip6_address, &local6))
13827         {
13828           local_set = 1;
13829           ipv6_set = 1;
13830         }
13831       else if (unformat (line_input, "remote %U",
13832                          unformat_ip6_address, &remote6))
13833         {
13834           remote_set = 1;
13835           ipv6_set = 1;
13836         }
13837       else if (unformat (line_input, "group %U %U",
13838                          unformat_ip4_address, &remote4,
13839                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13840         {
13841           grp_set = remote_set = 1;
13842           ipv4_set = 1;
13843         }
13844       else if (unformat (line_input, "group %U",
13845                          unformat_ip4_address, &remote4))
13846         {
13847           grp_set = remote_set = 1;
13848           ipv4_set = 1;
13849         }
13850       else if (unformat (line_input, "group %U %U",
13851                          unformat_ip6_address, &remote6,
13852                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13853         {
13854           grp_set = remote_set = 1;
13855           ipv6_set = 1;
13856         }
13857       else if (unformat (line_input, "group %U",
13858                          unformat_ip6_address, &remote6))
13859         {
13860           grp_set = remote_set = 1;
13861           ipv6_set = 1;
13862         }
13863       else
13864         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13865         ;
13866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13867         ;
13868       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13869         ;
13870       else if (unformat (line_input, "vni %d", &vni))
13871         vni_set = 1;
13872       else if (unformat (line_input, "next-ip4"))
13873         protocol = 1;
13874       else if (unformat (line_input, "next-ip6"))
13875         protocol = 2;
13876       else if (unformat (line_input, "next-ethernet"))
13877         protocol = 3;
13878       else if (unformat (line_input, "next-nsh"))
13879         protocol = 4;
13880       else
13881         {
13882           errmsg ("parse error '%U'", format_unformat_error, line_input);
13883           return -99;
13884         }
13885     }
13886
13887   if (local_set == 0)
13888     {
13889       errmsg ("tunnel local address not specified");
13890       return -99;
13891     }
13892   if (remote_set == 0)
13893     {
13894       errmsg ("tunnel remote address not specified");
13895       return -99;
13896     }
13897   if (grp_set && mcast_sw_if_index == ~0)
13898     {
13899       errmsg ("tunnel nonexistent multicast device");
13900       return -99;
13901     }
13902   if (ipv4_set && ipv6_set)
13903     {
13904       errmsg ("both IPv4 and IPv6 addresses specified");
13905       return -99;
13906     }
13907
13908   if (vni_set == 0)
13909     {
13910       errmsg ("vni not specified");
13911       return -99;
13912     }
13913
13914   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13915
13916
13917   if (ipv6_set)
13918     {
13919       clib_memcpy (&mp->local, &local6, sizeof (local6));
13920       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13921     }
13922   else
13923     {
13924       clib_memcpy (&mp->local, &local4, sizeof (local4));
13925       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13926     }
13927
13928   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13929   mp->encap_vrf_id = ntohl (encap_vrf_id);
13930   mp->decap_vrf_id = ntohl (decap_vrf_id);
13931   mp->protocol = protocol;
13932   mp->vni = ntohl (vni);
13933   mp->is_add = is_add;
13934   mp->is_ipv6 = ipv6_set;
13935
13936   S (mp);
13937   W (ret);
13938   return ret;
13939 }
13940
13941 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13942   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13943 {
13944   vat_main_t *vam = &vat_main;
13945   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13946   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13947
13948   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13949          ntohl (mp->sw_if_index),
13950          format_ip46_address, &local, IP46_TYPE_ANY,
13951          format_ip46_address, &remote, IP46_TYPE_ANY,
13952          ntohl (mp->vni), mp->protocol,
13953          ntohl (mp->mcast_sw_if_index),
13954          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13955 }
13956
13957
13958 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13959   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13960 {
13961   vat_main_t *vam = &vat_main;
13962   vat_json_node_t *node = NULL;
13963   struct in_addr ip4;
13964   struct in6_addr ip6;
13965
13966   if (VAT_JSON_ARRAY != vam->json_tree.type)
13967     {
13968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13969       vat_json_init_array (&vam->json_tree);
13970     }
13971   node = vat_json_array_add (&vam->json_tree);
13972
13973   vat_json_init_object (node);
13974   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13975   if (mp->is_ipv6)
13976     {
13977       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13978       vat_json_object_add_ip6 (node, "local", ip6);
13979       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13980       vat_json_object_add_ip6 (node, "remote", ip6);
13981     }
13982   else
13983     {
13984       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13985       vat_json_object_add_ip4 (node, "local", ip4);
13986       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13987       vat_json_object_add_ip4 (node, "remote", ip4);
13988     }
13989   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13990   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13991   vat_json_object_add_uint (node, "mcast_sw_if_index",
13992                             ntohl (mp->mcast_sw_if_index));
13993   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13994   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13995   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13996 }
13997
13998 static int
13999 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14000 {
14001   unformat_input_t *i = vam->input;
14002   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14003   vl_api_control_ping_t *mp_ping;
14004   u32 sw_if_index;
14005   u8 sw_if_index_set = 0;
14006   int ret;
14007
14008   /* Parse args required to build the message */
14009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14010     {
14011       if (unformat (i, "sw_if_index %d", &sw_if_index))
14012         sw_if_index_set = 1;
14013       else
14014         break;
14015     }
14016
14017   if (sw_if_index_set == 0)
14018     {
14019       sw_if_index = ~0;
14020     }
14021
14022   if (!vam->json_output)
14023     {
14024       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14025              "sw_if_index", "local", "remote", "vni",
14026              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14027     }
14028
14029   /* Get list of vxlan-tunnel interfaces */
14030   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14031
14032   mp->sw_if_index = htonl (sw_if_index);
14033
14034   S (mp);
14035
14036   /* Use a control ping for synchronization */
14037   MPING (CONTROL_PING, mp_ping);
14038   S (mp_ping);
14039
14040   W (ret);
14041   return ret;
14042 }
14043
14044 static void vl_api_l2_fib_table_details_t_handler
14045   (vl_api_l2_fib_table_details_t * mp)
14046 {
14047   vat_main_t *vam = &vat_main;
14048
14049   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14050          "       %d       %d     %d",
14051          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14052          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14053          mp->bvi_mac);
14054 }
14055
14056 static void vl_api_l2_fib_table_details_t_handler_json
14057   (vl_api_l2_fib_table_details_t * mp)
14058 {
14059   vat_main_t *vam = &vat_main;
14060   vat_json_node_t *node = NULL;
14061
14062   if (VAT_JSON_ARRAY != vam->json_tree.type)
14063     {
14064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14065       vat_json_init_array (&vam->json_tree);
14066     }
14067   node = vat_json_array_add (&vam->json_tree);
14068
14069   vat_json_init_object (node);
14070   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14071   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14073   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14074   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14075   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14076 }
14077
14078 static int
14079 api_l2_fib_table_dump (vat_main_t * vam)
14080 {
14081   unformat_input_t *i = vam->input;
14082   vl_api_l2_fib_table_dump_t *mp;
14083   vl_api_control_ping_t *mp_ping;
14084   u32 bd_id;
14085   u8 bd_id_set = 0;
14086   int ret;
14087
14088   /* Parse args required to build the message */
14089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14090     {
14091       if (unformat (i, "bd_id %d", &bd_id))
14092         bd_id_set = 1;
14093       else
14094         break;
14095     }
14096
14097   if (bd_id_set == 0)
14098     {
14099       errmsg ("missing bridge domain");
14100       return -99;
14101     }
14102
14103   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14104
14105   /* Get list of l2 fib entries */
14106   M (L2_FIB_TABLE_DUMP, mp);
14107
14108   mp->bd_id = ntohl (bd_id);
14109   S (mp);
14110
14111   /* Use a control ping for synchronization */
14112   MPING (CONTROL_PING, mp_ping);
14113   S (mp_ping);
14114
14115   W (ret);
14116   return ret;
14117 }
14118
14119
14120 static int
14121 api_interface_name_renumber (vat_main_t * vam)
14122 {
14123   unformat_input_t *line_input = vam->input;
14124   vl_api_interface_name_renumber_t *mp;
14125   u32 sw_if_index = ~0;
14126   u32 new_show_dev_instance = ~0;
14127   int ret;
14128
14129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14130     {
14131       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14132                     &sw_if_index))
14133         ;
14134       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14135         ;
14136       else if (unformat (line_input, "new_show_dev_instance %d",
14137                          &new_show_dev_instance))
14138         ;
14139       else
14140         break;
14141     }
14142
14143   if (sw_if_index == ~0)
14144     {
14145       errmsg ("missing interface name or sw_if_index");
14146       return -99;
14147     }
14148
14149   if (new_show_dev_instance == ~0)
14150     {
14151       errmsg ("missing new_show_dev_instance");
14152       return -99;
14153     }
14154
14155   M (INTERFACE_NAME_RENUMBER, mp);
14156
14157   mp->sw_if_index = ntohl (sw_if_index);
14158   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14159
14160   S (mp);
14161   W (ret);
14162   return ret;
14163 }
14164
14165 static int
14166 api_ip_probe_neighbor (vat_main_t * vam)
14167 {
14168   unformat_input_t *i = vam->input;
14169   vl_api_ip_probe_neighbor_t *mp;
14170   vl_api_address_t dst_adr;
14171   u8 int_set = 0;
14172   u8 adr_set = 0;
14173   u32 sw_if_index;
14174   int ret;
14175
14176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14177     {
14178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14179         int_set = 1;
14180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14181         int_set = 1;
14182       else if (unformat (i, "address %U", unformat_vl_api_address, dst_adr))
14183         adr_set = 1;
14184       else
14185         break;
14186     }
14187
14188   if (int_set == 0)
14189     {
14190       errmsg ("missing interface");
14191       return -99;
14192     }
14193
14194   if (adr_set == 0)
14195     {
14196       errmsg ("missing addresses");
14197       return -99;
14198     }
14199
14200   M (IP_PROBE_NEIGHBOR, mp);
14201
14202   mp->sw_if_index = ntohl (sw_if_index);
14203   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14204
14205   S (mp);
14206   W (ret);
14207   return ret;
14208 }
14209
14210 static int
14211 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14215   u8 mode = IP_SCAN_V46_NEIGHBORS;
14216   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14217   int ret;
14218
14219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14220     {
14221       if (unformat (i, "ip4"))
14222         mode = IP_SCAN_V4_NEIGHBORS;
14223       else if (unformat (i, "ip6"))
14224         mode = IP_SCAN_V6_NEIGHBORS;
14225       if (unformat (i, "both"))
14226         mode = IP_SCAN_V46_NEIGHBORS;
14227       else if (unformat (i, "disable"))
14228         mode = IP_SCAN_DISABLED;
14229       else if (unformat (i, "interval %d", &interval))
14230         ;
14231       else if (unformat (i, "max-time %d", &time))
14232         ;
14233       else if (unformat (i, "max-update %d", &update))
14234         ;
14235       else if (unformat (i, "delay %d", &delay))
14236         ;
14237       else if (unformat (i, "stale %d", &stale))
14238         ;
14239       else
14240         break;
14241     }
14242
14243   if (interval > 255)
14244     {
14245       errmsg ("interval cannot exceed 255 minutes.");
14246       return -99;
14247     }
14248   if (time > 255)
14249     {
14250       errmsg ("max-time cannot exceed 255 usec.");
14251       return -99;
14252     }
14253   if (update > 255)
14254     {
14255       errmsg ("max-update cannot exceed 255.");
14256       return -99;
14257     }
14258   if (delay > 255)
14259     {
14260       errmsg ("delay cannot exceed 255 msec.");
14261       return -99;
14262     }
14263   if (stale > 255)
14264     {
14265       errmsg ("stale cannot exceed 255 minutes.");
14266       return -99;
14267     }
14268
14269   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14270   mp->mode = mode;
14271   mp->scan_interval = interval;
14272   mp->max_proc_time = time;
14273   mp->max_update = update;
14274   mp->scan_int_delay = delay;
14275   mp->stale_threshold = stale;
14276
14277   S (mp);
14278   W (ret);
14279   return ret;
14280 }
14281
14282 static int
14283 api_want_ip4_arp_events (vat_main_t * vam)
14284 {
14285   unformat_input_t *line_input = vam->input;
14286   vl_api_want_ip4_arp_events_t *mp;
14287   ip4_address_t address;
14288   int address_set = 0;
14289   u32 enable_disable = 1;
14290   int ret;
14291
14292   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14295         address_set = 1;
14296       else if (unformat (line_input, "del"))
14297         enable_disable = 0;
14298       else
14299         break;
14300     }
14301
14302   if (address_set == 0)
14303     {
14304       errmsg ("missing addresses");
14305       return -99;
14306     }
14307
14308   M (WANT_IP4_ARP_EVENTS, mp);
14309   mp->enable_disable = enable_disable;
14310   mp->pid = htonl (getpid ());
14311   clib_memcpy (mp->ip, &address, sizeof (address));
14312
14313   S (mp);
14314   W (ret);
14315   return ret;
14316 }
14317
14318 static int
14319 api_want_ip6_nd_events (vat_main_t * vam)
14320 {
14321   unformat_input_t *line_input = vam->input;
14322   vl_api_want_ip6_nd_events_t *mp;
14323   vl_api_ip6_address_t address;
14324   int address_set = 0;
14325   u32 enable_disable = 1;
14326   int ret;
14327
14328   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14329     {
14330       if (unformat
14331           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14332         address_set = 1;
14333       else if (unformat (line_input, "del"))
14334         enable_disable = 0;
14335       else
14336         break;
14337     }
14338
14339   if (address_set == 0)
14340     {
14341       errmsg ("missing addresses");
14342       return -99;
14343     }
14344
14345   M (WANT_IP6_ND_EVENTS, mp);
14346   mp->enable_disable = enable_disable;
14347   mp->pid = htonl (getpid ());
14348   clib_memcpy (&mp->ip, &address, sizeof (address));
14349
14350   S (mp);
14351   W (ret);
14352   return ret;
14353 }
14354
14355 static int
14356 api_want_l2_macs_events (vat_main_t * vam)
14357 {
14358   unformat_input_t *line_input = vam->input;
14359   vl_api_want_l2_macs_events_t *mp;
14360   u8 enable_disable = 1;
14361   u32 scan_delay = 0;
14362   u32 max_macs_in_event = 0;
14363   u32 learn_limit = 0;
14364   int ret;
14365
14366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14367     {
14368       if (unformat (line_input, "learn-limit %d", &learn_limit))
14369         ;
14370       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14371         ;
14372       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14373         ;
14374       else if (unformat (line_input, "disable"))
14375         enable_disable = 0;
14376       else
14377         break;
14378     }
14379
14380   M (WANT_L2_MACS_EVENTS, mp);
14381   mp->enable_disable = enable_disable;
14382   mp->pid = htonl (getpid ());
14383   mp->learn_limit = htonl (learn_limit);
14384   mp->scan_delay = (u8) scan_delay;
14385   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14386   S (mp);
14387   W (ret);
14388   return ret;
14389 }
14390
14391 static int
14392 api_input_acl_set_interface (vat_main_t * vam)
14393 {
14394   unformat_input_t *i = vam->input;
14395   vl_api_input_acl_set_interface_t *mp;
14396   u32 sw_if_index;
14397   int sw_if_index_set;
14398   u32 ip4_table_index = ~0;
14399   u32 ip6_table_index = ~0;
14400   u32 l2_table_index = ~0;
14401   u8 is_add = 1;
14402   int ret;
14403
14404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14405     {
14406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14407         sw_if_index_set = 1;
14408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14409         sw_if_index_set = 1;
14410       else if (unformat (i, "del"))
14411         is_add = 0;
14412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14413         ;
14414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14415         ;
14416       else if (unformat (i, "l2-table %d", &l2_table_index))
14417         ;
14418       else
14419         {
14420           clib_warning ("parse error '%U'", format_unformat_error, i);
14421           return -99;
14422         }
14423     }
14424
14425   if (sw_if_index_set == 0)
14426     {
14427       errmsg ("missing interface name or sw_if_index");
14428       return -99;
14429     }
14430
14431   M (INPUT_ACL_SET_INTERFACE, mp);
14432
14433   mp->sw_if_index = ntohl (sw_if_index);
14434   mp->ip4_table_index = ntohl (ip4_table_index);
14435   mp->ip6_table_index = ntohl (ip6_table_index);
14436   mp->l2_table_index = ntohl (l2_table_index);
14437   mp->is_add = is_add;
14438
14439   S (mp);
14440   W (ret);
14441   return ret;
14442 }
14443
14444 static int
14445 api_output_acl_set_interface (vat_main_t * vam)
14446 {
14447   unformat_input_t *i = vam->input;
14448   vl_api_output_acl_set_interface_t *mp;
14449   u32 sw_if_index;
14450   int sw_if_index_set;
14451   u32 ip4_table_index = ~0;
14452   u32 ip6_table_index = ~0;
14453   u32 l2_table_index = ~0;
14454   u8 is_add = 1;
14455   int ret;
14456
14457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14458     {
14459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14460         sw_if_index_set = 1;
14461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14462         sw_if_index_set = 1;
14463       else if (unformat (i, "del"))
14464         is_add = 0;
14465       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14466         ;
14467       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14468         ;
14469       else if (unformat (i, "l2-table %d", &l2_table_index))
14470         ;
14471       else
14472         {
14473           clib_warning ("parse error '%U'", format_unformat_error, i);
14474           return -99;
14475         }
14476     }
14477
14478   if (sw_if_index_set == 0)
14479     {
14480       errmsg ("missing interface name or sw_if_index");
14481       return -99;
14482     }
14483
14484   M (OUTPUT_ACL_SET_INTERFACE, mp);
14485
14486   mp->sw_if_index = ntohl (sw_if_index);
14487   mp->ip4_table_index = ntohl (ip4_table_index);
14488   mp->ip6_table_index = ntohl (ip6_table_index);
14489   mp->l2_table_index = ntohl (l2_table_index);
14490   mp->is_add = is_add;
14491
14492   S (mp);
14493   W (ret);
14494   return ret;
14495 }
14496
14497 static int
14498 api_ip_address_dump (vat_main_t * vam)
14499 {
14500   unformat_input_t *i = vam->input;
14501   vl_api_ip_address_dump_t *mp;
14502   vl_api_control_ping_t *mp_ping;
14503   u32 sw_if_index = ~0;
14504   u8 sw_if_index_set = 0;
14505   u8 ipv4_set = 0;
14506   u8 ipv6_set = 0;
14507   int ret;
14508
14509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (i, "sw_if_index %d", &sw_if_index))
14512         sw_if_index_set = 1;
14513       else
14514         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14515         sw_if_index_set = 1;
14516       else if (unformat (i, "ipv4"))
14517         ipv4_set = 1;
14518       else if (unformat (i, "ipv6"))
14519         ipv6_set = 1;
14520       else
14521         break;
14522     }
14523
14524   if (ipv4_set && ipv6_set)
14525     {
14526       errmsg ("ipv4 and ipv6 flags cannot be both set");
14527       return -99;
14528     }
14529
14530   if ((!ipv4_set) && (!ipv6_set))
14531     {
14532       errmsg ("no ipv4 nor ipv6 flag set");
14533       return -99;
14534     }
14535
14536   if (sw_if_index_set == 0)
14537     {
14538       errmsg ("missing interface name or sw_if_index");
14539       return -99;
14540     }
14541
14542   vam->current_sw_if_index = sw_if_index;
14543   vam->is_ipv6 = ipv6_set;
14544
14545   M (IP_ADDRESS_DUMP, mp);
14546   mp->sw_if_index = ntohl (sw_if_index);
14547   mp->is_ipv6 = ipv6_set;
14548   S (mp);
14549
14550   /* Use a control ping for synchronization */
14551   MPING (CONTROL_PING, mp_ping);
14552   S (mp_ping);
14553
14554   W (ret);
14555   return ret;
14556 }
14557
14558 static int
14559 api_ip_dump (vat_main_t * vam)
14560 {
14561   vl_api_ip_dump_t *mp;
14562   vl_api_control_ping_t *mp_ping;
14563   unformat_input_t *in = vam->input;
14564   int ipv4_set = 0;
14565   int ipv6_set = 0;
14566   int is_ipv6;
14567   int i;
14568   int ret;
14569
14570   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14571     {
14572       if (unformat (in, "ipv4"))
14573         ipv4_set = 1;
14574       else if (unformat (in, "ipv6"))
14575         ipv6_set = 1;
14576       else
14577         break;
14578     }
14579
14580   if (ipv4_set && ipv6_set)
14581     {
14582       errmsg ("ipv4 and ipv6 flags cannot be both set");
14583       return -99;
14584     }
14585
14586   if ((!ipv4_set) && (!ipv6_set))
14587     {
14588       errmsg ("no ipv4 nor ipv6 flag set");
14589       return -99;
14590     }
14591
14592   is_ipv6 = ipv6_set;
14593   vam->is_ipv6 = is_ipv6;
14594
14595   /* free old data */
14596   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14597     {
14598       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14599     }
14600   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14601
14602   M (IP_DUMP, mp);
14603   mp->is_ipv6 = ipv6_set;
14604   S (mp);
14605
14606   /* Use a control ping for synchronization */
14607   MPING (CONTROL_PING, mp_ping);
14608   S (mp_ping);
14609
14610   W (ret);
14611   return ret;
14612 }
14613
14614 static int
14615 api_ipsec_spd_add_del (vat_main_t * vam)
14616 {
14617   unformat_input_t *i = vam->input;
14618   vl_api_ipsec_spd_add_del_t *mp;
14619   u32 spd_id = ~0;
14620   u8 is_add = 1;
14621   int ret;
14622
14623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (i, "spd_id %d", &spd_id))
14626         ;
14627       else if (unformat (i, "del"))
14628         is_add = 0;
14629       else
14630         {
14631           clib_warning ("parse error '%U'", format_unformat_error, i);
14632           return -99;
14633         }
14634     }
14635   if (spd_id == ~0)
14636     {
14637       errmsg ("spd_id must be set");
14638       return -99;
14639     }
14640
14641   M (IPSEC_SPD_ADD_DEL, mp);
14642
14643   mp->spd_id = ntohl (spd_id);
14644   mp->is_add = is_add;
14645
14646   S (mp);
14647   W (ret);
14648   return ret;
14649 }
14650
14651 static int
14652 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14653 {
14654   unformat_input_t *i = vam->input;
14655   vl_api_ipsec_interface_add_del_spd_t *mp;
14656   u32 sw_if_index;
14657   u8 sw_if_index_set = 0;
14658   u32 spd_id = (u32) ~ 0;
14659   u8 is_add = 1;
14660   int ret;
14661
14662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (i, "del"))
14665         is_add = 0;
14666       else if (unformat (i, "spd_id %d", &spd_id))
14667         ;
14668       else
14669         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14670         sw_if_index_set = 1;
14671       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14672         sw_if_index_set = 1;
14673       else
14674         {
14675           clib_warning ("parse error '%U'", format_unformat_error, i);
14676           return -99;
14677         }
14678
14679     }
14680
14681   if (spd_id == (u32) ~ 0)
14682     {
14683       errmsg ("spd_id must be set");
14684       return -99;
14685     }
14686
14687   if (sw_if_index_set == 0)
14688     {
14689       errmsg ("missing interface name or sw_if_index");
14690       return -99;
14691     }
14692
14693   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14694
14695   mp->spd_id = ntohl (spd_id);
14696   mp->sw_if_index = ntohl (sw_if_index);
14697   mp->is_add = is_add;
14698
14699   S (mp);
14700   W (ret);
14701   return ret;
14702 }
14703
14704 static int
14705 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14706 {
14707   unformat_input_t *i = vam->input;
14708   vl_api_ipsec_spd_entry_add_del_t *mp;
14709   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14710   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14711   i32 priority = 0;
14712   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14713   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14714   vl_api_address_t laddr_start = { }, laddr_stop =
14715   {
14716   }, raddr_start =
14717   {
14718   }, raddr_stop =
14719   {
14720   };
14721   int ret;
14722
14723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (i, "del"))
14726         is_add = 0;
14727       if (unformat (i, "outbound"))
14728         is_outbound = 1;
14729       if (unformat (i, "inbound"))
14730         is_outbound = 0;
14731       else if (unformat (i, "spd_id %d", &spd_id))
14732         ;
14733       else if (unformat (i, "sa_id %d", &sa_id))
14734         ;
14735       else if (unformat (i, "priority %d", &priority))
14736         ;
14737       else if (unformat (i, "protocol %d", &protocol))
14738         ;
14739       else if (unformat (i, "lport_start %d", &lport_start))
14740         ;
14741       else if (unformat (i, "lport_stop %d", &lport_stop))
14742         ;
14743       else if (unformat (i, "rport_start %d", &rport_start))
14744         ;
14745       else if (unformat (i, "rport_stop %d", &rport_stop))
14746         ;
14747       else if (unformat (i, "laddr_start %U",
14748                          unformat_vl_api_address, &laddr_start))
14749         is_ip_any = 0;
14750       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14751                          &laddr_stop))
14752         is_ip_any = 0;
14753       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14754                          &raddr_start))
14755         is_ip_any = 0;
14756       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14757                          &raddr_stop))
14758         is_ip_any = 0;
14759       else
14760         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14761         {
14762           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14763             {
14764               clib_warning ("unsupported action: 'resolve'");
14765               return -99;
14766             }
14767         }
14768       else
14769         {
14770           clib_warning ("parse error '%U'", format_unformat_error, i);
14771           return -99;
14772         }
14773
14774     }
14775
14776   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14777
14778   mp->is_add = is_add;
14779
14780   mp->entry.spd_id = ntohl (spd_id);
14781   mp->entry.priority = ntohl (priority);
14782   mp->entry.is_outbound = is_outbound;
14783
14784   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14785                sizeof (vl_api_address_t));
14786   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14787                sizeof (vl_api_address_t));
14788   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14789                sizeof (vl_api_address_t));
14790   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14791                sizeof (vl_api_address_t));
14792
14793   mp->entry.protocol = (u8) protocol;
14794   mp->entry.local_port_start = ntohs ((u16) lport_start);
14795   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14796   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14797   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14798   mp->entry.policy = (u8) policy;
14799   mp->entry.sa_id = ntohl (sa_id);
14800
14801   S (mp);
14802   W (ret);
14803   return ret;
14804 }
14805
14806 static int
14807 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14808 {
14809   unformat_input_t *i = vam->input;
14810   vl_api_ipsec_sad_entry_add_del_t *mp;
14811   u32 sad_id = 0, spi = 0;
14812   u8 *ck = 0, *ik = 0;
14813   u8 is_add = 1;
14814
14815   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14816   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14817   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14818   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14819   vl_api_address_t tun_src, tun_dst;
14820   int ret;
14821
14822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14823     {
14824       if (unformat (i, "del"))
14825         is_add = 0;
14826       else if (unformat (i, "sad_id %d", &sad_id))
14827         ;
14828       else if (unformat (i, "spi %d", &spi))
14829         ;
14830       else if (unformat (i, "esp"))
14831         protocol = IPSEC_API_PROTO_ESP;
14832       else
14833         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14834         {
14835           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14836           if (ADDRESS_IP6 == tun_src.af)
14837             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14838         }
14839       else
14840         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14841         {
14842           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14843           if (ADDRESS_IP6 == tun_src.af)
14844             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14845         }
14846       else
14847         if (unformat (i, "crypto_alg %U",
14848                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14849         ;
14850       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14851         ;
14852       else if (unformat (i, "integ_alg %U",
14853                          unformat_ipsec_api_integ_alg, &integ_alg))
14854         ;
14855       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14856         ;
14857       else
14858         {
14859           clib_warning ("parse error '%U'", format_unformat_error, i);
14860           return -99;
14861         }
14862
14863     }
14864
14865   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14866
14867   mp->is_add = is_add;
14868   mp->entry.sad_id = ntohl (sad_id);
14869   mp->entry.protocol = protocol;
14870   mp->entry.spi = ntohl (spi);
14871   mp->entry.flags = flags;
14872
14873   mp->entry.crypto_algorithm = crypto_alg;
14874   mp->entry.integrity_algorithm = integ_alg;
14875   mp->entry.crypto_key.length = vec_len (ck);
14876   mp->entry.integrity_key.length = vec_len (ik);
14877
14878   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14879     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14880
14881   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14882     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14883
14884   if (ck)
14885     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14886   if (ik)
14887     clib_memcpy (mp->entry.integrity_key.data, ik,
14888                  mp->entry.integrity_key.length);
14889
14890   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14891     {
14892       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14893                    sizeof (mp->entry.tunnel_src));
14894       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14895                    sizeof (mp->entry.tunnel_dst));
14896     }
14897
14898   S (mp);
14899   W (ret);
14900   return ret;
14901 }
14902
14903 static int
14904 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14905 {
14906   unformat_input_t *i = vam->input;
14907   vl_api_ipsec_tunnel_if_add_del_t *mp;
14908   u32 local_spi = 0, remote_spi = 0;
14909   u32 crypto_alg = 0, integ_alg = 0;
14910   u8 *lck = NULL, *rck = NULL;
14911   u8 *lik = NULL, *rik = NULL;
14912   vl_api_address_t local_ip = { 0 };
14913   vl_api_address_t remote_ip = { 0 };
14914   f64 before = 0;
14915   u8 is_add = 1;
14916   u8 esn = 0;
14917   u8 anti_replay = 0;
14918   u8 renumber = 0;
14919   u32 instance = ~0;
14920   u32 count = 1, jj;
14921   int ret;
14922
14923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (i, "del"))
14926         is_add = 0;
14927       else if (unformat (i, "esn"))
14928         esn = 1;
14929       else if (unformat (i, "anti-replay"))
14930         anti_replay = 1;
14931       else if (unformat (i, "count %d", &count))
14932         ;
14933       else if (unformat (i, "local_spi %d", &local_spi))
14934         ;
14935       else if (unformat (i, "remote_spi %d", &remote_spi))
14936         ;
14937       else
14938         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14939         ;
14940       else
14941         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14942         ;
14943       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14944         ;
14945       else
14946         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14947         ;
14948       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14949         ;
14950       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14951         ;
14952       else
14953         if (unformat
14954             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14955         {
14956           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14957             {
14958               errmsg ("unsupported crypto-alg: '%U'\n",
14959                       format_ipsec_crypto_alg, crypto_alg);
14960               return -99;
14961             }
14962         }
14963       else
14964         if (unformat
14965             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14966         {
14967           if (integ_alg >= IPSEC_INTEG_N_ALG)
14968             {
14969               errmsg ("unsupported integ-alg: '%U'\n",
14970                       format_ipsec_integ_alg, integ_alg);
14971               return -99;
14972             }
14973         }
14974       else if (unformat (i, "instance %u", &instance))
14975         renumber = 1;
14976       else
14977         {
14978           errmsg ("parse error '%U'\n", format_unformat_error, i);
14979           return -99;
14980         }
14981     }
14982
14983   if (count > 1)
14984     {
14985       /* Turn on async mode */
14986       vam->async_mode = 1;
14987       vam->async_errors = 0;
14988       before = vat_time_now (vam);
14989     }
14990
14991   for (jj = 0; jj < count; jj++)
14992     {
14993       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14994
14995       mp->is_add = is_add;
14996       mp->esn = esn;
14997       mp->anti_replay = anti_replay;
14998
14999       if (jj > 0)
15000         increment_vl_address (&remote_ip);
15001
15002       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15003       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15004
15005       mp->local_spi = htonl (local_spi + jj);
15006       mp->remote_spi = htonl (remote_spi + jj);
15007       mp->crypto_alg = (u8) crypto_alg;
15008
15009       mp->local_crypto_key_len = 0;
15010       if (lck)
15011         {
15012           mp->local_crypto_key_len = vec_len (lck);
15013           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15014             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15015           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15016         }
15017
15018       mp->remote_crypto_key_len = 0;
15019       if (rck)
15020         {
15021           mp->remote_crypto_key_len = vec_len (rck);
15022           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15023             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15024           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15025         }
15026
15027       mp->integ_alg = (u8) integ_alg;
15028
15029       mp->local_integ_key_len = 0;
15030       if (lik)
15031         {
15032           mp->local_integ_key_len = vec_len (lik);
15033           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15034             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15035           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15036         }
15037
15038       mp->remote_integ_key_len = 0;
15039       if (rik)
15040         {
15041           mp->remote_integ_key_len = vec_len (rik);
15042           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15043             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15044           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15045         }
15046
15047       if (renumber)
15048         {
15049           mp->renumber = renumber;
15050           mp->show_instance = ntohl (instance);
15051         }
15052       S (mp);
15053     }
15054
15055   /* When testing multiple add/del ops, use a control-ping to sync */
15056   if (count > 1)
15057     {
15058       vl_api_control_ping_t *mp_ping;
15059       f64 after;
15060       f64 timeout;
15061
15062       /* Shut off async mode */
15063       vam->async_mode = 0;
15064
15065       MPING (CONTROL_PING, mp_ping);
15066       S (mp_ping);
15067
15068       timeout = vat_time_now (vam) + 1.0;
15069       while (vat_time_now (vam) < timeout)
15070         if (vam->result_ready == 1)
15071           goto out;
15072       vam->retval = -99;
15073
15074     out:
15075       if (vam->retval == -99)
15076         errmsg ("timeout");
15077
15078       if (vam->async_errors > 0)
15079         {
15080           errmsg ("%d asynchronous errors", vam->async_errors);
15081           vam->retval = -98;
15082         }
15083       vam->async_errors = 0;
15084       after = vat_time_now (vam);
15085
15086       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15087       if (jj > 0)
15088         count = jj;
15089
15090       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15091              count, after - before, count / (after - before));
15092     }
15093   else
15094     {
15095       /* Wait for a reply... */
15096       W (ret);
15097       return ret;
15098     }
15099
15100   return ret;
15101 }
15102
15103 static void
15104 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15105 {
15106   vat_main_t *vam = &vat_main;
15107
15108   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15109          "crypto_key %U integ_alg %u integ_key %U flags %x "
15110          "tunnel_src_addr %U tunnel_dst_addr %U "
15111          "salt %u seq_outbound %lu last_seq_inbound %lu "
15112          "replay_window %lu\n",
15113          ntohl (mp->entry.sad_id),
15114          ntohl (mp->sw_if_index),
15115          ntohl (mp->entry.spi),
15116          ntohl (mp->entry.protocol),
15117          ntohl (mp->entry.crypto_algorithm),
15118          format_hex_bytes, mp->entry.crypto_key.data,
15119          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15120          format_hex_bytes, mp->entry.integrity_key.data,
15121          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15122          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15123          &mp->entry.tunnel_dst, ntohl (mp->salt),
15124          clib_net_to_host_u64 (mp->seq_outbound),
15125          clib_net_to_host_u64 (mp->last_seq_inbound),
15126          clib_net_to_host_u64 (mp->replay_window));
15127 }
15128
15129 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15130 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15131
15132 static void vl_api_ipsec_sa_details_t_handler_json
15133   (vl_api_ipsec_sa_details_t * mp)
15134 {
15135   vat_main_t *vam = &vat_main;
15136   vat_json_node_t *node = NULL;
15137   vl_api_ipsec_sad_flags_t flags;
15138
15139   if (VAT_JSON_ARRAY != vam->json_tree.type)
15140     {
15141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15142       vat_json_init_array (&vam->json_tree);
15143     }
15144   node = vat_json_array_add (&vam->json_tree);
15145
15146   vat_json_init_object (node);
15147   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15149   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15150   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15151   vat_json_object_add_uint (node, "crypto_alg",
15152                             ntohl (mp->entry.crypto_algorithm));
15153   vat_json_object_add_uint (node, "integ_alg",
15154                             ntohl (mp->entry.integrity_algorithm));
15155   flags = ntohl (mp->entry.flags);
15156   vat_json_object_add_uint (node, "use_esn",
15157                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15158   vat_json_object_add_uint (node, "use_anti_replay",
15159                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15160   vat_json_object_add_uint (node, "is_tunnel",
15161                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15162   vat_json_object_add_uint (node, "is_tunnel_ip6",
15163                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15164   vat_json_object_add_uint (node, "udp_encap",
15165                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15166   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15167                              mp->entry.crypto_key.length);
15168   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15169                              mp->entry.integrity_key.length);
15170   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15171   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15172   vat_json_object_add_uint (node, "replay_window",
15173                             clib_net_to_host_u64 (mp->replay_window));
15174 }
15175
15176 static int
15177 api_ipsec_sa_dump (vat_main_t * vam)
15178 {
15179   unformat_input_t *i = vam->input;
15180   vl_api_ipsec_sa_dump_t *mp;
15181   vl_api_control_ping_t *mp_ping;
15182   u32 sa_id = ~0;
15183   int ret;
15184
15185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (i, "sa_id %d", &sa_id))
15188         ;
15189       else
15190         {
15191           clib_warning ("parse error '%U'", format_unformat_error, i);
15192           return -99;
15193         }
15194     }
15195
15196   M (IPSEC_SA_DUMP, mp);
15197
15198   mp->sa_id = ntohl (sa_id);
15199
15200   S (mp);
15201
15202   /* Use a control ping for synchronization */
15203   M (CONTROL_PING, mp_ping);
15204   S (mp_ping);
15205
15206   W (ret);
15207   return ret;
15208 }
15209
15210 static int
15211 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15212 {
15213   unformat_input_t *i = vam->input;
15214   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15215   u32 sw_if_index = ~0;
15216   u32 sa_id = ~0;
15217   u8 is_outbound = (u8) ~ 0;
15218   int ret;
15219
15220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15221     {
15222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15223         ;
15224       else if (unformat (i, "sa_id %d", &sa_id))
15225         ;
15226       else if (unformat (i, "outbound"))
15227         is_outbound = 1;
15228       else if (unformat (i, "inbound"))
15229         is_outbound = 0;
15230       else
15231         {
15232           clib_warning ("parse error '%U'", format_unformat_error, i);
15233           return -99;
15234         }
15235     }
15236
15237   if (sw_if_index == ~0)
15238     {
15239       errmsg ("interface must be specified");
15240       return -99;
15241     }
15242
15243   if (sa_id == ~0)
15244     {
15245       errmsg ("SA ID must be specified");
15246       return -99;
15247     }
15248
15249   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15250
15251   mp->sw_if_index = htonl (sw_if_index);
15252   mp->sa_id = htonl (sa_id);
15253   mp->is_outbound = is_outbound;
15254
15255   S (mp);
15256   W (ret);
15257
15258   return ret;
15259 }
15260
15261 static int
15262 api_get_first_msg_id (vat_main_t * vam)
15263 {
15264   vl_api_get_first_msg_id_t *mp;
15265   unformat_input_t *i = vam->input;
15266   u8 *name;
15267   u8 name_set = 0;
15268   int ret;
15269
15270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15271     {
15272       if (unformat (i, "client %s", &name))
15273         name_set = 1;
15274       else
15275         break;
15276     }
15277
15278   if (name_set == 0)
15279     {
15280       errmsg ("missing client name");
15281       return -99;
15282     }
15283   vec_add1 (name, 0);
15284
15285   if (vec_len (name) > 63)
15286     {
15287       errmsg ("client name too long");
15288       return -99;
15289     }
15290
15291   M (GET_FIRST_MSG_ID, mp);
15292   clib_memcpy (mp->name, name, vec_len (name));
15293   S (mp);
15294   W (ret);
15295   return ret;
15296 }
15297
15298 static int
15299 api_cop_interface_enable_disable (vat_main_t * vam)
15300 {
15301   unformat_input_t *line_input = vam->input;
15302   vl_api_cop_interface_enable_disable_t *mp;
15303   u32 sw_if_index = ~0;
15304   u8 enable_disable = 1;
15305   int ret;
15306
15307   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15308     {
15309       if (unformat (line_input, "disable"))
15310         enable_disable = 0;
15311       if (unformat (line_input, "enable"))
15312         enable_disable = 1;
15313       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15314                          vam, &sw_if_index))
15315         ;
15316       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15317         ;
15318       else
15319         break;
15320     }
15321
15322   if (sw_if_index == ~0)
15323     {
15324       errmsg ("missing interface name or sw_if_index");
15325       return -99;
15326     }
15327
15328   /* Construct the API message */
15329   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15330   mp->sw_if_index = ntohl (sw_if_index);
15331   mp->enable_disable = enable_disable;
15332
15333   /* send it... */
15334   S (mp);
15335   /* Wait for the reply */
15336   W (ret);
15337   return ret;
15338 }
15339
15340 static int
15341 api_cop_whitelist_enable_disable (vat_main_t * vam)
15342 {
15343   unformat_input_t *line_input = vam->input;
15344   vl_api_cop_whitelist_enable_disable_t *mp;
15345   u32 sw_if_index = ~0;
15346   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15347   u32 fib_id = 0;
15348   int ret;
15349
15350   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (line_input, "ip4"))
15353         ip4 = 1;
15354       else if (unformat (line_input, "ip6"))
15355         ip6 = 1;
15356       else if (unformat (line_input, "default"))
15357         default_cop = 1;
15358       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15359                          vam, &sw_if_index))
15360         ;
15361       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15362         ;
15363       else if (unformat (line_input, "fib-id %d", &fib_id))
15364         ;
15365       else
15366         break;
15367     }
15368
15369   if (sw_if_index == ~0)
15370     {
15371       errmsg ("missing interface name or sw_if_index");
15372       return -99;
15373     }
15374
15375   /* Construct the API message */
15376   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15377   mp->sw_if_index = ntohl (sw_if_index);
15378   mp->fib_id = ntohl (fib_id);
15379   mp->ip4 = ip4;
15380   mp->ip6 = ip6;
15381   mp->default_cop = default_cop;
15382
15383   /* send it... */
15384   S (mp);
15385   /* Wait for the reply */
15386   W (ret);
15387   return ret;
15388 }
15389
15390 static int
15391 api_get_node_graph (vat_main_t * vam)
15392 {
15393   vl_api_get_node_graph_t *mp;
15394   int ret;
15395
15396   M (GET_NODE_GRAPH, mp);
15397
15398   /* send it... */
15399   S (mp);
15400   /* Wait for the reply */
15401   W (ret);
15402   return ret;
15403 }
15404
15405 /* *INDENT-OFF* */
15406 /** Used for parsing LISP eids */
15407 typedef CLIB_PACKED(struct{
15408   u8 addr[16];   /**< eid address */
15409   u32 len;       /**< prefix length if IP */
15410   u8 type;      /**< type of eid */
15411 }) lisp_eid_vat_t;
15412 /* *INDENT-ON* */
15413
15414 static uword
15415 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15416 {
15417   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15418
15419   clib_memset (a, 0, sizeof (a[0]));
15420
15421   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15422     {
15423       a->type = 0;              /* ipv4 type */
15424     }
15425   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15426     {
15427       a->type = 1;              /* ipv6 type */
15428     }
15429   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15430     {
15431       a->type = 2;              /* mac type */
15432     }
15433   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15434     {
15435       a->type = 3;              /* NSH type */
15436       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15437       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15438     }
15439   else
15440     {
15441       return 0;
15442     }
15443
15444   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15445     {
15446       return 0;
15447     }
15448
15449   return 1;
15450 }
15451
15452 static int
15453 lisp_eid_size_vat (u8 type)
15454 {
15455   switch (type)
15456     {
15457     case 0:
15458       return 4;
15459     case 1:
15460       return 16;
15461     case 2:
15462       return 6;
15463     case 3:
15464       return 5;
15465     }
15466   return 0;
15467 }
15468
15469 static void
15470 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15471 {
15472   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15473 }
15474
15475 static int
15476 api_one_add_del_locator_set (vat_main_t * vam)
15477 {
15478   unformat_input_t *input = vam->input;
15479   vl_api_one_add_del_locator_set_t *mp;
15480   u8 is_add = 1;
15481   u8 *locator_set_name = NULL;
15482   u8 locator_set_name_set = 0;
15483   vl_api_local_locator_t locator, *locators = 0;
15484   u32 sw_if_index, priority, weight;
15485   u32 data_len = 0;
15486
15487   int ret;
15488   /* Parse args required to build the message */
15489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15490     {
15491       if (unformat (input, "del"))
15492         {
15493           is_add = 0;
15494         }
15495       else if (unformat (input, "locator-set %s", &locator_set_name))
15496         {
15497           locator_set_name_set = 1;
15498         }
15499       else if (unformat (input, "sw_if_index %u p %u w %u",
15500                          &sw_if_index, &priority, &weight))
15501         {
15502           locator.sw_if_index = htonl (sw_if_index);
15503           locator.priority = priority;
15504           locator.weight = weight;
15505           vec_add1 (locators, locator);
15506         }
15507       else
15508         if (unformat
15509             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15510              &sw_if_index, &priority, &weight))
15511         {
15512           locator.sw_if_index = htonl (sw_if_index);
15513           locator.priority = priority;
15514           locator.weight = weight;
15515           vec_add1 (locators, locator);
15516         }
15517       else
15518         break;
15519     }
15520
15521   if (locator_set_name_set == 0)
15522     {
15523       errmsg ("missing locator-set name");
15524       vec_free (locators);
15525       return -99;
15526     }
15527
15528   if (vec_len (locator_set_name) > 64)
15529     {
15530       errmsg ("locator-set name too long");
15531       vec_free (locator_set_name);
15532       vec_free (locators);
15533       return -99;
15534     }
15535   vec_add1 (locator_set_name, 0);
15536
15537   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15538
15539   /* Construct the API message */
15540   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15541
15542   mp->is_add = is_add;
15543   clib_memcpy (mp->locator_set_name, locator_set_name,
15544                vec_len (locator_set_name));
15545   vec_free (locator_set_name);
15546
15547   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15548   if (locators)
15549     clib_memcpy (mp->locators, locators, data_len);
15550   vec_free (locators);
15551
15552   /* send it... */
15553   S (mp);
15554
15555   /* Wait for a reply... */
15556   W (ret);
15557   return ret;
15558 }
15559
15560 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15561
15562 static int
15563 api_one_add_del_locator (vat_main_t * vam)
15564 {
15565   unformat_input_t *input = vam->input;
15566   vl_api_one_add_del_locator_t *mp;
15567   u32 tmp_if_index = ~0;
15568   u32 sw_if_index = ~0;
15569   u8 sw_if_index_set = 0;
15570   u8 sw_if_index_if_name_set = 0;
15571   u32 priority = ~0;
15572   u8 priority_set = 0;
15573   u32 weight = ~0;
15574   u8 weight_set = 0;
15575   u8 is_add = 1;
15576   u8 *locator_set_name = NULL;
15577   u8 locator_set_name_set = 0;
15578   int ret;
15579
15580   /* Parse args required to build the message */
15581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15582     {
15583       if (unformat (input, "del"))
15584         {
15585           is_add = 0;
15586         }
15587       else if (unformat (input, "locator-set %s", &locator_set_name))
15588         {
15589           locator_set_name_set = 1;
15590         }
15591       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15592                          &tmp_if_index))
15593         {
15594           sw_if_index_if_name_set = 1;
15595           sw_if_index = tmp_if_index;
15596         }
15597       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15598         {
15599           sw_if_index_set = 1;
15600           sw_if_index = tmp_if_index;
15601         }
15602       else if (unformat (input, "p %d", &priority))
15603         {
15604           priority_set = 1;
15605         }
15606       else if (unformat (input, "w %d", &weight))
15607         {
15608           weight_set = 1;
15609         }
15610       else
15611         break;
15612     }
15613
15614   if (locator_set_name_set == 0)
15615     {
15616       errmsg ("missing locator-set name");
15617       return -99;
15618     }
15619
15620   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15621     {
15622       errmsg ("missing sw_if_index");
15623       vec_free (locator_set_name);
15624       return -99;
15625     }
15626
15627   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15628     {
15629       errmsg ("cannot use both params interface name and sw_if_index");
15630       vec_free (locator_set_name);
15631       return -99;
15632     }
15633
15634   if (priority_set == 0)
15635     {
15636       errmsg ("missing locator-set priority");
15637       vec_free (locator_set_name);
15638       return -99;
15639     }
15640
15641   if (weight_set == 0)
15642     {
15643       errmsg ("missing locator-set weight");
15644       vec_free (locator_set_name);
15645       return -99;
15646     }
15647
15648   if (vec_len (locator_set_name) > 64)
15649     {
15650       errmsg ("locator-set name too long");
15651       vec_free (locator_set_name);
15652       return -99;
15653     }
15654   vec_add1 (locator_set_name, 0);
15655
15656   /* Construct the API message */
15657   M (ONE_ADD_DEL_LOCATOR, mp);
15658
15659   mp->is_add = is_add;
15660   mp->sw_if_index = ntohl (sw_if_index);
15661   mp->priority = priority;
15662   mp->weight = weight;
15663   clib_memcpy (mp->locator_set_name, locator_set_name,
15664                vec_len (locator_set_name));
15665   vec_free (locator_set_name);
15666
15667   /* send it... */
15668   S (mp);
15669
15670   /* Wait for a reply... */
15671   W (ret);
15672   return ret;
15673 }
15674
15675 #define api_lisp_add_del_locator api_one_add_del_locator
15676
15677 uword
15678 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15679 {
15680   u32 *key_id = va_arg (*args, u32 *);
15681   u8 *s = 0;
15682
15683   if (unformat (input, "%s", &s))
15684     {
15685       if (!strcmp ((char *) s, "sha1"))
15686         key_id[0] = HMAC_SHA_1_96;
15687       else if (!strcmp ((char *) s, "sha256"))
15688         key_id[0] = HMAC_SHA_256_128;
15689       else
15690         {
15691           clib_warning ("invalid key_id: '%s'", s);
15692           key_id[0] = HMAC_NO_KEY;
15693         }
15694     }
15695   else
15696     return 0;
15697
15698   vec_free (s);
15699   return 1;
15700 }
15701
15702 static int
15703 api_one_add_del_local_eid (vat_main_t * vam)
15704 {
15705   unformat_input_t *input = vam->input;
15706   vl_api_one_add_del_local_eid_t *mp;
15707   u8 is_add = 1;
15708   u8 eid_set = 0;
15709   lisp_eid_vat_t _eid, *eid = &_eid;
15710   u8 *locator_set_name = 0;
15711   u8 locator_set_name_set = 0;
15712   u32 vni = 0;
15713   u16 key_id = 0;
15714   u8 *key = 0;
15715   int ret;
15716
15717   /* Parse args required to build the message */
15718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15719     {
15720       if (unformat (input, "del"))
15721         {
15722           is_add = 0;
15723         }
15724       else if (unformat (input, "vni %d", &vni))
15725         {
15726           ;
15727         }
15728       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15729         {
15730           eid_set = 1;
15731         }
15732       else if (unformat (input, "locator-set %s", &locator_set_name))
15733         {
15734           locator_set_name_set = 1;
15735         }
15736       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15737         ;
15738       else if (unformat (input, "secret-key %_%v%_", &key))
15739         ;
15740       else
15741         break;
15742     }
15743
15744   if (locator_set_name_set == 0)
15745     {
15746       errmsg ("missing locator-set name");
15747       return -99;
15748     }
15749
15750   if (0 == eid_set)
15751     {
15752       errmsg ("EID address not set!");
15753       vec_free (locator_set_name);
15754       return -99;
15755     }
15756
15757   if (key && (0 == key_id))
15758     {
15759       errmsg ("invalid key_id!");
15760       return -99;
15761     }
15762
15763   if (vec_len (key) > 64)
15764     {
15765       errmsg ("key too long");
15766       vec_free (key);
15767       return -99;
15768     }
15769
15770   if (vec_len (locator_set_name) > 64)
15771     {
15772       errmsg ("locator-set name too long");
15773       vec_free (locator_set_name);
15774       return -99;
15775     }
15776   vec_add1 (locator_set_name, 0);
15777
15778   /* Construct the API message */
15779   M (ONE_ADD_DEL_LOCAL_EID, mp);
15780
15781   mp->is_add = is_add;
15782   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15783   mp->eid_type = eid->type;
15784   mp->prefix_len = eid->len;
15785   mp->vni = clib_host_to_net_u32 (vni);
15786   mp->key_id = clib_host_to_net_u16 (key_id);
15787   clib_memcpy (mp->locator_set_name, locator_set_name,
15788                vec_len (locator_set_name));
15789   clib_memcpy (mp->key, key, vec_len (key));
15790
15791   vec_free (locator_set_name);
15792   vec_free (key);
15793
15794   /* send it... */
15795   S (mp);
15796
15797   /* Wait for a reply... */
15798   W (ret);
15799   return ret;
15800 }
15801
15802 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15803
15804 static int
15805 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15806 {
15807   u32 dp_table = 0, vni = 0;;
15808   unformat_input_t *input = vam->input;
15809   vl_api_gpe_add_del_fwd_entry_t *mp;
15810   u8 is_add = 1;
15811   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15812   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15813   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15814   u32 action = ~0, w;
15815   ip4_address_t rmt_rloc4, lcl_rloc4;
15816   ip6_address_t rmt_rloc6, lcl_rloc6;
15817   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15818   int ret;
15819
15820   clib_memset (&rloc, 0, sizeof (rloc));
15821
15822   /* Parse args required to build the message */
15823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15824     {
15825       if (unformat (input, "del"))
15826         is_add = 0;
15827       else if (unformat (input, "add"))
15828         is_add = 1;
15829       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15830         {
15831           rmt_eid_set = 1;
15832         }
15833       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15834         {
15835           lcl_eid_set = 1;
15836         }
15837       else if (unformat (input, "vrf %d", &dp_table))
15838         ;
15839       else if (unformat (input, "bd %d", &dp_table))
15840         ;
15841       else if (unformat (input, "vni %d", &vni))
15842         ;
15843       else if (unformat (input, "w %d", &w))
15844         {
15845           if (!curr_rloc)
15846             {
15847               errmsg ("No RLOC configured for setting priority/weight!");
15848               return -99;
15849             }
15850           curr_rloc->weight = w;
15851         }
15852       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15853                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15854         {
15855           rloc.is_ip4 = 1;
15856
15857           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15858           rloc.weight = 0;
15859           vec_add1 (lcl_locs, rloc);
15860
15861           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15862           vec_add1 (rmt_locs, rloc);
15863           /* weight saved in rmt loc */
15864           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15865         }
15866       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15867                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15868         {
15869           rloc.is_ip4 = 0;
15870           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15871           rloc.weight = 0;
15872           vec_add1 (lcl_locs, rloc);
15873
15874           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15875           vec_add1 (rmt_locs, rloc);
15876           /* weight saved in rmt loc */
15877           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15878         }
15879       else if (unformat (input, "action %d", &action))
15880         {
15881           ;
15882         }
15883       else
15884         {
15885           clib_warning ("parse error '%U'", format_unformat_error, input);
15886           return -99;
15887         }
15888     }
15889
15890   if (!rmt_eid_set)
15891     {
15892       errmsg ("remote eid addresses not set");
15893       return -99;
15894     }
15895
15896   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15897     {
15898       errmsg ("eid types don't match");
15899       return -99;
15900     }
15901
15902   if (0 == rmt_locs && (u32) ~ 0 == action)
15903     {
15904       errmsg ("action not set for negative mapping");
15905       return -99;
15906     }
15907
15908   /* Construct the API message */
15909   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15910       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15911
15912   mp->is_add = is_add;
15913   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15914   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15915   mp->eid_type = rmt_eid->type;
15916   mp->dp_table = clib_host_to_net_u32 (dp_table);
15917   mp->vni = clib_host_to_net_u32 (vni);
15918   mp->rmt_len = rmt_eid->len;
15919   mp->lcl_len = lcl_eid->len;
15920   mp->action = action;
15921
15922   if (0 != rmt_locs && 0 != lcl_locs)
15923     {
15924       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15925       clib_memcpy (mp->locs, lcl_locs,
15926                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15927
15928       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15929       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15930                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15931     }
15932   vec_free (lcl_locs);
15933   vec_free (rmt_locs);
15934
15935   /* send it... */
15936   S (mp);
15937
15938   /* Wait for a reply... */
15939   W (ret);
15940   return ret;
15941 }
15942
15943 static int
15944 api_one_add_del_map_server (vat_main_t * vam)
15945 {
15946   unformat_input_t *input = vam->input;
15947   vl_api_one_add_del_map_server_t *mp;
15948   u8 is_add = 1;
15949   u8 ipv4_set = 0;
15950   u8 ipv6_set = 0;
15951   ip4_address_t ipv4;
15952   ip6_address_t ipv6;
15953   int ret;
15954
15955   /* Parse args required to build the message */
15956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15957     {
15958       if (unformat (input, "del"))
15959         {
15960           is_add = 0;
15961         }
15962       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15963         {
15964           ipv4_set = 1;
15965         }
15966       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15967         {
15968           ipv6_set = 1;
15969         }
15970       else
15971         break;
15972     }
15973
15974   if (ipv4_set && ipv6_set)
15975     {
15976       errmsg ("both eid v4 and v6 addresses set");
15977       return -99;
15978     }
15979
15980   if (!ipv4_set && !ipv6_set)
15981     {
15982       errmsg ("eid addresses not set");
15983       return -99;
15984     }
15985
15986   /* Construct the API message */
15987   M (ONE_ADD_DEL_MAP_SERVER, mp);
15988
15989   mp->is_add = is_add;
15990   if (ipv6_set)
15991     {
15992       mp->is_ipv6 = 1;
15993       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15994     }
15995   else
15996     {
15997       mp->is_ipv6 = 0;
15998       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15999     }
16000
16001   /* send it... */
16002   S (mp);
16003
16004   /* Wait for a reply... */
16005   W (ret);
16006   return ret;
16007 }
16008
16009 #define api_lisp_add_del_map_server api_one_add_del_map_server
16010
16011 static int
16012 api_one_add_del_map_resolver (vat_main_t * vam)
16013 {
16014   unformat_input_t *input = vam->input;
16015   vl_api_one_add_del_map_resolver_t *mp;
16016   u8 is_add = 1;
16017   u8 ipv4_set = 0;
16018   u8 ipv6_set = 0;
16019   ip4_address_t ipv4;
16020   ip6_address_t ipv6;
16021   int ret;
16022
16023   /* Parse args required to build the message */
16024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16025     {
16026       if (unformat (input, "del"))
16027         {
16028           is_add = 0;
16029         }
16030       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16031         {
16032           ipv4_set = 1;
16033         }
16034       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16035         {
16036           ipv6_set = 1;
16037         }
16038       else
16039         break;
16040     }
16041
16042   if (ipv4_set && ipv6_set)
16043     {
16044       errmsg ("both eid v4 and v6 addresses set");
16045       return -99;
16046     }
16047
16048   if (!ipv4_set && !ipv6_set)
16049     {
16050       errmsg ("eid addresses not set");
16051       return -99;
16052     }
16053
16054   /* Construct the API message */
16055   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16056
16057   mp->is_add = is_add;
16058   if (ipv6_set)
16059     {
16060       mp->is_ipv6 = 1;
16061       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16062     }
16063   else
16064     {
16065       mp->is_ipv6 = 0;
16066       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16067     }
16068
16069   /* send it... */
16070   S (mp);
16071
16072   /* Wait for a reply... */
16073   W (ret);
16074   return ret;
16075 }
16076
16077 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16078
16079 static int
16080 api_lisp_gpe_enable_disable (vat_main_t * vam)
16081 {
16082   unformat_input_t *input = vam->input;
16083   vl_api_gpe_enable_disable_t *mp;
16084   u8 is_set = 0;
16085   u8 is_en = 1;
16086   int ret;
16087
16088   /* Parse args required to build the message */
16089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16090     {
16091       if (unformat (input, "enable"))
16092         {
16093           is_set = 1;
16094           is_en = 1;
16095         }
16096       else if (unformat (input, "disable"))
16097         {
16098           is_set = 1;
16099           is_en = 0;
16100         }
16101       else
16102         break;
16103     }
16104
16105   if (is_set == 0)
16106     {
16107       errmsg ("Value not set");
16108       return -99;
16109     }
16110
16111   /* Construct the API message */
16112   M (GPE_ENABLE_DISABLE, mp);
16113
16114   mp->is_en = is_en;
16115
16116   /* send it... */
16117   S (mp);
16118
16119   /* Wait for a reply... */
16120   W (ret);
16121   return ret;
16122 }
16123
16124 static int
16125 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16126 {
16127   unformat_input_t *input = vam->input;
16128   vl_api_one_rloc_probe_enable_disable_t *mp;
16129   u8 is_set = 0;
16130   u8 is_en = 0;
16131   int ret;
16132
16133   /* Parse args required to build the message */
16134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16135     {
16136       if (unformat (input, "enable"))
16137         {
16138           is_set = 1;
16139           is_en = 1;
16140         }
16141       else if (unformat (input, "disable"))
16142         is_set = 1;
16143       else
16144         break;
16145     }
16146
16147   if (!is_set)
16148     {
16149       errmsg ("Value not set");
16150       return -99;
16151     }
16152
16153   /* Construct the API message */
16154   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16155
16156   mp->is_enabled = is_en;
16157
16158   /* send it... */
16159   S (mp);
16160
16161   /* Wait for a reply... */
16162   W (ret);
16163   return ret;
16164 }
16165
16166 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16167
16168 static int
16169 api_one_map_register_enable_disable (vat_main_t * vam)
16170 {
16171   unformat_input_t *input = vam->input;
16172   vl_api_one_map_register_enable_disable_t *mp;
16173   u8 is_set = 0;
16174   u8 is_en = 0;
16175   int ret;
16176
16177   /* Parse args required to build the message */
16178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16179     {
16180       if (unformat (input, "enable"))
16181         {
16182           is_set = 1;
16183           is_en = 1;
16184         }
16185       else if (unformat (input, "disable"))
16186         is_set = 1;
16187       else
16188         break;
16189     }
16190
16191   if (!is_set)
16192     {
16193       errmsg ("Value not set");
16194       return -99;
16195     }
16196
16197   /* Construct the API message */
16198   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16199
16200   mp->is_enabled = is_en;
16201
16202   /* send it... */
16203   S (mp);
16204
16205   /* Wait for a reply... */
16206   W (ret);
16207   return ret;
16208 }
16209
16210 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16211
16212 static int
16213 api_one_enable_disable (vat_main_t * vam)
16214 {
16215   unformat_input_t *input = vam->input;
16216   vl_api_one_enable_disable_t *mp;
16217   u8 is_set = 0;
16218   u8 is_en = 0;
16219   int ret;
16220
16221   /* Parse args required to build the message */
16222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (input, "enable"))
16225         {
16226           is_set = 1;
16227           is_en = 1;
16228         }
16229       else if (unformat (input, "disable"))
16230         {
16231           is_set = 1;
16232         }
16233       else
16234         break;
16235     }
16236
16237   if (!is_set)
16238     {
16239       errmsg ("Value not set");
16240       return -99;
16241     }
16242
16243   /* Construct the API message */
16244   M (ONE_ENABLE_DISABLE, mp);
16245
16246   mp->is_en = is_en;
16247
16248   /* send it... */
16249   S (mp);
16250
16251   /* Wait for a reply... */
16252   W (ret);
16253   return ret;
16254 }
16255
16256 #define api_lisp_enable_disable api_one_enable_disable
16257
16258 static int
16259 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16260 {
16261   unformat_input_t *input = vam->input;
16262   vl_api_one_enable_disable_xtr_mode_t *mp;
16263   u8 is_set = 0;
16264   u8 is_en = 0;
16265   int ret;
16266
16267   /* Parse args required to build the message */
16268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16269     {
16270       if (unformat (input, "enable"))
16271         {
16272           is_set = 1;
16273           is_en = 1;
16274         }
16275       else if (unformat (input, "disable"))
16276         {
16277           is_set = 1;
16278         }
16279       else
16280         break;
16281     }
16282
16283   if (!is_set)
16284     {
16285       errmsg ("Value not set");
16286       return -99;
16287     }
16288
16289   /* Construct the API message */
16290   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16291
16292   mp->is_en = is_en;
16293
16294   /* send it... */
16295   S (mp);
16296
16297   /* Wait for a reply... */
16298   W (ret);
16299   return ret;
16300 }
16301
16302 static int
16303 api_one_show_xtr_mode (vat_main_t * vam)
16304 {
16305   vl_api_one_show_xtr_mode_t *mp;
16306   int ret;
16307
16308   /* Construct the API message */
16309   M (ONE_SHOW_XTR_MODE, mp);
16310
16311   /* send it... */
16312   S (mp);
16313
16314   /* Wait for a reply... */
16315   W (ret);
16316   return ret;
16317 }
16318
16319 static int
16320 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16321 {
16322   unformat_input_t *input = vam->input;
16323   vl_api_one_enable_disable_pitr_mode_t *mp;
16324   u8 is_set = 0;
16325   u8 is_en = 0;
16326   int ret;
16327
16328   /* Parse args required to build the message */
16329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16330     {
16331       if (unformat (input, "enable"))
16332         {
16333           is_set = 1;
16334           is_en = 1;
16335         }
16336       else if (unformat (input, "disable"))
16337         {
16338           is_set = 1;
16339         }
16340       else
16341         break;
16342     }
16343
16344   if (!is_set)
16345     {
16346       errmsg ("Value not set");
16347       return -99;
16348     }
16349
16350   /* Construct the API message */
16351   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16352
16353   mp->is_en = is_en;
16354
16355   /* send it... */
16356   S (mp);
16357
16358   /* Wait for a reply... */
16359   W (ret);
16360   return ret;
16361 }
16362
16363 static int
16364 api_one_show_pitr_mode (vat_main_t * vam)
16365 {
16366   vl_api_one_show_pitr_mode_t *mp;
16367   int ret;
16368
16369   /* Construct the API message */
16370   M (ONE_SHOW_PITR_MODE, mp);
16371
16372   /* send it... */
16373   S (mp);
16374
16375   /* Wait for a reply... */
16376   W (ret);
16377   return ret;
16378 }
16379
16380 static int
16381 api_one_enable_disable_petr_mode (vat_main_t * vam)
16382 {
16383   unformat_input_t *input = vam->input;
16384   vl_api_one_enable_disable_petr_mode_t *mp;
16385   u8 is_set = 0;
16386   u8 is_en = 0;
16387   int ret;
16388
16389   /* Parse args required to build the message */
16390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16391     {
16392       if (unformat (input, "enable"))
16393         {
16394           is_set = 1;
16395           is_en = 1;
16396         }
16397       else if (unformat (input, "disable"))
16398         {
16399           is_set = 1;
16400         }
16401       else
16402         break;
16403     }
16404
16405   if (!is_set)
16406     {
16407       errmsg ("Value not set");
16408       return -99;
16409     }
16410
16411   /* Construct the API message */
16412   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16413
16414   mp->is_en = is_en;
16415
16416   /* send it... */
16417   S (mp);
16418
16419   /* Wait for a reply... */
16420   W (ret);
16421   return ret;
16422 }
16423
16424 static int
16425 api_one_show_petr_mode (vat_main_t * vam)
16426 {
16427   vl_api_one_show_petr_mode_t *mp;
16428   int ret;
16429
16430   /* Construct the API message */
16431   M (ONE_SHOW_PETR_MODE, mp);
16432
16433   /* send it... */
16434   S (mp);
16435
16436   /* Wait for a reply... */
16437   W (ret);
16438   return ret;
16439 }
16440
16441 static int
16442 api_show_one_map_register_state (vat_main_t * vam)
16443 {
16444   vl_api_show_one_map_register_state_t *mp;
16445   int ret;
16446
16447   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16448
16449   /* send */
16450   S (mp);
16451
16452   /* wait for reply */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 #define api_show_lisp_map_register_state api_show_one_map_register_state
16458
16459 static int
16460 api_show_one_rloc_probe_state (vat_main_t * vam)
16461 {
16462   vl_api_show_one_rloc_probe_state_t *mp;
16463   int ret;
16464
16465   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16466
16467   /* send */
16468   S (mp);
16469
16470   /* wait for reply */
16471   W (ret);
16472   return ret;
16473 }
16474
16475 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16476
16477 static int
16478 api_one_add_del_ndp_entry (vat_main_t * vam)
16479 {
16480   vl_api_one_add_del_ndp_entry_t *mp;
16481   unformat_input_t *input = vam->input;
16482   u8 is_add = 1;
16483   u8 mac_set = 0;
16484   u8 bd_set = 0;
16485   u8 ip_set = 0;
16486   u8 mac[6] = { 0, };
16487   u8 ip6[16] = { 0, };
16488   u32 bd = ~0;
16489   int ret;
16490
16491   /* Parse args required to build the message */
16492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16493     {
16494       if (unformat (input, "del"))
16495         is_add = 0;
16496       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16497         mac_set = 1;
16498       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16499         ip_set = 1;
16500       else if (unformat (input, "bd %d", &bd))
16501         bd_set = 1;
16502       else
16503         {
16504           errmsg ("parse error '%U'", format_unformat_error, input);
16505           return -99;
16506         }
16507     }
16508
16509   if (!bd_set || !ip_set || (!mac_set && is_add))
16510     {
16511       errmsg ("Missing BD, IP or MAC!");
16512       return -99;
16513     }
16514
16515   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16516   mp->is_add = is_add;
16517   clib_memcpy (mp->mac, mac, 6);
16518   mp->bd = clib_host_to_net_u32 (bd);
16519   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16520
16521   /* send */
16522   S (mp);
16523
16524   /* wait for reply */
16525   W (ret);
16526   return ret;
16527 }
16528
16529 static int
16530 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16531 {
16532   vl_api_one_add_del_l2_arp_entry_t *mp;
16533   unformat_input_t *input = vam->input;
16534   u8 is_add = 1;
16535   u8 mac_set = 0;
16536   u8 bd_set = 0;
16537   u8 ip_set = 0;
16538   u8 mac[6] = { 0, };
16539   u32 ip4 = 0, bd = ~0;
16540   int ret;
16541
16542   /* Parse args required to build the message */
16543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16544     {
16545       if (unformat (input, "del"))
16546         is_add = 0;
16547       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16548         mac_set = 1;
16549       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16550         ip_set = 1;
16551       else if (unformat (input, "bd %d", &bd))
16552         bd_set = 1;
16553       else
16554         {
16555           errmsg ("parse error '%U'", format_unformat_error, input);
16556           return -99;
16557         }
16558     }
16559
16560   if (!bd_set || !ip_set || (!mac_set && is_add))
16561     {
16562       errmsg ("Missing BD, IP or MAC!");
16563       return -99;
16564     }
16565
16566   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16567   mp->is_add = is_add;
16568   clib_memcpy (mp->mac, mac, 6);
16569   mp->bd = clib_host_to_net_u32 (bd);
16570   mp->ip4 = ip4;
16571
16572   /* send */
16573   S (mp);
16574
16575   /* wait for reply */
16576   W (ret);
16577   return ret;
16578 }
16579
16580 static int
16581 api_one_ndp_bd_get (vat_main_t * vam)
16582 {
16583   vl_api_one_ndp_bd_get_t *mp;
16584   int ret;
16585
16586   M (ONE_NDP_BD_GET, mp);
16587
16588   /* send */
16589   S (mp);
16590
16591   /* wait for reply */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 static int
16597 api_one_ndp_entries_get (vat_main_t * vam)
16598 {
16599   vl_api_one_ndp_entries_get_t *mp;
16600   unformat_input_t *input = vam->input;
16601   u8 bd_set = 0;
16602   u32 bd = ~0;
16603   int ret;
16604
16605   /* Parse args required to build the message */
16606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (input, "bd %d", &bd))
16609         bd_set = 1;
16610       else
16611         {
16612           errmsg ("parse error '%U'", format_unformat_error, input);
16613           return -99;
16614         }
16615     }
16616
16617   if (!bd_set)
16618     {
16619       errmsg ("Expected bridge domain!");
16620       return -99;
16621     }
16622
16623   M (ONE_NDP_ENTRIES_GET, mp);
16624   mp->bd = clib_host_to_net_u32 (bd);
16625
16626   /* send */
16627   S (mp);
16628
16629   /* wait for reply */
16630   W (ret);
16631   return ret;
16632 }
16633
16634 static int
16635 api_one_l2_arp_bd_get (vat_main_t * vam)
16636 {
16637   vl_api_one_l2_arp_bd_get_t *mp;
16638   int ret;
16639
16640   M (ONE_L2_ARP_BD_GET, mp);
16641
16642   /* send */
16643   S (mp);
16644
16645   /* wait for reply */
16646   W (ret);
16647   return ret;
16648 }
16649
16650 static int
16651 api_one_l2_arp_entries_get (vat_main_t * vam)
16652 {
16653   vl_api_one_l2_arp_entries_get_t *mp;
16654   unformat_input_t *input = vam->input;
16655   u8 bd_set = 0;
16656   u32 bd = ~0;
16657   int ret;
16658
16659   /* Parse args required to build the message */
16660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (input, "bd %d", &bd))
16663         bd_set = 1;
16664       else
16665         {
16666           errmsg ("parse error '%U'", format_unformat_error, input);
16667           return -99;
16668         }
16669     }
16670
16671   if (!bd_set)
16672     {
16673       errmsg ("Expected bridge domain!");
16674       return -99;
16675     }
16676
16677   M (ONE_L2_ARP_ENTRIES_GET, mp);
16678   mp->bd = clib_host_to_net_u32 (bd);
16679
16680   /* send */
16681   S (mp);
16682
16683   /* wait for reply */
16684   W (ret);
16685   return ret;
16686 }
16687
16688 static int
16689 api_one_stats_enable_disable (vat_main_t * vam)
16690 {
16691   vl_api_one_stats_enable_disable_t *mp;
16692   unformat_input_t *input = vam->input;
16693   u8 is_set = 0;
16694   u8 is_en = 0;
16695   int ret;
16696
16697   /* Parse args required to build the message */
16698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (input, "enable"))
16701         {
16702           is_set = 1;
16703           is_en = 1;
16704         }
16705       else if (unformat (input, "disable"))
16706         {
16707           is_set = 1;
16708         }
16709       else
16710         break;
16711     }
16712
16713   if (!is_set)
16714     {
16715       errmsg ("Value not set");
16716       return -99;
16717     }
16718
16719   M (ONE_STATS_ENABLE_DISABLE, mp);
16720   mp->is_en = is_en;
16721
16722   /* send */
16723   S (mp);
16724
16725   /* wait for reply */
16726   W (ret);
16727   return ret;
16728 }
16729
16730 static int
16731 api_show_one_stats_enable_disable (vat_main_t * vam)
16732 {
16733   vl_api_show_one_stats_enable_disable_t *mp;
16734   int ret;
16735
16736   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16737
16738   /* send */
16739   S (mp);
16740
16741   /* wait for reply */
16742   W (ret);
16743   return ret;
16744 }
16745
16746 static int
16747 api_show_one_map_request_mode (vat_main_t * vam)
16748 {
16749   vl_api_show_one_map_request_mode_t *mp;
16750   int ret;
16751
16752   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16753
16754   /* send */
16755   S (mp);
16756
16757   /* wait for reply */
16758   W (ret);
16759   return ret;
16760 }
16761
16762 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16763
16764 static int
16765 api_one_map_request_mode (vat_main_t * vam)
16766 {
16767   unformat_input_t *input = vam->input;
16768   vl_api_one_map_request_mode_t *mp;
16769   u8 mode = 0;
16770   int ret;
16771
16772   /* Parse args required to build the message */
16773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16774     {
16775       if (unformat (input, "dst-only"))
16776         mode = 0;
16777       else if (unformat (input, "src-dst"))
16778         mode = 1;
16779       else
16780         {
16781           errmsg ("parse error '%U'", format_unformat_error, input);
16782           return -99;
16783         }
16784     }
16785
16786   M (ONE_MAP_REQUEST_MODE, mp);
16787
16788   mp->mode = mode;
16789
16790   /* send */
16791   S (mp);
16792
16793   /* wait for reply */
16794   W (ret);
16795   return ret;
16796 }
16797
16798 #define api_lisp_map_request_mode api_one_map_request_mode
16799
16800 /**
16801  * Enable/disable ONE proxy ITR.
16802  *
16803  * @param vam vpp API test context
16804  * @return return code
16805  */
16806 static int
16807 api_one_pitr_set_locator_set (vat_main_t * vam)
16808 {
16809   u8 ls_name_set = 0;
16810   unformat_input_t *input = vam->input;
16811   vl_api_one_pitr_set_locator_set_t *mp;
16812   u8 is_add = 1;
16813   u8 *ls_name = 0;
16814   int ret;
16815
16816   /* Parse args required to build the message */
16817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16818     {
16819       if (unformat (input, "del"))
16820         is_add = 0;
16821       else if (unformat (input, "locator-set %s", &ls_name))
16822         ls_name_set = 1;
16823       else
16824         {
16825           errmsg ("parse error '%U'", format_unformat_error, input);
16826           return -99;
16827         }
16828     }
16829
16830   if (!ls_name_set)
16831     {
16832       errmsg ("locator-set name not set!");
16833       return -99;
16834     }
16835
16836   M (ONE_PITR_SET_LOCATOR_SET, mp);
16837
16838   mp->is_add = is_add;
16839   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16840   vec_free (ls_name);
16841
16842   /* send */
16843   S (mp);
16844
16845   /* wait for reply */
16846   W (ret);
16847   return ret;
16848 }
16849
16850 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16851
16852 static int
16853 api_one_nsh_set_locator_set (vat_main_t * vam)
16854 {
16855   u8 ls_name_set = 0;
16856   unformat_input_t *input = vam->input;
16857   vl_api_one_nsh_set_locator_set_t *mp;
16858   u8 is_add = 1;
16859   u8 *ls_name = 0;
16860   int ret;
16861
16862   /* Parse args required to build the message */
16863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (input, "del"))
16866         is_add = 0;
16867       else if (unformat (input, "ls %s", &ls_name))
16868         ls_name_set = 1;
16869       else
16870         {
16871           errmsg ("parse error '%U'", format_unformat_error, input);
16872           return -99;
16873         }
16874     }
16875
16876   if (!ls_name_set && is_add)
16877     {
16878       errmsg ("locator-set name not set!");
16879       return -99;
16880     }
16881
16882   M (ONE_NSH_SET_LOCATOR_SET, mp);
16883
16884   mp->is_add = is_add;
16885   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16886   vec_free (ls_name);
16887
16888   /* send */
16889   S (mp);
16890
16891   /* wait for reply */
16892   W (ret);
16893   return ret;
16894 }
16895
16896 static int
16897 api_show_one_pitr (vat_main_t * vam)
16898 {
16899   vl_api_show_one_pitr_t *mp;
16900   int ret;
16901
16902   if (!vam->json_output)
16903     {
16904       print (vam->ofp, "%=20s", "lisp status:");
16905     }
16906
16907   M (SHOW_ONE_PITR, mp);
16908   /* send it... */
16909   S (mp);
16910
16911   /* Wait for a reply... */
16912   W (ret);
16913   return ret;
16914 }
16915
16916 #define api_show_lisp_pitr api_show_one_pitr
16917
16918 static int
16919 api_one_use_petr (vat_main_t * vam)
16920 {
16921   unformat_input_t *input = vam->input;
16922   vl_api_one_use_petr_t *mp;
16923   u8 is_add = 0;
16924   ip_address_t ip;
16925   int ret;
16926
16927   clib_memset (&ip, 0, sizeof (ip));
16928
16929   /* Parse args required to build the message */
16930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16931     {
16932       if (unformat (input, "disable"))
16933         is_add = 0;
16934       else
16935         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16936         {
16937           is_add = 1;
16938           ip_addr_version (&ip) = IP4;
16939         }
16940       else
16941         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16942         {
16943           is_add = 1;
16944           ip_addr_version (&ip) = IP6;
16945         }
16946       else
16947         {
16948           errmsg ("parse error '%U'", format_unformat_error, input);
16949           return -99;
16950         }
16951     }
16952
16953   M (ONE_USE_PETR, mp);
16954
16955   mp->is_add = is_add;
16956   if (is_add)
16957     {
16958       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16959       if (mp->is_ip4)
16960         clib_memcpy (mp->address, &ip, 4);
16961       else
16962         clib_memcpy (mp->address, &ip, 16);
16963     }
16964
16965   /* send */
16966   S (mp);
16967
16968   /* wait for reply */
16969   W (ret);
16970   return ret;
16971 }
16972
16973 #define api_lisp_use_petr api_one_use_petr
16974
16975 static int
16976 api_show_one_nsh_mapping (vat_main_t * vam)
16977 {
16978   vl_api_show_one_use_petr_t *mp;
16979   int ret;
16980
16981   if (!vam->json_output)
16982     {
16983       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16984     }
16985
16986   M (SHOW_ONE_NSH_MAPPING, mp);
16987   /* send it... */
16988   S (mp);
16989
16990   /* Wait for a reply... */
16991   W (ret);
16992   return ret;
16993 }
16994
16995 static int
16996 api_show_one_use_petr (vat_main_t * vam)
16997 {
16998   vl_api_show_one_use_petr_t *mp;
16999   int ret;
17000
17001   if (!vam->json_output)
17002     {
17003       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17004     }
17005
17006   M (SHOW_ONE_USE_PETR, mp);
17007   /* send it... */
17008   S (mp);
17009
17010   /* Wait for a reply... */
17011   W (ret);
17012   return ret;
17013 }
17014
17015 #define api_show_lisp_use_petr api_show_one_use_petr
17016
17017 /**
17018  * Add/delete mapping between vni and vrf
17019  */
17020 static int
17021 api_one_eid_table_add_del_map (vat_main_t * vam)
17022 {
17023   unformat_input_t *input = vam->input;
17024   vl_api_one_eid_table_add_del_map_t *mp;
17025   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17026   u32 vni, vrf, bd_index;
17027   int ret;
17028
17029   /* Parse args required to build the message */
17030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17031     {
17032       if (unformat (input, "del"))
17033         is_add = 0;
17034       else if (unformat (input, "vrf %d", &vrf))
17035         vrf_set = 1;
17036       else if (unformat (input, "bd_index %d", &bd_index))
17037         bd_index_set = 1;
17038       else if (unformat (input, "vni %d", &vni))
17039         vni_set = 1;
17040       else
17041         break;
17042     }
17043
17044   if (!vni_set || (!vrf_set && !bd_index_set))
17045     {
17046       errmsg ("missing arguments!");
17047       return -99;
17048     }
17049
17050   if (vrf_set && bd_index_set)
17051     {
17052       errmsg ("error: both vrf and bd entered!");
17053       return -99;
17054     }
17055
17056   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17057
17058   mp->is_add = is_add;
17059   mp->vni = htonl (vni);
17060   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17061   mp->is_l2 = bd_index_set;
17062
17063   /* send */
17064   S (mp);
17065
17066   /* wait for reply */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17072
17073 uword
17074 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17075 {
17076   u32 *action = va_arg (*args, u32 *);
17077   u8 *s = 0;
17078
17079   if (unformat (input, "%s", &s))
17080     {
17081       if (!strcmp ((char *) s, "no-action"))
17082         action[0] = 0;
17083       else if (!strcmp ((char *) s, "natively-forward"))
17084         action[0] = 1;
17085       else if (!strcmp ((char *) s, "send-map-request"))
17086         action[0] = 2;
17087       else if (!strcmp ((char *) s, "drop"))
17088         action[0] = 3;
17089       else
17090         {
17091           clib_warning ("invalid action: '%s'", s);
17092           action[0] = 3;
17093         }
17094     }
17095   else
17096     return 0;
17097
17098   vec_free (s);
17099   return 1;
17100 }
17101
17102 /**
17103  * Add/del remote mapping to/from ONE control plane
17104  *
17105  * @param vam vpp API test context
17106  * @return return code
17107  */
17108 static int
17109 api_one_add_del_remote_mapping (vat_main_t * vam)
17110 {
17111   unformat_input_t *input = vam->input;
17112   vl_api_one_add_del_remote_mapping_t *mp;
17113   u32 vni = 0;
17114   lisp_eid_vat_t _eid, *eid = &_eid;
17115   lisp_eid_vat_t _seid, *seid = &_seid;
17116   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17117   u32 action = ~0, p, w, data_len;
17118   ip4_address_t rloc4;
17119   ip6_address_t rloc6;
17120   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17121   int ret;
17122
17123   clib_memset (&rloc, 0, sizeof (rloc));
17124
17125   /* Parse args required to build the message */
17126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17127     {
17128       if (unformat (input, "del-all"))
17129         {
17130           del_all = 1;
17131         }
17132       else if (unformat (input, "del"))
17133         {
17134           is_add = 0;
17135         }
17136       else if (unformat (input, "add"))
17137         {
17138           is_add = 1;
17139         }
17140       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17141         {
17142           eid_set = 1;
17143         }
17144       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17145         {
17146           seid_set = 1;
17147         }
17148       else if (unformat (input, "vni %d", &vni))
17149         {
17150           ;
17151         }
17152       else if (unformat (input, "p %d w %d", &p, &w))
17153         {
17154           if (!curr_rloc)
17155             {
17156               errmsg ("No RLOC configured for setting priority/weight!");
17157               return -99;
17158             }
17159           curr_rloc->priority = p;
17160           curr_rloc->weight = w;
17161         }
17162       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17163         {
17164           rloc.is_ip4 = 1;
17165           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17166           vec_add1 (rlocs, rloc);
17167           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17168         }
17169       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17170         {
17171           rloc.is_ip4 = 0;
17172           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17173           vec_add1 (rlocs, rloc);
17174           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17175         }
17176       else if (unformat (input, "action %U",
17177                          unformat_negative_mapping_action, &action))
17178         {
17179           ;
17180         }
17181       else
17182         {
17183           clib_warning ("parse error '%U'", format_unformat_error, input);
17184           return -99;
17185         }
17186     }
17187
17188   if (0 == eid_set)
17189     {
17190       errmsg ("missing params!");
17191       return -99;
17192     }
17193
17194   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17195     {
17196       errmsg ("no action set for negative map-reply!");
17197       return -99;
17198     }
17199
17200   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17201
17202   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17203   mp->is_add = is_add;
17204   mp->vni = htonl (vni);
17205   mp->action = (u8) action;
17206   mp->is_src_dst = seid_set;
17207   mp->eid_len = eid->len;
17208   mp->seid_len = seid->len;
17209   mp->del_all = del_all;
17210   mp->eid_type = eid->type;
17211   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17212   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17213
17214   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17215   clib_memcpy (mp->rlocs, rlocs, data_len);
17216   vec_free (rlocs);
17217
17218   /* send it... */
17219   S (mp);
17220
17221   /* Wait for a reply... */
17222   W (ret);
17223   return ret;
17224 }
17225
17226 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17227
17228 /**
17229  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17230  * forwarding entries in data-plane accordingly.
17231  *
17232  * @param vam vpp API test context
17233  * @return return code
17234  */
17235 static int
17236 api_one_add_del_adjacency (vat_main_t * vam)
17237 {
17238   unformat_input_t *input = vam->input;
17239   vl_api_one_add_del_adjacency_t *mp;
17240   u32 vni = 0;
17241   ip4_address_t leid4, reid4;
17242   ip6_address_t leid6, reid6;
17243   u8 reid_mac[6] = { 0 };
17244   u8 leid_mac[6] = { 0 };
17245   u8 reid_type, leid_type;
17246   u32 leid_len = 0, reid_len = 0, len;
17247   u8 is_add = 1;
17248   int ret;
17249
17250   leid_type = reid_type = (u8) ~ 0;
17251
17252   /* Parse args required to build the message */
17253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17254     {
17255       if (unformat (input, "del"))
17256         {
17257           is_add = 0;
17258         }
17259       else if (unformat (input, "add"))
17260         {
17261           is_add = 1;
17262         }
17263       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17264                          &reid4, &len))
17265         {
17266           reid_type = 0;        /* ipv4 */
17267           reid_len = len;
17268         }
17269       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17270                          &reid6, &len))
17271         {
17272           reid_type = 1;        /* ipv6 */
17273           reid_len = len;
17274         }
17275       else if (unformat (input, "reid %U", unformat_ethernet_address,
17276                          reid_mac))
17277         {
17278           reid_type = 2;        /* mac */
17279         }
17280       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17281                          &leid4, &len))
17282         {
17283           leid_type = 0;        /* ipv4 */
17284           leid_len = len;
17285         }
17286       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17287                          &leid6, &len))
17288         {
17289           leid_type = 1;        /* ipv6 */
17290           leid_len = len;
17291         }
17292       else if (unformat (input, "leid %U", unformat_ethernet_address,
17293                          leid_mac))
17294         {
17295           leid_type = 2;        /* mac */
17296         }
17297       else if (unformat (input, "vni %d", &vni))
17298         {
17299           ;
17300         }
17301       else
17302         {
17303           errmsg ("parse error '%U'", format_unformat_error, input);
17304           return -99;
17305         }
17306     }
17307
17308   if ((u8) ~ 0 == reid_type)
17309     {
17310       errmsg ("missing params!");
17311       return -99;
17312     }
17313
17314   if (leid_type != reid_type)
17315     {
17316       errmsg ("remote and local EIDs are of different types!");
17317       return -99;
17318     }
17319
17320   M (ONE_ADD_DEL_ADJACENCY, mp);
17321   mp->is_add = is_add;
17322   mp->vni = htonl (vni);
17323   mp->leid_len = leid_len;
17324   mp->reid_len = reid_len;
17325   mp->eid_type = reid_type;
17326
17327   switch (mp->eid_type)
17328     {
17329     case 0:
17330       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17331       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17332       break;
17333     case 1:
17334       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17335       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17336       break;
17337     case 2:
17338       clib_memcpy (mp->leid, leid_mac, 6);
17339       clib_memcpy (mp->reid, reid_mac, 6);
17340       break;
17341     default:
17342       errmsg ("unknown EID type %d!", mp->eid_type);
17343       return 0;
17344     }
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_adjacency api_one_add_del_adjacency
17355
17356 uword
17357 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17358 {
17359   u32 *mode = va_arg (*args, u32 *);
17360
17361   if (unformat (input, "lisp"))
17362     *mode = 0;
17363   else if (unformat (input, "vxlan"))
17364     *mode = 1;
17365   else
17366     return 0;
17367
17368   return 1;
17369 }
17370
17371 static int
17372 api_gpe_get_encap_mode (vat_main_t * vam)
17373 {
17374   vl_api_gpe_get_encap_mode_t *mp;
17375   int ret;
17376
17377   /* Construct the API message */
17378   M (GPE_GET_ENCAP_MODE, mp);
17379
17380   /* send it... */
17381   S (mp);
17382
17383   /* Wait for a reply... */
17384   W (ret);
17385   return ret;
17386 }
17387
17388 static int
17389 api_gpe_set_encap_mode (vat_main_t * vam)
17390 {
17391   unformat_input_t *input = vam->input;
17392   vl_api_gpe_set_encap_mode_t *mp;
17393   int ret;
17394   u32 mode = 0;
17395
17396   /* Parse args required to build the message */
17397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17398     {
17399       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17400         ;
17401       else
17402         break;
17403     }
17404
17405   /* Construct the API message */
17406   M (GPE_SET_ENCAP_MODE, mp);
17407
17408   mp->mode = mode;
17409
17410   /* send it... */
17411   S (mp);
17412
17413   /* Wait for a reply... */
17414   W (ret);
17415   return ret;
17416 }
17417
17418 static int
17419 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17420 {
17421   unformat_input_t *input = vam->input;
17422   vl_api_gpe_add_del_iface_t *mp;
17423   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17424   u32 dp_table = 0, vni = 0;
17425   int ret;
17426
17427   /* Parse args required to build the message */
17428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat (input, "up"))
17431         {
17432           action_set = 1;
17433           is_add = 1;
17434         }
17435       else if (unformat (input, "down"))
17436         {
17437           action_set = 1;
17438           is_add = 0;
17439         }
17440       else if (unformat (input, "table_id %d", &dp_table))
17441         {
17442           dp_table_set = 1;
17443         }
17444       else if (unformat (input, "bd_id %d", &dp_table))
17445         {
17446           dp_table_set = 1;
17447           is_l2 = 1;
17448         }
17449       else if (unformat (input, "vni %d", &vni))
17450         {
17451           vni_set = 1;
17452         }
17453       else
17454         break;
17455     }
17456
17457   if (action_set == 0)
17458     {
17459       errmsg ("Action not set");
17460       return -99;
17461     }
17462   if (dp_table_set == 0 || vni_set == 0)
17463     {
17464       errmsg ("vni and dp_table must be set");
17465       return -99;
17466     }
17467
17468   /* Construct the API message */
17469   M (GPE_ADD_DEL_IFACE, mp);
17470
17471   mp->is_add = is_add;
17472   mp->dp_table = clib_host_to_net_u32 (dp_table);
17473   mp->is_l2 = is_l2;
17474   mp->vni = clib_host_to_net_u32 (vni);
17475
17476   /* send it... */
17477   S (mp);
17478
17479   /* Wait for a reply... */
17480   W (ret);
17481   return ret;
17482 }
17483
17484 static int
17485 api_one_map_register_fallback_threshold (vat_main_t * vam)
17486 {
17487   unformat_input_t *input = vam->input;
17488   vl_api_one_map_register_fallback_threshold_t *mp;
17489   u32 value = 0;
17490   u8 is_set = 0;
17491   int ret;
17492
17493   /* Parse args required to build the message */
17494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17495     {
17496       if (unformat (input, "%u", &value))
17497         is_set = 1;
17498       else
17499         {
17500           clib_warning ("parse error '%U'", format_unformat_error, input);
17501           return -99;
17502         }
17503     }
17504
17505   if (!is_set)
17506     {
17507       errmsg ("fallback threshold value is missing!");
17508       return -99;
17509     }
17510
17511   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17512   mp->value = clib_host_to_net_u32 (value);
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 static int
17523 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17524 {
17525   vl_api_show_one_map_register_fallback_threshold_t *mp;
17526   int ret;
17527
17528   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17529
17530   /* send it... */
17531   S (mp);
17532
17533   /* Wait for a reply... */
17534   W (ret);
17535   return ret;
17536 }
17537
17538 uword
17539 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17540 {
17541   u32 *proto = va_arg (*args, u32 *);
17542
17543   if (unformat (input, "udp"))
17544     *proto = 1;
17545   else if (unformat (input, "api"))
17546     *proto = 2;
17547   else
17548     return 0;
17549
17550   return 1;
17551 }
17552
17553 static int
17554 api_one_set_transport_protocol (vat_main_t * vam)
17555 {
17556   unformat_input_t *input = vam->input;
17557   vl_api_one_set_transport_protocol_t *mp;
17558   u8 is_set = 0;
17559   u32 protocol = 0;
17560   int ret;
17561
17562   /* Parse args required to build the message */
17563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17564     {
17565       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17566         is_set = 1;
17567       else
17568         {
17569           clib_warning ("parse error '%U'", format_unformat_error, input);
17570           return -99;
17571         }
17572     }
17573
17574   if (!is_set)
17575     {
17576       errmsg ("Transport protocol missing!");
17577       return -99;
17578     }
17579
17580   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17581   mp->protocol = (u8) protocol;
17582
17583   /* send it... */
17584   S (mp);
17585
17586   /* Wait for a reply... */
17587   W (ret);
17588   return ret;
17589 }
17590
17591 static int
17592 api_one_get_transport_protocol (vat_main_t * vam)
17593 {
17594   vl_api_one_get_transport_protocol_t *mp;
17595   int ret;
17596
17597   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17598
17599   /* send it... */
17600   S (mp);
17601
17602   /* Wait for a reply... */
17603   W (ret);
17604   return ret;
17605 }
17606
17607 static int
17608 api_one_map_register_set_ttl (vat_main_t * vam)
17609 {
17610   unformat_input_t *input = vam->input;
17611   vl_api_one_map_register_set_ttl_t *mp;
17612   u32 ttl = 0;
17613   u8 is_set = 0;
17614   int ret;
17615
17616   /* Parse args required to build the message */
17617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17618     {
17619       if (unformat (input, "%u", &ttl))
17620         is_set = 1;
17621       else
17622         {
17623           clib_warning ("parse error '%U'", format_unformat_error, input);
17624           return -99;
17625         }
17626     }
17627
17628   if (!is_set)
17629     {
17630       errmsg ("TTL value missing!");
17631       return -99;
17632     }
17633
17634   M (ONE_MAP_REGISTER_SET_TTL, mp);
17635   mp->ttl = clib_host_to_net_u32 (ttl);
17636
17637   /* send it... */
17638   S (mp);
17639
17640   /* Wait for a reply... */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 static int
17646 api_show_one_map_register_ttl (vat_main_t * vam)
17647 {
17648   vl_api_show_one_map_register_ttl_t *mp;
17649   int ret;
17650
17651   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17652
17653   /* send it... */
17654   S (mp);
17655
17656   /* Wait for a reply... */
17657   W (ret);
17658   return ret;
17659 }
17660
17661 /**
17662  * Add/del map request itr rlocs from ONE control plane and updates
17663  *
17664  * @param vam vpp API test context
17665  * @return return code
17666  */
17667 static int
17668 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17669 {
17670   unformat_input_t *input = vam->input;
17671   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17672   u8 *locator_set_name = 0;
17673   u8 locator_set_name_set = 0;
17674   u8 is_add = 1;
17675   int ret;
17676
17677   /* Parse args required to build the message */
17678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17679     {
17680       if (unformat (input, "del"))
17681         {
17682           is_add = 0;
17683         }
17684       else if (unformat (input, "%_%v%_", &locator_set_name))
17685         {
17686           locator_set_name_set = 1;
17687         }
17688       else
17689         {
17690           clib_warning ("parse error '%U'", format_unformat_error, input);
17691           return -99;
17692         }
17693     }
17694
17695   if (is_add && !locator_set_name_set)
17696     {
17697       errmsg ("itr-rloc is not set!");
17698       return -99;
17699     }
17700
17701   if (is_add && vec_len (locator_set_name) > 64)
17702     {
17703       errmsg ("itr-rloc locator-set name too long");
17704       vec_free (locator_set_name);
17705       return -99;
17706     }
17707
17708   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17709   mp->is_add = is_add;
17710   if (is_add)
17711     {
17712       clib_memcpy (mp->locator_set_name, locator_set_name,
17713                    vec_len (locator_set_name));
17714     }
17715   else
17716     {
17717       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17718     }
17719   vec_free (locator_set_name);
17720
17721   /* send it... */
17722   S (mp);
17723
17724   /* Wait for a reply... */
17725   W (ret);
17726   return ret;
17727 }
17728
17729 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17730
17731 static int
17732 api_one_locator_dump (vat_main_t * vam)
17733 {
17734   unformat_input_t *input = vam->input;
17735   vl_api_one_locator_dump_t *mp;
17736   vl_api_control_ping_t *mp_ping;
17737   u8 is_index_set = 0, is_name_set = 0;
17738   u8 *ls_name = 0;
17739   u32 ls_index = ~0;
17740   int ret;
17741
17742   /* Parse args required to build the message */
17743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17744     {
17745       if (unformat (input, "ls_name %_%v%_", &ls_name))
17746         {
17747           is_name_set = 1;
17748         }
17749       else if (unformat (input, "ls_index %d", &ls_index))
17750         {
17751           is_index_set = 1;
17752         }
17753       else
17754         {
17755           errmsg ("parse error '%U'", format_unformat_error, input);
17756           return -99;
17757         }
17758     }
17759
17760   if (!is_index_set && !is_name_set)
17761     {
17762       errmsg ("error: expected one of index or name!");
17763       return -99;
17764     }
17765
17766   if (is_index_set && is_name_set)
17767     {
17768       errmsg ("error: only one param expected!");
17769       return -99;
17770     }
17771
17772   if (vec_len (ls_name) > 62)
17773     {
17774       errmsg ("error: locator set name too long!");
17775       return -99;
17776     }
17777
17778   if (!vam->json_output)
17779     {
17780       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17781     }
17782
17783   M (ONE_LOCATOR_DUMP, mp);
17784   mp->is_index_set = is_index_set;
17785
17786   if (is_index_set)
17787     mp->ls_index = clib_host_to_net_u32 (ls_index);
17788   else
17789     {
17790       vec_add1 (ls_name, 0);
17791       strncpy ((char *) mp->ls_name, (char *) ls_name,
17792                sizeof (mp->ls_name) - 1);
17793     }
17794
17795   /* send it... */
17796   S (mp);
17797
17798   /* Use a control ping for synchronization */
17799   MPING (CONTROL_PING, mp_ping);
17800   S (mp_ping);
17801
17802   /* Wait for a reply... */
17803   W (ret);
17804   return ret;
17805 }
17806
17807 #define api_lisp_locator_dump api_one_locator_dump
17808
17809 static int
17810 api_one_locator_set_dump (vat_main_t * vam)
17811 {
17812   vl_api_one_locator_set_dump_t *mp;
17813   vl_api_control_ping_t *mp_ping;
17814   unformat_input_t *input = vam->input;
17815   u8 filter = 0;
17816   int ret;
17817
17818   /* Parse args required to build the message */
17819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17820     {
17821       if (unformat (input, "local"))
17822         {
17823           filter = 1;
17824         }
17825       else if (unformat (input, "remote"))
17826         {
17827           filter = 2;
17828         }
17829       else
17830         {
17831           errmsg ("parse error '%U'", format_unformat_error, input);
17832           return -99;
17833         }
17834     }
17835
17836   if (!vam->json_output)
17837     {
17838       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17839     }
17840
17841   M (ONE_LOCATOR_SET_DUMP, mp);
17842
17843   mp->filter = filter;
17844
17845   /* send it... */
17846   S (mp);
17847
17848   /* Use a control ping for synchronization */
17849   MPING (CONTROL_PING, mp_ping);
17850   S (mp_ping);
17851
17852   /* Wait for a reply... */
17853   W (ret);
17854   return ret;
17855 }
17856
17857 #define api_lisp_locator_set_dump api_one_locator_set_dump
17858
17859 static int
17860 api_one_eid_table_map_dump (vat_main_t * vam)
17861 {
17862   u8 is_l2 = 0;
17863   u8 mode_set = 0;
17864   unformat_input_t *input = vam->input;
17865   vl_api_one_eid_table_map_dump_t *mp;
17866   vl_api_control_ping_t *mp_ping;
17867   int ret;
17868
17869   /* Parse args required to build the message */
17870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17871     {
17872       if (unformat (input, "l2"))
17873         {
17874           is_l2 = 1;
17875           mode_set = 1;
17876         }
17877       else if (unformat (input, "l3"))
17878         {
17879           is_l2 = 0;
17880           mode_set = 1;
17881         }
17882       else
17883         {
17884           errmsg ("parse error '%U'", format_unformat_error, input);
17885           return -99;
17886         }
17887     }
17888
17889   if (!mode_set)
17890     {
17891       errmsg ("expected one of 'l2' or 'l3' parameter!");
17892       return -99;
17893     }
17894
17895   if (!vam->json_output)
17896     {
17897       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17898     }
17899
17900   M (ONE_EID_TABLE_MAP_DUMP, mp);
17901   mp->is_l2 = is_l2;
17902
17903   /* send it... */
17904   S (mp);
17905
17906   /* Use a control ping for synchronization */
17907   MPING (CONTROL_PING, mp_ping);
17908   S (mp_ping);
17909
17910   /* Wait for a reply... */
17911   W (ret);
17912   return ret;
17913 }
17914
17915 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17916
17917 static int
17918 api_one_eid_table_vni_dump (vat_main_t * vam)
17919 {
17920   vl_api_one_eid_table_vni_dump_t *mp;
17921   vl_api_control_ping_t *mp_ping;
17922   int ret;
17923
17924   if (!vam->json_output)
17925     {
17926       print (vam->ofp, "VNI");
17927     }
17928
17929   M (ONE_EID_TABLE_VNI_DUMP, mp);
17930
17931   /* send it... */
17932   S (mp);
17933
17934   /* Use a control ping for synchronization */
17935   MPING (CONTROL_PING, mp_ping);
17936   S (mp_ping);
17937
17938   /* Wait for a reply... */
17939   W (ret);
17940   return ret;
17941 }
17942
17943 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17944
17945 static int
17946 api_one_eid_table_dump (vat_main_t * vam)
17947 {
17948   unformat_input_t *i = vam->input;
17949   vl_api_one_eid_table_dump_t *mp;
17950   vl_api_control_ping_t *mp_ping;
17951   struct in_addr ip4;
17952   struct in6_addr ip6;
17953   u8 mac[6];
17954   u8 eid_type = ~0, eid_set = 0;
17955   u32 prefix_length = ~0, t, vni = 0;
17956   u8 filter = 0;
17957   int ret;
17958   lisp_nsh_api_t nsh;
17959
17960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17961     {
17962       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17963         {
17964           eid_set = 1;
17965           eid_type = 0;
17966           prefix_length = t;
17967         }
17968       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17969         {
17970           eid_set = 1;
17971           eid_type = 1;
17972           prefix_length = t;
17973         }
17974       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17975         {
17976           eid_set = 1;
17977           eid_type = 2;
17978         }
17979       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17980         {
17981           eid_set = 1;
17982           eid_type = 3;
17983         }
17984       else if (unformat (i, "vni %d", &t))
17985         {
17986           vni = t;
17987         }
17988       else if (unformat (i, "local"))
17989         {
17990           filter = 1;
17991         }
17992       else if (unformat (i, "remote"))
17993         {
17994           filter = 2;
17995         }
17996       else
17997         {
17998           errmsg ("parse error '%U'", format_unformat_error, i);
17999           return -99;
18000         }
18001     }
18002
18003   if (!vam->json_output)
18004     {
18005       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18006              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18007     }
18008
18009   M (ONE_EID_TABLE_DUMP, mp);
18010
18011   mp->filter = filter;
18012   if (eid_set)
18013     {
18014       mp->eid_set = 1;
18015       mp->vni = htonl (vni);
18016       mp->eid_type = eid_type;
18017       switch (eid_type)
18018         {
18019         case 0:
18020           mp->prefix_length = prefix_length;
18021           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18022           break;
18023         case 1:
18024           mp->prefix_length = prefix_length;
18025           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18026           break;
18027         case 2:
18028           clib_memcpy (mp->eid, mac, sizeof (mac));
18029           break;
18030         case 3:
18031           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18032           break;
18033         default:
18034           errmsg ("unknown EID type %d!", eid_type);
18035           return -99;
18036         }
18037     }
18038
18039   /* send it... */
18040   S (mp);
18041
18042   /* Use a control ping for synchronization */
18043   MPING (CONTROL_PING, mp_ping);
18044   S (mp_ping);
18045
18046   /* Wait for a reply... */
18047   W (ret);
18048   return ret;
18049 }
18050
18051 #define api_lisp_eid_table_dump api_one_eid_table_dump
18052
18053 static int
18054 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18055 {
18056   unformat_input_t *i = vam->input;
18057   vl_api_gpe_fwd_entries_get_t *mp;
18058   u8 vni_set = 0;
18059   u32 vni = ~0;
18060   int ret;
18061
18062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18063     {
18064       if (unformat (i, "vni %d", &vni))
18065         {
18066           vni_set = 1;
18067         }
18068       else
18069         {
18070           errmsg ("parse error '%U'", format_unformat_error, i);
18071           return -99;
18072         }
18073     }
18074
18075   if (!vni_set)
18076     {
18077       errmsg ("vni not set!");
18078       return -99;
18079     }
18080
18081   if (!vam->json_output)
18082     {
18083       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18084              "leid", "reid");
18085     }
18086
18087   M (GPE_FWD_ENTRIES_GET, mp);
18088   mp->vni = clib_host_to_net_u32 (vni);
18089
18090   /* send it... */
18091   S (mp);
18092
18093   /* Wait for a reply... */
18094   W (ret);
18095   return ret;
18096 }
18097
18098 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18099 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18100 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18101 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18102 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18103 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18104 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18105 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18106
18107 static int
18108 api_one_adjacencies_get (vat_main_t * vam)
18109 {
18110   unformat_input_t *i = vam->input;
18111   vl_api_one_adjacencies_get_t *mp;
18112   u8 vni_set = 0;
18113   u32 vni = ~0;
18114   int ret;
18115
18116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18117     {
18118       if (unformat (i, "vni %d", &vni))
18119         {
18120           vni_set = 1;
18121         }
18122       else
18123         {
18124           errmsg ("parse error '%U'", format_unformat_error, i);
18125           return -99;
18126         }
18127     }
18128
18129   if (!vni_set)
18130     {
18131       errmsg ("vni not set!");
18132       return -99;
18133     }
18134
18135   if (!vam->json_output)
18136     {
18137       print (vam->ofp, "%s %40s", "leid", "reid");
18138     }
18139
18140   M (ONE_ADJACENCIES_GET, mp);
18141   mp->vni = clib_host_to_net_u32 (vni);
18142
18143   /* send it... */
18144   S (mp);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 #define api_lisp_adjacencies_get api_one_adjacencies_get
18152
18153 static int
18154 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18155 {
18156   unformat_input_t *i = vam->input;
18157   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18158   int ret;
18159   u8 ip_family_set = 0, is_ip4 = 1;
18160
18161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18162     {
18163       if (unformat (i, "ip4"))
18164         {
18165           ip_family_set = 1;
18166           is_ip4 = 1;
18167         }
18168       else if (unformat (i, "ip6"))
18169         {
18170           ip_family_set = 1;
18171           is_ip4 = 0;
18172         }
18173       else
18174         {
18175           errmsg ("parse error '%U'", format_unformat_error, i);
18176           return -99;
18177         }
18178     }
18179
18180   if (!ip_family_set)
18181     {
18182       errmsg ("ip family not set!");
18183       return -99;
18184     }
18185
18186   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18187   mp->is_ip4 = is_ip4;
18188
18189   /* send it... */
18190   S (mp);
18191
18192   /* Wait for a reply... */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18199 {
18200   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18201   int ret;
18202
18203   if (!vam->json_output)
18204     {
18205       print (vam->ofp, "VNIs");
18206     }
18207
18208   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18209
18210   /* send it... */
18211   S (mp);
18212
18213   /* Wait for a reply... */
18214   W (ret);
18215   return ret;
18216 }
18217
18218 static int
18219 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18220 {
18221   unformat_input_t *i = vam->input;
18222   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18223   int ret = 0;
18224   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18225   struct in_addr ip4;
18226   struct in6_addr ip6;
18227   u32 table_id = 0, nh_sw_if_index = ~0;
18228
18229   clib_memset (&ip4, 0, sizeof (ip4));
18230   clib_memset (&ip6, 0, sizeof (ip6));
18231
18232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18233     {
18234       if (unformat (i, "del"))
18235         is_add = 0;
18236       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18237                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18238         {
18239           ip_set = 1;
18240           is_ip4 = 1;
18241         }
18242       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18243                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18244         {
18245           ip_set = 1;
18246           is_ip4 = 0;
18247         }
18248       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18249         {
18250           ip_set = 1;
18251           is_ip4 = 1;
18252           nh_sw_if_index = ~0;
18253         }
18254       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18255         {
18256           ip_set = 1;
18257           is_ip4 = 0;
18258           nh_sw_if_index = ~0;
18259         }
18260       else if (unformat (i, "table %d", &table_id))
18261         ;
18262       else
18263         {
18264           errmsg ("parse error '%U'", format_unformat_error, i);
18265           return -99;
18266         }
18267     }
18268
18269   if (!ip_set)
18270     {
18271       errmsg ("nh addr not set!");
18272       return -99;
18273     }
18274
18275   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18276   mp->is_add = is_add;
18277   mp->table_id = clib_host_to_net_u32 (table_id);
18278   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18279   mp->is_ip4 = is_ip4;
18280   if (is_ip4)
18281     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18282   else
18283     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18284
18285   /* send it... */
18286   S (mp);
18287
18288   /* Wait for a reply... */
18289   W (ret);
18290   return ret;
18291 }
18292
18293 static int
18294 api_one_map_server_dump (vat_main_t * vam)
18295 {
18296   vl_api_one_map_server_dump_t *mp;
18297   vl_api_control_ping_t *mp_ping;
18298   int ret;
18299
18300   if (!vam->json_output)
18301     {
18302       print (vam->ofp, "%=20s", "Map server");
18303     }
18304
18305   M (ONE_MAP_SERVER_DUMP, mp);
18306   /* send it... */
18307   S (mp);
18308
18309   /* Use a control ping for synchronization */
18310   MPING (CONTROL_PING, mp_ping);
18311   S (mp_ping);
18312
18313   /* Wait for a reply... */
18314   W (ret);
18315   return ret;
18316 }
18317
18318 #define api_lisp_map_server_dump api_one_map_server_dump
18319
18320 static int
18321 api_one_map_resolver_dump (vat_main_t * vam)
18322 {
18323   vl_api_one_map_resolver_dump_t *mp;
18324   vl_api_control_ping_t *mp_ping;
18325   int ret;
18326
18327   if (!vam->json_output)
18328     {
18329       print (vam->ofp, "%=20s", "Map resolver");
18330     }
18331
18332   M (ONE_MAP_RESOLVER_DUMP, mp);
18333   /* send it... */
18334   S (mp);
18335
18336   /* Use a control ping for synchronization */
18337   MPING (CONTROL_PING, mp_ping);
18338   S (mp_ping);
18339
18340   /* Wait for a reply... */
18341   W (ret);
18342   return ret;
18343 }
18344
18345 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18346
18347 static int
18348 api_one_stats_flush (vat_main_t * vam)
18349 {
18350   vl_api_one_stats_flush_t *mp;
18351   int ret = 0;
18352
18353   M (ONE_STATS_FLUSH, mp);
18354   S (mp);
18355   W (ret);
18356   return ret;
18357 }
18358
18359 static int
18360 api_one_stats_dump (vat_main_t * vam)
18361 {
18362   vl_api_one_stats_dump_t *mp;
18363   vl_api_control_ping_t *mp_ping;
18364   int ret;
18365
18366   M (ONE_STATS_DUMP, mp);
18367   /* send it... */
18368   S (mp);
18369
18370   /* Use a control ping for synchronization */
18371   MPING (CONTROL_PING, mp_ping);
18372   S (mp_ping);
18373
18374   /* Wait for a reply... */
18375   W (ret);
18376   return ret;
18377 }
18378
18379 static int
18380 api_show_one_status (vat_main_t * vam)
18381 {
18382   vl_api_show_one_status_t *mp;
18383   int ret;
18384
18385   if (!vam->json_output)
18386     {
18387       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18388     }
18389
18390   M (SHOW_ONE_STATUS, mp);
18391   /* send it... */
18392   S (mp);
18393   /* Wait for a reply... */
18394   W (ret);
18395   return ret;
18396 }
18397
18398 #define api_show_lisp_status api_show_one_status
18399
18400 static int
18401 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18402 {
18403   vl_api_gpe_fwd_entry_path_dump_t *mp;
18404   vl_api_control_ping_t *mp_ping;
18405   unformat_input_t *i = vam->input;
18406   u32 fwd_entry_index = ~0;
18407   int ret;
18408
18409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18410     {
18411       if (unformat (i, "index %d", &fwd_entry_index))
18412         ;
18413       else
18414         break;
18415     }
18416
18417   if (~0 == fwd_entry_index)
18418     {
18419       errmsg ("no index specified!");
18420       return -99;
18421     }
18422
18423   if (!vam->json_output)
18424     {
18425       print (vam->ofp, "first line");
18426     }
18427
18428   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18429
18430   /* send it... */
18431   S (mp);
18432   /* Use a control ping for synchronization */
18433   MPING (CONTROL_PING, mp_ping);
18434   S (mp_ping);
18435
18436   /* Wait for a reply... */
18437   W (ret);
18438   return ret;
18439 }
18440
18441 static int
18442 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18443 {
18444   vl_api_one_get_map_request_itr_rlocs_t *mp;
18445   int ret;
18446
18447   if (!vam->json_output)
18448     {
18449       print (vam->ofp, "%=20s", "itr-rlocs:");
18450     }
18451
18452   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18453   /* send it... */
18454   S (mp);
18455   /* Wait for a reply... */
18456   W (ret);
18457   return ret;
18458 }
18459
18460 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18461
18462 static int
18463 api_af_packet_create (vat_main_t * vam)
18464 {
18465   unformat_input_t *i = vam->input;
18466   vl_api_af_packet_create_t *mp;
18467   u8 *host_if_name = 0;
18468   u8 hw_addr[6];
18469   u8 random_hw_addr = 1;
18470   int ret;
18471
18472   clib_memset (hw_addr, 0, sizeof (hw_addr));
18473
18474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18475     {
18476       if (unformat (i, "name %s", &host_if_name))
18477         vec_add1 (host_if_name, 0);
18478       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18479         random_hw_addr = 0;
18480       else
18481         break;
18482     }
18483
18484   if (!vec_len (host_if_name))
18485     {
18486       errmsg ("host-interface name must be specified");
18487       return -99;
18488     }
18489
18490   if (vec_len (host_if_name) > 64)
18491     {
18492       errmsg ("host-interface name too long");
18493       return -99;
18494     }
18495
18496   M (AF_PACKET_CREATE, mp);
18497
18498   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18499   clib_memcpy (mp->hw_addr, hw_addr, 6);
18500   mp->use_random_hw_addr = random_hw_addr;
18501   vec_free (host_if_name);
18502
18503   S (mp);
18504
18505   /* *INDENT-OFF* */
18506   W2 (ret,
18507       ({
18508         if (ret == 0)
18509           fprintf (vam->ofp ? vam->ofp : stderr,
18510                    " new sw_if_index = %d\n", vam->sw_if_index);
18511       }));
18512   /* *INDENT-ON* */
18513   return ret;
18514 }
18515
18516 static int
18517 api_af_packet_delete (vat_main_t * vam)
18518 {
18519   unformat_input_t *i = vam->input;
18520   vl_api_af_packet_delete_t *mp;
18521   u8 *host_if_name = 0;
18522   int ret;
18523
18524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18525     {
18526       if (unformat (i, "name %s", &host_if_name))
18527         vec_add1 (host_if_name, 0);
18528       else
18529         break;
18530     }
18531
18532   if (!vec_len (host_if_name))
18533     {
18534       errmsg ("host-interface name must be specified");
18535       return -99;
18536     }
18537
18538   if (vec_len (host_if_name) > 64)
18539     {
18540       errmsg ("host-interface name too long");
18541       return -99;
18542     }
18543
18544   M (AF_PACKET_DELETE, mp);
18545
18546   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18547   vec_free (host_if_name);
18548
18549   S (mp);
18550   W (ret);
18551   return ret;
18552 }
18553
18554 static void vl_api_af_packet_details_t_handler
18555   (vl_api_af_packet_details_t * mp)
18556 {
18557   vat_main_t *vam = &vat_main;
18558
18559   print (vam->ofp, "%-16s %d",
18560          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18561 }
18562
18563 static void vl_api_af_packet_details_t_handler_json
18564   (vl_api_af_packet_details_t * mp)
18565 {
18566   vat_main_t *vam = &vat_main;
18567   vat_json_node_t *node = NULL;
18568
18569   if (VAT_JSON_ARRAY != vam->json_tree.type)
18570     {
18571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18572       vat_json_init_array (&vam->json_tree);
18573     }
18574   node = vat_json_array_add (&vam->json_tree);
18575
18576   vat_json_init_object (node);
18577   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18578   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18579 }
18580
18581 static int
18582 api_af_packet_dump (vat_main_t * vam)
18583 {
18584   vl_api_af_packet_dump_t *mp;
18585   vl_api_control_ping_t *mp_ping;
18586   int ret;
18587
18588   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18589   /* Get list of tap interfaces */
18590   M (AF_PACKET_DUMP, mp);
18591   S (mp);
18592
18593   /* Use a control ping for synchronization */
18594   MPING (CONTROL_PING, mp_ping);
18595   S (mp_ping);
18596
18597   W (ret);
18598   return ret;
18599 }
18600
18601 static int
18602 api_policer_add_del (vat_main_t * vam)
18603 {
18604   unformat_input_t *i = vam->input;
18605   vl_api_policer_add_del_t *mp;
18606   u8 is_add = 1;
18607   u8 *name = 0;
18608   u32 cir = 0;
18609   u32 eir = 0;
18610   u64 cb = 0;
18611   u64 eb = 0;
18612   u8 rate_type = 0;
18613   u8 round_type = 0;
18614   u8 type = 0;
18615   u8 color_aware = 0;
18616   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18617   int ret;
18618
18619   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18620   conform_action.dscp = 0;
18621   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18622   exceed_action.dscp = 0;
18623   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18624   violate_action.dscp = 0;
18625
18626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (i, "del"))
18629         is_add = 0;
18630       else if (unformat (i, "name %s", &name))
18631         vec_add1 (name, 0);
18632       else if (unformat (i, "cir %u", &cir))
18633         ;
18634       else if (unformat (i, "eir %u", &eir))
18635         ;
18636       else if (unformat (i, "cb %u", &cb))
18637         ;
18638       else if (unformat (i, "eb %u", &eb))
18639         ;
18640       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18641                          &rate_type))
18642         ;
18643       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18644                          &round_type))
18645         ;
18646       else if (unformat (i, "type %U", unformat_policer_type, &type))
18647         ;
18648       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18649                          &conform_action))
18650         ;
18651       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18652                          &exceed_action))
18653         ;
18654       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18655                          &violate_action))
18656         ;
18657       else if (unformat (i, "color-aware"))
18658         color_aware = 1;
18659       else
18660         break;
18661     }
18662
18663   if (!vec_len (name))
18664     {
18665       errmsg ("policer name must be specified");
18666       return -99;
18667     }
18668
18669   if (vec_len (name) > 64)
18670     {
18671       errmsg ("policer name too long");
18672       return -99;
18673     }
18674
18675   M (POLICER_ADD_DEL, mp);
18676
18677   clib_memcpy (mp->name, name, vec_len (name));
18678   vec_free (name);
18679   mp->is_add = is_add;
18680   mp->cir = ntohl (cir);
18681   mp->eir = ntohl (eir);
18682   mp->cb = clib_net_to_host_u64 (cb);
18683   mp->eb = clib_net_to_host_u64 (eb);
18684   mp->rate_type = rate_type;
18685   mp->round_type = round_type;
18686   mp->type = type;
18687   mp->conform_action_type = conform_action.action_type;
18688   mp->conform_dscp = conform_action.dscp;
18689   mp->exceed_action_type = exceed_action.action_type;
18690   mp->exceed_dscp = exceed_action.dscp;
18691   mp->violate_action_type = violate_action.action_type;
18692   mp->violate_dscp = violate_action.dscp;
18693   mp->color_aware = color_aware;
18694
18695   S (mp);
18696   W (ret);
18697   return ret;
18698 }
18699
18700 static int
18701 api_policer_dump (vat_main_t * vam)
18702 {
18703   unformat_input_t *i = vam->input;
18704   vl_api_policer_dump_t *mp;
18705   vl_api_control_ping_t *mp_ping;
18706   u8 *match_name = 0;
18707   u8 match_name_valid = 0;
18708   int ret;
18709
18710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18711     {
18712       if (unformat (i, "name %s", &match_name))
18713         {
18714           vec_add1 (match_name, 0);
18715           match_name_valid = 1;
18716         }
18717       else
18718         break;
18719     }
18720
18721   M (POLICER_DUMP, mp);
18722   mp->match_name_valid = match_name_valid;
18723   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18724   vec_free (match_name);
18725   /* send it... */
18726   S (mp);
18727
18728   /* Use a control ping for synchronization */
18729   MPING (CONTROL_PING, mp_ping);
18730   S (mp_ping);
18731
18732   /* Wait for a reply... */
18733   W (ret);
18734   return ret;
18735 }
18736
18737 static int
18738 api_policer_classify_set_interface (vat_main_t * vam)
18739 {
18740   unformat_input_t *i = vam->input;
18741   vl_api_policer_classify_set_interface_t *mp;
18742   u32 sw_if_index;
18743   int sw_if_index_set;
18744   u32 ip4_table_index = ~0;
18745   u32 ip6_table_index = ~0;
18746   u32 l2_table_index = ~0;
18747   u8 is_add = 1;
18748   int ret;
18749
18750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18753         sw_if_index_set = 1;
18754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18755         sw_if_index_set = 1;
18756       else if (unformat (i, "del"))
18757         is_add = 0;
18758       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18759         ;
18760       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18761         ;
18762       else if (unformat (i, "l2-table %d", &l2_table_index))
18763         ;
18764       else
18765         {
18766           clib_warning ("parse error '%U'", format_unformat_error, i);
18767           return -99;
18768         }
18769     }
18770
18771   if (sw_if_index_set == 0)
18772     {
18773       errmsg ("missing interface name or sw_if_index");
18774       return -99;
18775     }
18776
18777   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18778
18779   mp->sw_if_index = ntohl (sw_if_index);
18780   mp->ip4_table_index = ntohl (ip4_table_index);
18781   mp->ip6_table_index = ntohl (ip6_table_index);
18782   mp->l2_table_index = ntohl (l2_table_index);
18783   mp->is_add = is_add;
18784
18785   S (mp);
18786   W (ret);
18787   return ret;
18788 }
18789
18790 static int
18791 api_policer_classify_dump (vat_main_t * vam)
18792 {
18793   unformat_input_t *i = vam->input;
18794   vl_api_policer_classify_dump_t *mp;
18795   vl_api_control_ping_t *mp_ping;
18796   u8 type = POLICER_CLASSIFY_N_TABLES;
18797   int ret;
18798
18799   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18800     ;
18801   else
18802     {
18803       errmsg ("classify table type must be specified");
18804       return -99;
18805     }
18806
18807   if (!vam->json_output)
18808     {
18809       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18810     }
18811
18812   M (POLICER_CLASSIFY_DUMP, mp);
18813   mp->type = type;
18814   /* send it... */
18815   S (mp);
18816
18817   /* Use a control ping for synchronization */
18818   MPING (CONTROL_PING, mp_ping);
18819   S (mp_ping);
18820
18821   /* Wait for a reply... */
18822   W (ret);
18823   return ret;
18824 }
18825
18826 static int
18827 api_netmap_create (vat_main_t * vam)
18828 {
18829   unformat_input_t *i = vam->input;
18830   vl_api_netmap_create_t *mp;
18831   u8 *if_name = 0;
18832   u8 hw_addr[6];
18833   u8 random_hw_addr = 1;
18834   u8 is_pipe = 0;
18835   u8 is_master = 0;
18836   int ret;
18837
18838   clib_memset (hw_addr, 0, sizeof (hw_addr));
18839
18840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (i, "name %s", &if_name))
18843         vec_add1 (if_name, 0);
18844       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18845         random_hw_addr = 0;
18846       else if (unformat (i, "pipe"))
18847         is_pipe = 1;
18848       else if (unformat (i, "master"))
18849         is_master = 1;
18850       else if (unformat (i, "slave"))
18851         is_master = 0;
18852       else
18853         break;
18854     }
18855
18856   if (!vec_len (if_name))
18857     {
18858       errmsg ("interface name must be specified");
18859       return -99;
18860     }
18861
18862   if (vec_len (if_name) > 64)
18863     {
18864       errmsg ("interface name too long");
18865       return -99;
18866     }
18867
18868   M (NETMAP_CREATE, mp);
18869
18870   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18871   clib_memcpy (mp->hw_addr, hw_addr, 6);
18872   mp->use_random_hw_addr = random_hw_addr;
18873   mp->is_pipe = is_pipe;
18874   mp->is_master = is_master;
18875   vec_free (if_name);
18876
18877   S (mp);
18878   W (ret);
18879   return ret;
18880 }
18881
18882 static int
18883 api_netmap_delete (vat_main_t * vam)
18884 {
18885   unformat_input_t *i = vam->input;
18886   vl_api_netmap_delete_t *mp;
18887   u8 *if_name = 0;
18888   int ret;
18889
18890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18891     {
18892       if (unformat (i, "name %s", &if_name))
18893         vec_add1 (if_name, 0);
18894       else
18895         break;
18896     }
18897
18898   if (!vec_len (if_name))
18899     {
18900       errmsg ("interface name must be specified");
18901       return -99;
18902     }
18903
18904   if (vec_len (if_name) > 64)
18905     {
18906       errmsg ("interface name too long");
18907       return -99;
18908     }
18909
18910   M (NETMAP_DELETE, mp);
18911
18912   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18913   vec_free (if_name);
18914
18915   S (mp);
18916   W (ret);
18917   return ret;
18918 }
18919
18920 static void
18921 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18922 {
18923   if (fp->afi == IP46_TYPE_IP6)
18924     print (vam->ofp,
18925            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18926            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18927            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18928            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18929            format_ip6_address, fp->next_hop);
18930   else if (fp->afi == IP46_TYPE_IP4)
18931     print (vam->ofp,
18932            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18933            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18934            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18935            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18936            format_ip4_address, fp->next_hop);
18937 }
18938
18939 static void
18940 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18941                                  vl_api_fib_path_t * fp)
18942 {
18943   struct in_addr ip4;
18944   struct in6_addr ip6;
18945
18946   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18947   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18948   vat_json_object_add_uint (node, "is_local", fp->is_local);
18949   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18950   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18951   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18952   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18953   if (fp->afi == IP46_TYPE_IP4)
18954     {
18955       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18956       vat_json_object_add_ip4 (node, "next_hop", ip4);
18957     }
18958   else if (fp->afi == IP46_TYPE_IP6)
18959     {
18960       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18961       vat_json_object_add_ip6 (node, "next_hop", ip6);
18962     }
18963 }
18964
18965 static void
18966 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18967 {
18968   vat_main_t *vam = &vat_main;
18969   int count = ntohl (mp->mt_count);
18970   vl_api_fib_path_t *fp;
18971   i32 i;
18972
18973   print (vam->ofp, "[%d]: sw_if_index %d via:",
18974          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18975   fp = mp->mt_paths;
18976   for (i = 0; i < count; i++)
18977     {
18978       vl_api_mpls_fib_path_print (vam, fp);
18979       fp++;
18980     }
18981
18982   print (vam->ofp, "");
18983 }
18984
18985 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18986 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18987
18988 static void
18989 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18990 {
18991   vat_main_t *vam = &vat_main;
18992   vat_json_node_t *node = NULL;
18993   int count = ntohl (mp->mt_count);
18994   vl_api_fib_path_t *fp;
18995   i32 i;
18996
18997   if (VAT_JSON_ARRAY != vam->json_tree.type)
18998     {
18999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19000       vat_json_init_array (&vam->json_tree);
19001     }
19002   node = vat_json_array_add (&vam->json_tree);
19003
19004   vat_json_init_object (node);
19005   vat_json_object_add_uint (node, "tunnel_index",
19006                             ntohl (mp->mt_tunnel_index));
19007   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19008
19009   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19010
19011   fp = mp->mt_paths;
19012   for (i = 0; i < count; i++)
19013     {
19014       vl_api_mpls_fib_path_json_print (node, fp);
19015       fp++;
19016     }
19017 }
19018
19019 static int
19020 api_mpls_tunnel_dump (vat_main_t * vam)
19021 {
19022   vl_api_mpls_tunnel_dump_t *mp;
19023   vl_api_control_ping_t *mp_ping;
19024   u32 sw_if_index = ~0;
19025   int ret;
19026
19027   /* Parse args required to build the message */
19028   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19029     {
19030       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19031         ;
19032     }
19033
19034   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19035
19036   M (MPLS_TUNNEL_DUMP, mp);
19037   mp->sw_if_index = htonl (sw_if_index);
19038   S (mp);
19039
19040   /* Use a control ping for synchronization */
19041   MPING (CONTROL_PING, mp_ping);
19042   S (mp_ping);
19043
19044   W (ret);
19045   return ret;
19046 }
19047
19048 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19049 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19050
19051
19052 static void
19053 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19054 {
19055   vat_main_t *vam = &vat_main;
19056   int count = ntohl (mp->count);
19057   vl_api_fib_path_t *fp;
19058   int i;
19059
19060   print (vam->ofp,
19061          "table-id %d, label %u, ess_bit %u",
19062          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19063   fp = mp->path;
19064   for (i = 0; i < count; i++)
19065     {
19066       vl_api_mpls_fib_path_print (vam, fp);
19067       fp++;
19068     }
19069 }
19070
19071 static void vl_api_mpls_fib_details_t_handler_json
19072   (vl_api_mpls_fib_details_t * mp)
19073 {
19074   vat_main_t *vam = &vat_main;
19075   int count = ntohl (mp->count);
19076   vat_json_node_t *node = NULL;
19077   vl_api_fib_path_t *fp;
19078   int i;
19079
19080   if (VAT_JSON_ARRAY != vam->json_tree.type)
19081     {
19082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19083       vat_json_init_array (&vam->json_tree);
19084     }
19085   node = vat_json_array_add (&vam->json_tree);
19086
19087   vat_json_init_object (node);
19088   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19089   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19090   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19091   vat_json_object_add_uint (node, "path_count", count);
19092   fp = mp->path;
19093   for (i = 0; i < count; i++)
19094     {
19095       vl_api_mpls_fib_path_json_print (node, fp);
19096       fp++;
19097     }
19098 }
19099
19100 static int
19101 api_mpls_fib_dump (vat_main_t * vam)
19102 {
19103   vl_api_mpls_fib_dump_t *mp;
19104   vl_api_control_ping_t *mp_ping;
19105   int ret;
19106
19107   M (MPLS_FIB_DUMP, mp);
19108   S (mp);
19109
19110   /* Use a control ping for synchronization */
19111   MPING (CONTROL_PING, mp_ping);
19112   S (mp_ping);
19113
19114   W (ret);
19115   return ret;
19116 }
19117
19118 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19119 #define vl_api_ip_fib_details_t_print vl_noop_handler
19120
19121 static void
19122 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19123 {
19124   vat_main_t *vam = &vat_main;
19125   int count = ntohl (mp->count);
19126   vl_api_fib_path_t *fp;
19127   int i;
19128
19129   print (vam->ofp,
19130          "table-id %d, prefix %U/%d stats-index %d",
19131          ntohl (mp->table_id), format_ip4_address, mp->address,
19132          mp->address_length, ntohl (mp->stats_index));
19133   fp = mp->path;
19134   for (i = 0; i < count; i++)
19135     {
19136       if (fp->afi == IP46_TYPE_IP6)
19137         print (vam->ofp,
19138                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19139                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19140                "next_hop_table %d",
19141                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19142                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19143                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19144       else if (fp->afi == IP46_TYPE_IP4)
19145         print (vam->ofp,
19146                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19147                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19148                "next_hop_table %d",
19149                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19150                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19151                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19152       fp++;
19153     }
19154 }
19155
19156 static void vl_api_ip_fib_details_t_handler_json
19157   (vl_api_ip_fib_details_t * mp)
19158 {
19159   vat_main_t *vam = &vat_main;
19160   int count = ntohl (mp->count);
19161   vat_json_node_t *node = NULL;
19162   struct in_addr ip4;
19163   struct in6_addr ip6;
19164   vl_api_fib_path_t *fp;
19165   int i;
19166
19167   if (VAT_JSON_ARRAY != vam->json_tree.type)
19168     {
19169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19170       vat_json_init_array (&vam->json_tree);
19171     }
19172   node = vat_json_array_add (&vam->json_tree);
19173
19174   vat_json_init_object (node);
19175   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19176   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19177   vat_json_object_add_ip4 (node, "prefix", ip4);
19178   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19179   vat_json_object_add_uint (node, "path_count", count);
19180   fp = mp->path;
19181   for (i = 0; i < count; i++)
19182     {
19183       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19184       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19185       vat_json_object_add_uint (node, "is_local", fp->is_local);
19186       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19187       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19188       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19189       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19190       if (fp->afi == IP46_TYPE_IP4)
19191         {
19192           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19193           vat_json_object_add_ip4 (node, "next_hop", ip4);
19194         }
19195       else if (fp->afi == IP46_TYPE_IP6)
19196         {
19197           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19198           vat_json_object_add_ip6 (node, "next_hop", ip6);
19199         }
19200     }
19201 }
19202
19203 static int
19204 api_ip_fib_dump (vat_main_t * vam)
19205 {
19206   vl_api_ip_fib_dump_t *mp;
19207   vl_api_control_ping_t *mp_ping;
19208   int ret;
19209
19210   M (IP_FIB_DUMP, mp);
19211   S (mp);
19212
19213   /* Use a control ping for synchronization */
19214   MPING (CONTROL_PING, mp_ping);
19215   S (mp_ping);
19216
19217   W (ret);
19218   return ret;
19219 }
19220
19221 static int
19222 api_ip_mfib_dump (vat_main_t * vam)
19223 {
19224   vl_api_ip_mfib_dump_t *mp;
19225   vl_api_control_ping_t *mp_ping;
19226   int ret;
19227
19228   M (IP_MFIB_DUMP, mp);
19229   S (mp);
19230
19231   /* Use a control ping for synchronization */
19232   MPING (CONTROL_PING, mp_ping);
19233   S (mp_ping);
19234
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static void vl_api_ip_neighbor_details_t_handler
19240   (vl_api_ip_neighbor_details_t * mp)
19241 {
19242   vat_main_t *vam = &vat_main;
19243
19244   print (vam->ofp, "%c %U %U",
19245          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19246          format_vl_api_mac_address, &mp->neighbor.mac_address,
19247          format_vl_api_address, &mp->neighbor.ip_address);
19248 }
19249
19250 static void vl_api_ip_neighbor_details_t_handler_json
19251   (vl_api_ip_neighbor_details_t * mp)
19252 {
19253
19254   vat_main_t *vam = &vat_main;
19255   vat_json_node_t *node;
19256
19257   if (VAT_JSON_ARRAY != vam->json_tree.type)
19258     {
19259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19260       vat_json_init_array (&vam->json_tree);
19261     }
19262   node = vat_json_array_add (&vam->json_tree);
19263
19264   vat_json_init_object (node);
19265   vat_json_object_add_string_copy
19266     (node, "flag",
19267      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19268       (u8 *) "static" : (u8 *) "dynamic"));
19269
19270   vat_json_object_add_string_copy (node, "link_layer",
19271                                    format (0, "%U", format_vl_api_mac_address,
19272                                            &mp->neighbor.mac_address));
19273   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19274 }
19275
19276 static int
19277 api_ip_neighbor_dump (vat_main_t * vam)
19278 {
19279   unformat_input_t *i = vam->input;
19280   vl_api_ip_neighbor_dump_t *mp;
19281   vl_api_control_ping_t *mp_ping;
19282   u8 is_ipv6 = 0;
19283   u32 sw_if_index = ~0;
19284   int ret;
19285
19286   /* Parse args required to build the message */
19287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19288     {
19289       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19290         ;
19291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19292         ;
19293       else if (unformat (i, "ip6"))
19294         is_ipv6 = 1;
19295       else
19296         break;
19297     }
19298
19299   if (sw_if_index == ~0)
19300     {
19301       errmsg ("missing interface name or sw_if_index");
19302       return -99;
19303     }
19304
19305   M (IP_NEIGHBOR_DUMP, mp);
19306   mp->is_ipv6 = (u8) is_ipv6;
19307   mp->sw_if_index = ntohl (sw_if_index);
19308   S (mp);
19309
19310   /* Use a control ping for synchronization */
19311   MPING (CONTROL_PING, mp_ping);
19312   S (mp_ping);
19313
19314   W (ret);
19315   return ret;
19316 }
19317
19318 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19319 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19320
19321 static void
19322 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19323 {
19324   vat_main_t *vam = &vat_main;
19325   int count = ntohl (mp->count);
19326   vl_api_fib_path_t *fp;
19327   int i;
19328
19329   print (vam->ofp,
19330          "table-id %d, prefix %U/%d stats-index %d",
19331          ntohl (mp->table_id), format_ip6_address, mp->address,
19332          mp->address_length, ntohl (mp->stats_index));
19333   fp = mp->path;
19334   for (i = 0; i < count; i++)
19335     {
19336       if (fp->afi == IP46_TYPE_IP6)
19337         print (vam->ofp,
19338                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19339                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19340                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19341                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19342                format_ip6_address, fp->next_hop);
19343       else if (fp->afi == IP46_TYPE_IP4)
19344         print (vam->ofp,
19345                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19346                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19347                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19348                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19349                format_ip4_address, fp->next_hop);
19350       fp++;
19351     }
19352 }
19353
19354 static void vl_api_ip6_fib_details_t_handler_json
19355   (vl_api_ip6_fib_details_t * mp)
19356 {
19357   vat_main_t *vam = &vat_main;
19358   int count = ntohl (mp->count);
19359   vat_json_node_t *node = NULL;
19360   struct in_addr ip4;
19361   struct in6_addr ip6;
19362   vl_api_fib_path_t *fp;
19363   int i;
19364
19365   if (VAT_JSON_ARRAY != vam->json_tree.type)
19366     {
19367       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19368       vat_json_init_array (&vam->json_tree);
19369     }
19370   node = vat_json_array_add (&vam->json_tree);
19371
19372   vat_json_init_object (node);
19373   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19374   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19375   vat_json_object_add_ip6 (node, "prefix", ip6);
19376   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19377   vat_json_object_add_uint (node, "path_count", count);
19378   fp = mp->path;
19379   for (i = 0; i < count; i++)
19380     {
19381       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19382       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19383       vat_json_object_add_uint (node, "is_local", fp->is_local);
19384       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19385       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19386       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19387       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19388       if (fp->afi == IP46_TYPE_IP4)
19389         {
19390           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19391           vat_json_object_add_ip4 (node, "next_hop", ip4);
19392         }
19393       else if (fp->afi == IP46_TYPE_IP6)
19394         {
19395           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19396           vat_json_object_add_ip6 (node, "next_hop", ip6);
19397         }
19398     }
19399 }
19400
19401 static int
19402 api_ip6_fib_dump (vat_main_t * vam)
19403 {
19404   vl_api_ip6_fib_dump_t *mp;
19405   vl_api_control_ping_t *mp_ping;
19406   int ret;
19407
19408   M (IP6_FIB_DUMP, mp);
19409   S (mp);
19410
19411   /* Use a control ping for synchronization */
19412   MPING (CONTROL_PING, mp_ping);
19413   S (mp_ping);
19414
19415   W (ret);
19416   return ret;
19417 }
19418
19419 static int
19420 api_ip6_mfib_dump (vat_main_t * vam)
19421 {
19422   vl_api_ip6_mfib_dump_t *mp;
19423   vl_api_control_ping_t *mp_ping;
19424   int ret;
19425
19426   M (IP6_MFIB_DUMP, mp);
19427   S (mp);
19428
19429   /* Use a control ping for synchronization */
19430   MPING (CONTROL_PING, mp_ping);
19431   S (mp_ping);
19432
19433   W (ret);
19434   return ret;
19435 }
19436
19437 int
19438 api_classify_table_ids (vat_main_t * vam)
19439 {
19440   vl_api_classify_table_ids_t *mp;
19441   int ret;
19442
19443   /* Construct the API message */
19444   M (CLASSIFY_TABLE_IDS, mp);
19445   mp->context = 0;
19446
19447   S (mp);
19448   W (ret);
19449   return ret;
19450 }
19451
19452 int
19453 api_classify_table_by_interface (vat_main_t * vam)
19454 {
19455   unformat_input_t *input = vam->input;
19456   vl_api_classify_table_by_interface_t *mp;
19457
19458   u32 sw_if_index = ~0;
19459   int ret;
19460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19461     {
19462       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19463         ;
19464       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19465         ;
19466       else
19467         break;
19468     }
19469   if (sw_if_index == ~0)
19470     {
19471       errmsg ("missing interface name or sw_if_index");
19472       return -99;
19473     }
19474
19475   /* Construct the API message */
19476   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19477   mp->context = 0;
19478   mp->sw_if_index = ntohl (sw_if_index);
19479
19480   S (mp);
19481   W (ret);
19482   return ret;
19483 }
19484
19485 int
19486 api_classify_table_info (vat_main_t * vam)
19487 {
19488   unformat_input_t *input = vam->input;
19489   vl_api_classify_table_info_t *mp;
19490
19491   u32 table_id = ~0;
19492   int ret;
19493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19494     {
19495       if (unformat (input, "table_id %d", &table_id))
19496         ;
19497       else
19498         break;
19499     }
19500   if (table_id == ~0)
19501     {
19502       errmsg ("missing table id");
19503       return -99;
19504     }
19505
19506   /* Construct the API message */
19507   M (CLASSIFY_TABLE_INFO, mp);
19508   mp->context = 0;
19509   mp->table_id = ntohl (table_id);
19510
19511   S (mp);
19512   W (ret);
19513   return ret;
19514 }
19515
19516 int
19517 api_classify_session_dump (vat_main_t * vam)
19518 {
19519   unformat_input_t *input = vam->input;
19520   vl_api_classify_session_dump_t *mp;
19521   vl_api_control_ping_t *mp_ping;
19522
19523   u32 table_id = ~0;
19524   int ret;
19525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19526     {
19527       if (unformat (input, "table_id %d", &table_id))
19528         ;
19529       else
19530         break;
19531     }
19532   if (table_id == ~0)
19533     {
19534       errmsg ("missing table id");
19535       return -99;
19536     }
19537
19538   /* Construct the API message */
19539   M (CLASSIFY_SESSION_DUMP, mp);
19540   mp->context = 0;
19541   mp->table_id = ntohl (table_id);
19542   S (mp);
19543
19544   /* Use a control ping for synchronization */
19545   MPING (CONTROL_PING, mp_ping);
19546   S (mp_ping);
19547
19548   W (ret);
19549   return ret;
19550 }
19551
19552 static void
19553 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19554 {
19555   vat_main_t *vam = &vat_main;
19556
19557   print (vam->ofp, "collector_address %U, collector_port %d, "
19558          "src_address %U, vrf_id %d, path_mtu %u, "
19559          "template_interval %u, udp_checksum %d",
19560          format_ip4_address, mp->collector_address,
19561          ntohs (mp->collector_port),
19562          format_ip4_address, mp->src_address,
19563          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19564          ntohl (mp->template_interval), mp->udp_checksum);
19565
19566   vam->retval = 0;
19567   vam->result_ready = 1;
19568 }
19569
19570 static void
19571   vl_api_ipfix_exporter_details_t_handler_json
19572   (vl_api_ipfix_exporter_details_t * mp)
19573 {
19574   vat_main_t *vam = &vat_main;
19575   vat_json_node_t node;
19576   struct in_addr collector_address;
19577   struct in_addr src_address;
19578
19579   vat_json_init_object (&node);
19580   clib_memcpy (&collector_address, &mp->collector_address,
19581                sizeof (collector_address));
19582   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19583   vat_json_object_add_uint (&node, "collector_port",
19584                             ntohs (mp->collector_port));
19585   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19586   vat_json_object_add_ip4 (&node, "src_address", src_address);
19587   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19588   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19589   vat_json_object_add_uint (&node, "template_interval",
19590                             ntohl (mp->template_interval));
19591   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19592
19593   vat_json_print (vam->ofp, &node);
19594   vat_json_free (&node);
19595   vam->retval = 0;
19596   vam->result_ready = 1;
19597 }
19598
19599 int
19600 api_ipfix_exporter_dump (vat_main_t * vam)
19601 {
19602   vl_api_ipfix_exporter_dump_t *mp;
19603   int ret;
19604
19605   /* Construct the API message */
19606   M (IPFIX_EXPORTER_DUMP, mp);
19607   mp->context = 0;
19608
19609   S (mp);
19610   W (ret);
19611   return ret;
19612 }
19613
19614 static int
19615 api_ipfix_classify_stream_dump (vat_main_t * vam)
19616 {
19617   vl_api_ipfix_classify_stream_dump_t *mp;
19618   int ret;
19619
19620   /* Construct the API message */
19621   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19622   mp->context = 0;
19623
19624   S (mp);
19625   W (ret);
19626   return ret;
19627   /* NOTREACHED */
19628   return 0;
19629 }
19630
19631 static void
19632   vl_api_ipfix_classify_stream_details_t_handler
19633   (vl_api_ipfix_classify_stream_details_t * mp)
19634 {
19635   vat_main_t *vam = &vat_main;
19636   print (vam->ofp, "domain_id %d, src_port %d",
19637          ntohl (mp->domain_id), ntohs (mp->src_port));
19638   vam->retval = 0;
19639   vam->result_ready = 1;
19640 }
19641
19642 static void
19643   vl_api_ipfix_classify_stream_details_t_handler_json
19644   (vl_api_ipfix_classify_stream_details_t * mp)
19645 {
19646   vat_main_t *vam = &vat_main;
19647   vat_json_node_t node;
19648
19649   vat_json_init_object (&node);
19650   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19651   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19652
19653   vat_json_print (vam->ofp, &node);
19654   vat_json_free (&node);
19655   vam->retval = 0;
19656   vam->result_ready = 1;
19657 }
19658
19659 static int
19660 api_ipfix_classify_table_dump (vat_main_t * vam)
19661 {
19662   vl_api_ipfix_classify_table_dump_t *mp;
19663   vl_api_control_ping_t *mp_ping;
19664   int ret;
19665
19666   if (!vam->json_output)
19667     {
19668       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19669              "transport_protocol");
19670     }
19671
19672   /* Construct the API message */
19673   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19674
19675   /* send it... */
19676   S (mp);
19677
19678   /* Use a control ping for synchronization */
19679   MPING (CONTROL_PING, mp_ping);
19680   S (mp_ping);
19681
19682   W (ret);
19683   return ret;
19684 }
19685
19686 static void
19687   vl_api_ipfix_classify_table_details_t_handler
19688   (vl_api_ipfix_classify_table_details_t * mp)
19689 {
19690   vat_main_t *vam = &vat_main;
19691   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19692          mp->transport_protocol);
19693 }
19694
19695 static void
19696   vl_api_ipfix_classify_table_details_t_handler_json
19697   (vl_api_ipfix_classify_table_details_t * mp)
19698 {
19699   vat_json_node_t *node = NULL;
19700   vat_main_t *vam = &vat_main;
19701
19702   if (VAT_JSON_ARRAY != vam->json_tree.type)
19703     {
19704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19705       vat_json_init_array (&vam->json_tree);
19706     }
19707
19708   node = vat_json_array_add (&vam->json_tree);
19709   vat_json_init_object (node);
19710
19711   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19712   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19713   vat_json_object_add_uint (node, "transport_protocol",
19714                             mp->transport_protocol);
19715 }
19716
19717 static int
19718 api_sw_interface_span_enable_disable (vat_main_t * vam)
19719 {
19720   unformat_input_t *i = vam->input;
19721   vl_api_sw_interface_span_enable_disable_t *mp;
19722   u32 src_sw_if_index = ~0;
19723   u32 dst_sw_if_index = ~0;
19724   u8 state = 3;
19725   int ret;
19726   u8 is_l2 = 0;
19727
19728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19729     {
19730       if (unformat
19731           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19732         ;
19733       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19734         ;
19735       else
19736         if (unformat
19737             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19738         ;
19739       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19740         ;
19741       else if (unformat (i, "disable"))
19742         state = 0;
19743       else if (unformat (i, "rx"))
19744         state = 1;
19745       else if (unformat (i, "tx"))
19746         state = 2;
19747       else if (unformat (i, "both"))
19748         state = 3;
19749       else if (unformat (i, "l2"))
19750         is_l2 = 1;
19751       else
19752         break;
19753     }
19754
19755   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19756
19757   mp->sw_if_index_from = htonl (src_sw_if_index);
19758   mp->sw_if_index_to = htonl (dst_sw_if_index);
19759   mp->state = state;
19760   mp->is_l2 = is_l2;
19761
19762   S (mp);
19763   W (ret);
19764   return ret;
19765 }
19766
19767 static void
19768 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19769                                             * mp)
19770 {
19771   vat_main_t *vam = &vat_main;
19772   u8 *sw_if_from_name = 0;
19773   u8 *sw_if_to_name = 0;
19774   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19775   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19776   char *states[] = { "none", "rx", "tx", "both" };
19777   hash_pair_t *p;
19778
19779   /* *INDENT-OFF* */
19780   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19781   ({
19782     if ((u32) p->value[0] == sw_if_index_from)
19783       {
19784         sw_if_from_name = (u8 *)(p->key);
19785         if (sw_if_to_name)
19786           break;
19787       }
19788     if ((u32) p->value[0] == sw_if_index_to)
19789       {
19790         sw_if_to_name = (u8 *)(p->key);
19791         if (sw_if_from_name)
19792           break;
19793       }
19794   }));
19795   /* *INDENT-ON* */
19796   print (vam->ofp, "%20s => %20s (%s) %s",
19797          sw_if_from_name, sw_if_to_name, states[mp->state],
19798          mp->is_l2 ? "l2" : "device");
19799 }
19800
19801 static void
19802   vl_api_sw_interface_span_details_t_handler_json
19803   (vl_api_sw_interface_span_details_t * mp)
19804 {
19805   vat_main_t *vam = &vat_main;
19806   vat_json_node_t *node = NULL;
19807   u8 *sw_if_from_name = 0;
19808   u8 *sw_if_to_name = 0;
19809   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19810   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19811   hash_pair_t *p;
19812
19813   /* *INDENT-OFF* */
19814   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19815   ({
19816     if ((u32) p->value[0] == sw_if_index_from)
19817       {
19818         sw_if_from_name = (u8 *)(p->key);
19819         if (sw_if_to_name)
19820           break;
19821       }
19822     if ((u32) p->value[0] == sw_if_index_to)
19823       {
19824         sw_if_to_name = (u8 *)(p->key);
19825         if (sw_if_from_name)
19826           break;
19827       }
19828   }));
19829   /* *INDENT-ON* */
19830
19831   if (VAT_JSON_ARRAY != vam->json_tree.type)
19832     {
19833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19834       vat_json_init_array (&vam->json_tree);
19835     }
19836   node = vat_json_array_add (&vam->json_tree);
19837
19838   vat_json_init_object (node);
19839   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19840   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19841   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19842   if (0 != sw_if_to_name)
19843     {
19844       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19845     }
19846   vat_json_object_add_uint (node, "state", mp->state);
19847   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19848 }
19849
19850 static int
19851 api_sw_interface_span_dump (vat_main_t * vam)
19852 {
19853   unformat_input_t *input = vam->input;
19854   vl_api_sw_interface_span_dump_t *mp;
19855   vl_api_control_ping_t *mp_ping;
19856   u8 is_l2 = 0;
19857   int ret;
19858
19859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19860     {
19861       if (unformat (input, "l2"))
19862         is_l2 = 1;
19863       else
19864         break;
19865     }
19866
19867   M (SW_INTERFACE_SPAN_DUMP, mp);
19868   mp->is_l2 = is_l2;
19869   S (mp);
19870
19871   /* Use a control ping for synchronization */
19872   MPING (CONTROL_PING, mp_ping);
19873   S (mp_ping);
19874
19875   W (ret);
19876   return ret;
19877 }
19878
19879 int
19880 api_pg_create_interface (vat_main_t * vam)
19881 {
19882   unformat_input_t *input = vam->input;
19883   vl_api_pg_create_interface_t *mp;
19884
19885   u32 if_id = ~0;
19886   int ret;
19887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19888     {
19889       if (unformat (input, "if_id %d", &if_id))
19890         ;
19891       else
19892         break;
19893     }
19894   if (if_id == ~0)
19895     {
19896       errmsg ("missing pg interface index");
19897       return -99;
19898     }
19899
19900   /* Construct the API message */
19901   M (PG_CREATE_INTERFACE, mp);
19902   mp->context = 0;
19903   mp->interface_id = ntohl (if_id);
19904
19905   S (mp);
19906   W (ret);
19907   return ret;
19908 }
19909
19910 int
19911 api_pg_capture (vat_main_t * vam)
19912 {
19913   unformat_input_t *input = vam->input;
19914   vl_api_pg_capture_t *mp;
19915
19916   u32 if_id = ~0;
19917   u8 enable = 1;
19918   u32 count = 1;
19919   u8 pcap_file_set = 0;
19920   u8 *pcap_file = 0;
19921   int ret;
19922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19923     {
19924       if (unformat (input, "if_id %d", &if_id))
19925         ;
19926       else if (unformat (input, "pcap %s", &pcap_file))
19927         pcap_file_set = 1;
19928       else if (unformat (input, "count %d", &count))
19929         ;
19930       else if (unformat (input, "disable"))
19931         enable = 0;
19932       else
19933         break;
19934     }
19935   if (if_id == ~0)
19936     {
19937       errmsg ("missing pg interface index");
19938       return -99;
19939     }
19940   if (pcap_file_set > 0)
19941     {
19942       if (vec_len (pcap_file) > 255)
19943         {
19944           errmsg ("pcap file name is too long");
19945           return -99;
19946         }
19947     }
19948
19949   u32 name_len = vec_len (pcap_file);
19950   /* Construct the API message */
19951   M (PG_CAPTURE, mp);
19952   mp->context = 0;
19953   mp->interface_id = ntohl (if_id);
19954   mp->is_enabled = enable;
19955   mp->count = ntohl (count);
19956   mp->pcap_name_length = ntohl (name_len);
19957   if (pcap_file_set != 0)
19958     {
19959       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19960     }
19961   vec_free (pcap_file);
19962
19963   S (mp);
19964   W (ret);
19965   return ret;
19966 }
19967
19968 int
19969 api_pg_enable_disable (vat_main_t * vam)
19970 {
19971   unformat_input_t *input = vam->input;
19972   vl_api_pg_enable_disable_t *mp;
19973
19974   u8 enable = 1;
19975   u8 stream_name_set = 0;
19976   u8 *stream_name = 0;
19977   int ret;
19978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19979     {
19980       if (unformat (input, "stream %s", &stream_name))
19981         stream_name_set = 1;
19982       else if (unformat (input, "disable"))
19983         enable = 0;
19984       else
19985         break;
19986     }
19987
19988   if (stream_name_set > 0)
19989     {
19990       if (vec_len (stream_name) > 255)
19991         {
19992           errmsg ("stream name too long");
19993           return -99;
19994         }
19995     }
19996
19997   u32 name_len = vec_len (stream_name);
19998   /* Construct the API message */
19999   M (PG_ENABLE_DISABLE, mp);
20000   mp->context = 0;
20001   mp->is_enabled = enable;
20002   if (stream_name_set != 0)
20003     {
20004       mp->stream_name_length = ntohl (name_len);
20005       clib_memcpy (mp->stream_name, stream_name, name_len);
20006     }
20007   vec_free (stream_name);
20008
20009   S (mp);
20010   W (ret);
20011   return ret;
20012 }
20013
20014 int
20015 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20016 {
20017   unformat_input_t *input = vam->input;
20018   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20019
20020   u16 *low_ports = 0;
20021   u16 *high_ports = 0;
20022   u16 this_low;
20023   u16 this_hi;
20024   vl_api_prefix_t prefix;
20025   u32 tmp, tmp2;
20026   u8 prefix_set = 0;
20027   u32 vrf_id = ~0;
20028   u8 is_add = 1;
20029   u8 is_ipv6 = 0;
20030   int ret;
20031
20032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20033     {
20034       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20035         prefix_set = 1;
20036       else if (unformat (input, "vrf %d", &vrf_id))
20037         ;
20038       else if (unformat (input, "del"))
20039         is_add = 0;
20040       else if (unformat (input, "port %d", &tmp))
20041         {
20042           if (tmp == 0 || tmp > 65535)
20043             {
20044               errmsg ("port %d out of range", tmp);
20045               return -99;
20046             }
20047           this_low = tmp;
20048           this_hi = this_low + 1;
20049           vec_add1 (low_ports, this_low);
20050           vec_add1 (high_ports, this_hi);
20051         }
20052       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20053         {
20054           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20055             {
20056               errmsg ("incorrect range parameters");
20057               return -99;
20058             }
20059           this_low = tmp;
20060           /* Note: in debug CLI +1 is added to high before
20061              passing to real fn that does "the work"
20062              (ip_source_and_port_range_check_add_del).
20063              This fn is a wrapper around the binary API fn a
20064              control plane will call, which expects this increment
20065              to have occurred. Hence letting the binary API control
20066              plane fn do the increment for consistency between VAT
20067              and other control planes.
20068            */
20069           this_hi = tmp2;
20070           vec_add1 (low_ports, this_low);
20071           vec_add1 (high_ports, this_hi);
20072         }
20073       else
20074         break;
20075     }
20076
20077   if (prefix_set == 0)
20078     {
20079       errmsg ("<address>/<mask> not specified");
20080       return -99;
20081     }
20082
20083   if (vrf_id == ~0)
20084     {
20085       errmsg ("VRF ID required, not specified");
20086       return -99;
20087     }
20088
20089   if (vrf_id == 0)
20090     {
20091       errmsg
20092         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20093       return -99;
20094     }
20095
20096   if (vec_len (low_ports) == 0)
20097     {
20098       errmsg ("At least one port or port range required");
20099       return -99;
20100     }
20101
20102   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20103
20104   mp->is_add = is_add;
20105
20106   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20107
20108   mp->number_of_ranges = vec_len (low_ports);
20109
20110   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20111   vec_free (low_ports);
20112
20113   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20114   vec_free (high_ports);
20115
20116   mp->vrf_id = ntohl (vrf_id);
20117
20118   S (mp);
20119   W (ret);
20120   return ret;
20121 }
20122
20123 int
20124 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20125 {
20126   unformat_input_t *input = vam->input;
20127   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20128   u32 sw_if_index = ~0;
20129   int vrf_set = 0;
20130   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20131   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20132   u8 is_add = 1;
20133   int ret;
20134
20135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20136     {
20137       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20138         ;
20139       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20140         ;
20141       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20142         vrf_set = 1;
20143       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20144         vrf_set = 1;
20145       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20146         vrf_set = 1;
20147       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20148         vrf_set = 1;
20149       else if (unformat (input, "del"))
20150         is_add = 0;
20151       else
20152         break;
20153     }
20154
20155   if (sw_if_index == ~0)
20156     {
20157       errmsg ("Interface required but not specified");
20158       return -99;
20159     }
20160
20161   if (vrf_set == 0)
20162     {
20163       errmsg ("VRF ID required but not specified");
20164       return -99;
20165     }
20166
20167   if (tcp_out_vrf_id == 0
20168       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20169     {
20170       errmsg
20171         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20172       return -99;
20173     }
20174
20175   /* Construct the API message */
20176   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20177
20178   mp->sw_if_index = ntohl (sw_if_index);
20179   mp->is_add = is_add;
20180   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20181   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20182   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20183   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20184
20185   /* send it... */
20186   S (mp);
20187
20188   /* Wait for a reply... */
20189   W (ret);
20190   return ret;
20191 }
20192
20193 static int
20194 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20195 {
20196   unformat_input_t *i = vam->input;
20197   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20198   u32 local_sa_id = 0;
20199   u32 remote_sa_id = 0;
20200   vl_api_ip4_address_t src_address;
20201   vl_api_ip4_address_t dst_address;
20202   u8 is_add = 1;
20203   int ret;
20204
20205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20206     {
20207       if (unformat (i, "local_sa %d", &local_sa_id))
20208         ;
20209       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20210         ;
20211       else
20212         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20213         ;
20214       else
20215         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20216         ;
20217       else if (unformat (i, "del"))
20218         is_add = 0;
20219       else
20220         {
20221           clib_warning ("parse error '%U'", format_unformat_error, i);
20222           return -99;
20223         }
20224     }
20225
20226   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20227
20228   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20229   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20230   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20231   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20232   mp->is_add = is_add;
20233
20234   S (mp);
20235   W (ret);
20236   return ret;
20237 }
20238
20239 static int
20240 api_set_punt (vat_main_t * vam)
20241 {
20242   unformat_input_t *i = vam->input;
20243   vl_api_address_family_t af;
20244   vl_api_set_punt_t *mp;
20245   u32 ipv = ~0;
20246   u32 protocol = ~0;
20247   u32 port = ~0;
20248   int is_add = 1;
20249   u8 is_ip4 = 1;
20250   int ret;
20251
20252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20253     {
20254       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20255         ;
20256       else if (unformat (i, "protocol %d", &protocol))
20257         ;
20258       else if (unformat (i, "port %d", &port))
20259         ;
20260       else if (unformat (i, "del"))
20261         is_add = 0;
20262       else
20263         {
20264           clib_warning ("parse error '%U'", format_unformat_error, i);
20265           return -99;
20266         }
20267     }
20268
20269   M (SET_PUNT, mp);
20270
20271   mp->is_add = (u8) is_add;
20272   mp->punt.type = PUNT_API_TYPE_L4;
20273   mp->punt.punt.l4.af = af;
20274   mp->punt.punt.l4.protocol = (u8) protocol;
20275   mp->punt.punt.l4.port = htons ((u16) port);
20276
20277   S (mp);
20278   W (ret);
20279   return ret;
20280 }
20281
20282 static void vl_api_ipsec_gre_tunnel_details_t_handler
20283   (vl_api_ipsec_gre_tunnel_details_t * mp)
20284 {
20285   vat_main_t *vam = &vat_main;
20286
20287   print (vam->ofp, "%11d%15U%15U%14d%14d",
20288          ntohl (mp->tunnel.sw_if_index),
20289          format_vl_api_ip4_address, mp->tunnel.src,
20290          format_vl_api_ip4_address, mp->tunnel.dst,
20291          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20292 }
20293
20294 static void
20295 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20296                                 const char *name,
20297                                 const vl_api_ip4_address_t addr)
20298 {
20299   struct in_addr ip4;
20300
20301   clib_memcpy (&ip4, addr, sizeof (ip4));
20302   vat_json_object_add_ip4 (node, name, ip4);
20303 }
20304
20305 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20306   (vl_api_ipsec_gre_tunnel_details_t * mp)
20307 {
20308   vat_main_t *vam = &vat_main;
20309   vat_json_node_t *node = NULL;
20310   struct in_addr ip4;
20311
20312   if (VAT_JSON_ARRAY != vam->json_tree.type)
20313     {
20314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20315       vat_json_init_array (&vam->json_tree);
20316     }
20317   node = vat_json_array_add (&vam->json_tree);
20318
20319   vat_json_init_object (node);
20320   vat_json_object_add_uint (node, "sw_if_index",
20321                             ntohl (mp->tunnel.sw_if_index));
20322   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20323   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20324   vat_json_object_add_uint (node, "local_sa_id",
20325                             ntohl (mp->tunnel.local_sa_id));
20326   vat_json_object_add_uint (node, "remote_sa_id",
20327                             ntohl (mp->tunnel.remote_sa_id));
20328 }
20329
20330 static int
20331 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20332 {
20333   unformat_input_t *i = vam->input;
20334   vl_api_ipsec_gre_tunnel_dump_t *mp;
20335   vl_api_control_ping_t *mp_ping;
20336   u32 sw_if_index;
20337   u8 sw_if_index_set = 0;
20338   int ret;
20339
20340   /* Parse args required to build the message */
20341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20342     {
20343       if (unformat (i, "sw_if_index %d", &sw_if_index))
20344         sw_if_index_set = 1;
20345       else
20346         break;
20347     }
20348
20349   if (sw_if_index_set == 0)
20350     {
20351       sw_if_index = ~0;
20352     }
20353
20354   if (!vam->json_output)
20355     {
20356       print (vam->ofp, "%11s%15s%15s%14s%14s",
20357              "sw_if_index", "src_address", "dst_address",
20358              "local_sa_id", "remote_sa_id");
20359     }
20360
20361   /* Get list of gre-tunnel interfaces */
20362   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20363
20364   mp->sw_if_index = htonl (sw_if_index);
20365
20366   S (mp);
20367
20368   /* Use a control ping for synchronization */
20369   MPING (CONTROL_PING, mp_ping);
20370   S (mp_ping);
20371
20372   W (ret);
20373   return ret;
20374 }
20375
20376 static int
20377 api_delete_subif (vat_main_t * vam)
20378 {
20379   unformat_input_t *i = vam->input;
20380   vl_api_delete_subif_t *mp;
20381   u32 sw_if_index = ~0;
20382   int ret;
20383
20384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20385     {
20386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20387         ;
20388       if (unformat (i, "sw_if_index %d", &sw_if_index))
20389         ;
20390       else
20391         break;
20392     }
20393
20394   if (sw_if_index == ~0)
20395     {
20396       errmsg ("missing sw_if_index");
20397       return -99;
20398     }
20399
20400   /* Construct the API message */
20401   M (DELETE_SUBIF, mp);
20402   mp->sw_if_index = ntohl (sw_if_index);
20403
20404   S (mp);
20405   W (ret);
20406   return ret;
20407 }
20408
20409 #define foreach_pbb_vtr_op      \
20410 _("disable",  L2_VTR_DISABLED)  \
20411 _("pop",  L2_VTR_POP_2)         \
20412 _("push",  L2_VTR_PUSH_2)
20413
20414 static int
20415 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20416 {
20417   unformat_input_t *i = vam->input;
20418   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20419   u32 sw_if_index = ~0, vtr_op = ~0;
20420   u16 outer_tag = ~0;
20421   u8 dmac[6], smac[6];
20422   u8 dmac_set = 0, smac_set = 0;
20423   u16 vlanid = 0;
20424   u32 sid = ~0;
20425   u32 tmp;
20426   int ret;
20427
20428   /* Shut up coverity */
20429   clib_memset (dmac, 0, sizeof (dmac));
20430   clib_memset (smac, 0, sizeof (smac));
20431
20432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20433     {
20434       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20435         ;
20436       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20437         ;
20438       else if (unformat (i, "vtr_op %d", &vtr_op))
20439         ;
20440 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20441       foreach_pbb_vtr_op
20442 #undef _
20443         else if (unformat (i, "translate_pbb_stag"))
20444         {
20445           if (unformat (i, "%d", &tmp))
20446             {
20447               vtr_op = L2_VTR_TRANSLATE_2_1;
20448               outer_tag = tmp;
20449             }
20450           else
20451             {
20452               errmsg
20453                 ("translate_pbb_stag operation requires outer tag definition");
20454               return -99;
20455             }
20456         }
20457       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20458         dmac_set++;
20459       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20460         smac_set++;
20461       else if (unformat (i, "sid %d", &sid))
20462         ;
20463       else if (unformat (i, "vlanid %d", &tmp))
20464         vlanid = tmp;
20465       else
20466         {
20467           clib_warning ("parse error '%U'", format_unformat_error, i);
20468           return -99;
20469         }
20470     }
20471
20472   if ((sw_if_index == ~0) || (vtr_op == ~0))
20473     {
20474       errmsg ("missing sw_if_index or vtr operation");
20475       return -99;
20476     }
20477   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20478       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20479     {
20480       errmsg
20481         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20482       return -99;
20483     }
20484
20485   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20486   mp->sw_if_index = ntohl (sw_if_index);
20487   mp->vtr_op = ntohl (vtr_op);
20488   mp->outer_tag = ntohs (outer_tag);
20489   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20490   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20491   mp->b_vlanid = ntohs (vlanid);
20492   mp->i_sid = ntohl (sid);
20493
20494   S (mp);
20495   W (ret);
20496   return ret;
20497 }
20498
20499 static int
20500 api_flow_classify_set_interface (vat_main_t * vam)
20501 {
20502   unformat_input_t *i = vam->input;
20503   vl_api_flow_classify_set_interface_t *mp;
20504   u32 sw_if_index;
20505   int sw_if_index_set;
20506   u32 ip4_table_index = ~0;
20507   u32 ip6_table_index = ~0;
20508   u8 is_add = 1;
20509   int ret;
20510
20511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20512     {
20513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20514         sw_if_index_set = 1;
20515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20516         sw_if_index_set = 1;
20517       else if (unformat (i, "del"))
20518         is_add = 0;
20519       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20520         ;
20521       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20522         ;
20523       else
20524         {
20525           clib_warning ("parse error '%U'", format_unformat_error, i);
20526           return -99;
20527         }
20528     }
20529
20530   if (sw_if_index_set == 0)
20531     {
20532       errmsg ("missing interface name or sw_if_index");
20533       return -99;
20534     }
20535
20536   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20537
20538   mp->sw_if_index = ntohl (sw_if_index);
20539   mp->ip4_table_index = ntohl (ip4_table_index);
20540   mp->ip6_table_index = ntohl (ip6_table_index);
20541   mp->is_add = is_add;
20542
20543   S (mp);
20544   W (ret);
20545   return ret;
20546 }
20547
20548 static int
20549 api_flow_classify_dump (vat_main_t * vam)
20550 {
20551   unformat_input_t *i = vam->input;
20552   vl_api_flow_classify_dump_t *mp;
20553   vl_api_control_ping_t *mp_ping;
20554   u8 type = FLOW_CLASSIFY_N_TABLES;
20555   int ret;
20556
20557   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20558     ;
20559   else
20560     {
20561       errmsg ("classify table type must be specified");
20562       return -99;
20563     }
20564
20565   if (!vam->json_output)
20566     {
20567       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20568     }
20569
20570   M (FLOW_CLASSIFY_DUMP, mp);
20571   mp->type = type;
20572   /* send it... */
20573   S (mp);
20574
20575   /* Use a control ping for synchronization */
20576   MPING (CONTROL_PING, mp_ping);
20577   S (mp_ping);
20578
20579   /* Wait for a reply... */
20580   W (ret);
20581   return ret;
20582 }
20583
20584 static int
20585 api_feature_enable_disable (vat_main_t * vam)
20586 {
20587   unformat_input_t *i = vam->input;
20588   vl_api_feature_enable_disable_t *mp;
20589   u8 *arc_name = 0;
20590   u8 *feature_name = 0;
20591   u32 sw_if_index = ~0;
20592   u8 enable = 1;
20593   int ret;
20594
20595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20596     {
20597       if (unformat (i, "arc_name %s", &arc_name))
20598         ;
20599       else if (unformat (i, "feature_name %s", &feature_name))
20600         ;
20601       else
20602         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20603         ;
20604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20605         ;
20606       else if (unformat (i, "disable"))
20607         enable = 0;
20608       else
20609         break;
20610     }
20611
20612   if (arc_name == 0)
20613     {
20614       errmsg ("missing arc name");
20615       return -99;
20616     }
20617   if (vec_len (arc_name) > 63)
20618     {
20619       errmsg ("arc name too long");
20620     }
20621
20622   if (feature_name == 0)
20623     {
20624       errmsg ("missing feature name");
20625       return -99;
20626     }
20627   if (vec_len (feature_name) > 63)
20628     {
20629       errmsg ("feature name too long");
20630     }
20631
20632   if (sw_if_index == ~0)
20633     {
20634       errmsg ("missing interface name or sw_if_index");
20635       return -99;
20636     }
20637
20638   /* Construct the API message */
20639   M (FEATURE_ENABLE_DISABLE, mp);
20640   mp->sw_if_index = ntohl (sw_if_index);
20641   mp->enable = enable;
20642   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20643   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20644   vec_free (arc_name);
20645   vec_free (feature_name);
20646
20647   S (mp);
20648   W (ret);
20649   return ret;
20650 }
20651
20652 static int
20653 api_sw_interface_tag_add_del (vat_main_t * vam)
20654 {
20655   unformat_input_t *i = vam->input;
20656   vl_api_sw_interface_tag_add_del_t *mp;
20657   u32 sw_if_index = ~0;
20658   u8 *tag = 0;
20659   u8 enable = 1;
20660   int ret;
20661
20662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20663     {
20664       if (unformat (i, "tag %s", &tag))
20665         ;
20666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20667         ;
20668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20669         ;
20670       else if (unformat (i, "del"))
20671         enable = 0;
20672       else
20673         break;
20674     }
20675
20676   if (sw_if_index == ~0)
20677     {
20678       errmsg ("missing interface name or sw_if_index");
20679       return -99;
20680     }
20681
20682   if (enable && (tag == 0))
20683     {
20684       errmsg ("no tag specified");
20685       return -99;
20686     }
20687
20688   /* Construct the API message */
20689   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20690   mp->sw_if_index = ntohl (sw_if_index);
20691   mp->is_add = enable;
20692   if (enable)
20693     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20694   vec_free (tag);
20695
20696   S (mp);
20697   W (ret);
20698   return ret;
20699 }
20700
20701 static void vl_api_l2_xconnect_details_t_handler
20702   (vl_api_l2_xconnect_details_t * mp)
20703 {
20704   vat_main_t *vam = &vat_main;
20705
20706   print (vam->ofp, "%15d%15d",
20707          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20708 }
20709
20710 static void vl_api_l2_xconnect_details_t_handler_json
20711   (vl_api_l2_xconnect_details_t * mp)
20712 {
20713   vat_main_t *vam = &vat_main;
20714   vat_json_node_t *node = NULL;
20715
20716   if (VAT_JSON_ARRAY != vam->json_tree.type)
20717     {
20718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20719       vat_json_init_array (&vam->json_tree);
20720     }
20721   node = vat_json_array_add (&vam->json_tree);
20722
20723   vat_json_init_object (node);
20724   vat_json_object_add_uint (node, "rx_sw_if_index",
20725                             ntohl (mp->rx_sw_if_index));
20726   vat_json_object_add_uint (node, "tx_sw_if_index",
20727                             ntohl (mp->tx_sw_if_index));
20728 }
20729
20730 static int
20731 api_l2_xconnect_dump (vat_main_t * vam)
20732 {
20733   vl_api_l2_xconnect_dump_t *mp;
20734   vl_api_control_ping_t *mp_ping;
20735   int ret;
20736
20737   if (!vam->json_output)
20738     {
20739       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20740     }
20741
20742   M (L2_XCONNECT_DUMP, mp);
20743
20744   S (mp);
20745
20746   /* Use a control ping for synchronization */
20747   MPING (CONTROL_PING, mp_ping);
20748   S (mp_ping);
20749
20750   W (ret);
20751   return ret;
20752 }
20753
20754 static int
20755 api_hw_interface_set_mtu (vat_main_t * vam)
20756 {
20757   unformat_input_t *i = vam->input;
20758   vl_api_hw_interface_set_mtu_t *mp;
20759   u32 sw_if_index = ~0;
20760   u32 mtu = 0;
20761   int ret;
20762
20763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20764     {
20765       if (unformat (i, "mtu %d", &mtu))
20766         ;
20767       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20768         ;
20769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20770         ;
20771       else
20772         break;
20773     }
20774
20775   if (sw_if_index == ~0)
20776     {
20777       errmsg ("missing interface name or sw_if_index");
20778       return -99;
20779     }
20780
20781   if (mtu == 0)
20782     {
20783       errmsg ("no mtu specified");
20784       return -99;
20785     }
20786
20787   /* Construct the API message */
20788   M (HW_INTERFACE_SET_MTU, mp);
20789   mp->sw_if_index = ntohl (sw_if_index);
20790   mp->mtu = ntohs ((u16) mtu);
20791
20792   S (mp);
20793   W (ret);
20794   return ret;
20795 }
20796
20797 static int
20798 api_p2p_ethernet_add (vat_main_t * vam)
20799 {
20800   unformat_input_t *i = vam->input;
20801   vl_api_p2p_ethernet_add_t *mp;
20802   u32 parent_if_index = ~0;
20803   u32 sub_id = ~0;
20804   u8 remote_mac[6];
20805   u8 mac_set = 0;
20806   int ret;
20807
20808   clib_memset (remote_mac, 0, sizeof (remote_mac));
20809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20810     {
20811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20812         ;
20813       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20814         ;
20815       else
20816         if (unformat
20817             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20818         mac_set++;
20819       else if (unformat (i, "sub_id %d", &sub_id))
20820         ;
20821       else
20822         {
20823           clib_warning ("parse error '%U'", format_unformat_error, i);
20824           return -99;
20825         }
20826     }
20827
20828   if (parent_if_index == ~0)
20829     {
20830       errmsg ("missing interface name or sw_if_index");
20831       return -99;
20832     }
20833   if (mac_set == 0)
20834     {
20835       errmsg ("missing remote mac address");
20836       return -99;
20837     }
20838   if (sub_id == ~0)
20839     {
20840       errmsg ("missing sub-interface id");
20841       return -99;
20842     }
20843
20844   M (P2P_ETHERNET_ADD, mp);
20845   mp->parent_if_index = ntohl (parent_if_index);
20846   mp->subif_id = ntohl (sub_id);
20847   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20848
20849   S (mp);
20850   W (ret);
20851   return ret;
20852 }
20853
20854 static int
20855 api_p2p_ethernet_del (vat_main_t * vam)
20856 {
20857   unformat_input_t *i = vam->input;
20858   vl_api_p2p_ethernet_del_t *mp;
20859   u32 parent_if_index = ~0;
20860   u8 remote_mac[6];
20861   u8 mac_set = 0;
20862   int ret;
20863
20864   clib_memset (remote_mac, 0, sizeof (remote_mac));
20865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20866     {
20867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20868         ;
20869       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20870         ;
20871       else
20872         if (unformat
20873             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20874         mac_set++;
20875       else
20876         {
20877           clib_warning ("parse error '%U'", format_unformat_error, i);
20878           return -99;
20879         }
20880     }
20881
20882   if (parent_if_index == ~0)
20883     {
20884       errmsg ("missing interface name or sw_if_index");
20885       return -99;
20886     }
20887   if (mac_set == 0)
20888     {
20889       errmsg ("missing remote mac address");
20890       return -99;
20891     }
20892
20893   M (P2P_ETHERNET_DEL, mp);
20894   mp->parent_if_index = ntohl (parent_if_index);
20895   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20896
20897   S (mp);
20898   W (ret);
20899   return ret;
20900 }
20901
20902 static int
20903 api_lldp_config (vat_main_t * vam)
20904 {
20905   unformat_input_t *i = vam->input;
20906   vl_api_lldp_config_t *mp;
20907   int tx_hold = 0;
20908   int tx_interval = 0;
20909   u8 *sys_name = NULL;
20910   int ret;
20911
20912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20913     {
20914       if (unformat (i, "system-name %s", &sys_name))
20915         ;
20916       else if (unformat (i, "tx-hold %d", &tx_hold))
20917         ;
20918       else if (unformat (i, "tx-interval %d", &tx_interval))
20919         ;
20920       else
20921         {
20922           clib_warning ("parse error '%U'", format_unformat_error, i);
20923           return -99;
20924         }
20925     }
20926
20927   vec_add1 (sys_name, 0);
20928
20929   M (LLDP_CONFIG, mp);
20930   mp->tx_hold = htonl (tx_hold);
20931   mp->tx_interval = htonl (tx_interval);
20932   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20933   vec_free (sys_name);
20934
20935   S (mp);
20936   W (ret);
20937   return ret;
20938 }
20939
20940 static int
20941 api_sw_interface_set_lldp (vat_main_t * vam)
20942 {
20943   unformat_input_t *i = vam->input;
20944   vl_api_sw_interface_set_lldp_t *mp;
20945   u32 sw_if_index = ~0;
20946   u32 enable = 1;
20947   u8 *port_desc = NULL, *mgmt_oid = NULL;
20948   ip4_address_t ip4_addr;
20949   ip6_address_t ip6_addr;
20950   int ret;
20951
20952   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20953   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20954
20955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20956     {
20957       if (unformat (i, "disable"))
20958         enable = 0;
20959       else
20960         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20961         ;
20962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20963         ;
20964       else if (unformat (i, "port-desc %s", &port_desc))
20965         ;
20966       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20967         ;
20968       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20969         ;
20970       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20971         ;
20972       else
20973         break;
20974     }
20975
20976   if (sw_if_index == ~0)
20977     {
20978       errmsg ("missing interface name or sw_if_index");
20979       return -99;
20980     }
20981
20982   /* Construct the API message */
20983   vec_add1 (port_desc, 0);
20984   vec_add1 (mgmt_oid, 0);
20985   M (SW_INTERFACE_SET_LLDP, mp);
20986   mp->sw_if_index = ntohl (sw_if_index);
20987   mp->enable = enable;
20988   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20989   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20990   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20991   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20992   vec_free (port_desc);
20993   vec_free (mgmt_oid);
20994
20995   S (mp);
20996   W (ret);
20997   return ret;
20998 }
20999
21000 static int
21001 api_tcp_configure_src_addresses (vat_main_t * vam)
21002 {
21003   vl_api_tcp_configure_src_addresses_t *mp;
21004   unformat_input_t *i = vam->input;
21005   ip4_address_t v4first, v4last;
21006   ip6_address_t v6first, v6last;
21007   u8 range_set = 0;
21008   u32 vrf_id = 0;
21009   int ret;
21010
21011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21012     {
21013       if (unformat (i, "%U - %U",
21014                     unformat_ip4_address, &v4first,
21015                     unformat_ip4_address, &v4last))
21016         {
21017           if (range_set)
21018             {
21019               errmsg ("one range per message (range already set)");
21020               return -99;
21021             }
21022           range_set = 1;
21023         }
21024       else if (unformat (i, "%U - %U",
21025                          unformat_ip6_address, &v6first,
21026                          unformat_ip6_address, &v6last))
21027         {
21028           if (range_set)
21029             {
21030               errmsg ("one range per message (range already set)");
21031               return -99;
21032             }
21033           range_set = 2;
21034         }
21035       else if (unformat (i, "vrf %d", &vrf_id))
21036         ;
21037       else
21038         break;
21039     }
21040
21041   if (range_set == 0)
21042     {
21043       errmsg ("address range not set");
21044       return -99;
21045     }
21046
21047   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21048   mp->vrf_id = ntohl (vrf_id);
21049   /* ipv6? */
21050   if (range_set == 2)
21051     {
21052       mp->is_ipv6 = 1;
21053       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21054       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21055     }
21056   else
21057     {
21058       mp->is_ipv6 = 0;
21059       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21060       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21061     }
21062   S (mp);
21063   W (ret);
21064   return ret;
21065 }
21066
21067 static void vl_api_app_namespace_add_del_reply_t_handler
21068   (vl_api_app_namespace_add_del_reply_t * mp)
21069 {
21070   vat_main_t *vam = &vat_main;
21071   i32 retval = ntohl (mp->retval);
21072   if (vam->async_mode)
21073     {
21074       vam->async_errors += (retval < 0);
21075     }
21076   else
21077     {
21078       vam->retval = retval;
21079       if (retval == 0)
21080         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21081       vam->result_ready = 1;
21082     }
21083 }
21084
21085 static void vl_api_app_namespace_add_del_reply_t_handler_json
21086   (vl_api_app_namespace_add_del_reply_t * mp)
21087 {
21088   vat_main_t *vam = &vat_main;
21089   vat_json_node_t node;
21090
21091   vat_json_init_object (&node);
21092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21093   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21094
21095   vat_json_print (vam->ofp, &node);
21096   vat_json_free (&node);
21097
21098   vam->retval = ntohl (mp->retval);
21099   vam->result_ready = 1;
21100 }
21101
21102 static int
21103 api_app_namespace_add_del (vat_main_t * vam)
21104 {
21105   vl_api_app_namespace_add_del_t *mp;
21106   unformat_input_t *i = vam->input;
21107   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21108   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21109   u64 secret;
21110   int ret;
21111
21112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21113     {
21114       if (unformat (i, "id %_%v%_", &ns_id))
21115         ;
21116       else if (unformat (i, "secret %lu", &secret))
21117         secret_set = 1;
21118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21119         sw_if_index_set = 1;
21120       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21121         ;
21122       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21123         ;
21124       else
21125         break;
21126     }
21127   if (!ns_id || !secret_set || !sw_if_index_set)
21128     {
21129       errmsg ("namespace id, secret and sw_if_index must be set");
21130       return -99;
21131     }
21132   if (vec_len (ns_id) > 64)
21133     {
21134       errmsg ("namespace id too long");
21135       return -99;
21136     }
21137   M (APP_NAMESPACE_ADD_DEL, mp);
21138
21139   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21140   mp->namespace_id_len = vec_len (ns_id);
21141   mp->secret = clib_host_to_net_u64 (secret);
21142   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21143   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21144   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21145   vec_free (ns_id);
21146   S (mp);
21147   W (ret);
21148   return ret;
21149 }
21150
21151 static int
21152 api_sock_init_shm (vat_main_t * vam)
21153 {
21154 #if VPP_API_TEST_BUILTIN == 0
21155   unformat_input_t *i = vam->input;
21156   vl_api_shm_elem_config_t *config = 0;
21157   u64 size = 64 << 20;
21158   int rv;
21159
21160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21161     {
21162       if (unformat (i, "size %U", unformat_memory_size, &size))
21163         ;
21164       else
21165         break;
21166     }
21167
21168   /*
21169    * Canned custom ring allocator config.
21170    * Should probably parse all of this
21171    */
21172   vec_validate (config, 6);
21173   config[0].type = VL_API_VLIB_RING;
21174   config[0].size = 256;
21175   config[0].count = 32;
21176
21177   config[1].type = VL_API_VLIB_RING;
21178   config[1].size = 1024;
21179   config[1].count = 16;
21180
21181   config[2].type = VL_API_VLIB_RING;
21182   config[2].size = 4096;
21183   config[2].count = 2;
21184
21185   config[3].type = VL_API_CLIENT_RING;
21186   config[3].size = 256;
21187   config[3].count = 32;
21188
21189   config[4].type = VL_API_CLIENT_RING;
21190   config[4].size = 1024;
21191   config[4].count = 16;
21192
21193   config[5].type = VL_API_CLIENT_RING;
21194   config[5].size = 4096;
21195   config[5].count = 2;
21196
21197   config[6].type = VL_API_QUEUE;
21198   config[6].count = 128;
21199   config[6].size = sizeof (uword);
21200
21201   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21202   if (!rv)
21203     vam->client_index_invalid = 1;
21204   return rv;
21205 #else
21206   return -99;
21207 #endif
21208 }
21209
21210 static int
21211 api_dns_enable_disable (vat_main_t * vam)
21212 {
21213   unformat_input_t *line_input = vam->input;
21214   vl_api_dns_enable_disable_t *mp;
21215   u8 enable_disable = 1;
21216   int ret;
21217
21218   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21219     {
21220       if (unformat (line_input, "disable"))
21221         enable_disable = 0;
21222       if (unformat (line_input, "enable"))
21223         enable_disable = 1;
21224       else
21225         break;
21226     }
21227
21228   /* Construct the API message */
21229   M (DNS_ENABLE_DISABLE, mp);
21230   mp->enable = enable_disable;
21231
21232   /* send it... */
21233   S (mp);
21234   /* Wait for the reply */
21235   W (ret);
21236   return ret;
21237 }
21238
21239 static int
21240 api_dns_resolve_name (vat_main_t * vam)
21241 {
21242   unformat_input_t *line_input = vam->input;
21243   vl_api_dns_resolve_name_t *mp;
21244   u8 *name = 0;
21245   int ret;
21246
21247   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21248     {
21249       if (unformat (line_input, "%s", &name))
21250         ;
21251       else
21252         break;
21253     }
21254
21255   if (vec_len (name) > 127)
21256     {
21257       errmsg ("name too long");
21258       return -99;
21259     }
21260
21261   /* Construct the API message */
21262   M (DNS_RESOLVE_NAME, mp);
21263   memcpy (mp->name, name, vec_len (name));
21264   vec_free (name);
21265
21266   /* send it... */
21267   S (mp);
21268   /* Wait for the reply */
21269   W (ret);
21270   return ret;
21271 }
21272
21273 static int
21274 api_dns_resolve_ip (vat_main_t * vam)
21275 {
21276   unformat_input_t *line_input = vam->input;
21277   vl_api_dns_resolve_ip_t *mp;
21278   int is_ip6 = -1;
21279   ip4_address_t addr4;
21280   ip6_address_t addr6;
21281   int ret;
21282
21283   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21284     {
21285       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21286         is_ip6 = 1;
21287       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21288         is_ip6 = 0;
21289       else
21290         break;
21291     }
21292
21293   if (is_ip6 == -1)
21294     {
21295       errmsg ("missing address");
21296       return -99;
21297     }
21298
21299   /* Construct the API message */
21300   M (DNS_RESOLVE_IP, mp);
21301   mp->is_ip6 = is_ip6;
21302   if (is_ip6)
21303     memcpy (mp->address, &addr6, sizeof (addr6));
21304   else
21305     memcpy (mp->address, &addr4, sizeof (addr4));
21306
21307   /* send it... */
21308   S (mp);
21309   /* Wait for the reply */
21310   W (ret);
21311   return ret;
21312 }
21313
21314 static int
21315 api_dns_name_server_add_del (vat_main_t * vam)
21316 {
21317   unformat_input_t *i = vam->input;
21318   vl_api_dns_name_server_add_del_t *mp;
21319   u8 is_add = 1;
21320   ip6_address_t ip6_server;
21321   ip4_address_t ip4_server;
21322   int ip6_set = 0;
21323   int ip4_set = 0;
21324   int ret = 0;
21325
21326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21327     {
21328       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21329         ip6_set = 1;
21330       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21331         ip4_set = 1;
21332       else if (unformat (i, "del"))
21333         is_add = 0;
21334       else
21335         {
21336           clib_warning ("parse error '%U'", format_unformat_error, i);
21337           return -99;
21338         }
21339     }
21340
21341   if (ip4_set && ip6_set)
21342     {
21343       errmsg ("Only one server address allowed per message");
21344       return -99;
21345     }
21346   if ((ip4_set + ip6_set) == 0)
21347     {
21348       errmsg ("Server address required");
21349       return -99;
21350     }
21351
21352   /* Construct the API message */
21353   M (DNS_NAME_SERVER_ADD_DEL, mp);
21354
21355   if (ip6_set)
21356     {
21357       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21358       mp->is_ip6 = 1;
21359     }
21360   else
21361     {
21362       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21363       mp->is_ip6 = 0;
21364     }
21365
21366   mp->is_add = is_add;
21367
21368   /* send it... */
21369   S (mp);
21370
21371   /* Wait for a reply, return good/bad news  */
21372   W (ret);
21373   return ret;
21374 }
21375
21376 static void
21377 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21378 {
21379   vat_main_t *vam = &vat_main;
21380
21381   if (mp->is_ip4)
21382     {
21383       print (vam->ofp,
21384              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21385              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21386              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21387              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21388              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21389              clib_net_to_host_u32 (mp->action_index), mp->tag);
21390     }
21391   else
21392     {
21393       print (vam->ofp,
21394              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21395              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21396              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21397              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21398              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21399              clib_net_to_host_u32 (mp->action_index), mp->tag);
21400     }
21401 }
21402
21403 static void
21404 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21405                                              mp)
21406 {
21407   vat_main_t *vam = &vat_main;
21408   vat_json_node_t *node = NULL;
21409   struct in6_addr ip6;
21410   struct in_addr ip4;
21411
21412   if (VAT_JSON_ARRAY != vam->json_tree.type)
21413     {
21414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21415       vat_json_init_array (&vam->json_tree);
21416     }
21417   node = vat_json_array_add (&vam->json_tree);
21418   vat_json_init_object (node);
21419
21420   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21421   vat_json_object_add_uint (node, "appns_index",
21422                             clib_net_to_host_u32 (mp->appns_index));
21423   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21424   vat_json_object_add_uint (node, "scope", mp->scope);
21425   vat_json_object_add_uint (node, "action_index",
21426                             clib_net_to_host_u32 (mp->action_index));
21427   vat_json_object_add_uint (node, "lcl_port",
21428                             clib_net_to_host_u16 (mp->lcl_port));
21429   vat_json_object_add_uint (node, "rmt_port",
21430                             clib_net_to_host_u16 (mp->rmt_port));
21431   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21432   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21433   vat_json_object_add_string_copy (node, "tag", mp->tag);
21434   if (mp->is_ip4)
21435     {
21436       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21437       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21438       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21439       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21440     }
21441   else
21442     {
21443       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21444       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21445       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21446       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21447     }
21448 }
21449
21450 static int
21451 api_session_rule_add_del (vat_main_t * vam)
21452 {
21453   vl_api_session_rule_add_del_t *mp;
21454   unformat_input_t *i = vam->input;
21455   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21456   u32 appns_index = 0, scope = 0;
21457   ip4_address_t lcl_ip4, rmt_ip4;
21458   ip6_address_t lcl_ip6, rmt_ip6;
21459   u8 is_ip4 = 1, conn_set = 0;
21460   u8 is_add = 1, *tag = 0;
21461   int ret;
21462
21463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21464     {
21465       if (unformat (i, "del"))
21466         is_add = 0;
21467       else if (unformat (i, "add"))
21468         ;
21469       else if (unformat (i, "proto tcp"))
21470         proto = 0;
21471       else if (unformat (i, "proto udp"))
21472         proto = 1;
21473       else if (unformat (i, "appns %d", &appns_index))
21474         ;
21475       else if (unformat (i, "scope %d", &scope))
21476         ;
21477       else if (unformat (i, "tag %_%v%_", &tag))
21478         ;
21479       else
21480         if (unformat
21481             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21482              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21483              &rmt_port))
21484         {
21485           is_ip4 = 1;
21486           conn_set = 1;
21487         }
21488       else
21489         if (unformat
21490             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21491              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21492              &rmt_port))
21493         {
21494           is_ip4 = 0;
21495           conn_set = 1;
21496         }
21497       else if (unformat (i, "action %d", &action))
21498         ;
21499       else
21500         break;
21501     }
21502   if (proto == ~0 || !conn_set || action == ~0)
21503     {
21504       errmsg ("transport proto, connection and action must be set");
21505       return -99;
21506     }
21507
21508   if (scope > 3)
21509     {
21510       errmsg ("scope should be 0-3");
21511       return -99;
21512     }
21513
21514   M (SESSION_RULE_ADD_DEL, mp);
21515
21516   mp->is_ip4 = is_ip4;
21517   mp->transport_proto = proto;
21518   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21519   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21520   mp->lcl_plen = lcl_plen;
21521   mp->rmt_plen = rmt_plen;
21522   mp->action_index = clib_host_to_net_u32 (action);
21523   mp->appns_index = clib_host_to_net_u32 (appns_index);
21524   mp->scope = scope;
21525   mp->is_add = is_add;
21526   if (is_ip4)
21527     {
21528       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21529       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21530     }
21531   else
21532     {
21533       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21534       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21535     }
21536   if (tag)
21537     {
21538       clib_memcpy (mp->tag, tag, vec_len (tag));
21539       vec_free (tag);
21540     }
21541
21542   S (mp);
21543   W (ret);
21544   return ret;
21545 }
21546
21547 static int
21548 api_session_rules_dump (vat_main_t * vam)
21549 {
21550   vl_api_session_rules_dump_t *mp;
21551   vl_api_control_ping_t *mp_ping;
21552   int ret;
21553
21554   if (!vam->json_output)
21555     {
21556       print (vam->ofp, "%=20s", "Session Rules");
21557     }
21558
21559   M (SESSION_RULES_DUMP, mp);
21560   /* send it... */
21561   S (mp);
21562
21563   /* Use a control ping for synchronization */
21564   MPING (CONTROL_PING, mp_ping);
21565   S (mp_ping);
21566
21567   /* Wait for a reply... */
21568   W (ret);
21569   return ret;
21570 }
21571
21572 static int
21573 api_ip_container_proxy_add_del (vat_main_t * vam)
21574 {
21575   vl_api_ip_container_proxy_add_del_t *mp;
21576   unformat_input_t *i = vam->input;
21577   u32 sw_if_index = ~0;
21578   vl_api_prefix_t pfx = { };
21579   u8 is_add = 1;
21580   int ret;
21581
21582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21583     {
21584       if (unformat (i, "del"))
21585         is_add = 0;
21586       else if (unformat (i, "add"))
21587         ;
21588       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21589         ;
21590       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21591         ;
21592       else
21593         break;
21594     }
21595   if (sw_if_index == ~0 || pfx.address_length == 0)
21596     {
21597       errmsg ("address and sw_if_index must be set");
21598       return -99;
21599     }
21600
21601   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21602
21603   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21604   mp->is_add = is_add;
21605   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21606
21607   S (mp);
21608   W (ret);
21609   return ret;
21610 }
21611
21612 static int
21613 api_qos_record_enable_disable (vat_main_t * vam)
21614 {
21615   unformat_input_t *i = vam->input;
21616   vl_api_qos_record_enable_disable_t *mp;
21617   u32 sw_if_index, qs = 0xff;
21618   u8 sw_if_index_set = 0;
21619   u8 enable = 1;
21620   int ret;
21621
21622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21623     {
21624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21625         sw_if_index_set = 1;
21626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21627         sw_if_index_set = 1;
21628       else if (unformat (i, "%U", unformat_qos_source, &qs))
21629         ;
21630       else if (unformat (i, "disable"))
21631         enable = 0;
21632       else
21633         {
21634           clib_warning ("parse error '%U'", format_unformat_error, i);
21635           return -99;
21636         }
21637     }
21638
21639   if (sw_if_index_set == 0)
21640     {
21641       errmsg ("missing interface name or sw_if_index");
21642       return -99;
21643     }
21644   if (qs == 0xff)
21645     {
21646       errmsg ("input location must be specified");
21647       return -99;
21648     }
21649
21650   M (QOS_RECORD_ENABLE_DISABLE, mp);
21651
21652   mp->sw_if_index = ntohl (sw_if_index);
21653   mp->input_source = qs;
21654   mp->enable = enable;
21655
21656   S (mp);
21657   W (ret);
21658   return ret;
21659 }
21660
21661
21662 static int
21663 q_or_quit (vat_main_t * vam)
21664 {
21665 #if VPP_API_TEST_BUILTIN == 0
21666   longjmp (vam->jump_buf, 1);
21667 #endif
21668   return 0;                     /* not so much */
21669 }
21670
21671 static int
21672 q (vat_main_t * vam)
21673 {
21674   return q_or_quit (vam);
21675 }
21676
21677 static int
21678 quit (vat_main_t * vam)
21679 {
21680   return q_or_quit (vam);
21681 }
21682
21683 static int
21684 comment (vat_main_t * vam)
21685 {
21686   return 0;
21687 }
21688
21689 static int
21690 statseg (vat_main_t * vam)
21691 {
21692   ssvm_private_t *ssvmp = &vam->stat_segment;
21693   ssvm_shared_header_t *shared_header = ssvmp->sh;
21694   vlib_counter_t **counters;
21695   u64 thread0_index1_packets;
21696   u64 thread0_index1_bytes;
21697   f64 vector_rate, input_rate;
21698   uword *p;
21699
21700   uword *counter_vector_by_name;
21701   if (vam->stat_segment_lockp == 0)
21702     {
21703       errmsg ("Stat segment not mapped...");
21704       return -99;
21705     }
21706
21707   /* look up "/if/rx for sw_if_index 1 as a test */
21708
21709   clib_spinlock_lock (vam->stat_segment_lockp);
21710
21711   counter_vector_by_name = (uword *) shared_header->opaque[1];
21712
21713   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21714   if (p == 0)
21715     {
21716       clib_spinlock_unlock (vam->stat_segment_lockp);
21717       errmsg ("/if/tx not found?");
21718       return -99;
21719     }
21720
21721   /* Fish per-thread vector of combined counters from shared memory */
21722   counters = (vlib_counter_t **) p[0];
21723
21724   if (vec_len (counters[0]) < 2)
21725     {
21726       clib_spinlock_unlock (vam->stat_segment_lockp);
21727       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21728       return -99;
21729     }
21730
21731   /* Read thread 0 sw_if_index 1 counter */
21732   thread0_index1_packets = counters[0][1].packets;
21733   thread0_index1_bytes = counters[0][1].bytes;
21734
21735   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21736   if (p == 0)
21737     {
21738       clib_spinlock_unlock (vam->stat_segment_lockp);
21739       errmsg ("vector_rate not found?");
21740       return -99;
21741     }
21742
21743   vector_rate = *(f64 *) (p[0]);
21744   p = hash_get_mem (counter_vector_by_name, "input_rate");
21745   if (p == 0)
21746     {
21747       clib_spinlock_unlock (vam->stat_segment_lockp);
21748       errmsg ("input_rate not found?");
21749       return -99;
21750     }
21751   input_rate = *(f64 *) (p[0]);
21752
21753   clib_spinlock_unlock (vam->stat_segment_lockp);
21754
21755   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21756          vector_rate, input_rate);
21757   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21758          thread0_index1_packets, thread0_index1_bytes);
21759
21760   return 0;
21761 }
21762
21763 static int
21764 cmd_cmp (void *a1, void *a2)
21765 {
21766   u8 **c1 = a1;
21767   u8 **c2 = a2;
21768
21769   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21770 }
21771
21772 static int
21773 help (vat_main_t * vam)
21774 {
21775   u8 **cmds = 0;
21776   u8 *name = 0;
21777   hash_pair_t *p;
21778   unformat_input_t *i = vam->input;
21779   int j;
21780
21781   if (unformat (i, "%s", &name))
21782     {
21783       uword *hs;
21784
21785       vec_add1 (name, 0);
21786
21787       hs = hash_get_mem (vam->help_by_name, name);
21788       if (hs)
21789         print (vam->ofp, "usage: %s %s", name, hs[0]);
21790       else
21791         print (vam->ofp, "No such msg / command '%s'", name);
21792       vec_free (name);
21793       return 0;
21794     }
21795
21796   print (vam->ofp, "Help is available for the following:");
21797
21798     /* *INDENT-OFF* */
21799     hash_foreach_pair (p, vam->function_by_name,
21800     ({
21801       vec_add1 (cmds, (u8 *)(p->key));
21802     }));
21803     /* *INDENT-ON* */
21804
21805   vec_sort_with_function (cmds, cmd_cmp);
21806
21807   for (j = 0; j < vec_len (cmds); j++)
21808     print (vam->ofp, "%s", cmds[j]);
21809
21810   vec_free (cmds);
21811   return 0;
21812 }
21813
21814 static int
21815 set (vat_main_t * vam)
21816 {
21817   u8 *name = 0, *value = 0;
21818   unformat_input_t *i = vam->input;
21819
21820   if (unformat (i, "%s", &name))
21821     {
21822       /* The input buffer is a vector, not a string. */
21823       value = vec_dup (i->buffer);
21824       vec_delete (value, i->index, 0);
21825       /* Almost certainly has a trailing newline */
21826       if (value[vec_len (value) - 1] == '\n')
21827         value[vec_len (value) - 1] = 0;
21828       /* Make sure it's a proper string, one way or the other */
21829       vec_add1 (value, 0);
21830       (void) clib_macro_set_value (&vam->macro_main,
21831                                    (char *) name, (char *) value);
21832     }
21833   else
21834     errmsg ("usage: set <name> <value>");
21835
21836   vec_free (name);
21837   vec_free (value);
21838   return 0;
21839 }
21840
21841 static int
21842 unset (vat_main_t * vam)
21843 {
21844   u8 *name = 0;
21845
21846   if (unformat (vam->input, "%s", &name))
21847     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21848       errmsg ("unset: %s wasn't set", name);
21849   vec_free (name);
21850   return 0;
21851 }
21852
21853 typedef struct
21854 {
21855   u8 *name;
21856   u8 *value;
21857 } macro_sort_t;
21858
21859
21860 static int
21861 macro_sort_cmp (void *a1, void *a2)
21862 {
21863   macro_sort_t *s1 = a1;
21864   macro_sort_t *s2 = a2;
21865
21866   return strcmp ((char *) (s1->name), (char *) (s2->name));
21867 }
21868
21869 static int
21870 dump_macro_table (vat_main_t * vam)
21871 {
21872   macro_sort_t *sort_me = 0, *sm;
21873   int i;
21874   hash_pair_t *p;
21875
21876     /* *INDENT-OFF* */
21877     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21878     ({
21879       vec_add2 (sort_me, sm, 1);
21880       sm->name = (u8 *)(p->key);
21881       sm->value = (u8 *) (p->value[0]);
21882     }));
21883     /* *INDENT-ON* */
21884
21885   vec_sort_with_function (sort_me, macro_sort_cmp);
21886
21887   if (vec_len (sort_me))
21888     print (vam->ofp, "%-15s%s", "Name", "Value");
21889   else
21890     print (vam->ofp, "The macro table is empty...");
21891
21892   for (i = 0; i < vec_len (sort_me); i++)
21893     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21894   return 0;
21895 }
21896
21897 static int
21898 dump_node_table (vat_main_t * vam)
21899 {
21900   int i, j;
21901   vlib_node_t *node, *next_node;
21902
21903   if (vec_len (vam->graph_nodes) == 0)
21904     {
21905       print (vam->ofp, "Node table empty, issue get_node_graph...");
21906       return 0;
21907     }
21908
21909   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21910     {
21911       node = vam->graph_nodes[0][i];
21912       print (vam->ofp, "[%d] %s", i, node->name);
21913       for (j = 0; j < vec_len (node->next_nodes); j++)
21914         {
21915           if (node->next_nodes[j] != ~0)
21916             {
21917               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21918               print (vam->ofp, "  [%d] %s", j, next_node->name);
21919             }
21920         }
21921     }
21922   return 0;
21923 }
21924
21925 static int
21926 value_sort_cmp (void *a1, void *a2)
21927 {
21928   name_sort_t *n1 = a1;
21929   name_sort_t *n2 = a2;
21930
21931   if (n1->value < n2->value)
21932     return -1;
21933   if (n1->value > n2->value)
21934     return 1;
21935   return 0;
21936 }
21937
21938
21939 static int
21940 dump_msg_api_table (vat_main_t * vam)
21941 {
21942   api_main_t *am = &api_main;
21943   name_sort_t *nses = 0, *ns;
21944   hash_pair_t *hp;
21945   int i;
21946
21947   /* *INDENT-OFF* */
21948   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21949   ({
21950     vec_add2 (nses, ns, 1);
21951     ns->name = (u8 *)(hp->key);
21952     ns->value = (u32) hp->value[0];
21953   }));
21954   /* *INDENT-ON* */
21955
21956   vec_sort_with_function (nses, value_sort_cmp);
21957
21958   for (i = 0; i < vec_len (nses); i++)
21959     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21960   vec_free (nses);
21961   return 0;
21962 }
21963
21964 static int
21965 get_msg_id (vat_main_t * vam)
21966 {
21967   u8 *name_and_crc;
21968   u32 message_index;
21969
21970   if (unformat (vam->input, "%s", &name_and_crc))
21971     {
21972       message_index = vl_msg_api_get_msg_index (name_and_crc);
21973       if (message_index == ~0)
21974         {
21975           print (vam->ofp, " '%s' not found", name_and_crc);
21976           return 0;
21977         }
21978       print (vam->ofp, " '%s' has message index %d",
21979              name_and_crc, message_index);
21980       return 0;
21981     }
21982   errmsg ("name_and_crc required...");
21983   return 0;
21984 }
21985
21986 static int
21987 search_node_table (vat_main_t * vam)
21988 {
21989   unformat_input_t *line_input = vam->input;
21990   u8 *node_to_find;
21991   int j;
21992   vlib_node_t *node, *next_node;
21993   uword *p;
21994
21995   if (vam->graph_node_index_by_name == 0)
21996     {
21997       print (vam->ofp, "Node table empty, issue get_node_graph...");
21998       return 0;
21999     }
22000
22001   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22002     {
22003       if (unformat (line_input, "%s", &node_to_find))
22004         {
22005           vec_add1 (node_to_find, 0);
22006           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22007           if (p == 0)
22008             {
22009               print (vam->ofp, "%s not found...", node_to_find);
22010               goto out;
22011             }
22012           node = vam->graph_nodes[0][p[0]];
22013           print (vam->ofp, "[%d] %s", p[0], node->name);
22014           for (j = 0; j < vec_len (node->next_nodes); j++)
22015             {
22016               if (node->next_nodes[j] != ~0)
22017                 {
22018                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22019                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22020                 }
22021             }
22022         }
22023
22024       else
22025         {
22026           clib_warning ("parse error '%U'", format_unformat_error,
22027                         line_input);
22028           return -99;
22029         }
22030
22031     out:
22032       vec_free (node_to_find);
22033
22034     }
22035
22036   return 0;
22037 }
22038
22039
22040 static int
22041 script (vat_main_t * vam)
22042 {
22043 #if (VPP_API_TEST_BUILTIN==0)
22044   u8 *s = 0;
22045   char *save_current_file;
22046   unformat_input_t save_input;
22047   jmp_buf save_jump_buf;
22048   u32 save_line_number;
22049
22050   FILE *new_fp, *save_ifp;
22051
22052   if (unformat (vam->input, "%s", &s))
22053     {
22054       new_fp = fopen ((char *) s, "r");
22055       if (new_fp == 0)
22056         {
22057           errmsg ("Couldn't open script file %s", s);
22058           vec_free (s);
22059           return -99;
22060         }
22061     }
22062   else
22063     {
22064       errmsg ("Missing script name");
22065       return -99;
22066     }
22067
22068   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22069   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22070   save_ifp = vam->ifp;
22071   save_line_number = vam->input_line_number;
22072   save_current_file = (char *) vam->current_file;
22073
22074   vam->input_line_number = 0;
22075   vam->ifp = new_fp;
22076   vam->current_file = s;
22077   do_one_file (vam);
22078
22079   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22080   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22081   vam->ifp = save_ifp;
22082   vam->input_line_number = save_line_number;
22083   vam->current_file = (u8 *) save_current_file;
22084   vec_free (s);
22085
22086   return 0;
22087 #else
22088   clib_warning ("use the exec command...");
22089   return -99;
22090 #endif
22091 }
22092
22093 static int
22094 echo (vat_main_t * vam)
22095 {
22096   print (vam->ofp, "%v", vam->input->buffer);
22097   return 0;
22098 }
22099
22100 /* List of API message constructors, CLI names map to api_xxx */
22101 #define foreach_vpe_api_msg                                             \
22102 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22103 _(sw_interface_dump,"")                                                 \
22104 _(sw_interface_set_flags,                                               \
22105   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22106 _(sw_interface_add_del_address,                                         \
22107   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22108 _(sw_interface_set_rx_mode,                                             \
22109   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22110 _(sw_interface_set_rx_placement,                                        \
22111   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22112 _(sw_interface_rx_placement_dump,                                       \
22113   "[<intfc> | sw_if_index <id>]")                                         \
22114 _(sw_interface_set_table,                                               \
22115   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22116 _(sw_interface_set_mpls_enable,                                         \
22117   "<intfc> | sw_if_index [disable | dis]")                              \
22118 _(sw_interface_set_vpath,                                               \
22119   "<intfc> | sw_if_index <id> enable | disable")                        \
22120 _(sw_interface_set_vxlan_bypass,                                        \
22121   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22122 _(sw_interface_set_geneve_bypass,                                       \
22123   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22124 _(sw_interface_set_l2_xconnect,                                         \
22125   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22126   "enable | disable")                                                   \
22127 _(sw_interface_set_l2_bridge,                                           \
22128   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22129   "[shg <split-horizon-group>] [bvi]\n"                                 \
22130   "enable | disable")                                                   \
22131 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22132 _(bridge_domain_add_del,                                                \
22133   "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") \
22134 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22135 _(l2fib_add_del,                                                        \
22136   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22137 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22138 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22139 _(l2_flags,                                                             \
22140   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22141 _(bridge_flags,                                                         \
22142   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22143 _(tap_create_v2,                                                        \
22144   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22145 _(tap_delete_v2,                                                        \
22146   "<vpp-if-name> | sw_if_index <id>")                                   \
22147 _(sw_interface_tap_v2_dump, "")                                         \
22148 _(virtio_pci_create,                                                    \
22149   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
22150 _(virtio_pci_delete,                                                    \
22151   "<vpp-if-name> | sw_if_index <id>")                                   \
22152 _(sw_interface_virtio_pci_dump, "")                                     \
22153 _(bond_create,                                                          \
22154   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22155   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22156   "[id <if-id>]")                                                       \
22157 _(bond_delete,                                                          \
22158   "<vpp-if-name> | sw_if_index <id>")                                   \
22159 _(bond_enslave,                                                         \
22160   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22161 _(bond_detach_slave,                                                    \
22162   "sw_if_index <n>")                                                    \
22163 _(sw_interface_bond_dump, "")                                           \
22164 _(sw_interface_slave_dump,                                              \
22165   "<vpp-if-name> | sw_if_index <id>")                                   \
22166 _(ip_table_add_del,                                                     \
22167   "table <n> [ipv6] [add | del]\n")                                     \
22168 _(ip_add_del_route,                                                     \
22169   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22170   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22171   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22172   "[multipath] [count <n>] [del]")                                      \
22173 _(ip_mroute_add_del,                                                    \
22174   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22175   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22176 _(mpls_table_add_del,                                                   \
22177   "table <n> [add | del]\n")                                            \
22178 _(mpls_route_add_del,                                                   \
22179   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22180   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22181   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22182   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22183   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22184   "[count <n>] [del]")                                                  \
22185 _(mpls_ip_bind_unbind,                                                  \
22186   "<label> <addr/len>")                                                 \
22187 _(mpls_tunnel_add_del,                                                  \
22188   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22189   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22190   "[l2-only]  [out-label <n>]")                                         \
22191 _(sr_mpls_policy_add,                                                   \
22192   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22193 _(sr_mpls_policy_del,                                                   \
22194   "bsid <id>")                                                          \
22195 _(bier_table_add_del,                                                   \
22196   "<label> <sub-domain> <set> <bsl> [del]")                             \
22197 _(bier_route_add_del,                                                   \
22198   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22199   "[<intfc> | sw_if_index <id>]"                                        \
22200   "[weight <n>] [del] [multipath]")                                     \
22201 _(proxy_arp_add_del,                                                    \
22202   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22203 _(proxy_arp_intfc_enable_disable,                                       \
22204   "<intfc> | sw_if_index <id> enable | disable")                        \
22205 _(sw_interface_set_unnumbered,                                          \
22206   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22207 _(ip_neighbor_add_del,                                                  \
22208   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22209   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22210 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22211 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22212   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22213   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22214   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22215 _(reset_fib, "vrf <n> [ipv6]")                                          \
22216 _(dhcp_proxy_config,                                                    \
22217   "svr <v46-address> src <v46-address>\n"                               \
22218    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22219 _(dhcp_proxy_set_vss,                                                   \
22220   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22221 _(dhcp_proxy_dump, "ip6")                                               \
22222 _(dhcp_client_config,                                                   \
22223   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22224 _(set_ip_flow_hash,                                                     \
22225   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22226 _(sw_interface_ip6_enable_disable,                                      \
22227   "<intfc> | sw_if_index <id> enable | disable")                        \
22228 _(ip6nd_proxy_add_del,                                                  \
22229   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22230 _(ip6nd_proxy_dump, "")                                                 \
22231 _(sw_interface_ip6nd_ra_prefix,                                         \
22232   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22233   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22234   "[nolink] [isno]")                                                    \
22235 _(sw_interface_ip6nd_ra_config,                                         \
22236   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22237   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22238   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22239 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22240 _(l2_patch_add_del,                                                     \
22241   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22242   "enable | disable")                                                   \
22243 _(sr_localsid_add_del,                                                  \
22244   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22245   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22246 _(classify_add_del_table,                                               \
22247   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22248   " [del] [del-chain] mask <mask-value>\n"                              \
22249   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22250   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22251 _(classify_add_del_session,                                             \
22252   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22253   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22254   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22255   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22256 _(classify_set_interface_ip_table,                                      \
22257   "<intfc> | sw_if_index <nn> table <nn>")                              \
22258 _(classify_set_interface_l2_tables,                                     \
22259   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22260   "  [other-table <nn>]")                                               \
22261 _(get_node_index, "node <node-name")                                    \
22262 _(add_node_next, "node <node-name> next <next-node-name>")              \
22263 _(l2tpv3_create_tunnel,                                                 \
22264   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22265   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22266   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22267 _(l2tpv3_set_tunnel_cookies,                                            \
22268   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22269   "[new_remote_cookie <nn>]\n")                                         \
22270 _(l2tpv3_interface_enable_disable,                                      \
22271   "<intfc> | sw_if_index <nn> enable | disable")                        \
22272 _(l2tpv3_set_lookup_key,                                                \
22273   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22274 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22275 _(vxlan_offload_rx,                                                     \
22276   "hw { <interface name> | hw_if_index <nn>} "                          \
22277   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22278 _(vxlan_add_del_tunnel,                                                 \
22279   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22280   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22281   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22282 _(geneve_add_del_tunnel,                                                \
22283   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22284   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22285   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22286 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22287 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22288 _(gre_tunnel_add_del,                                                   \
22289   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22290   "[teb | erspan <session-id>] [del]")                                  \
22291 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22292 _(l2_fib_clear_table, "")                                               \
22293 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22294 _(l2_interface_vlan_tag_rewrite,                                        \
22295   "<intfc> | sw_if_index <nn> \n"                                       \
22296   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22297   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22298 _(create_vhost_user_if,                                                 \
22299         "socket <filename> [server] [renumber <dev_instance>] "         \
22300         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22301         "[mac <mac_address>]")                                          \
22302 _(modify_vhost_user_if,                                                 \
22303         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22304         "[server] [renumber <dev_instance>]")                           \
22305 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22306 _(sw_interface_vhost_user_dump, "")                                     \
22307 _(show_version, "")                                                     \
22308 _(show_threads, "")                                                     \
22309 _(vxlan_gpe_add_del_tunnel,                                             \
22310   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22311   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22312   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22313   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22314 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22315 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22316 _(interface_name_renumber,                                              \
22317   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22318 _(input_acl_set_interface,                                              \
22319   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22320   "  [l2-table <nn>] [del]")                                            \
22321 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22322 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22323   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22324 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22325 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22326 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22327 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22328 _(ip_dump, "ipv4 | ipv6")                                               \
22329 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22330 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22331   "  spid_id <n> ")                                                     \
22332 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22333   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22334   "  integ_alg <alg> integ_key <hex>")                                  \
22335 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22336   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22337   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22338   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22339 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22340   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22341   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22342   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22343   "  [instance <n>]")     \
22344 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22345 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22346 _(delete_loopback,"sw_if_index <nn>")                                   \
22347 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22348 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22349 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22350 _(want_interface_events,  "enable|disable")                             \
22351 _(get_first_msg_id, "client <name>")                                    \
22352 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22353 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22354   "fib-id <nn> [ip4][ip6][default]")                                    \
22355 _(get_node_graph, " ")                                                  \
22356 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22357 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22358 _(ioam_disable, "")                                                     \
22359 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22360                             " sw_if_index <sw_if_index> p <priority> "  \
22361                             "w <weight>] [del]")                        \
22362 _(one_add_del_locator, "locator-set <locator_name> "                    \
22363                         "iface <intf> | sw_if_index <sw_if_index> "     \
22364                         "p <priority> w <weight> [del]")                \
22365 _(one_add_del_local_eid,"vni <vni> eid "                                \
22366                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22367                          "locator-set <locator_name> [del]"             \
22368                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22369 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22370 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22371 _(one_enable_disable, "enable|disable")                                 \
22372 _(one_map_register_enable_disable, "enable|disable")                    \
22373 _(one_map_register_fallback_threshold, "<value>")                       \
22374 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22375 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22376                                "[seid <seid>] "                         \
22377                                "rloc <locator> p <prio> "               \
22378                                "w <weight> [rloc <loc> ... ] "          \
22379                                "action <action> [del-all]")             \
22380 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22381                           "<local-eid>")                                \
22382 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22383 _(one_use_petr, "ip-address> | disable")                                \
22384 _(one_map_request_mode, "src-dst|dst-only")                             \
22385 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22386 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22387 _(one_locator_set_dump, "[local | remote]")                             \
22388 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22389 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22390                        "[local] | [remote]")                            \
22391 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22392 _(one_ndp_bd_get, "")                                                   \
22393 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22394 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22395 _(one_l2_arp_bd_get, "")                                                \
22396 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22397 _(one_stats_enable_disable, "enable|disable")                           \
22398 _(show_one_stats_enable_disable, "")                                    \
22399 _(one_eid_table_vni_dump, "")                                           \
22400 _(one_eid_table_map_dump, "l2|l3")                                      \
22401 _(one_map_resolver_dump, "")                                            \
22402 _(one_map_server_dump, "")                                              \
22403 _(one_adjacencies_get, "vni <vni>")                                     \
22404 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22405 _(show_one_rloc_probe_state, "")                                        \
22406 _(show_one_map_register_state, "")                                      \
22407 _(show_one_status, "")                                                  \
22408 _(one_stats_dump, "")                                                   \
22409 _(one_stats_flush, "")                                                  \
22410 _(one_get_map_request_itr_rlocs, "")                                    \
22411 _(one_map_register_set_ttl, "<ttl>")                                    \
22412 _(one_set_transport_protocol, "udp|api")                                \
22413 _(one_get_transport_protocol, "")                                       \
22414 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22415 _(one_show_xtr_mode, "")                                                \
22416 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22417 _(one_show_pitr_mode, "")                                               \
22418 _(one_enable_disable_petr_mode, "enable|disable")                       \
22419 _(one_show_petr_mode, "")                                               \
22420 _(show_one_nsh_mapping, "")                                             \
22421 _(show_one_pitr, "")                                                    \
22422 _(show_one_use_petr, "")                                                \
22423 _(show_one_map_request_mode, "")                                        \
22424 _(show_one_map_register_ttl, "")                                        \
22425 _(show_one_map_register_fallback_threshold, "")                         \
22426 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22427                             " sw_if_index <sw_if_index> p <priority> "  \
22428                             "w <weight>] [del]")                        \
22429 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22430                         "iface <intf> | sw_if_index <sw_if_index> "     \
22431                         "p <priority> w <weight> [del]")                \
22432 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22433                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22434                          "locator-set <locator_name> [del]"             \
22435                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22436 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22437 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22438 _(lisp_enable_disable, "enable|disable")                                \
22439 _(lisp_map_register_enable_disable, "enable|disable")                   \
22440 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22441 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22442                                "[seid <seid>] "                         \
22443                                "rloc <locator> p <prio> "               \
22444                                "w <weight> [rloc <loc> ... ] "          \
22445                                "action <action> [del-all]")             \
22446 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22447                           "<local-eid>")                                \
22448 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22449 _(lisp_use_petr, "<ip-address> | disable")                              \
22450 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22451 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22452 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22453 _(lisp_locator_set_dump, "[local | remote]")                            \
22454 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22455 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22456                        "[local] | [remote]")                            \
22457 _(lisp_eid_table_vni_dump, "")                                          \
22458 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22459 _(lisp_map_resolver_dump, "")                                           \
22460 _(lisp_map_server_dump, "")                                             \
22461 _(lisp_adjacencies_get, "vni <vni>")                                    \
22462 _(gpe_fwd_entry_vnis_get, "")                                           \
22463 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22464 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22465                                 "[table <table-id>]")                   \
22466 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22467 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22468 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22469 _(gpe_get_encap_mode, "")                                               \
22470 _(lisp_gpe_add_del_iface, "up|down")                                    \
22471 _(lisp_gpe_enable_disable, "enable|disable")                            \
22472 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22473   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22474 _(show_lisp_rloc_probe_state, "")                                       \
22475 _(show_lisp_map_register_state, "")                                     \
22476 _(show_lisp_status, "")                                                 \
22477 _(lisp_get_map_request_itr_rlocs, "")                                   \
22478 _(show_lisp_pitr, "")                                                   \
22479 _(show_lisp_use_petr, "")                                               \
22480 _(show_lisp_map_request_mode, "")                                       \
22481 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22482 _(af_packet_delete, "name <host interface name>")                       \
22483 _(af_packet_dump, "")                                                   \
22484 _(policer_add_del, "name <policer name> <params> [del]")                \
22485 _(policer_dump, "[name <policer name>]")                                \
22486 _(policer_classify_set_interface,                                       \
22487   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22488   "  [l2-table <nn>] [del]")                                            \
22489 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22490 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22491     "[master|slave]")                                                   \
22492 _(netmap_delete, "name <interface name>")                               \
22493 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22494 _(mpls_fib_dump, "")                                                    \
22495 _(classify_table_ids, "")                                               \
22496 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22497 _(classify_table_info, "table_id <nn>")                                 \
22498 _(classify_session_dump, "table_id <nn>")                               \
22499 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22500     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22501     "[template_interval <nn>] [udp_checksum]")                          \
22502 _(ipfix_exporter_dump, "")                                              \
22503 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22504 _(ipfix_classify_stream_dump, "")                                       \
22505 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22506 _(ipfix_classify_table_dump, "")                                        \
22507 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22508 _(sw_interface_span_dump, "[l2]")                                           \
22509 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22510 _(pg_create_interface, "if_id <nn>")                                    \
22511 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22512 _(pg_enable_disable, "[stream <id>] disable")                           \
22513 _(ip_source_and_port_range_check_add_del,                               \
22514   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22515 _(ip_source_and_port_range_check_interface_add_del,                     \
22516   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22517   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22518 _(ipsec_gre_tunnel_add_del,                                             \
22519   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22520 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22521 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22522 _(l2_interface_pbb_tag_rewrite,                                         \
22523   "<intfc> | sw_if_index <nn> \n"                                       \
22524   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22525   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22526 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22527 _(flow_classify_set_interface,                                          \
22528   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22529 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22530 _(ip_fib_dump, "")                                                      \
22531 _(ip_mfib_dump, "")                                                     \
22532 _(ip6_fib_dump, "")                                                     \
22533 _(ip6_mfib_dump, "")                                                    \
22534 _(feature_enable_disable, "arc_name <arc_name> "                        \
22535   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22536 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22537 "[disable]")                                                            \
22538 _(l2_xconnect_dump, "")                                                 \
22539 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22540 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22541 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22542 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22543 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22544 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22545 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22546   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22547 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22548 _(sock_init_shm, "size <nnn>")                                          \
22549 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22550 _(dns_enable_disable, "[enable][disable]")                              \
22551 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22552 _(dns_resolve_name, "<hostname>")                                       \
22553 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22554 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22555 _(dns_resolve_name, "<hostname>")                                       \
22556 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22557   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22558 _(session_rules_dump, "")                                               \
22559 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22560 _(output_acl_set_interface,                                             \
22561   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22562   "  [l2-table <nn>] [del]")                                            \
22563 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22564
22565 /* List of command functions, CLI names map directly to functions */
22566 #define foreach_cli_function                                    \
22567 _(comment, "usage: comment <ignore-rest-of-line>")              \
22568 _(dump_interface_table, "usage: dump_interface_table")          \
22569 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22570 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22571 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22572 _(dump_macro_table, "usage: dump_macro_table ")                 \
22573 _(dump_node_table, "usage: dump_node_table")                    \
22574 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22575 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22576 _(echo, "usage: echo <message>")                                \
22577 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22578 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22579 _(help, "usage: help")                                          \
22580 _(q, "usage: quit")                                             \
22581 _(quit, "usage: quit")                                          \
22582 _(search_node_table, "usage: search_node_table <name>...")      \
22583 _(set, "usage: set <variable-name> <value>")                    \
22584 _(script, "usage: script <file-name>")                          \
22585 _(statseg, "usage: statseg");                                   \
22586 _(unset, "usage: unset <variable-name>")
22587
22588 #define _(N,n)                                  \
22589     static void vl_api_##n##_t_handler_uni      \
22590     (vl_api_##n##_t * mp)                       \
22591     {                                           \
22592         vat_main_t * vam = &vat_main;           \
22593         if (vam->json_output) {                 \
22594             vl_api_##n##_t_handler_json(mp);    \
22595         } else {                                \
22596             vl_api_##n##_t_handler(mp);         \
22597         }                                       \
22598     }
22599 foreach_vpe_api_reply_msg;
22600 #if VPP_API_TEST_BUILTIN == 0
22601 foreach_standalone_reply_msg;
22602 #endif
22603 #undef _
22604
22605 void
22606 vat_api_hookup (vat_main_t * vam)
22607 {
22608 #define _(N,n)                                                  \
22609     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22610                            vl_api_##n##_t_handler_uni,          \
22611                            vl_noop_handler,                     \
22612                            vl_api_##n##_t_endian,               \
22613                            vl_api_##n##_t_print,                \
22614                            sizeof(vl_api_##n##_t), 1);
22615   foreach_vpe_api_reply_msg;
22616 #if VPP_API_TEST_BUILTIN == 0
22617   foreach_standalone_reply_msg;
22618 #endif
22619 #undef _
22620
22621 #if (VPP_API_TEST_BUILTIN==0)
22622   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22623
22624   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22625
22626   vam->function_by_name = hash_create_string (0, sizeof (uword));
22627
22628   vam->help_by_name = hash_create_string (0, sizeof (uword));
22629 #endif
22630
22631   /* API messages we can send */
22632 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22633   foreach_vpe_api_msg;
22634 #undef _
22635
22636   /* Help strings */
22637 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22638   foreach_vpe_api_msg;
22639 #undef _
22640
22641   /* CLI functions */
22642 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22643   foreach_cli_function;
22644 #undef _
22645
22646   /* Help strings */
22647 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22648   foreach_cli_function;
22649 #undef _
22650 }
22651
22652 #if VPP_API_TEST_BUILTIN
22653 static clib_error_t *
22654 vat_api_hookup_shim (vlib_main_t * vm)
22655 {
22656   vat_api_hookup (&vat_main);
22657   return 0;
22658 }
22659
22660 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22661 #endif
22662
22663 /*
22664  * fd.io coding-style-patch-verification: ON
22665  *
22666  * Local Variables:
22667  * eval: (c-set-style "gnu")
22668  * End:
22669  */