virtio: Add api support in vat
[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/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.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 "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 u32
86 vl (void *p)
87 {
88   return vec_len (p);
89 }
90
91 int
92 vat_socket_connect (vat_main_t * vam)
93 {
94   int rv;
95   vam->socket_client_main = &socket_client_main;
96   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
97                                       "vpp_api_test",
98                                       0 /* default socket rx, tx buffer */ )))
99     return rv;
100   /* vpp expects the client index in network order */
101   vam->my_client_index = htonl (socket_client_main.client_index);
102   return 0;
103 }
104 #else /* vpp built-in case, we don't do sockets... */
105 int
106 vat_socket_connect (vat_main_t * vam)
107 {
108   return 0;
109 }
110
111 int
112 vl_socket_client_read (int wait)
113 {
114   return -1;
115 };
116
117 int
118 vl_socket_client_write ()
119 {
120   return -1;
121 };
122
123 void *
124 vl_socket_client_msg_alloc (int nbytes)
125 {
126   return 0;
127 }
128 #endif
129
130
131 f64
132 vat_time_now (vat_main_t * vam)
133 {
134 #if VPP_API_TEST_BUILTIN
135   return vlib_time_now (vam->vlib_main);
136 #else
137   return clib_time_now (&vam->clib_time);
138 #endif
139 }
140
141 void
142 errmsg (char *fmt, ...)
143 {
144   vat_main_t *vam = &vat_main;
145   va_list va;
146   u8 *s;
147
148   va_start (va, fmt);
149   s = va_format (0, fmt, &va);
150   va_end (va);
151
152   vec_add1 (s, 0);
153
154 #if VPP_API_TEST_BUILTIN
155   vlib_cli_output (vam->vlib_main, (char *) s);
156 #else
157   {
158     if (vam->ifp != stdin)
159       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
160                vam->input_line_number);
161     fformat (vam->ofp, (char *) s);
162     fflush (vam->ofp);
163   }
164 #endif
165
166   vec_free (s);
167 }
168
169 #if VPP_API_TEST_BUILTIN == 0
170 static uword
171 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
172 {
173   vat_main_t *vam = va_arg (*args, vat_main_t *);
174   u32 *result = va_arg (*args, u32 *);
175   u8 *if_name;
176   uword *p;
177
178   if (!unformat (input, "%s", &if_name))
179     return 0;
180
181   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
182   if (p == 0)
183     return 0;
184   *result = p[0];
185   return 1;
186 }
187
188 static uword
189 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
190 {
191   return 0;
192 }
193
194 /* Parse an IP4 address %d.%d.%d.%d. */
195 uword
196 unformat_ip4_address (unformat_input_t * input, va_list * args)
197 {
198   u8 *result = va_arg (*args, u8 *);
199   unsigned a[4];
200
201   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
202     return 0;
203
204   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
205     return 0;
206
207   result[0] = a[0];
208   result[1] = a[1];
209   result[2] = a[2];
210   result[3] = a[3];
211
212   return 1;
213 }
214
215 uword
216 unformat_ethernet_address (unformat_input_t * input, va_list * args)
217 {
218   u8 *result = va_arg (*args, u8 *);
219   u32 i, a[6];
220
221   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
222                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
223     return 0;
224
225   /* Check range. */
226   for (i = 0; i < 6; i++)
227     if (a[i] >= (1 << 8))
228       return 0;
229
230   for (i = 0; i < 6; i++)
231     result[i] = a[i];
232
233   return 1;
234 }
235
236 /* Returns ethernet type as an int in host byte order. */
237 uword
238 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
239                                         va_list * args)
240 {
241   u16 *result = va_arg (*args, u16 *);
242   int type;
243
244   /* Numeric type. */
245   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
246     {
247       if (type >= (1 << 16))
248         return 0;
249       *result = type;
250       return 1;
251     }
252   return 0;
253 }
254
255 /* Parse an IP6 address. */
256 uword
257 unformat_ip6_address (unformat_input_t * input, va_list * args)
258 {
259   ip6_address_t *result = va_arg (*args, ip6_address_t *);
260   u16 hex_quads[8];
261   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
262   uword c, n_colon, double_colon_index;
263
264   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
265   double_colon_index = ARRAY_LEN (hex_quads);
266   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
267     {
268       hex_digit = 16;
269       if (c >= '0' && c <= '9')
270         hex_digit = c - '0';
271       else if (c >= 'a' && c <= 'f')
272         hex_digit = c + 10 - 'a';
273       else if (c >= 'A' && c <= 'F')
274         hex_digit = c + 10 - 'A';
275       else if (c == ':' && n_colon < 2)
276         n_colon++;
277       else
278         {
279           unformat_put_input (input);
280           break;
281         }
282
283       /* Too many hex quads. */
284       if (n_hex_quads >= ARRAY_LEN (hex_quads))
285         return 0;
286
287       if (hex_digit < 16)
288         {
289           hex_quad = (hex_quad << 4) | hex_digit;
290
291           /* Hex quad must fit in 16 bits. */
292           if (n_hex_digits >= 4)
293             return 0;
294
295           n_colon = 0;
296           n_hex_digits++;
297         }
298
299       /* Save position of :: */
300       if (n_colon == 2)
301         {
302           /* More than one :: ? */
303           if (double_colon_index < ARRAY_LEN (hex_quads))
304             return 0;
305           double_colon_index = n_hex_quads;
306         }
307
308       if (n_colon > 0 && n_hex_digits > 0)
309         {
310           hex_quads[n_hex_quads++] = hex_quad;
311           hex_quad = 0;
312           n_hex_digits = 0;
313         }
314     }
315
316   if (n_hex_digits > 0)
317     hex_quads[n_hex_quads++] = hex_quad;
318
319   {
320     word i;
321
322     /* Expand :: to appropriate number of zero hex quads. */
323     if (double_colon_index < ARRAY_LEN (hex_quads))
324       {
325         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
326
327         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
328           hex_quads[n_zero + i] = hex_quads[i];
329
330         for (i = 0; i < n_zero; i++)
331           hex_quads[double_colon_index + i] = 0;
332
333         n_hex_quads = ARRAY_LEN (hex_quads);
334       }
335
336     /* Too few hex quads given. */
337     if (n_hex_quads < ARRAY_LEN (hex_quads))
338       return 0;
339
340     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
341       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
342
343     return 1;
344   }
345 }
346
347 uword
348 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
349 {
350   u32 *r = va_arg (*args, u32 *);
351
352   if (0);
353 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
354   foreach_ipsec_policy_action
355 #undef _
356     else
357     return 0;
358   return 1;
359 }
360
361 uword
362 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
363 {
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
368   foreach_ipsec_crypto_alg
369 #undef _
370     else
371     return 0;
372   return 1;
373 }
374
375 u8 *
376 format_ipsec_crypto_alg (u8 * s, va_list * args)
377 {
378   u32 i = va_arg (*args, u32);
379   u8 *t = 0;
380
381   switch (i)
382     {
383 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
384       foreach_ipsec_crypto_alg
385 #undef _
386     default:
387       return format (s, "unknown");
388     }
389   return format (s, "%s", t);
390 }
391
392 uword
393 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
394 {
395   u32 *r = va_arg (*args, u32 *);
396
397   if (0);
398 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
399   foreach_ipsec_integ_alg
400 #undef _
401     else
402     return 0;
403   return 1;
404 }
405
406 u8 *
407 format_ipsec_integ_alg (u8 * s, va_list * args)
408 {
409   u32 i = va_arg (*args, u32);
410   u8 *t = 0;
411
412   switch (i)
413     {
414 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
415       foreach_ipsec_integ_alg
416 #undef _
417     default:
418       return format (s, "unknown");
419     }
420   return format (s, "%s", t);
421 }
422
423 uword
424 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
425 {
426   u32 *r = va_arg (*args, u32 *);
427
428   if (0);
429 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
430   foreach_ikev2_auth_method
431 #undef _
432     else
433     return 0;
434   return 1;
435 }
436
437 uword
438 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
439 {
440   u32 *r = va_arg (*args, u32 *);
441
442   if (0);
443 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
444   foreach_ikev2_id_type
445 #undef _
446     else
447     return 0;
448   return 1;
449 }
450 #else /* VPP_API_TEST_BUILTIN == 1 */
451 static uword
452 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
453 {
454   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
455   vnet_main_t *vnm = vnet_get_main ();
456   u32 *result = va_arg (*args, u32 *);
457
458   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
459 }
460
461 static uword
462 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
463 {
464   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
465   vnet_main_t *vnm = vnet_get_main ();
466   u32 *result = va_arg (*args, u32 *);
467
468   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
469 }
470
471 #endif /* VPP_API_TEST_BUILTIN */
472
473 static uword
474 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
475 {
476   u8 *r = va_arg (*args, u8 *);
477
478   if (unformat (input, "kbps"))
479     *r = SSE2_QOS_RATE_KBPS;
480   else if (unformat (input, "pps"))
481     *r = SSE2_QOS_RATE_PPS;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_round_type (unformat_input_t * input, va_list * args)
489 {
490   u8 *r = va_arg (*args, u8 *);
491
492   if (unformat (input, "closest"))
493     *r = SSE2_QOS_ROUND_TO_CLOSEST;
494   else if (unformat (input, "up"))
495     *r = SSE2_QOS_ROUND_TO_UP;
496   else if (unformat (input, "down"))
497     *r = SSE2_QOS_ROUND_TO_DOWN;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_policer_type (unformat_input_t * input, va_list * args)
505 {
506   u8 *r = va_arg (*args, u8 *);
507
508   if (unformat (input, "1r2c"))
509     *r = SSE2_QOS_POLICER_TYPE_1R2C;
510   else if (unformat (input, "1r3c"))
511     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
512   else if (unformat (input, "2r3c-2698"))
513     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
514   else if (unformat (input, "2r3c-4115"))
515     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
516   else if (unformat (input, "2r3c-mef5cf1"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
518   else
519     return 0;
520   return 1;
521 }
522
523 static uword
524 unformat_dscp (unformat_input_t * input, va_list * va)
525 {
526   u8 *r = va_arg (*va, u8 *);
527
528   if (0);
529 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
530   foreach_vnet_dscp
531 #undef _
532     else
533     return 0;
534   return 1;
535 }
536
537 static uword
538 unformat_policer_action_type (unformat_input_t * input, va_list * va)
539 {
540   sse2_qos_pol_action_params_st *a
541     = va_arg (*va, sse2_qos_pol_action_params_st *);
542
543   if (unformat (input, "drop"))
544     a->action_type = SSE2_QOS_ACTION_DROP;
545   else if (unformat (input, "transmit"))
546     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
547   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
548     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
549   else
550     return 0;
551   return 1;
552 }
553
554 static uword
555 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
556 {
557   u32 *r = va_arg (*va, u32 *);
558   u32 tid;
559
560   if (unformat (input, "ip4"))
561     tid = POLICER_CLASSIFY_TABLE_IP4;
562   else if (unformat (input, "ip6"))
563     tid = POLICER_CLASSIFY_TABLE_IP6;
564   else if (unformat (input, "l2"))
565     tid = POLICER_CLASSIFY_TABLE_L2;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 static uword
574 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
575 {
576   u32 *r = va_arg (*va, u32 *);
577   u32 tid;
578
579   if (unformat (input, "ip4"))
580     tid = FLOW_CLASSIFY_TABLE_IP4;
581   else if (unformat (input, "ip6"))
582     tid = FLOW_CLASSIFY_TABLE_IP6;
583   else
584     return 0;
585
586   *r = tid;
587   return 1;
588 }
589
590 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
591 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
592 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
593 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
594
595 #if (VPP_API_TEST_BUILTIN==0)
596 uword
597 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
598 {
599   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
600   mfib_itf_attribute_t attr;
601
602   old = *iflags;
603   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
604   {
605     if (unformat (input, mfib_itf_flag_long_names[attr]))
606       *iflags |= (1 << attr);
607   }
608   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_itf_flag_names[attr]))
611       *iflags |= (1 << attr);
612   }
613
614   return (old == *iflags ? 0 : 1);
615 }
616
617 uword
618 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
619 {
620   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
621   mfib_entry_attribute_t attr;
622
623   old = *eflags;
624   FOR_EACH_MFIB_ATTRIBUTE (attr)
625   {
626     if (unformat (input, mfib_flag_long_names[attr]))
627       *eflags |= (1 << attr);
628   }
629   FOR_EACH_MFIB_ATTRIBUTE (attr)
630   {
631     if (unformat (input, mfib_flag_names[attr]))
632       *eflags |= (1 << attr);
633   }
634
635   return (old == *eflags ? 0 : 1);
636 }
637
638 u8 *
639 format_ip4_address (u8 * s, va_list * args)
640 {
641   u8 *a = va_arg (*args, u8 *);
642   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
643 }
644
645 u8 *
646 format_ip6_address (u8 * s, va_list * args)
647 {
648   ip6_address_t *a = va_arg (*args, ip6_address_t *);
649   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
650
651   i_max_n_zero = ARRAY_LEN (a->as_u16);
652   max_n_zeros = 0;
653   i_first_zero = i_max_n_zero;
654   n_zeros = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       u32 is_zero = a->as_u16[i] == 0;
658       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
659         {
660           i_first_zero = i;
661           n_zeros = 0;
662         }
663       n_zeros += is_zero;
664       if ((!is_zero && n_zeros > max_n_zeros)
665           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
666         {
667           i_max_n_zero = i_first_zero;
668           max_n_zeros = n_zeros;
669           i_first_zero = ARRAY_LEN (a->as_u16);
670           n_zeros = 0;
671         }
672     }
673
674   last_double_colon = 0;
675   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
676     {
677       if (i == i_max_n_zero && max_n_zeros > 1)
678         {
679           s = format (s, "::");
680           i += max_n_zeros - 1;
681           last_double_colon = 1;
682         }
683       else
684         {
685           s = format (s, "%s%x",
686                       (last_double_colon || i == 0) ? "" : ":",
687                       clib_net_to_host_u16 (a->as_u16[i]));
688           last_double_colon = 0;
689         }
690     }
691
692   return s;
693 }
694
695 /* Format an IP46 address. */
696 u8 *
697 format_ip46_address (u8 * s, va_list * args)
698 {
699   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
700   ip46_type_t type = va_arg (*args, ip46_type_t);
701   int is_ip4 = 1;
702
703   switch (type)
704     {
705     case IP46_TYPE_ANY:
706       is_ip4 = ip46_address_is_ip4 (ip46);
707       break;
708     case IP46_TYPE_IP4:
709       is_ip4 = 1;
710       break;
711     case IP46_TYPE_IP6:
712       is_ip4 = 0;
713       break;
714     }
715
716   return is_ip4 ?
717     format (s, "%U", format_ip4_address, &ip46->ip4) :
718     format (s, "%U", format_ip6_address, &ip46->ip6);
719 }
720
721 u8 *
722 format_ethernet_address (u8 * s, va_list * args)
723 {
724   u8 *a = va_arg (*args, u8 *);
725
726   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
727                  a[0], a[1], a[2], a[3], a[4], a[5]);
728 }
729 #endif
730
731 static void
732 increment_v4_address (ip4_address_t * a)
733 {
734   u32 v;
735
736   v = ntohl (a->as_u32) + 1;
737   a->as_u32 = ntohl (v);
738 }
739
740 static void
741 increment_v6_address (ip6_address_t * a)
742 {
743   u64 v0, v1;
744
745   v0 = clib_net_to_host_u64 (a->as_u64[0]);
746   v1 = clib_net_to_host_u64 (a->as_u64[1]);
747
748   v1 += 1;
749   if (v1 == 0)
750     v0 += 1;
751   a->as_u64[0] = clib_net_to_host_u64 (v0);
752   a->as_u64[1] = clib_net_to_host_u64 (v1);
753 }
754
755 static void
756 increment_mac_address (u8 * mac)
757 {
758   u64 tmp = *((u64 *) mac);
759   tmp = clib_net_to_host_u64 (tmp);
760   tmp += 1 << 16;               /* skip unused (least significant) octets */
761   tmp = clib_host_to_net_u64 (tmp);
762
763   clib_memcpy (mac, &tmp, 6);
764 }
765
766 static void vl_api_create_loopback_reply_t_handler
767   (vl_api_create_loopback_reply_t * mp)
768 {
769   vat_main_t *vam = &vat_main;
770   i32 retval = ntohl (mp->retval);
771
772   vam->retval = retval;
773   vam->regenerate_interface_table = 1;
774   vam->sw_if_index = ntohl (mp->sw_if_index);
775   vam->result_ready = 1;
776 }
777
778 static void vl_api_create_loopback_reply_t_handler_json
779   (vl_api_create_loopback_reply_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t node;
783
784   vat_json_init_object (&node);
785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
787
788   vat_json_print (vam->ofp, &node);
789   vat_json_free (&node);
790   vam->retval = ntohl (mp->retval);
791   vam->result_ready = 1;
792 }
793
794 static void vl_api_create_loopback_instance_reply_t_handler
795   (vl_api_create_loopback_instance_reply_t * mp)
796 {
797   vat_main_t *vam = &vat_main;
798   i32 retval = ntohl (mp->retval);
799
800   vam->retval = retval;
801   vam->regenerate_interface_table = 1;
802   vam->sw_if_index = ntohl (mp->sw_if_index);
803   vam->result_ready = 1;
804 }
805
806 static void vl_api_create_loopback_instance_reply_t_handler_json
807   (vl_api_create_loopback_instance_reply_t * mp)
808 {
809   vat_main_t *vam = &vat_main;
810   vat_json_node_t node;
811
812   vat_json_init_object (&node);
813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
814   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
815
816   vat_json_print (vam->ofp, &node);
817   vat_json_free (&node);
818   vam->retval = ntohl (mp->retval);
819   vam->result_ready = 1;
820 }
821
822 static void vl_api_af_packet_create_reply_t_handler
823   (vl_api_af_packet_create_reply_t * mp)
824 {
825   vat_main_t *vam = &vat_main;
826   i32 retval = ntohl (mp->retval);
827
828   vam->retval = retval;
829   vam->regenerate_interface_table = 1;
830   vam->sw_if_index = ntohl (mp->sw_if_index);
831   vam->result_ready = 1;
832 }
833
834 static void vl_api_af_packet_create_reply_t_handler_json
835   (vl_api_af_packet_create_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   vat_json_node_t node;
839
840   vat_json_init_object (&node);
841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
842   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
843
844   vat_json_print (vam->ofp, &node);
845   vat_json_free (&node);
846
847   vam->retval = ntohl (mp->retval);
848   vam->result_ready = 1;
849 }
850
851 static void vl_api_create_vlan_subif_reply_t_handler
852   (vl_api_create_vlan_subif_reply_t * mp)
853 {
854   vat_main_t *vam = &vat_main;
855   i32 retval = ntohl (mp->retval);
856
857   vam->retval = retval;
858   vam->regenerate_interface_table = 1;
859   vam->sw_if_index = ntohl (mp->sw_if_index);
860   vam->result_ready = 1;
861 }
862
863 static void vl_api_create_vlan_subif_reply_t_handler_json
864   (vl_api_create_vlan_subif_reply_t * mp)
865 {
866   vat_main_t *vam = &vat_main;
867   vat_json_node_t node;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
872
873   vat_json_print (vam->ofp, &node);
874   vat_json_free (&node);
875
876   vam->retval = ntohl (mp->retval);
877   vam->result_ready = 1;
878 }
879
880 static void vl_api_create_subif_reply_t_handler
881   (vl_api_create_subif_reply_t * mp)
882 {
883   vat_main_t *vam = &vat_main;
884   i32 retval = ntohl (mp->retval);
885
886   vam->retval = retval;
887   vam->regenerate_interface_table = 1;
888   vam->sw_if_index = ntohl (mp->sw_if_index);
889   vam->result_ready = 1;
890 }
891
892 static void vl_api_create_subif_reply_t_handler_json
893   (vl_api_create_subif_reply_t * mp)
894 {
895   vat_main_t *vam = &vat_main;
896   vat_json_node_t node;
897
898   vat_json_init_object (&node);
899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
900   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 static void vl_api_interface_name_renumber_reply_t_handler
910   (vl_api_interface_name_renumber_reply_t * mp)
911 {
912   vat_main_t *vam = &vat_main;
913   i32 retval = ntohl (mp->retval);
914
915   vam->retval = retval;
916   vam->regenerate_interface_table = 1;
917   vam->result_ready = 1;
918 }
919
920 static void vl_api_interface_name_renumber_reply_t_handler_json
921   (vl_api_interface_name_renumber_reply_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   vat_json_node_t node;
925
926   vat_json_init_object (&node);
927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
928
929   vat_json_print (vam->ofp, &node);
930   vat_json_free (&node);
931
932   vam->retval = ntohl (mp->retval);
933   vam->result_ready = 1;
934 }
935
936 /*
937  * Special-case: build the interface table, maintain
938  * the next loopback sw_if_index vbl.
939  */
940 static void vl_api_sw_interface_details_t_handler
941   (vl_api_sw_interface_details_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   u8 *s = format (0, "%s%c", mp->interface_name, 0);
945
946   hash_set_mem (vam->sw_if_index_by_interface_name, s,
947                 ntohl (mp->sw_if_index));
948
949   /* In sub interface case, fill the sub interface table entry */
950   if (mp->sw_if_index != mp->sup_sw_if_index)
951     {
952       sw_interface_subif_t *sub = NULL;
953
954       vec_add2 (vam->sw_if_subif_table, sub, 1);
955
956       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
957       strncpy ((char *) sub->interface_name, (char *) s,
958                vec_len (sub->interface_name));
959       sub->sw_if_index = ntohl (mp->sw_if_index);
960       sub->sub_id = ntohl (mp->sub_id);
961
962       sub->sub_dot1ad = mp->sub_dot1ad;
963       sub->sub_number_of_tags = mp->sub_number_of_tags;
964       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
965       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
966       sub->sub_exact_match = mp->sub_exact_match;
967       sub->sub_default = mp->sub_default;
968       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
969       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
970
971       /* vlan tag rewrite */
972       sub->vtr_op = ntohl (mp->vtr_op);
973       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
974       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
975       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
976     }
977 }
978
979 static void vl_api_sw_interface_details_t_handler_json
980   (vl_api_sw_interface_details_t * mp)
981 {
982   vat_main_t *vam = &vat_main;
983   vat_json_node_t *node = NULL;
984
985   if (VAT_JSON_ARRAY != vam->json_tree.type)
986     {
987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
988       vat_json_init_array (&vam->json_tree);
989     }
990   node = vat_json_array_add (&vam->json_tree);
991
992   vat_json_init_object (node);
993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
994   vat_json_object_add_uint (node, "sup_sw_if_index",
995                             ntohl (mp->sup_sw_if_index));
996   vat_json_object_add_uint (node, "l2_address_length",
997                             ntohl (mp->l2_address_length));
998   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
999                              sizeof (mp->l2_address));
1000   vat_json_object_add_string_copy (node, "interface_name",
1001                                    mp->interface_name);
1002   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1003   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1004   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1005   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1006   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1007   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1008   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1009   vat_json_object_add_uint (node, "sub_number_of_tags",
1010                             mp->sub_number_of_tags);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1012                             ntohs (mp->sub_outer_vlan_id));
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1014                             ntohs (mp->sub_inner_vlan_id));
1015   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1016   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1017   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1018                             mp->sub_outer_vlan_id_any);
1019   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1020                             mp->sub_inner_vlan_id_any);
1021   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1022   vat_json_object_add_uint (node, "vtr_push_dot1q",
1023                             ntohl (mp->vtr_push_dot1q));
1024   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1025   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1026   if (mp->sub_dot1ah)
1027     {
1028       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1029                                        format (0, "%U",
1030                                                format_ethernet_address,
1031                                                &mp->b_dmac));
1032       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1033                                        format (0, "%U",
1034                                                format_ethernet_address,
1035                                                &mp->b_smac));
1036       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1037       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1038     }
1039 }
1040
1041 #if VPP_API_TEST_BUILTIN == 0
1042 static void vl_api_sw_interface_event_t_handler
1043   (vl_api_sw_interface_event_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   if (vam->interface_event_display)
1047     errmsg ("interface flags: sw_if_index %d %s %s",
1048             ntohl (mp->sw_if_index),
1049             mp->admin_up_down ? "admin-up" : "admin-down",
1050             mp->link_up_down ? "link-up" : "link-down");
1051 }
1052 #endif
1053
1054 static void vl_api_sw_interface_event_t_handler_json
1055   (vl_api_sw_interface_event_t * mp)
1056 {
1057   /* JSON output not supported */
1058 }
1059
1060 static void
1061 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   i32 retval = ntohl (mp->retval);
1065
1066   vam->retval = retval;
1067   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1068   vam->result_ready = 1;
1069 }
1070
1071 static void
1072 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1073 {
1074   vat_main_t *vam = &vat_main;
1075   vat_json_node_t node;
1076   api_main_t *am = &api_main;
1077   void *oldheap;
1078   u8 *reply;
1079
1080   vat_json_init_object (&node);
1081   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1082   vat_json_object_add_uint (&node, "reply_in_shmem",
1083                             ntohl (mp->reply_in_shmem));
1084   /* Toss the shared-memory original... */
1085   pthread_mutex_lock (&am->vlib_rp->mutex);
1086   oldheap = svm_push_data_heap (am->vlib_rp);
1087
1088   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1089   vec_free (reply);
1090
1091   svm_pop_heap (oldheap);
1092   pthread_mutex_unlock (&am->vlib_rp->mutex);
1093
1094   vat_json_print (vam->ofp, &node);
1095   vat_json_free (&node);
1096
1097   vam->retval = ntohl (mp->retval);
1098   vam->result_ready = 1;
1099 }
1100
1101 static void
1102 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   i32 retval = ntohl (mp->retval);
1106   u32 length = vl_api_string_len (&mp->reply);
1107
1108   vec_reset_length (vam->cmd_reply);
1109
1110   vam->retval = retval;
1111   if (retval == 0)
1112     {
1113       vec_validate (vam->cmd_reply, length);
1114       clib_memcpy ((char *) (vam->cmd_reply),
1115                    vl_api_from_api_string (&mp->reply), length);
1116       vam->cmd_reply[length] = 0;
1117     }
1118   vam->result_ready = 1;
1119 }
1120
1121 static void
1122 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   vat_json_node_t node;
1126
1127   vec_reset_length (vam->cmd_reply);
1128
1129   vat_json_init_object (&node);
1130   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1131   vat_json_object_add_string_copy (&node, "reply",
1132                                    vl_api_from_api_string (&mp->reply));
1133
1134   vat_json_print (vam->ofp, &node);
1135   vat_json_free (&node);
1136
1137   vam->retval = ntohl (mp->retval);
1138   vam->result_ready = 1;
1139 }
1140
1141 static void vl_api_classify_add_del_table_reply_t_handler
1142   (vl_api_classify_add_del_table_reply_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   i32 retval = ntohl (mp->retval);
1146   if (vam->async_mode)
1147     {
1148       vam->async_errors += (retval < 0);
1149     }
1150   else
1151     {
1152       vam->retval = retval;
1153       if (retval == 0 &&
1154           ((mp->new_table_index != 0xFFFFFFFF) ||
1155            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1156            (mp->match_n_vectors != 0xFFFFFFFF)))
1157         /*
1158          * Note: this is just barely thread-safe, depends on
1159          * the main thread spinning waiting for an answer...
1160          */
1161         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1162                 ntohl (mp->new_table_index),
1163                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1164       vam->result_ready = 1;
1165     }
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler_json
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_uint (&node, "new_table_index",
1177                             ntohl (mp->new_table_index));
1178   vat_json_object_add_uint (&node, "skip_n_vectors",
1179                             ntohl (mp->skip_n_vectors));
1180   vat_json_object_add_uint (&node, "match_n_vectors",
1181                             ntohl (mp->match_n_vectors));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_node_index_reply_t_handler
1191   (vl_api_get_node_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("node index %d", ntohl (mp->node_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_node_index_reply_t_handler_json
1209   (vl_api_get_node_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_get_next_index_reply_t_handler
1226   (vl_api_get_next_index_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next node index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_get_next_index_reply_t_handler_json
1244   (vl_api_get_next_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_add_node_next_reply_t_handler
1261   (vl_api_add_node_next_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265   if (vam->async_mode)
1266     {
1267       vam->async_errors += (retval < 0);
1268     }
1269   else
1270     {
1271       vam->retval = retval;
1272       if (retval == 0)
1273         errmsg ("next index %d", ntohl (mp->next_index));
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_add_node_next_reply_t_handler_json
1279   (vl_api_add_node_next_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t node;
1283
1284   vat_json_init_object (&node);
1285   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1286   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void vl_api_show_version_reply_t_handler
1296   (vl_api_show_version_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   i32 retval = ntohl (mp->retval);
1300
1301   if (retval >= 0)
1302     {
1303       char *s;
1304       char *p = (char *) &mp->program;
1305
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        program: %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 ("        version: %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 date: %s\n", s);
1320       free (s);
1321
1322       p +=
1323         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1324       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1325       errmsg ("build directory: %s\n", s);
1326       free (s);
1327     }
1328   vam->retval = retval;
1329   vam->result_ready = 1;
1330 }
1331
1332 static void vl_api_show_version_reply_t_handler_json
1333   (vl_api_show_version_reply_t * mp)
1334 {
1335   vat_main_t *vam = &vat_main;
1336   vat_json_node_t node;
1337
1338   vat_json_init_object (&node);
1339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1340   char *p = (char *) &mp->program;
1341   vat_json_object_add_string_copy (&node, "program",
1342                                    vl_api_from_api_string ((vl_api_string_t *)
1343                                                            p));
1344   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1345   vat_json_object_add_string_copy (&node, "version",
1346                                    vl_api_from_api_string ((vl_api_string_t *)
1347                                                            p));
1348   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1349   vat_json_object_add_string_copy (&node, "build_date",
1350                                    vl_api_from_api_string ((vl_api_string_t *)
1351                                                            p));
1352   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1353   vat_json_object_add_string_copy (&node, "build_directory",
1354                                    vl_api_from_api_string ((vl_api_string_t *)
1355                                                            p));
1356
1357   vat_json_print (vam->ofp, &node);
1358   vat_json_free (&node);
1359
1360   vam->retval = ntohl (mp->retval);
1361   vam->result_ready = 1;
1362 }
1363
1364 static void vl_api_show_threads_reply_t_handler
1365   (vl_api_show_threads_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   i32 retval = ntohl (mp->retval);
1369   int i, count = 0;
1370
1371   if (retval >= 0)
1372     count = ntohl (mp->count);
1373
1374   for (i = 0; i < count; i++)
1375     print (vam->ofp,
1376            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1377            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1378            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1379            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1380            ntohl (mp->thread_data[i].cpu_socket));
1381
1382   vam->retval = retval;
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler_json
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   vat_json_node_t node;
1391   vl_api_thread_data_t *td;
1392   i32 retval = ntohl (mp->retval);
1393   int i, count = 0;
1394
1395   if (retval >= 0)
1396     count = ntohl (mp->count);
1397
1398   vat_json_init_object (&node);
1399   vat_json_object_add_int (&node, "retval", retval);
1400   vat_json_object_add_uint (&node, "count", count);
1401
1402   for (i = 0; i < count; i++)
1403     {
1404       td = &mp->thread_data[i];
1405       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1406       vat_json_object_add_string_copy (&node, "name", td->name);
1407       vat_json_object_add_string_copy (&node, "type", td->type);
1408       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1409       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1410       vat_json_object_add_int (&node, "core", ntohl (td->id));
1411       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1412     }
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static int
1422 api_show_threads (vat_main_t * vam)
1423 {
1424   vl_api_show_threads_t *mp;
1425   int ret;
1426
1427   print (vam->ofp,
1428          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1429          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1430
1431   M (SHOW_THREADS, mp);
1432
1433   S (mp);
1434   W (ret);
1435   return ret;
1436 }
1437
1438 static void
1439 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1440 {
1441   u32 sw_if_index = ntohl (mp->sw_if_index);
1442   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1443           mp->mac_ip ? "mac/ip binding" : "address resolution",
1444           ntohl (mp->pid), format_ip4_address, &mp->address,
1445           format_ethernet_address, mp->new_mac, sw_if_index);
1446 }
1447
1448 static void
1449 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1450 {
1451   /* JSON output not supported */
1452 }
1453
1454 static void
1455 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1456 {
1457   u32 sw_if_index = ntohl (mp->sw_if_index);
1458   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1459           mp->mac_ip ? "mac/ip binding" : "address resolution",
1460           ntohl (mp->pid), format_ip6_address, mp->address,
1461           format_ethernet_address, mp->new_mac, sw_if_index);
1462 }
1463
1464 static void
1465 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1466 {
1467   /* JSON output not supported */
1468 }
1469
1470 static void
1471 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1472 {
1473   u32 n_macs = ntohl (mp->n_macs);
1474   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1475           ntohl (mp->pid), mp->client_index, n_macs);
1476   int i;
1477   for (i = 0; i < n_macs; i++)
1478     {
1479       vl_api_mac_entry_t *mac = &mp->mac[i];
1480       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1481               i + 1, ntohl (mac->sw_if_index),
1482               format_ethernet_address, mac->mac_addr, mac->action);
1483       if (i == 1000)
1484         break;
1485     }
1486 }
1487
1488 static void
1489 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1490 {
1491   /* JSON output not supported */
1492 }
1493
1494 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1495 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1496
1497 /*
1498  * Special-case: build the bridge domain table, maintain
1499  * the next bd id vbl.
1500  */
1501 static void vl_api_bridge_domain_details_t_handler
1502   (vl_api_bridge_domain_details_t * mp)
1503 {
1504   vat_main_t *vam = &vat_main;
1505   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1506   int i;
1507
1508   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1509          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1510
1511   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1512          ntohl (mp->bd_id), mp->learn, mp->forward,
1513          mp->flood, ntohl (mp->bvi_sw_if_index),
1514          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1515
1516   if (n_sw_ifs)
1517     {
1518       vl_api_bridge_domain_sw_if_t *sw_ifs;
1519       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1520              "Interface Name");
1521
1522       sw_ifs = mp->sw_if_details;
1523       for (i = 0; i < n_sw_ifs; i++)
1524         {
1525           u8 *sw_if_name = 0;
1526           u32 sw_if_index;
1527           hash_pair_t *p;
1528
1529           sw_if_index = ntohl (sw_ifs->sw_if_index);
1530
1531           /* *INDENT-OFF* */
1532           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1533                              ({
1534                                if ((u32) p->value[0] == sw_if_index)
1535                                  {
1536                                    sw_if_name = (u8 *)(p->key);
1537                                    break;
1538                                  }
1539                              }));
1540           /* *INDENT-ON* */
1541           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1542                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1543                  "sw_if_index not found!");
1544
1545           sw_ifs++;
1546         }
1547     }
1548 }
1549
1550 static void vl_api_bridge_domain_details_t_handler_json
1551   (vl_api_bridge_domain_details_t * mp)
1552 {
1553   vat_main_t *vam = &vat_main;
1554   vat_json_node_t *node, *array = NULL;
1555   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1556
1557   if (VAT_JSON_ARRAY != vam->json_tree.type)
1558     {
1559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1560       vat_json_init_array (&vam->json_tree);
1561     }
1562   node = vat_json_array_add (&vam->json_tree);
1563
1564   vat_json_init_object (node);
1565   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1566   vat_json_object_add_uint (node, "flood", mp->flood);
1567   vat_json_object_add_uint (node, "forward", mp->forward);
1568   vat_json_object_add_uint (node, "learn", mp->learn);
1569   vat_json_object_add_uint (node, "bvi_sw_if_index",
1570                             ntohl (mp->bvi_sw_if_index));
1571   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1572   array = vat_json_object_add (node, "sw_if");
1573   vat_json_init_array (array);
1574
1575
1576
1577   if (n_sw_ifs)
1578     {
1579       vl_api_bridge_domain_sw_if_t *sw_ifs;
1580       int i;
1581
1582       sw_ifs = mp->sw_if_details;
1583       for (i = 0; i < n_sw_ifs; i++)
1584         {
1585           node = vat_json_array_add (array);
1586           vat_json_init_object (node);
1587           vat_json_object_add_uint (node, "sw_if_index",
1588                                     ntohl (sw_ifs->sw_if_index));
1589           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1590           sw_ifs++;
1591         }
1592     }
1593 }
1594
1595 static void vl_api_control_ping_reply_t_handler
1596   (vl_api_control_ping_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600   if (vam->async_mode)
1601     {
1602       vam->async_errors += (retval < 0);
1603     }
1604   else
1605     {
1606       vam->retval = retval;
1607       vam->result_ready = 1;
1608     }
1609   if (vam->socket_client_main)
1610     vam->socket_client_main->control_pings_outstanding--;
1611 }
1612
1613 static void vl_api_control_ping_reply_t_handler_json
1614   (vl_api_control_ping_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618
1619   if (VAT_JSON_NONE != vam->json_tree.type)
1620     {
1621       vat_json_print (vam->ofp, &vam->json_tree);
1622       vat_json_free (&vam->json_tree);
1623       vam->json_tree.type = VAT_JSON_NONE;
1624     }
1625   else
1626     {
1627       /* just print [] */
1628       vat_json_init_array (&vam->json_tree);
1629       vat_json_print (vam->ofp, &vam->json_tree);
1630       vam->json_tree.type = VAT_JSON_NONE;
1631     }
1632
1633   vam->retval = retval;
1634   vam->result_ready = 1;
1635 }
1636
1637 static void
1638   vl_api_bridge_domain_set_mac_age_reply_t_handler
1639   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1640 {
1641   vat_main_t *vam = &vat_main;
1642   i32 retval = ntohl (mp->retval);
1643   if (vam->async_mode)
1644     {
1645       vam->async_errors += (retval < 0);
1646     }
1647   else
1648     {
1649       vam->retval = retval;
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1655   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662
1663   vat_json_print (vam->ofp, &node);
1664   vat_json_free (&node);
1665
1666   vam->retval = ntohl (mp->retval);
1667   vam->result_ready = 1;
1668 }
1669
1670 static void
1671 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1672 {
1673   vat_main_t *vam = &vat_main;
1674   i32 retval = ntohl (mp->retval);
1675   if (vam->async_mode)
1676     {
1677       vam->async_errors += (retval < 0);
1678     }
1679   else
1680     {
1681       vam->retval = retval;
1682       vam->result_ready = 1;
1683     }
1684 }
1685
1686 static void vl_api_l2_flags_reply_t_handler_json
1687   (vl_api_l2_flags_reply_t * mp)
1688 {
1689   vat_main_t *vam = &vat_main;
1690   vat_json_node_t node;
1691
1692   vat_json_init_object (&node);
1693   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1694   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1695                             ntohl (mp->resulting_feature_bitmap));
1696
1697   vat_json_print (vam->ofp, &node);
1698   vat_json_free (&node);
1699
1700   vam->retval = ntohl (mp->retval);
1701   vam->result_ready = 1;
1702 }
1703
1704 static void vl_api_bridge_flags_reply_t_handler
1705   (vl_api_bridge_flags_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   i32 retval = ntohl (mp->retval);
1709   if (vam->async_mode)
1710     {
1711       vam->async_errors += (retval < 0);
1712     }
1713   else
1714     {
1715       vam->retval = retval;
1716       vam->result_ready = 1;
1717     }
1718 }
1719
1720 static void vl_api_bridge_flags_reply_t_handler_json
1721   (vl_api_bridge_flags_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t node;
1725
1726   vat_json_init_object (&node);
1727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1729                             ntohl (mp->resulting_feature_bitmap));
1730
1731   vat_json_print (vam->ofp, &node);
1732   vat_json_free (&node);
1733
1734   vam->retval = ntohl (mp->retval);
1735   vam->result_ready = 1;
1736 }
1737
1738 static void vl_api_tap_connect_reply_t_handler
1739   (vl_api_tap_connect_reply_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   i32 retval = ntohl (mp->retval);
1743   if (vam->async_mode)
1744     {
1745       vam->async_errors += (retval < 0);
1746     }
1747   else
1748     {
1749       vam->retval = retval;
1750       vam->sw_if_index = ntohl (mp->sw_if_index);
1751       vam->result_ready = 1;
1752     }
1753
1754 }
1755
1756 static void vl_api_tap_connect_reply_t_handler_json
1757   (vl_api_tap_connect_reply_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   vat_json_node_t node;
1761
1762   vat_json_init_object (&node);
1763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1765
1766   vat_json_print (vam->ofp, &node);
1767   vat_json_free (&node);
1768
1769   vam->retval = ntohl (mp->retval);
1770   vam->result_ready = 1;
1771
1772 }
1773
1774 static void
1775 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1776 {
1777   vat_main_t *vam = &vat_main;
1778   i32 retval = ntohl (mp->retval);
1779   if (vam->async_mode)
1780     {
1781       vam->async_errors += (retval < 0);
1782     }
1783   else
1784     {
1785       vam->retval = retval;
1786       vam->sw_if_index = ntohl (mp->sw_if_index);
1787       vam->result_ready = 1;
1788     }
1789 }
1790
1791 static void vl_api_tap_modify_reply_t_handler_json
1792   (vl_api_tap_modify_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   vat_json_node_t node;
1796
1797   vat_json_init_object (&node);
1798   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1799   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1800
1801   vat_json_print (vam->ofp, &node);
1802   vat_json_free (&node);
1803
1804   vam->retval = ntohl (mp->retval);
1805   vam->result_ready = 1;
1806 }
1807
1808 static void
1809 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812   i32 retval = ntohl (mp->retval);
1813   if (vam->async_mode)
1814     {
1815       vam->async_errors += (retval < 0);
1816     }
1817   else
1818     {
1819       vam->retval = retval;
1820       vam->result_ready = 1;
1821     }
1822 }
1823
1824 static void vl_api_tap_delete_reply_t_handler_json
1825   (vl_api_tap_delete_reply_t * mp)
1826 {
1827   vat_main_t *vam = &vat_main;
1828   vat_json_node_t node;
1829
1830   vat_json_init_object (&node);
1831   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1832
1833   vat_json_print (vam->ofp, &node);
1834   vat_json_free (&node);
1835
1836   vam->retval = ntohl (mp->retval);
1837   vam->result_ready = 1;
1838 }
1839
1840 static void
1841 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   i32 retval = ntohl (mp->retval);
1845   if (vam->async_mode)
1846     {
1847       vam->async_errors += (retval < 0);
1848     }
1849   else
1850     {
1851       vam->retval = retval;
1852       vam->sw_if_index = ntohl (mp->sw_if_index);
1853       vam->result_ready = 1;
1854     }
1855
1856 }
1857
1858 static void vl_api_tap_create_v2_reply_t_handler_json
1859   (vl_api_tap_create_v2_reply_t * mp)
1860 {
1861   vat_main_t *vam = &vat_main;
1862   vat_json_node_t node;
1863
1864   vat_json_init_object (&node);
1865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1866   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1867
1868   vat_json_print (vam->ofp, &node);
1869   vat_json_free (&node);
1870
1871   vam->retval = ntohl (mp->retval);
1872   vam->result_ready = 1;
1873
1874 }
1875
1876 static void
1877 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   i32 retval = ntohl (mp->retval);
1881   if (vam->async_mode)
1882     {
1883       vam->async_errors += (retval < 0);
1884     }
1885   else
1886     {
1887       vam->retval = retval;
1888       vam->result_ready = 1;
1889     }
1890 }
1891
1892 static void vl_api_tap_delete_v2_reply_t_handler_json
1893   (vl_api_tap_delete_v2_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   vat_json_node_t node;
1897
1898   vat_json_init_object (&node);
1899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1900
1901   vat_json_print (vam->ofp, &node);
1902   vat_json_free (&node);
1903
1904   vam->retval = ntohl (mp->retval);
1905   vam->result_ready = 1;
1906 }
1907
1908 static void
1909 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1910                                           mp)
1911 {
1912   vat_main_t *vam = &vat_main;
1913   i32 retval = ntohl (mp->retval);
1914   if (vam->async_mode)
1915     {
1916       vam->async_errors += (retval < 0);
1917     }
1918   else
1919     {
1920       vam->retval = retval;
1921       vam->sw_if_index = ntohl (mp->sw_if_index);
1922       vam->result_ready = 1;
1923     }
1924 }
1925
1926 static void vl_api_virtio_pci_create_reply_t_handler_json
1927   (vl_api_virtio_pci_create_reply_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t node;
1931
1932   vat_json_init_object (&node);
1933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1934   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1935
1936   vat_json_print (vam->ofp, &node);
1937   vat_json_free (&node);
1938
1939   vam->retval = ntohl (mp->retval);
1940   vam->result_ready = 1;
1941
1942 }
1943
1944 static void
1945 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1946                                           mp)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   i32 retval = ntohl (mp->retval);
1950   if (vam->async_mode)
1951     {
1952       vam->async_errors += (retval < 0);
1953     }
1954   else
1955     {
1956       vam->retval = retval;
1957       vam->result_ready = 1;
1958     }
1959 }
1960
1961 static void vl_api_virtio_pci_delete_reply_t_handler_json
1962   (vl_api_virtio_pci_delete_reply_t * mp)
1963 {
1964   vat_main_t *vam = &vat_main;
1965   vat_json_node_t node;
1966
1967   vat_json_init_object (&node);
1968   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1969
1970   vat_json_print (vam->ofp, &node);
1971   vat_json_free (&node);
1972
1973   vam->retval = ntohl (mp->retval);
1974   vam->result_ready = 1;
1975 }
1976
1977 static void
1978 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1979 {
1980   vat_main_t *vam = &vat_main;
1981   i32 retval = ntohl (mp->retval);
1982
1983   if (vam->async_mode)
1984     {
1985       vam->async_errors += (retval < 0);
1986     }
1987   else
1988     {
1989       vam->retval = retval;
1990       vam->sw_if_index = ntohl (mp->sw_if_index);
1991       vam->result_ready = 1;
1992     }
1993 }
1994
1995 static void vl_api_bond_create_reply_t_handler_json
1996   (vl_api_bond_create_reply_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t node;
2000
2001   vat_json_init_object (&node);
2002   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2003   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2004
2005   vat_json_print (vam->ofp, &node);
2006   vat_json_free (&node);
2007
2008   vam->retval = ntohl (mp->retval);
2009   vam->result_ready = 1;
2010 }
2011
2012 static void
2013 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   i32 retval = ntohl (mp->retval);
2017
2018   if (vam->async_mode)
2019     {
2020       vam->async_errors += (retval < 0);
2021     }
2022   else
2023     {
2024       vam->retval = retval;
2025       vam->result_ready = 1;
2026     }
2027 }
2028
2029 static void vl_api_bond_delete_reply_t_handler_json
2030   (vl_api_bond_delete_reply_t * mp)
2031 {
2032   vat_main_t *vam = &vat_main;
2033   vat_json_node_t node;
2034
2035   vat_json_init_object (&node);
2036   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2037
2038   vat_json_print (vam->ofp, &node);
2039   vat_json_free (&node);
2040
2041   vam->retval = ntohl (mp->retval);
2042   vam->result_ready = 1;
2043 }
2044
2045 static void
2046 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
2047 {
2048   vat_main_t *vam = &vat_main;
2049   i32 retval = ntohl (mp->retval);
2050
2051   if (vam->async_mode)
2052     {
2053       vam->async_errors += (retval < 0);
2054     }
2055   else
2056     {
2057       vam->retval = retval;
2058       vam->result_ready = 1;
2059     }
2060 }
2061
2062 static void vl_api_bond_enslave_reply_t_handler_json
2063   (vl_api_bond_enslave_reply_t * mp)
2064 {
2065   vat_main_t *vam = &vat_main;
2066   vat_json_node_t node;
2067
2068   vat_json_init_object (&node);
2069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2070
2071   vat_json_print (vam->ofp, &node);
2072   vat_json_free (&node);
2073
2074   vam->retval = ntohl (mp->retval);
2075   vam->result_ready = 1;
2076 }
2077
2078 static void
2079 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2080                                           mp)
2081 {
2082   vat_main_t *vam = &vat_main;
2083   i32 retval = ntohl (mp->retval);
2084
2085   if (vam->async_mode)
2086     {
2087       vam->async_errors += (retval < 0);
2088     }
2089   else
2090     {
2091       vam->retval = retval;
2092       vam->result_ready = 1;
2093     }
2094 }
2095
2096 static void vl_api_bond_detach_slave_reply_t_handler_json
2097   (vl_api_bond_detach_slave_reply_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100   vat_json_node_t node;
2101
2102   vat_json_init_object (&node);
2103   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2104
2105   vat_json_print (vam->ofp, &node);
2106   vat_json_free (&node);
2107
2108   vam->retval = ntohl (mp->retval);
2109   vam->result_ready = 1;
2110 }
2111
2112 static void vl_api_sw_interface_bond_details_t_handler
2113   (vl_api_sw_interface_bond_details_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116
2117   print (vam->ofp,
2118          "%-16s %-12d %-12U %-13U %-14u %-14u",
2119          mp->interface_name, ntohl (mp->sw_if_index),
2120          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2121          ntohl (mp->active_slaves), ntohl (mp->slaves));
2122 }
2123
2124 static void vl_api_sw_interface_bond_details_t_handler_json
2125   (vl_api_sw_interface_bond_details_t * mp)
2126 {
2127   vat_main_t *vam = &vat_main;
2128   vat_json_node_t *node = NULL;
2129
2130   if (VAT_JSON_ARRAY != vam->json_tree.type)
2131     {
2132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2133       vat_json_init_array (&vam->json_tree);
2134     }
2135   node = vat_json_array_add (&vam->json_tree);
2136
2137   vat_json_init_object (node);
2138   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2139   vat_json_object_add_string_copy (node, "interface_name",
2140                                    mp->interface_name);
2141   vat_json_object_add_uint (node, "mode", mp->mode);
2142   vat_json_object_add_uint (node, "load_balance", mp->lb);
2143   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2144   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2145 }
2146
2147 static int
2148 api_sw_interface_bond_dump (vat_main_t * vam)
2149 {
2150   vl_api_sw_interface_bond_dump_t *mp;
2151   vl_api_control_ping_t *mp_ping;
2152   int ret;
2153
2154   print (vam->ofp,
2155          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2156          "interface name", "sw_if_index", "mode", "load balance",
2157          "active slaves", "slaves");
2158
2159   /* Get list of bond interfaces */
2160   M (SW_INTERFACE_BOND_DUMP, mp);
2161   S (mp);
2162
2163   /* Use a control ping for synchronization */
2164   MPING (CONTROL_PING, mp_ping);
2165   S (mp_ping);
2166
2167   W (ret);
2168   return ret;
2169 }
2170
2171 static void vl_api_sw_interface_slave_details_t_handler
2172   (vl_api_sw_interface_slave_details_t * mp)
2173 {
2174   vat_main_t *vam = &vat_main;
2175
2176   print (vam->ofp,
2177          "%-25s %-12d %-12d %d", mp->interface_name,
2178          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2179 }
2180
2181 static void vl_api_sw_interface_slave_details_t_handler_json
2182   (vl_api_sw_interface_slave_details_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   vat_json_node_t *node = NULL;
2186
2187   if (VAT_JSON_ARRAY != vam->json_tree.type)
2188     {
2189       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2190       vat_json_init_array (&vam->json_tree);
2191     }
2192   node = vat_json_array_add (&vam->json_tree);
2193
2194   vat_json_init_object (node);
2195   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2196   vat_json_object_add_string_copy (node, "interface_name",
2197                                    mp->interface_name);
2198   vat_json_object_add_uint (node, "passive", mp->is_passive);
2199   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2200 }
2201
2202 static int
2203 api_sw_interface_slave_dump (vat_main_t * vam)
2204 {
2205   unformat_input_t *i = vam->input;
2206   vl_api_sw_interface_slave_dump_t *mp;
2207   vl_api_control_ping_t *mp_ping;
2208   u32 sw_if_index = ~0;
2209   u8 sw_if_index_set = 0;
2210   int ret;
2211
2212   /* Parse args required to build the message */
2213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2214     {
2215       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2216         sw_if_index_set = 1;
2217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2218         sw_if_index_set = 1;
2219       else
2220         break;
2221     }
2222
2223   if (sw_if_index_set == 0)
2224     {
2225       errmsg ("missing vpp interface name. ");
2226       return -99;
2227     }
2228
2229   print (vam->ofp,
2230          "\n%-25s %-12s %-12s %s",
2231          "slave interface name", "sw_if_index", "passive", "long_timeout");
2232
2233   /* Get list of bond interfaces */
2234   M (SW_INTERFACE_SLAVE_DUMP, mp);
2235   mp->sw_if_index = ntohl (sw_if_index);
2236   S (mp);
2237
2238   /* Use a control ping for synchronization */
2239   MPING (CONTROL_PING, mp_ping);
2240   S (mp_ping);
2241
2242   W (ret);
2243   return ret;
2244 }
2245
2246 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2247   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   i32 retval = ntohl (mp->retval);
2251   if (vam->async_mode)
2252     {
2253       vam->async_errors += (retval < 0);
2254     }
2255   else
2256     {
2257       vam->retval = retval;
2258       vam->sw_if_index = ntohl (mp->sw_if_index);
2259       vam->result_ready = 1;
2260     }
2261   vam->regenerate_interface_table = 1;
2262 }
2263
2264 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2265   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   vat_json_node_t node;
2269
2270   vat_json_init_object (&node);
2271   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2272   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2273                             ntohl (mp->sw_if_index));
2274
2275   vat_json_print (vam->ofp, &node);
2276   vat_json_free (&node);
2277
2278   vam->retval = ntohl (mp->retval);
2279   vam->result_ready = 1;
2280 }
2281
2282 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2283   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2284 {
2285   vat_main_t *vam = &vat_main;
2286   i32 retval = ntohl (mp->retval);
2287   if (vam->async_mode)
2288     {
2289       vam->async_errors += (retval < 0);
2290     }
2291   else
2292     {
2293       vam->retval = retval;
2294       vam->sw_if_index = ntohl (mp->sw_if_index);
2295       vam->result_ready = 1;
2296     }
2297 }
2298
2299 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2300   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   vat_json_node_t node;
2304
2305   vat_json_init_object (&node);
2306   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2307   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2308
2309   vat_json_print (vam->ofp, &node);
2310   vat_json_free (&node);
2311
2312   vam->retval = ntohl (mp->retval);
2313   vam->result_ready = 1;
2314 }
2315
2316 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2317   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2318 {
2319   vat_main_t *vam = &vat_main;
2320   i32 retval = ntohl (mp->retval);
2321   if (vam->async_mode)
2322     {
2323       vam->async_errors += (retval < 0);
2324     }
2325   else
2326     {
2327       vam->retval = retval;
2328       vam->result_ready = 1;
2329     }
2330 }
2331
2332 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2333   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2334 {
2335   vat_main_t *vam = &vat_main;
2336   vat_json_node_t node;
2337
2338   vat_json_init_object (&node);
2339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2340   vat_json_object_add_uint (&node, "fwd_entry_index",
2341                             clib_net_to_host_u32 (mp->fwd_entry_index));
2342
2343   vat_json_print (vam->ofp, &node);
2344   vat_json_free (&node);
2345
2346   vam->retval = ntohl (mp->retval);
2347   vam->result_ready = 1;
2348 }
2349
2350 u8 *
2351 format_lisp_transport_protocol (u8 * s, va_list * args)
2352 {
2353   u32 proto = va_arg (*args, u32);
2354
2355   switch (proto)
2356     {
2357     case 1:
2358       return format (s, "udp");
2359     case 2:
2360       return format (s, "api");
2361     default:
2362       return 0;
2363     }
2364   return 0;
2365 }
2366
2367 static void vl_api_one_get_transport_protocol_reply_t_handler
2368   (vl_api_one_get_transport_protocol_reply_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   i32 retval = ntohl (mp->retval);
2372   if (vam->async_mode)
2373     {
2374       vam->async_errors += (retval < 0);
2375     }
2376   else
2377     {
2378       u32 proto = mp->protocol;
2379       print (vam->ofp, "Transport protocol: %U",
2380              format_lisp_transport_protocol, proto);
2381       vam->retval = retval;
2382       vam->result_ready = 1;
2383     }
2384 }
2385
2386 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2387   (vl_api_one_get_transport_protocol_reply_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390   vat_json_node_t node;
2391   u8 *s;
2392
2393   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2394   vec_add1 (s, 0);
2395
2396   vat_json_init_object (&node);
2397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2398   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2399
2400   vec_free (s);
2401   vat_json_print (vam->ofp, &node);
2402   vat_json_free (&node);
2403
2404   vam->retval = ntohl (mp->retval);
2405   vam->result_ready = 1;
2406 }
2407
2408 static void vl_api_one_add_del_locator_set_reply_t_handler
2409   (vl_api_one_add_del_locator_set_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   i32 retval = ntohl (mp->retval);
2413   if (vam->async_mode)
2414     {
2415       vam->async_errors += (retval < 0);
2416     }
2417   else
2418     {
2419       vam->retval = retval;
2420       vam->result_ready = 1;
2421     }
2422 }
2423
2424 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2425   (vl_api_one_add_del_locator_set_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   vat_json_node_t node;
2429
2430   vat_json_init_object (&node);
2431   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2432   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2433
2434   vat_json_print (vam->ofp, &node);
2435   vat_json_free (&node);
2436
2437   vam->retval = ntohl (mp->retval);
2438   vam->result_ready = 1;
2439 }
2440
2441 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2442   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   i32 retval = ntohl (mp->retval);
2446   if (vam->async_mode)
2447     {
2448       vam->async_errors += (retval < 0);
2449     }
2450   else
2451     {
2452       vam->retval = retval;
2453       vam->sw_if_index = ntohl (mp->sw_if_index);
2454       vam->result_ready = 1;
2455     }
2456   vam->regenerate_interface_table = 1;
2457 }
2458
2459 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2460   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   vat_json_node_t node;
2464
2465   vat_json_init_object (&node);
2466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2467   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2468
2469   vat_json_print (vam->ofp, &node);
2470   vat_json_free (&node);
2471
2472   vam->retval = ntohl (mp->retval);
2473   vam->result_ready = 1;
2474 }
2475
2476 static void vl_api_vxlan_offload_rx_reply_t_handler
2477   (vl_api_vxlan_offload_rx_reply_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   i32 retval = ntohl (mp->retval);
2481   if (vam->async_mode)
2482     {
2483       vam->async_errors += (retval < 0);
2484     }
2485   else
2486     {
2487       vam->retval = retval;
2488       vam->result_ready = 1;
2489     }
2490 }
2491
2492 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2493   (vl_api_vxlan_offload_rx_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t node;
2497
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500
2501   vat_json_print (vam->ofp, &node);
2502   vat_json_free (&node);
2503
2504   vam->retval = ntohl (mp->retval);
2505   vam->result_ready = 1;
2506 }
2507
2508 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2509   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   i32 retval = ntohl (mp->retval);
2513   if (vam->async_mode)
2514     {
2515       vam->async_errors += (retval < 0);
2516     }
2517   else
2518     {
2519       vam->retval = retval;
2520       vam->sw_if_index = ntohl (mp->sw_if_index);
2521       vam->result_ready = 1;
2522     }
2523 }
2524
2525 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2526   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t node;
2530
2531   vat_json_init_object (&node);
2532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2533   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2534
2535   vat_json_print (vam->ofp, &node);
2536   vat_json_free (&node);
2537
2538   vam->retval = ntohl (mp->retval);
2539   vam->result_ready = 1;
2540 }
2541
2542 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2543   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   i32 retval = ntohl (mp->retval);
2547   if (vam->async_mode)
2548     {
2549       vam->async_errors += (retval < 0);
2550     }
2551   else
2552     {
2553       vam->retval = retval;
2554       vam->sw_if_index = ntohl (mp->sw_if_index);
2555       vam->result_ready = 1;
2556     }
2557   vam->regenerate_interface_table = 1;
2558 }
2559
2560 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2561   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   vat_json_node_t node;
2565
2566   vat_json_init_object (&node);
2567   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2568   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2569
2570   vat_json_print (vam->ofp, &node);
2571   vat_json_free (&node);
2572
2573   vam->retval = ntohl (mp->retval);
2574   vam->result_ready = 1;
2575 }
2576
2577 static void vl_api_gre_add_del_tunnel_reply_t_handler
2578   (vl_api_gre_add_del_tunnel_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   i32 retval = ntohl (mp->retval);
2582   if (vam->async_mode)
2583     {
2584       vam->async_errors += (retval < 0);
2585     }
2586   else
2587     {
2588       vam->retval = retval;
2589       vam->sw_if_index = ntohl (mp->sw_if_index);
2590       vam->result_ready = 1;
2591     }
2592 }
2593
2594 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2595   (vl_api_gre_add_del_tunnel_reply_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   vat_json_node_t node;
2599
2600   vat_json_init_object (&node);
2601   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2602   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2603
2604   vat_json_print (vam->ofp, &node);
2605   vat_json_free (&node);
2606
2607   vam->retval = ntohl (mp->retval);
2608   vam->result_ready = 1;
2609 }
2610
2611 static void vl_api_create_vhost_user_if_reply_t_handler
2612   (vl_api_create_vhost_user_if_reply_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   i32 retval = ntohl (mp->retval);
2616   if (vam->async_mode)
2617     {
2618       vam->async_errors += (retval < 0);
2619     }
2620   else
2621     {
2622       vam->retval = retval;
2623       vam->sw_if_index = ntohl (mp->sw_if_index);
2624       vam->result_ready = 1;
2625     }
2626   vam->regenerate_interface_table = 1;
2627 }
2628
2629 static void vl_api_create_vhost_user_if_reply_t_handler_json
2630   (vl_api_create_vhost_user_if_reply_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   vat_json_node_t node;
2634
2635   vat_json_init_object (&node);
2636   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2637   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2638
2639   vat_json_print (vam->ofp, &node);
2640   vat_json_free (&node);
2641
2642   vam->retval = ntohl (mp->retval);
2643   vam->result_ready = 1;
2644 }
2645
2646 static void vl_api_dns_resolve_name_reply_t_handler
2647   (vl_api_dns_resolve_name_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   i32 retval = ntohl (mp->retval);
2651   if (vam->async_mode)
2652     {
2653       vam->async_errors += (retval < 0);
2654     }
2655   else
2656     {
2657       vam->retval = retval;
2658       vam->result_ready = 1;
2659
2660       if (retval == 0)
2661         {
2662           if (mp->ip4_set)
2663             clib_warning ("ip4 address %U", format_ip4_address,
2664                           (ip4_address_t *) mp->ip4_address);
2665           if (mp->ip6_set)
2666             clib_warning ("ip6 address %U", format_ip6_address,
2667                           (ip6_address_t *) mp->ip6_address);
2668         }
2669       else
2670         clib_warning ("retval %d", retval);
2671     }
2672 }
2673
2674 static void vl_api_dns_resolve_name_reply_t_handler_json
2675   (vl_api_dns_resolve_name_reply_t * mp)
2676 {
2677   clib_warning ("not implemented");
2678 }
2679
2680 static void vl_api_dns_resolve_ip_reply_t_handler
2681   (vl_api_dns_resolve_ip_reply_t * mp)
2682 {
2683   vat_main_t *vam = &vat_main;
2684   i32 retval = ntohl (mp->retval);
2685   if (vam->async_mode)
2686     {
2687       vam->async_errors += (retval < 0);
2688     }
2689   else
2690     {
2691       vam->retval = retval;
2692       vam->result_ready = 1;
2693
2694       if (retval == 0)
2695         {
2696           clib_warning ("canonical name %s", mp->name);
2697         }
2698       else
2699         clib_warning ("retval %d", retval);
2700     }
2701 }
2702
2703 static void vl_api_dns_resolve_ip_reply_t_handler_json
2704   (vl_api_dns_resolve_ip_reply_t * mp)
2705 {
2706   clib_warning ("not implemented");
2707 }
2708
2709
2710 static void vl_api_ip_address_details_t_handler
2711   (vl_api_ip_address_details_t * mp)
2712 {
2713   vat_main_t *vam = &vat_main;
2714   static ip_address_details_t empty_ip_address_details = { {0} };
2715   ip_address_details_t *address = NULL;
2716   ip_details_t *current_ip_details = NULL;
2717   ip_details_t *details = NULL;
2718
2719   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2720
2721   if (!details || vam->current_sw_if_index >= vec_len (details)
2722       || !details[vam->current_sw_if_index].present)
2723     {
2724       errmsg ("ip address details arrived but not stored");
2725       errmsg ("ip_dump should be called first");
2726       return;
2727     }
2728
2729   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2730
2731 #define addresses (current_ip_details->addr)
2732
2733   vec_validate_init_empty (addresses, vec_len (addresses),
2734                            empty_ip_address_details);
2735
2736   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2737
2738   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2739   address->prefix_length = mp->prefix_length;
2740 #undef addresses
2741 }
2742
2743 static void vl_api_ip_address_details_t_handler_json
2744   (vl_api_ip_address_details_t * mp)
2745 {
2746   vat_main_t *vam = &vat_main;
2747   vat_json_node_t *node = NULL;
2748   struct in6_addr ip6;
2749   struct in_addr ip4;
2750
2751   if (VAT_JSON_ARRAY != vam->json_tree.type)
2752     {
2753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2754       vat_json_init_array (&vam->json_tree);
2755     }
2756   node = vat_json_array_add (&vam->json_tree);
2757
2758   vat_json_init_object (node);
2759   if (vam->is_ipv6)
2760     {
2761       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2762       vat_json_object_add_ip6 (node, "ip", ip6);
2763     }
2764   else
2765     {
2766       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2767       vat_json_object_add_ip4 (node, "ip", ip4);
2768     }
2769   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2770 }
2771
2772 static void
2773 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   static ip_details_t empty_ip_details = { 0 };
2777   ip_details_t *ip = NULL;
2778   u32 sw_if_index = ~0;
2779
2780   sw_if_index = ntohl (mp->sw_if_index);
2781
2782   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2783                            sw_if_index, empty_ip_details);
2784
2785   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2786                          sw_if_index);
2787
2788   ip->present = 1;
2789 }
2790
2791 static void
2792 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2793 {
2794   vat_main_t *vam = &vat_main;
2795
2796   if (VAT_JSON_ARRAY != vam->json_tree.type)
2797     {
2798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2799       vat_json_init_array (&vam->json_tree);
2800     }
2801   vat_json_array_add_uint (&vam->json_tree,
2802                            clib_net_to_host_u32 (mp->sw_if_index));
2803 }
2804
2805 static void
2806 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2807 {
2808   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2809           "router_addr %U host_mac %U",
2810           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2811           mp->lease.hostname,
2812           format_ip4_address, &mp->lease.host_address,
2813           format_ip4_address, &mp->lease.router_address,
2814           format_ethernet_address, mp->lease.host_mac);
2815 }
2816
2817 static void vl_api_dhcp_compl_event_t_handler_json
2818   (vl_api_dhcp_compl_event_t * mp)
2819 {
2820   /* JSON output not supported */
2821 }
2822
2823 static void vl_api_get_first_msg_id_reply_t_handler
2824   (vl_api_get_first_msg_id_reply_t * mp)
2825 {
2826   vat_main_t *vam = &vat_main;
2827   i32 retval = ntohl (mp->retval);
2828
2829   if (vam->async_mode)
2830     {
2831       vam->async_errors += (retval < 0);
2832     }
2833   else
2834     {
2835       vam->retval = retval;
2836       vam->result_ready = 1;
2837     }
2838   if (retval >= 0)
2839     {
2840       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2841     }
2842 }
2843
2844 static void vl_api_get_first_msg_id_reply_t_handler_json
2845   (vl_api_get_first_msg_id_reply_t * mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t node;
2849
2850   vat_json_init_object (&node);
2851   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2852   vat_json_object_add_uint (&node, "first_msg_id",
2853                             (uint) ntohs (mp->first_msg_id));
2854
2855   vat_json_print (vam->ofp, &node);
2856   vat_json_free (&node);
2857
2858   vam->retval = ntohl (mp->retval);
2859   vam->result_ready = 1;
2860 }
2861
2862 static void vl_api_get_node_graph_reply_t_handler
2863   (vl_api_get_node_graph_reply_t * mp)
2864 {
2865   vat_main_t *vam = &vat_main;
2866   api_main_t *am = &api_main;
2867   i32 retval = ntohl (mp->retval);
2868   u8 *pvt_copy, *reply;
2869   void *oldheap;
2870   vlib_node_t *node;
2871   int i;
2872
2873   if (vam->async_mode)
2874     {
2875       vam->async_errors += (retval < 0);
2876     }
2877   else
2878     {
2879       vam->retval = retval;
2880       vam->result_ready = 1;
2881     }
2882
2883   /* "Should never happen..." */
2884   if (retval != 0)
2885     return;
2886
2887   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2888   pvt_copy = vec_dup (reply);
2889
2890   /* Toss the shared-memory original... */
2891   pthread_mutex_lock (&am->vlib_rp->mutex);
2892   oldheap = svm_push_data_heap (am->vlib_rp);
2893
2894   vec_free (reply);
2895
2896   svm_pop_heap (oldheap);
2897   pthread_mutex_unlock (&am->vlib_rp->mutex);
2898
2899   if (vam->graph_nodes)
2900     {
2901       hash_free (vam->graph_node_index_by_name);
2902
2903       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2904         {
2905           node = vam->graph_nodes[0][i];
2906           vec_free (node->name);
2907           vec_free (node->next_nodes);
2908           vec_free (node);
2909         }
2910       vec_free (vam->graph_nodes[0]);
2911       vec_free (vam->graph_nodes);
2912     }
2913
2914   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2915   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2916   vec_free (pvt_copy);
2917
2918   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2919     {
2920       node = vam->graph_nodes[0][i];
2921       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2922     }
2923 }
2924
2925 static void vl_api_get_node_graph_reply_t_handler_json
2926   (vl_api_get_node_graph_reply_t * mp)
2927 {
2928   vat_main_t *vam = &vat_main;
2929   api_main_t *am = &api_main;
2930   void *oldheap;
2931   vat_json_node_t node;
2932   u8 *reply;
2933
2934   /* $$$$ make this real? */
2935   vat_json_init_object (&node);
2936   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2937   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2938
2939   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2940
2941   /* Toss the shared-memory original... */
2942   pthread_mutex_lock (&am->vlib_rp->mutex);
2943   oldheap = svm_push_data_heap (am->vlib_rp);
2944
2945   vec_free (reply);
2946
2947   svm_pop_heap (oldheap);
2948   pthread_mutex_unlock (&am->vlib_rp->mutex);
2949
2950   vat_json_print (vam->ofp, &node);
2951   vat_json_free (&node);
2952
2953   vam->retval = ntohl (mp->retval);
2954   vam->result_ready = 1;
2955 }
2956
2957 static void
2958 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   u8 *s = 0;
2962
2963   if (mp->local)
2964     {
2965       s = format (s, "%=16d%=16d%=16d",
2966                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2967     }
2968   else
2969     {
2970       s = format (s, "%=16U%=16d%=16d",
2971                   mp->is_ipv6 ? format_ip6_address :
2972                   format_ip4_address,
2973                   mp->ip_address, mp->priority, mp->weight);
2974     }
2975
2976   print (vam->ofp, "%v", s);
2977   vec_free (s);
2978 }
2979
2980 static void
2981 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   vat_json_node_t *node = NULL;
2985   struct in6_addr ip6;
2986   struct in_addr ip4;
2987
2988   if (VAT_JSON_ARRAY != vam->json_tree.type)
2989     {
2990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2991       vat_json_init_array (&vam->json_tree);
2992     }
2993   node = vat_json_array_add (&vam->json_tree);
2994   vat_json_init_object (node);
2995
2996   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2997   vat_json_object_add_uint (node, "priority", mp->priority);
2998   vat_json_object_add_uint (node, "weight", mp->weight);
2999
3000   if (mp->local)
3001     vat_json_object_add_uint (node, "sw_if_index",
3002                               clib_net_to_host_u32 (mp->sw_if_index));
3003   else
3004     {
3005       if (mp->is_ipv6)
3006         {
3007           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3008           vat_json_object_add_ip6 (node, "address", ip6);
3009         }
3010       else
3011         {
3012           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3013           vat_json_object_add_ip4 (node, "address", ip4);
3014         }
3015     }
3016 }
3017
3018 static void
3019 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3020                                           mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   u8 *ls_name = 0;
3024
3025   ls_name = format (0, "%s", mp->ls_name);
3026
3027   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3028          ls_name);
3029   vec_free (ls_name);
3030 }
3031
3032 static void
3033   vl_api_one_locator_set_details_t_handler_json
3034   (vl_api_one_locator_set_details_t * mp)
3035 {
3036   vat_main_t *vam = &vat_main;
3037   vat_json_node_t *node = 0;
3038   u8 *ls_name = 0;
3039
3040   ls_name = format (0, "%s", mp->ls_name);
3041   vec_add1 (ls_name, 0);
3042
3043   if (VAT_JSON_ARRAY != vam->json_tree.type)
3044     {
3045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3046       vat_json_init_array (&vam->json_tree);
3047     }
3048   node = vat_json_array_add (&vam->json_tree);
3049
3050   vat_json_init_object (node);
3051   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3052   vat_json_object_add_uint (node, "ls_index",
3053                             clib_net_to_host_u32 (mp->ls_index));
3054   vec_free (ls_name);
3055 }
3056
3057 typedef struct
3058 {
3059   u32 spi;
3060   u8 si;
3061 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3062
3063 uword
3064 unformat_nsh_address (unformat_input_t * input, va_list * args)
3065 {
3066   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3067   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3068 }
3069
3070 u8 *
3071 format_nsh_address_vat (u8 * s, va_list * args)
3072 {
3073   nsh_t *a = va_arg (*args, nsh_t *);
3074   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3075 }
3076
3077 static u8 *
3078 format_lisp_flat_eid (u8 * s, va_list * args)
3079 {
3080   u32 type = va_arg (*args, u32);
3081   u8 *eid = va_arg (*args, u8 *);
3082   u32 eid_len = va_arg (*args, u32);
3083
3084   switch (type)
3085     {
3086     case 0:
3087       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3088     case 1:
3089       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3090     case 2:
3091       return format (s, "%U", format_ethernet_address, eid);
3092     case 3:
3093       return format (s, "%U", format_nsh_address_vat, eid);
3094     }
3095   return 0;
3096 }
3097
3098 static u8 *
3099 format_lisp_eid_vat (u8 * s, va_list * args)
3100 {
3101   u32 type = va_arg (*args, u32);
3102   u8 *eid = va_arg (*args, u8 *);
3103   u32 eid_len = va_arg (*args, u32);
3104   u8 *seid = va_arg (*args, u8 *);
3105   u32 seid_len = va_arg (*args, u32);
3106   u32 is_src_dst = va_arg (*args, u32);
3107
3108   if (is_src_dst)
3109     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3110
3111   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3112
3113   return s;
3114 }
3115
3116 static void
3117 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3118 {
3119   vat_main_t *vam = &vat_main;
3120   u8 *s = 0, *eid = 0;
3121
3122   if (~0 == mp->locator_set_index)
3123     s = format (0, "action: %d", mp->action);
3124   else
3125     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3126
3127   eid = format (0, "%U", format_lisp_eid_vat,
3128                 mp->eid_type,
3129                 mp->eid,
3130                 mp->eid_prefix_len,
3131                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3132   vec_add1 (eid, 0);
3133
3134   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3135          clib_net_to_host_u32 (mp->vni),
3136          eid,
3137          mp->is_local ? "local" : "remote",
3138          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3139          clib_net_to_host_u16 (mp->key_id), mp->key);
3140
3141   vec_free (s);
3142   vec_free (eid);
3143 }
3144
3145 static void
3146 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3147                                              * mp)
3148 {
3149   vat_main_t *vam = &vat_main;
3150   vat_json_node_t *node = 0;
3151   u8 *eid = 0;
3152
3153   if (VAT_JSON_ARRAY != vam->json_tree.type)
3154     {
3155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3156       vat_json_init_array (&vam->json_tree);
3157     }
3158   node = vat_json_array_add (&vam->json_tree);
3159
3160   vat_json_init_object (node);
3161   if (~0 == mp->locator_set_index)
3162     vat_json_object_add_uint (node, "action", mp->action);
3163   else
3164     vat_json_object_add_uint (node, "locator_set_index",
3165                               clib_net_to_host_u32 (mp->locator_set_index));
3166
3167   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3168   if (mp->eid_type == 3)
3169     {
3170       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3171       vat_json_init_object (nsh_json);
3172       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3173       vat_json_object_add_uint (nsh_json, "spi",
3174                                 clib_net_to_host_u32 (nsh->spi));
3175       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3176     }
3177   else
3178     {
3179       eid = format (0, "%U", format_lisp_eid_vat,
3180                     mp->eid_type,
3181                     mp->eid,
3182                     mp->eid_prefix_len,
3183                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3184       vec_add1 (eid, 0);
3185       vat_json_object_add_string_copy (node, "eid", eid);
3186       vec_free (eid);
3187     }
3188   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3189   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3190   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3191
3192   if (mp->key_id)
3193     {
3194       vat_json_object_add_uint (node, "key_id",
3195                                 clib_net_to_host_u16 (mp->key_id));
3196       vat_json_object_add_string_copy (node, "key", mp->key);
3197     }
3198 }
3199
3200 static void
3201 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3202 {
3203   vat_main_t *vam = &vat_main;
3204   u8 *seid = 0, *deid = 0;
3205   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3206
3207   deid = format (0, "%U", format_lisp_eid_vat,
3208                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3209
3210   seid = format (0, "%U", format_lisp_eid_vat,
3211                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3212
3213   vec_add1 (deid, 0);
3214   vec_add1 (seid, 0);
3215
3216   if (mp->is_ip4)
3217     format_ip_address_fcn = format_ip4_address;
3218   else
3219     format_ip_address_fcn = format_ip6_address;
3220
3221
3222   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3223          clib_net_to_host_u32 (mp->vni),
3224          seid, deid,
3225          format_ip_address_fcn, mp->lloc,
3226          format_ip_address_fcn, mp->rloc,
3227          clib_net_to_host_u32 (mp->pkt_count),
3228          clib_net_to_host_u32 (mp->bytes));
3229
3230   vec_free (deid);
3231   vec_free (seid);
3232 }
3233
3234 static void
3235 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3236 {
3237   struct in6_addr ip6;
3238   struct in_addr ip4;
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t *node = 0;
3241   u8 *deid = 0, *seid = 0;
3242
3243   if (VAT_JSON_ARRAY != vam->json_tree.type)
3244     {
3245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3246       vat_json_init_array (&vam->json_tree);
3247     }
3248   node = vat_json_array_add (&vam->json_tree);
3249
3250   vat_json_init_object (node);
3251   deid = format (0, "%U", format_lisp_eid_vat,
3252                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3253
3254   seid = format (0, "%U", format_lisp_eid_vat,
3255                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3256
3257   vec_add1 (deid, 0);
3258   vec_add1 (seid, 0);
3259
3260   vat_json_object_add_string_copy (node, "seid", seid);
3261   vat_json_object_add_string_copy (node, "deid", deid);
3262   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3263
3264   if (mp->is_ip4)
3265     {
3266       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3267       vat_json_object_add_ip4 (node, "lloc", ip4);
3268       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3269       vat_json_object_add_ip4 (node, "rloc", ip4);
3270     }
3271   else
3272     {
3273       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3274       vat_json_object_add_ip6 (node, "lloc", ip6);
3275       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3276       vat_json_object_add_ip6 (node, "rloc", ip6);
3277     }
3278   vat_json_object_add_uint (node, "pkt_count",
3279                             clib_net_to_host_u32 (mp->pkt_count));
3280   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3281
3282   vec_free (deid);
3283   vec_free (seid);
3284 }
3285
3286 static void
3287   vl_api_one_eid_table_map_details_t_handler
3288   (vl_api_one_eid_table_map_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291
3292   u8 *line = format (0, "%=10d%=10d",
3293                      clib_net_to_host_u32 (mp->vni),
3294                      clib_net_to_host_u32 (mp->dp_table));
3295   print (vam->ofp, "%v", line);
3296   vec_free (line);
3297 }
3298
3299 static void
3300   vl_api_one_eid_table_map_details_t_handler_json
3301   (vl_api_one_eid_table_map_details_t * mp)
3302 {
3303   vat_main_t *vam = &vat_main;
3304   vat_json_node_t *node = NULL;
3305
3306   if (VAT_JSON_ARRAY != vam->json_tree.type)
3307     {
3308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3309       vat_json_init_array (&vam->json_tree);
3310     }
3311   node = vat_json_array_add (&vam->json_tree);
3312   vat_json_init_object (node);
3313   vat_json_object_add_uint (node, "dp_table",
3314                             clib_net_to_host_u32 (mp->dp_table));
3315   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3316 }
3317
3318 static void
3319   vl_api_one_eid_table_vni_details_t_handler
3320   (vl_api_one_eid_table_vni_details_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323
3324   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3325   print (vam->ofp, "%v", line);
3326   vec_free (line);
3327 }
3328
3329 static void
3330   vl_api_one_eid_table_vni_details_t_handler_json
3331   (vl_api_one_eid_table_vni_details_t * mp)
3332 {
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = NULL;
3335
3336   if (VAT_JSON_ARRAY != vam->json_tree.type)
3337     {
3338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3339       vat_json_init_array (&vam->json_tree);
3340     }
3341   node = vat_json_array_add (&vam->json_tree);
3342   vat_json_init_object (node);
3343   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3344 }
3345
3346 static void
3347   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3348   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3349 {
3350   vat_main_t *vam = &vat_main;
3351   int retval = clib_net_to_host_u32 (mp->retval);
3352
3353   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3354   print (vam->ofp, "fallback threshold value: %d", mp->value);
3355
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3362   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t _node, *node = &_node;
3366   int retval = clib_net_to_host_u32 (mp->retval);
3367
3368   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3369   vat_json_init_object (node);
3370   vat_json_object_add_uint (node, "value", mp->value);
3371
3372   vat_json_print (vam->ofp, node);
3373   vat_json_free (node);
3374
3375   vam->retval = retval;
3376   vam->result_ready = 1;
3377 }
3378
3379 static void
3380   vl_api_show_one_map_register_state_reply_t_handler
3381   (vl_api_show_one_map_register_state_reply_t * mp)
3382 {
3383   vat_main_t *vam = &vat_main;
3384   int retval = clib_net_to_host_u32 (mp->retval);
3385
3386   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3387
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393   vl_api_show_one_map_register_state_reply_t_handler_json
3394   (vl_api_show_one_map_register_state_reply_t * mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397   vat_json_node_t _node, *node = &_node;
3398   int retval = clib_net_to_host_u32 (mp->retval);
3399
3400   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3401
3402   vat_json_init_object (node);
3403   vat_json_object_add_string_copy (node, "state", s);
3404
3405   vat_json_print (vam->ofp, node);
3406   vat_json_free (node);
3407
3408   vam->retval = retval;
3409   vam->result_ready = 1;
3410   vec_free (s);
3411 }
3412
3413 static void
3414   vl_api_show_one_rloc_probe_state_reply_t_handler
3415   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3416 {
3417   vat_main_t *vam = &vat_main;
3418   int retval = clib_net_to_host_u32 (mp->retval);
3419
3420   if (retval)
3421     goto end;
3422
3423   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3424 end:
3425   vam->retval = retval;
3426   vam->result_ready = 1;
3427 }
3428
3429 static void
3430   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3431   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434   vat_json_node_t _node, *node = &_node;
3435   int retval = clib_net_to_host_u32 (mp->retval);
3436
3437   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3438   vat_json_init_object (node);
3439   vat_json_object_add_string_copy (node, "state", s);
3440
3441   vat_json_print (vam->ofp, node);
3442   vat_json_free (node);
3443
3444   vam->retval = retval;
3445   vam->result_ready = 1;
3446   vec_free (s);
3447 }
3448
3449 static void
3450   vl_api_show_one_stats_enable_disable_reply_t_handler
3451   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3452 {
3453   vat_main_t *vam = &vat_main;
3454   int retval = clib_net_to_host_u32 (mp->retval);
3455
3456   if (retval)
3457     goto end;
3458
3459   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3460 end:
3461   vam->retval = retval;
3462   vam->result_ready = 1;
3463 }
3464
3465 static void
3466   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3467   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3468 {
3469   vat_main_t *vam = &vat_main;
3470   vat_json_node_t _node, *node = &_node;
3471   int retval = clib_net_to_host_u32 (mp->retval);
3472
3473   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3474   vat_json_init_object (node);
3475   vat_json_object_add_string_copy (node, "state", s);
3476
3477   vat_json_print (vam->ofp, node);
3478   vat_json_free (node);
3479
3480   vam->retval = retval;
3481   vam->result_ready = 1;
3482   vec_free (s);
3483 }
3484
3485 static void
3486 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3487 {
3488   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3489   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3490   e->vni = clib_net_to_host_u32 (e->vni);
3491 }
3492
3493 static void
3494   gpe_fwd_entries_get_reply_t_net_to_host
3495   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3496 {
3497   u32 i;
3498
3499   mp->count = clib_net_to_host_u32 (mp->count);
3500   for (i = 0; i < mp->count; i++)
3501     {
3502       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3503     }
3504 }
3505
3506 static u8 *
3507 format_gpe_encap_mode (u8 * s, va_list * args)
3508 {
3509   u32 mode = va_arg (*args, u32);
3510
3511   switch (mode)
3512     {
3513     case 0:
3514       return format (s, "lisp");
3515     case 1:
3516       return format (s, "vxlan");
3517     }
3518   return 0;
3519 }
3520
3521 static void
3522   vl_api_gpe_get_encap_mode_reply_t_handler
3523   (vl_api_gpe_get_encap_mode_reply_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526
3527   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3528   vam->retval = ntohl (mp->retval);
3529   vam->result_ready = 1;
3530 }
3531
3532 static void
3533   vl_api_gpe_get_encap_mode_reply_t_handler_json
3534   (vl_api_gpe_get_encap_mode_reply_t * mp)
3535 {
3536   vat_main_t *vam = &vat_main;
3537   vat_json_node_t node;
3538
3539   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3540   vec_add1 (encap_mode, 0);
3541
3542   vat_json_init_object (&node);
3543   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3544
3545   vec_free (encap_mode);
3546   vat_json_print (vam->ofp, &node);
3547   vat_json_free (&node);
3548
3549   vam->retval = ntohl (mp->retval);
3550   vam->result_ready = 1;
3551 }
3552
3553 static void
3554   vl_api_gpe_fwd_entry_path_details_t_handler
3555   (vl_api_gpe_fwd_entry_path_details_t * mp)
3556 {
3557   vat_main_t *vam = &vat_main;
3558   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3559
3560   if (mp->lcl_loc.is_ip4)
3561     format_ip_address_fcn = format_ip4_address;
3562   else
3563     format_ip_address_fcn = format_ip6_address;
3564
3565   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3566          format_ip_address_fcn, &mp->lcl_loc,
3567          format_ip_address_fcn, &mp->rmt_loc);
3568 }
3569
3570 static void
3571 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3572 {
3573   struct in6_addr ip6;
3574   struct in_addr ip4;
3575
3576   if (loc->is_ip4)
3577     {
3578       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3579       vat_json_object_add_ip4 (n, "address", ip4);
3580     }
3581   else
3582     {
3583       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3584       vat_json_object_add_ip6 (n, "address", ip6);
3585     }
3586   vat_json_object_add_uint (n, "weight", loc->weight);
3587 }
3588
3589 static void
3590   vl_api_gpe_fwd_entry_path_details_t_handler_json
3591   (vl_api_gpe_fwd_entry_path_details_t * mp)
3592 {
3593   vat_main_t *vam = &vat_main;
3594   vat_json_node_t *node = NULL;
3595   vat_json_node_t *loc_node;
3596
3597   if (VAT_JSON_ARRAY != vam->json_tree.type)
3598     {
3599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3600       vat_json_init_array (&vam->json_tree);
3601     }
3602   node = vat_json_array_add (&vam->json_tree);
3603   vat_json_init_object (node);
3604
3605   loc_node = vat_json_object_add (node, "local_locator");
3606   vat_json_init_object (loc_node);
3607   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3608
3609   loc_node = vat_json_object_add (node, "remote_locator");
3610   vat_json_init_object (loc_node);
3611   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3612 }
3613
3614 static void
3615   vl_api_gpe_fwd_entries_get_reply_t_handler
3616   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   u32 i;
3620   int retval = clib_net_to_host_u32 (mp->retval);
3621   vl_api_gpe_fwd_entry_t *e;
3622
3623   if (retval)
3624     goto end;
3625
3626   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3627
3628   for (i = 0; i < mp->count; i++)
3629     {
3630       e = &mp->entries[i];
3631       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3632              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3633              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3634     }
3635
3636 end:
3637   vam->retval = retval;
3638   vam->result_ready = 1;
3639 }
3640
3641 static void
3642   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3643   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3644 {
3645   u8 *s = 0;
3646   vat_main_t *vam = &vat_main;
3647   vat_json_node_t *e = 0, root;
3648   u32 i;
3649   int retval = clib_net_to_host_u32 (mp->retval);
3650   vl_api_gpe_fwd_entry_t *fwd;
3651
3652   if (retval)
3653     goto end;
3654
3655   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3656   vat_json_init_array (&root);
3657
3658   for (i = 0; i < mp->count; i++)
3659     {
3660       e = vat_json_array_add (&root);
3661       fwd = &mp->entries[i];
3662
3663       vat_json_init_object (e);
3664       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3665       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3666       vat_json_object_add_int (e, "vni", fwd->vni);
3667       vat_json_object_add_int (e, "action", fwd->action);
3668
3669       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3670                   fwd->leid_prefix_len);
3671       vec_add1 (s, 0);
3672       vat_json_object_add_string_copy (e, "leid", s);
3673       vec_free (s);
3674
3675       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3676                   fwd->reid_prefix_len);
3677       vec_add1 (s, 0);
3678       vat_json_object_add_string_copy (e, "reid", s);
3679       vec_free (s);
3680     }
3681
3682   vat_json_print (vam->ofp, &root);
3683   vat_json_free (&root);
3684
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3692   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   u32 i, n;
3696   int retval = clib_net_to_host_u32 (mp->retval);
3697   vl_api_gpe_native_fwd_rpath_t *r;
3698
3699   if (retval)
3700     goto end;
3701
3702   n = clib_net_to_host_u32 (mp->count);
3703
3704   for (i = 0; i < n; i++)
3705     {
3706       r = &mp->entries[i];
3707       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3708              clib_net_to_host_u32 (r->fib_index),
3709              clib_net_to_host_u32 (r->nh_sw_if_index),
3710              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3711     }
3712
3713 end:
3714   vam->retval = retval;
3715   vam->result_ready = 1;
3716 }
3717
3718 static void
3719   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3720   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3721 {
3722   vat_main_t *vam = &vat_main;
3723   vat_json_node_t root, *e;
3724   u32 i, n;
3725   int retval = clib_net_to_host_u32 (mp->retval);
3726   vl_api_gpe_native_fwd_rpath_t *r;
3727   u8 *s;
3728
3729   if (retval)
3730     goto end;
3731
3732   n = clib_net_to_host_u32 (mp->count);
3733   vat_json_init_array (&root);
3734
3735   for (i = 0; i < n; i++)
3736     {
3737       e = vat_json_array_add (&root);
3738       vat_json_init_object (e);
3739       r = &mp->entries[i];
3740       s =
3741         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3742                 r->nh_addr);
3743       vec_add1 (s, 0);
3744       vat_json_object_add_string_copy (e, "ip4", s);
3745       vec_free (s);
3746
3747       vat_json_object_add_uint (e, "fib_index",
3748                                 clib_net_to_host_u32 (r->fib_index));
3749       vat_json_object_add_uint (e, "nh_sw_if_index",
3750                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3751     }
3752
3753   vat_json_print (vam->ofp, &root);
3754   vat_json_free (&root);
3755
3756 end:
3757   vam->retval = retval;
3758   vam->result_ready = 1;
3759 }
3760
3761 static void
3762   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3763   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3764 {
3765   vat_main_t *vam = &vat_main;
3766   u32 i, n;
3767   int retval = clib_net_to_host_u32 (mp->retval);
3768
3769   if (retval)
3770     goto end;
3771
3772   n = clib_net_to_host_u32 (mp->count);
3773
3774   for (i = 0; i < n; i++)
3775     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3776
3777 end:
3778   vam->retval = retval;
3779   vam->result_ready = 1;
3780 }
3781
3782 static void
3783   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3784   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3785 {
3786   vat_main_t *vam = &vat_main;
3787   vat_json_node_t root;
3788   u32 i, n;
3789   int retval = clib_net_to_host_u32 (mp->retval);
3790
3791   if (retval)
3792     goto end;
3793
3794   n = clib_net_to_host_u32 (mp->count);
3795   vat_json_init_array (&root);
3796
3797   for (i = 0; i < n; i++)
3798     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3799
3800   vat_json_print (vam->ofp, &root);
3801   vat_json_free (&root);
3802
3803 end:
3804   vam->retval = retval;
3805   vam->result_ready = 1;
3806 }
3807
3808 static void
3809   vl_api_one_ndp_entries_get_reply_t_handler
3810   (vl_api_one_ndp_entries_get_reply_t * mp)
3811 {
3812   vat_main_t *vam = &vat_main;
3813   u32 i, n;
3814   int retval = clib_net_to_host_u32 (mp->retval);
3815
3816   if (retval)
3817     goto end;
3818
3819   n = clib_net_to_host_u32 (mp->count);
3820
3821   for (i = 0; i < n; i++)
3822     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3823            format_ethernet_address, mp->entries[i].mac);
3824
3825 end:
3826   vam->retval = retval;
3827   vam->result_ready = 1;
3828 }
3829
3830 static void
3831   vl_api_one_ndp_entries_get_reply_t_handler_json
3832   (vl_api_one_ndp_entries_get_reply_t * mp)
3833 {
3834   u8 *s = 0;
3835   vat_main_t *vam = &vat_main;
3836   vat_json_node_t *e = 0, root;
3837   u32 i, n;
3838   int retval = clib_net_to_host_u32 (mp->retval);
3839   vl_api_one_ndp_entry_t *arp_entry;
3840
3841   if (retval)
3842     goto end;
3843
3844   n = clib_net_to_host_u32 (mp->count);
3845   vat_json_init_array (&root);
3846
3847   for (i = 0; i < n; i++)
3848     {
3849       e = vat_json_array_add (&root);
3850       arp_entry = &mp->entries[i];
3851
3852       vat_json_init_object (e);
3853       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3854       vec_add1 (s, 0);
3855
3856       vat_json_object_add_string_copy (e, "mac", s);
3857       vec_free (s);
3858
3859       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3860       vec_add1 (s, 0);
3861       vat_json_object_add_string_copy (e, "ip6", s);
3862       vec_free (s);
3863     }
3864
3865   vat_json_print (vam->ofp, &root);
3866   vat_json_free (&root);
3867
3868 end:
3869   vam->retval = retval;
3870   vam->result_ready = 1;
3871 }
3872
3873 static void
3874   vl_api_one_l2_arp_entries_get_reply_t_handler
3875   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3876 {
3877   vat_main_t *vam = &vat_main;
3878   u32 i, n;
3879   int retval = clib_net_to_host_u32 (mp->retval);
3880
3881   if (retval)
3882     goto end;
3883
3884   n = clib_net_to_host_u32 (mp->count);
3885
3886   for (i = 0; i < n; i++)
3887     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3888            format_ethernet_address, mp->entries[i].mac);
3889
3890 end:
3891   vam->retval = retval;
3892   vam->result_ready = 1;
3893 }
3894
3895 static void
3896   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3897   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3898 {
3899   u8 *s = 0;
3900   vat_main_t *vam = &vat_main;
3901   vat_json_node_t *e = 0, root;
3902   u32 i, n;
3903   int retval = clib_net_to_host_u32 (mp->retval);
3904   vl_api_one_l2_arp_entry_t *arp_entry;
3905
3906   if (retval)
3907     goto end;
3908
3909   n = clib_net_to_host_u32 (mp->count);
3910   vat_json_init_array (&root);
3911
3912   for (i = 0; i < n; i++)
3913     {
3914       e = vat_json_array_add (&root);
3915       arp_entry = &mp->entries[i];
3916
3917       vat_json_init_object (e);
3918       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3919       vec_add1 (s, 0);
3920
3921       vat_json_object_add_string_copy (e, "mac", s);
3922       vec_free (s);
3923
3924       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "ip4", s);
3927       vec_free (s);
3928     }
3929
3930   vat_json_print (vam->ofp, &root);
3931   vat_json_free (&root);
3932
3933 end:
3934   vam->retval = retval;
3935   vam->result_ready = 1;
3936 }
3937
3938 static void
3939 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   u32 i, n;
3943   int retval = clib_net_to_host_u32 (mp->retval);
3944
3945   if (retval)
3946     goto end;
3947
3948   n = clib_net_to_host_u32 (mp->count);
3949
3950   for (i = 0; i < n; i++)
3951     {
3952       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3953     }
3954
3955 end:
3956   vam->retval = retval;
3957   vam->result_ready = 1;
3958 }
3959
3960 static void
3961   vl_api_one_ndp_bd_get_reply_t_handler_json
3962   (vl_api_one_ndp_bd_get_reply_t * mp)
3963 {
3964   vat_main_t *vam = &vat_main;
3965   vat_json_node_t root;
3966   u32 i, n;
3967   int retval = clib_net_to_host_u32 (mp->retval);
3968
3969   if (retval)
3970     goto end;
3971
3972   n = clib_net_to_host_u32 (mp->count);
3973   vat_json_init_array (&root);
3974
3975   for (i = 0; i < n; i++)
3976     {
3977       vat_json_array_add_uint (&root,
3978                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3979     }
3980
3981   vat_json_print (vam->ofp, &root);
3982   vat_json_free (&root);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_bd_get_reply_t_handler
3991   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994   u32 i, n;
3995   int retval = clib_net_to_host_u32 (mp->retval);
3996
3997   if (retval)
3998     goto end;
3999
4000   n = clib_net_to_host_u32 (mp->count);
4001
4002   for (i = 0; i < n; i++)
4003     {
4004       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4005     }
4006
4007 end:
4008   vam->retval = retval;
4009   vam->result_ready = 1;
4010 }
4011
4012 static void
4013   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4014   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4015 {
4016   vat_main_t *vam = &vat_main;
4017   vat_json_node_t root;
4018   u32 i, n;
4019   int retval = clib_net_to_host_u32 (mp->retval);
4020
4021   if (retval)
4022     goto end;
4023
4024   n = clib_net_to_host_u32 (mp->count);
4025   vat_json_init_array (&root);
4026
4027   for (i = 0; i < n; i++)
4028     {
4029       vat_json_array_add_uint (&root,
4030                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4031     }
4032
4033   vat_json_print (vam->ofp, &root);
4034   vat_json_free (&root);
4035
4036 end:
4037   vam->retval = retval;
4038   vam->result_ready = 1;
4039 }
4040
4041 static void
4042   vl_api_one_adjacencies_get_reply_t_handler
4043   (vl_api_one_adjacencies_get_reply_t * mp)
4044 {
4045   vat_main_t *vam = &vat_main;
4046   u32 i, n;
4047   int retval = clib_net_to_host_u32 (mp->retval);
4048   vl_api_one_adjacency_t *a;
4049
4050   if (retval)
4051     goto end;
4052
4053   n = clib_net_to_host_u32 (mp->count);
4054
4055   for (i = 0; i < n; i++)
4056     {
4057       a = &mp->adjacencies[i];
4058       print (vam->ofp, "%U %40U",
4059              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4060              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4061     }
4062
4063 end:
4064   vam->retval = retval;
4065   vam->result_ready = 1;
4066 }
4067
4068 static void
4069   vl_api_one_adjacencies_get_reply_t_handler_json
4070   (vl_api_one_adjacencies_get_reply_t * mp)
4071 {
4072   u8 *s = 0;
4073   vat_main_t *vam = &vat_main;
4074   vat_json_node_t *e = 0, root;
4075   u32 i, n;
4076   int retval = clib_net_to_host_u32 (mp->retval);
4077   vl_api_one_adjacency_t *a;
4078
4079   if (retval)
4080     goto end;
4081
4082   n = clib_net_to_host_u32 (mp->count);
4083   vat_json_init_array (&root);
4084
4085   for (i = 0; i < n; i++)
4086     {
4087       e = vat_json_array_add (&root);
4088       a = &mp->adjacencies[i];
4089
4090       vat_json_init_object (e);
4091       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4092                   a->leid_prefix_len);
4093       vec_add1 (s, 0);
4094       vat_json_object_add_string_copy (e, "leid", s);
4095       vec_free (s);
4096
4097       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4098                   a->reid_prefix_len);
4099       vec_add1 (s, 0);
4100       vat_json_object_add_string_copy (e, "reid", s);
4101       vec_free (s);
4102     }
4103
4104   vat_json_print (vam->ofp, &root);
4105   vat_json_free (&root);
4106
4107 end:
4108   vam->retval = retval;
4109   vam->result_ready = 1;
4110 }
4111
4112 static void
4113 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116
4117   print (vam->ofp, "%=20U",
4118          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4119          mp->ip_address);
4120 }
4121
4122 static void
4123   vl_api_one_map_server_details_t_handler_json
4124   (vl_api_one_map_server_details_t * mp)
4125 {
4126   vat_main_t *vam = &vat_main;
4127   vat_json_node_t *node = NULL;
4128   struct in6_addr ip6;
4129   struct in_addr ip4;
4130
4131   if (VAT_JSON_ARRAY != vam->json_tree.type)
4132     {
4133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4134       vat_json_init_array (&vam->json_tree);
4135     }
4136   node = vat_json_array_add (&vam->json_tree);
4137
4138   vat_json_init_object (node);
4139   if (mp->is_ipv6)
4140     {
4141       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4142       vat_json_object_add_ip6 (node, "map-server", ip6);
4143     }
4144   else
4145     {
4146       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4147       vat_json_object_add_ip4 (node, "map-server", ip4);
4148     }
4149 }
4150
4151 static void
4152 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4153                                            * mp)
4154 {
4155   vat_main_t *vam = &vat_main;
4156
4157   print (vam->ofp, "%=20U",
4158          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4159          mp->ip_address);
4160 }
4161
4162 static void
4163   vl_api_one_map_resolver_details_t_handler_json
4164   (vl_api_one_map_resolver_details_t * mp)
4165 {
4166   vat_main_t *vam = &vat_main;
4167   vat_json_node_t *node = NULL;
4168   struct in6_addr ip6;
4169   struct in_addr ip4;
4170
4171   if (VAT_JSON_ARRAY != vam->json_tree.type)
4172     {
4173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4174       vat_json_init_array (&vam->json_tree);
4175     }
4176   node = vat_json_array_add (&vam->json_tree);
4177
4178   vat_json_init_object (node);
4179   if (mp->is_ipv6)
4180     {
4181       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4182       vat_json_object_add_ip6 (node, "map resolver", ip6);
4183     }
4184   else
4185     {
4186       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4187       vat_json_object_add_ip4 (node, "map resolver", ip4);
4188     }
4189 }
4190
4191 static void
4192 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4193 {
4194   vat_main_t *vam = &vat_main;
4195   i32 retval = ntohl (mp->retval);
4196
4197   if (0 <= retval)
4198     {
4199       print (vam->ofp, "feature: %s\ngpe: %s",
4200              mp->feature_status ? "enabled" : "disabled",
4201              mp->gpe_status ? "enabled" : "disabled");
4202     }
4203
4204   vam->retval = retval;
4205   vam->result_ready = 1;
4206 }
4207
4208 static void
4209   vl_api_show_one_status_reply_t_handler_json
4210   (vl_api_show_one_status_reply_t * mp)
4211 {
4212   vat_main_t *vam = &vat_main;
4213   vat_json_node_t node;
4214   u8 *gpe_status = NULL;
4215   u8 *feature_status = NULL;
4216
4217   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4218   feature_status = format (0, "%s",
4219                            mp->feature_status ? "enabled" : "disabled");
4220   vec_add1 (gpe_status, 0);
4221   vec_add1 (feature_status, 0);
4222
4223   vat_json_init_object (&node);
4224   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4225   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4226
4227   vec_free (gpe_status);
4228   vec_free (feature_status);
4229
4230   vat_json_print (vam->ofp, &node);
4231   vat_json_free (&node);
4232
4233   vam->retval = ntohl (mp->retval);
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4239   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4240 {
4241   vat_main_t *vam = &vat_main;
4242   i32 retval = ntohl (mp->retval);
4243
4244   if (retval >= 0)
4245     {
4246       print (vam->ofp, "%=20s", mp->locator_set_name);
4247     }
4248
4249   vam->retval = retval;
4250   vam->result_ready = 1;
4251 }
4252
4253 static void
4254   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4255   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258   vat_json_node_t *node = NULL;
4259
4260   if (VAT_JSON_ARRAY != vam->json_tree.type)
4261     {
4262       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4263       vat_json_init_array (&vam->json_tree);
4264     }
4265   node = vat_json_array_add (&vam->json_tree);
4266
4267   vat_json_init_object (node);
4268   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4269
4270   vat_json_print (vam->ofp, node);
4271   vat_json_free (node);
4272
4273   vam->retval = ntohl (mp->retval);
4274   vam->result_ready = 1;
4275 }
4276
4277 static u8 *
4278 format_lisp_map_request_mode (u8 * s, va_list * args)
4279 {
4280   u32 mode = va_arg (*args, u32);
4281
4282   switch (mode)
4283     {
4284     case 0:
4285       return format (0, "dst-only");
4286     case 1:
4287       return format (0, "src-dst");
4288     }
4289   return 0;
4290 }
4291
4292 static void
4293   vl_api_show_one_map_request_mode_reply_t_handler
4294   (vl_api_show_one_map_request_mode_reply_t * mp)
4295 {
4296   vat_main_t *vam = &vat_main;
4297   i32 retval = ntohl (mp->retval);
4298
4299   if (0 <= retval)
4300     {
4301       u32 mode = mp->mode;
4302       print (vam->ofp, "map_request_mode: %U",
4303              format_lisp_map_request_mode, mode);
4304     }
4305
4306   vam->retval = retval;
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_show_one_map_request_mode_reply_t_handler_json
4312   (vl_api_show_one_map_request_mode_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   vat_json_node_t node;
4316   u8 *s = 0;
4317   u32 mode;
4318
4319   mode = mp->mode;
4320   s = format (0, "%U", format_lisp_map_request_mode, mode);
4321   vec_add1 (s, 0);
4322
4323   vat_json_init_object (&node);
4324   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4325   vat_json_print (vam->ofp, &node);
4326   vat_json_free (&node);
4327
4328   vec_free (s);
4329   vam->retval = ntohl (mp->retval);
4330   vam->result_ready = 1;
4331 }
4332
4333 static void
4334   vl_api_one_show_xtr_mode_reply_t_handler
4335   (vl_api_one_show_xtr_mode_reply_t * mp)
4336 {
4337   vat_main_t *vam = &vat_main;
4338   i32 retval = ntohl (mp->retval);
4339
4340   if (0 <= retval)
4341     {
4342       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4343     }
4344
4345   vam->retval = retval;
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_one_show_xtr_mode_reply_t_handler_json
4351   (vl_api_one_show_xtr_mode_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   vat_json_node_t node;
4355   u8 *status = 0;
4356
4357   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4358   vec_add1 (status, 0);
4359
4360   vat_json_init_object (&node);
4361   vat_json_object_add_string_copy (&node, "status", status);
4362
4363   vec_free (status);
4364
4365   vat_json_print (vam->ofp, &node);
4366   vat_json_free (&node);
4367
4368   vam->retval = ntohl (mp->retval);
4369   vam->result_ready = 1;
4370 }
4371
4372 static void
4373   vl_api_one_show_pitr_mode_reply_t_handler
4374   (vl_api_one_show_pitr_mode_reply_t * mp)
4375 {
4376   vat_main_t *vam = &vat_main;
4377   i32 retval = ntohl (mp->retval);
4378
4379   if (0 <= retval)
4380     {
4381       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4382     }
4383
4384   vam->retval = retval;
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389   vl_api_one_show_pitr_mode_reply_t_handler_json
4390   (vl_api_one_show_pitr_mode_reply_t * mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393   vat_json_node_t node;
4394   u8 *status = 0;
4395
4396   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4397   vec_add1 (status, 0);
4398
4399   vat_json_init_object (&node);
4400   vat_json_object_add_string_copy (&node, "status", status);
4401
4402   vec_free (status);
4403
4404   vat_json_print (vam->ofp, &node);
4405   vat_json_free (&node);
4406
4407   vam->retval = ntohl (mp->retval);
4408   vam->result_ready = 1;
4409 }
4410
4411 static void
4412   vl_api_one_show_petr_mode_reply_t_handler
4413   (vl_api_one_show_petr_mode_reply_t * mp)
4414 {
4415   vat_main_t *vam = &vat_main;
4416   i32 retval = ntohl (mp->retval);
4417
4418   if (0 <= retval)
4419     {
4420       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4421     }
4422
4423   vam->retval = retval;
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_petr_mode_reply_t_handler_json
4429   (vl_api_one_show_petr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   vat_json_node_t node;
4433   u8 *status = 0;
4434
4435   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4436   vec_add1 (status, 0);
4437
4438   vat_json_init_object (&node);
4439   vat_json_object_add_string_copy (&node, "status", status);
4440
4441   vec_free (status);
4442
4443   vat_json_print (vam->ofp, &node);
4444   vat_json_free (&node);
4445
4446   vam->retval = ntohl (mp->retval);
4447   vam->result_ready = 1;
4448 }
4449
4450 static void
4451   vl_api_show_one_use_petr_reply_t_handler
4452   (vl_api_show_one_use_petr_reply_t * mp)
4453 {
4454   vat_main_t *vam = &vat_main;
4455   i32 retval = ntohl (mp->retval);
4456
4457   if (0 <= retval)
4458     {
4459       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4460       if (mp->status)
4461         {
4462           print (vam->ofp, "Proxy-ETR address; %U",
4463                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4464                  mp->address);
4465         }
4466     }
4467
4468   vam->retval = retval;
4469   vam->result_ready = 1;
4470 }
4471
4472 static void
4473   vl_api_show_one_use_petr_reply_t_handler_json
4474   (vl_api_show_one_use_petr_reply_t * mp)
4475 {
4476   vat_main_t *vam = &vat_main;
4477   vat_json_node_t node;
4478   u8 *status = 0;
4479   struct in_addr ip4;
4480   struct in6_addr ip6;
4481
4482   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4483   vec_add1 (status, 0);
4484
4485   vat_json_init_object (&node);
4486   vat_json_object_add_string_copy (&node, "status", status);
4487   if (mp->status)
4488     {
4489       if (mp->is_ip4)
4490         {
4491           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4492           vat_json_object_add_ip6 (&node, "address", ip6);
4493         }
4494       else
4495         {
4496           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4497           vat_json_object_add_ip4 (&node, "address", ip4);
4498         }
4499     }
4500
4501   vec_free (status);
4502
4503   vat_json_print (vam->ofp, &node);
4504   vat_json_free (&node);
4505
4506   vam->retval = ntohl (mp->retval);
4507   vam->result_ready = 1;
4508 }
4509
4510 static void
4511   vl_api_show_one_nsh_mapping_reply_t_handler
4512   (vl_api_show_one_nsh_mapping_reply_t * mp)
4513 {
4514   vat_main_t *vam = &vat_main;
4515   i32 retval = ntohl (mp->retval);
4516
4517   if (0 <= retval)
4518     {
4519       print (vam->ofp, "%-20s%-16s",
4520              mp->is_set ? "set" : "not-set",
4521              mp->is_set ? (char *) mp->locator_set_name : "");
4522     }
4523
4524   vam->retval = retval;
4525   vam->result_ready = 1;
4526 }
4527
4528 static void
4529   vl_api_show_one_nsh_mapping_reply_t_handler_json
4530   (vl_api_show_one_nsh_mapping_reply_t * mp)
4531 {
4532   vat_main_t *vam = &vat_main;
4533   vat_json_node_t node;
4534   u8 *status = 0;
4535
4536   status = format (0, "%s", mp->is_set ? "yes" : "no");
4537   vec_add1 (status, 0);
4538
4539   vat_json_init_object (&node);
4540   vat_json_object_add_string_copy (&node, "is_set", status);
4541   if (mp->is_set)
4542     {
4543       vat_json_object_add_string_copy (&node, "locator_set",
4544                                        mp->locator_set_name);
4545     }
4546
4547   vec_free (status);
4548
4549   vat_json_print (vam->ofp, &node);
4550   vat_json_free (&node);
4551
4552   vam->retval = ntohl (mp->retval);
4553   vam->result_ready = 1;
4554 }
4555
4556 static void
4557   vl_api_show_one_map_register_ttl_reply_t_handler
4558   (vl_api_show_one_map_register_ttl_reply_t * mp)
4559 {
4560   vat_main_t *vam = &vat_main;
4561   i32 retval = ntohl (mp->retval);
4562
4563   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4564
4565   if (0 <= retval)
4566     {
4567       print (vam->ofp, "ttl: %u", mp->ttl);
4568     }
4569
4570   vam->retval = retval;
4571   vam->result_ready = 1;
4572 }
4573
4574 static void
4575   vl_api_show_one_map_register_ttl_reply_t_handler_json
4576   (vl_api_show_one_map_register_ttl_reply_t * mp)
4577 {
4578   vat_main_t *vam = &vat_main;
4579   vat_json_node_t node;
4580
4581   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4582   vat_json_init_object (&node);
4583   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4584
4585   vat_json_print (vam->ofp, &node);
4586   vat_json_free (&node);
4587
4588   vam->retval = ntohl (mp->retval);
4589   vam->result_ready = 1;
4590 }
4591
4592 static void
4593 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4594 {
4595   vat_main_t *vam = &vat_main;
4596   i32 retval = ntohl (mp->retval);
4597
4598   if (0 <= retval)
4599     {
4600       print (vam->ofp, "%-20s%-16s",
4601              mp->status ? "enabled" : "disabled",
4602              mp->status ? (char *) mp->locator_set_name : "");
4603     }
4604
4605   vam->retval = retval;
4606   vam->result_ready = 1;
4607 }
4608
4609 static void
4610 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4611 {
4612   vat_main_t *vam = &vat_main;
4613   vat_json_node_t node;
4614   u8 *status = 0;
4615
4616   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4617   vec_add1 (status, 0);
4618
4619   vat_json_init_object (&node);
4620   vat_json_object_add_string_copy (&node, "status", status);
4621   if (mp->status)
4622     {
4623       vat_json_object_add_string_copy (&node, "locator_set",
4624                                        mp->locator_set_name);
4625     }
4626
4627   vec_free (status);
4628
4629   vat_json_print (vam->ofp, &node);
4630   vat_json_free (&node);
4631
4632   vam->retval = ntohl (mp->retval);
4633   vam->result_ready = 1;
4634 }
4635
4636 static u8 *
4637 format_policer_type (u8 * s, va_list * va)
4638 {
4639   u32 i = va_arg (*va, u32);
4640
4641   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4642     s = format (s, "1r2c");
4643   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4644     s = format (s, "1r3c");
4645   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4646     s = format (s, "2r3c-2698");
4647   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4648     s = format (s, "2r3c-4115");
4649   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4650     s = format (s, "2r3c-mef5cf1");
4651   else
4652     s = format (s, "ILLEGAL");
4653   return s;
4654 }
4655
4656 static u8 *
4657 format_policer_rate_type (u8 * s, va_list * va)
4658 {
4659   u32 i = va_arg (*va, u32);
4660
4661   if (i == SSE2_QOS_RATE_KBPS)
4662     s = format (s, "kbps");
4663   else if (i == SSE2_QOS_RATE_PPS)
4664     s = format (s, "pps");
4665   else
4666     s = format (s, "ILLEGAL");
4667   return s;
4668 }
4669
4670 static u8 *
4671 format_policer_round_type (u8 * s, va_list * va)
4672 {
4673   u32 i = va_arg (*va, u32);
4674
4675   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4676     s = format (s, "closest");
4677   else if (i == SSE2_QOS_ROUND_TO_UP)
4678     s = format (s, "up");
4679   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4680     s = format (s, "down");
4681   else
4682     s = format (s, "ILLEGAL");
4683   return s;
4684 }
4685
4686 static u8 *
4687 format_policer_action_type (u8 * s, va_list * va)
4688 {
4689   u32 i = va_arg (*va, u32);
4690
4691   if (i == SSE2_QOS_ACTION_DROP)
4692     s = format (s, "drop");
4693   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4694     s = format (s, "transmit");
4695   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4696     s = format (s, "mark-and-transmit");
4697   else
4698     s = format (s, "ILLEGAL");
4699   return s;
4700 }
4701
4702 static u8 *
4703 format_dscp (u8 * s, va_list * va)
4704 {
4705   u32 i = va_arg (*va, u32);
4706   char *t = 0;
4707
4708   switch (i)
4709     {
4710 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4711       foreach_vnet_dscp
4712 #undef _
4713     default:
4714       return format (s, "ILLEGAL");
4715     }
4716   s = format (s, "%s", t);
4717   return s;
4718 }
4719
4720 static void
4721 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4722 {
4723   vat_main_t *vam = &vat_main;
4724   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4725
4726   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4727     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4728   else
4729     conform_dscp_str = format (0, "");
4730
4731   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4732     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4733   else
4734     exceed_dscp_str = format (0, "");
4735
4736   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4737     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4738   else
4739     violate_dscp_str = format (0, "");
4740
4741   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4742          "rate type %U, round type %U, %s rate, %s color-aware, "
4743          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4744          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4745          "conform action %U%s, exceed action %U%s, violate action %U%s",
4746          mp->name,
4747          format_policer_type, mp->type,
4748          ntohl (mp->cir),
4749          ntohl (mp->eir),
4750          clib_net_to_host_u64 (mp->cb),
4751          clib_net_to_host_u64 (mp->eb),
4752          format_policer_rate_type, mp->rate_type,
4753          format_policer_round_type, mp->round_type,
4754          mp->single_rate ? "single" : "dual",
4755          mp->color_aware ? "is" : "not",
4756          ntohl (mp->cir_tokens_per_period),
4757          ntohl (mp->pir_tokens_per_period),
4758          ntohl (mp->scale),
4759          ntohl (mp->current_limit),
4760          ntohl (mp->current_bucket),
4761          ntohl (mp->extended_limit),
4762          ntohl (mp->extended_bucket),
4763          clib_net_to_host_u64 (mp->last_update_time),
4764          format_policer_action_type, mp->conform_action_type,
4765          conform_dscp_str,
4766          format_policer_action_type, mp->exceed_action_type,
4767          exceed_dscp_str,
4768          format_policer_action_type, mp->violate_action_type,
4769          violate_dscp_str);
4770
4771   vec_free (conform_dscp_str);
4772   vec_free (exceed_dscp_str);
4773   vec_free (violate_dscp_str);
4774 }
4775
4776 static void vl_api_policer_details_t_handler_json
4777   (vl_api_policer_details_t * mp)
4778 {
4779   vat_main_t *vam = &vat_main;
4780   vat_json_node_t *node;
4781   u8 *rate_type_str, *round_type_str, *type_str;
4782   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4783
4784   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4785   round_type_str =
4786     format (0, "%U", format_policer_round_type, mp->round_type);
4787   type_str = format (0, "%U", format_policer_type, mp->type);
4788   conform_action_str = format (0, "%U", format_policer_action_type,
4789                                mp->conform_action_type);
4790   exceed_action_str = format (0, "%U", format_policer_action_type,
4791                               mp->exceed_action_type);
4792   violate_action_str = format (0, "%U", format_policer_action_type,
4793                                mp->violate_action_type);
4794
4795   if (VAT_JSON_ARRAY != vam->json_tree.type)
4796     {
4797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4798       vat_json_init_array (&vam->json_tree);
4799     }
4800   node = vat_json_array_add (&vam->json_tree);
4801
4802   vat_json_init_object (node);
4803   vat_json_object_add_string_copy (node, "name", mp->name);
4804   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4805   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4806   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4807   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4808   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4809   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4810   vat_json_object_add_string_copy (node, "type", type_str);
4811   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4812   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4813   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4814   vat_json_object_add_uint (node, "cir_tokens_per_period",
4815                             ntohl (mp->cir_tokens_per_period));
4816   vat_json_object_add_uint (node, "eir_tokens_per_period",
4817                             ntohl (mp->pir_tokens_per_period));
4818   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4819   vat_json_object_add_uint (node, "current_bucket",
4820                             ntohl (mp->current_bucket));
4821   vat_json_object_add_uint (node, "extended_limit",
4822                             ntohl (mp->extended_limit));
4823   vat_json_object_add_uint (node, "extended_bucket",
4824                             ntohl (mp->extended_bucket));
4825   vat_json_object_add_uint (node, "last_update_time",
4826                             ntohl (mp->last_update_time));
4827   vat_json_object_add_string_copy (node, "conform_action",
4828                                    conform_action_str);
4829   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4830     {
4831       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4832       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4833       vec_free (dscp_str);
4834     }
4835   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4836   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4837     {
4838       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4839       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4840       vec_free (dscp_str);
4841     }
4842   vat_json_object_add_string_copy (node, "violate_action",
4843                                    violate_action_str);
4844   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4845     {
4846       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4847       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4848       vec_free (dscp_str);
4849     }
4850
4851   vec_free (rate_type_str);
4852   vec_free (round_type_str);
4853   vec_free (type_str);
4854   vec_free (conform_action_str);
4855   vec_free (exceed_action_str);
4856   vec_free (violate_action_str);
4857 }
4858
4859 static void
4860 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4861                                            mp)
4862 {
4863   vat_main_t *vam = &vat_main;
4864   int i, count = ntohl (mp->count);
4865
4866   if (count > 0)
4867     print (vam->ofp, "classify table ids (%d) : ", count);
4868   for (i = 0; i < count; i++)
4869     {
4870       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4871       print (vam->ofp, (i < count - 1) ? "," : "");
4872     }
4873   vam->retval = ntohl (mp->retval);
4874   vam->result_ready = 1;
4875 }
4876
4877 static void
4878   vl_api_classify_table_ids_reply_t_handler_json
4879   (vl_api_classify_table_ids_reply_t * mp)
4880 {
4881   vat_main_t *vam = &vat_main;
4882   int i, count = ntohl (mp->count);
4883
4884   if (count > 0)
4885     {
4886       vat_json_node_t node;
4887
4888       vat_json_init_object (&node);
4889       for (i = 0; i < count; i++)
4890         {
4891           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4892         }
4893       vat_json_print (vam->ofp, &node);
4894       vat_json_free (&node);
4895     }
4896   vam->retval = ntohl (mp->retval);
4897   vam->result_ready = 1;
4898 }
4899
4900 static void
4901   vl_api_classify_table_by_interface_reply_t_handler
4902   (vl_api_classify_table_by_interface_reply_t * mp)
4903 {
4904   vat_main_t *vam = &vat_main;
4905   u32 table_id;
4906
4907   table_id = ntohl (mp->l2_table_id);
4908   if (table_id != ~0)
4909     print (vam->ofp, "l2 table id : %d", table_id);
4910   else
4911     print (vam->ofp, "l2 table id : No input ACL tables configured");
4912   table_id = ntohl (mp->ip4_table_id);
4913   if (table_id != ~0)
4914     print (vam->ofp, "ip4 table id : %d", table_id);
4915   else
4916     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4917   table_id = ntohl (mp->ip6_table_id);
4918   if (table_id != ~0)
4919     print (vam->ofp, "ip6 table id : %d", table_id);
4920   else
4921     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4922   vam->retval = ntohl (mp->retval);
4923   vam->result_ready = 1;
4924 }
4925
4926 static void
4927   vl_api_classify_table_by_interface_reply_t_handler_json
4928   (vl_api_classify_table_by_interface_reply_t * mp)
4929 {
4930   vat_main_t *vam = &vat_main;
4931   vat_json_node_t node;
4932
4933   vat_json_init_object (&node);
4934
4935   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4936   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4937   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4938
4939   vat_json_print (vam->ofp, &node);
4940   vat_json_free (&node);
4941
4942   vam->retval = ntohl (mp->retval);
4943   vam->result_ready = 1;
4944 }
4945
4946 static void vl_api_policer_add_del_reply_t_handler
4947   (vl_api_policer_add_del_reply_t * mp)
4948 {
4949   vat_main_t *vam = &vat_main;
4950   i32 retval = ntohl (mp->retval);
4951   if (vam->async_mode)
4952     {
4953       vam->async_errors += (retval < 0);
4954     }
4955   else
4956     {
4957       vam->retval = retval;
4958       vam->result_ready = 1;
4959       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4960         /*
4961          * Note: this is just barely thread-safe, depends on
4962          * the main thread spinning waiting for an answer...
4963          */
4964         errmsg ("policer index %d", ntohl (mp->policer_index));
4965     }
4966 }
4967
4968 static void vl_api_policer_add_del_reply_t_handler_json
4969   (vl_api_policer_add_del_reply_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t node;
4973
4974   vat_json_init_object (&node);
4975   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4976   vat_json_object_add_uint (&node, "policer_index",
4977                             ntohl (mp->policer_index));
4978
4979   vat_json_print (vam->ofp, &node);
4980   vat_json_free (&node);
4981
4982   vam->retval = ntohl (mp->retval);
4983   vam->result_ready = 1;
4984 }
4985
4986 /* Format hex dump. */
4987 u8 *
4988 format_hex_bytes (u8 * s, va_list * va)
4989 {
4990   u8 *bytes = va_arg (*va, u8 *);
4991   int n_bytes = va_arg (*va, int);
4992   uword i;
4993
4994   /* Print short or long form depending on byte count. */
4995   uword short_form = n_bytes <= 32;
4996   u32 indent = format_get_indent (s);
4997
4998   if (n_bytes == 0)
4999     return s;
5000
5001   for (i = 0; i < n_bytes; i++)
5002     {
5003       if (!short_form && (i % 32) == 0)
5004         s = format (s, "%08x: ", i);
5005       s = format (s, "%02x", bytes[i]);
5006       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5007         s = format (s, "\n%U", format_white_space, indent);
5008     }
5009
5010   return s;
5011 }
5012
5013 static void
5014 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5015                                             * mp)
5016 {
5017   vat_main_t *vam = &vat_main;
5018   i32 retval = ntohl (mp->retval);
5019   if (retval == 0)
5020     {
5021       print (vam->ofp, "classify table info :");
5022       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5023              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5024              ntohl (mp->miss_next_index));
5025       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5026              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5027              ntohl (mp->match_n_vectors));
5028       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5029              ntohl (mp->mask_length));
5030     }
5031   vam->retval = retval;
5032   vam->result_ready = 1;
5033 }
5034
5035 static void
5036   vl_api_classify_table_info_reply_t_handler_json
5037   (vl_api_classify_table_info_reply_t * mp)
5038 {
5039   vat_main_t *vam = &vat_main;
5040   vat_json_node_t node;
5041
5042   i32 retval = ntohl (mp->retval);
5043   if (retval == 0)
5044     {
5045       vat_json_init_object (&node);
5046
5047       vat_json_object_add_int (&node, "sessions",
5048                                ntohl (mp->active_sessions));
5049       vat_json_object_add_int (&node, "nexttbl",
5050                                ntohl (mp->next_table_index));
5051       vat_json_object_add_int (&node, "nextnode",
5052                                ntohl (mp->miss_next_index));
5053       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5054       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5055       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5056       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5057                       ntohl (mp->mask_length), 0);
5058       vat_json_object_add_string_copy (&node, "mask", s);
5059
5060       vat_json_print (vam->ofp, &node);
5061       vat_json_free (&node);
5062     }
5063   vam->retval = ntohl (mp->retval);
5064   vam->result_ready = 1;
5065 }
5066
5067 static void
5068 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5069                                            mp)
5070 {
5071   vat_main_t *vam = &vat_main;
5072
5073   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5074          ntohl (mp->hit_next_index), ntohl (mp->advance),
5075          ntohl (mp->opaque_index));
5076   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5077          ntohl (mp->match_length));
5078 }
5079
5080 static void
5081   vl_api_classify_session_details_t_handler_json
5082   (vl_api_classify_session_details_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085   vat_json_node_t *node = NULL;
5086
5087   if (VAT_JSON_ARRAY != vam->json_tree.type)
5088     {
5089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5090       vat_json_init_array (&vam->json_tree);
5091     }
5092   node = vat_json_array_add (&vam->json_tree);
5093
5094   vat_json_init_object (node);
5095   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5096   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5097   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5098   u8 *s =
5099     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5100             0);
5101   vat_json_object_add_string_copy (node, "match", s);
5102 }
5103
5104 static void vl_api_pg_create_interface_reply_t_handler
5105   (vl_api_pg_create_interface_reply_t * mp)
5106 {
5107   vat_main_t *vam = &vat_main;
5108
5109   vam->retval = ntohl (mp->retval);
5110   vam->result_ready = 1;
5111 }
5112
5113 static void vl_api_pg_create_interface_reply_t_handler_json
5114   (vl_api_pg_create_interface_reply_t * mp)
5115 {
5116   vat_main_t *vam = &vat_main;
5117   vat_json_node_t node;
5118
5119   i32 retval = ntohl (mp->retval);
5120   if (retval == 0)
5121     {
5122       vat_json_init_object (&node);
5123
5124       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5125
5126       vat_json_print (vam->ofp, &node);
5127       vat_json_free (&node);
5128     }
5129   vam->retval = ntohl (mp->retval);
5130   vam->result_ready = 1;
5131 }
5132
5133 static void vl_api_policer_classify_details_t_handler
5134   (vl_api_policer_classify_details_t * mp)
5135 {
5136   vat_main_t *vam = &vat_main;
5137
5138   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5139          ntohl (mp->table_index));
5140 }
5141
5142 static void vl_api_policer_classify_details_t_handler_json
5143   (vl_api_policer_classify_details_t * mp)
5144 {
5145   vat_main_t *vam = &vat_main;
5146   vat_json_node_t *node;
5147
5148   if (VAT_JSON_ARRAY != vam->json_tree.type)
5149     {
5150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5151       vat_json_init_array (&vam->json_tree);
5152     }
5153   node = vat_json_array_add (&vam->json_tree);
5154
5155   vat_json_init_object (node);
5156   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5157   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5158 }
5159
5160 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5161   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5162 {
5163   vat_main_t *vam = &vat_main;
5164   i32 retval = ntohl (mp->retval);
5165   if (vam->async_mode)
5166     {
5167       vam->async_errors += (retval < 0);
5168     }
5169   else
5170     {
5171       vam->retval = retval;
5172       vam->sw_if_index = ntohl (mp->sw_if_index);
5173       vam->result_ready = 1;
5174     }
5175   vam->regenerate_interface_table = 1;
5176 }
5177
5178 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5179   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5180 {
5181   vat_main_t *vam = &vat_main;
5182   vat_json_node_t node;
5183
5184   vat_json_init_object (&node);
5185   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5186   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5187
5188   vat_json_print (vam->ofp, &node);
5189   vat_json_free (&node);
5190
5191   vam->retval = ntohl (mp->retval);
5192   vam->result_ready = 1;
5193 }
5194
5195 static void vl_api_flow_classify_details_t_handler
5196   (vl_api_flow_classify_details_t * mp)
5197 {
5198   vat_main_t *vam = &vat_main;
5199
5200   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5201          ntohl (mp->table_index));
5202 }
5203
5204 static void vl_api_flow_classify_details_t_handler_json
5205   (vl_api_flow_classify_details_t * mp)
5206 {
5207   vat_main_t *vam = &vat_main;
5208   vat_json_node_t *node;
5209
5210   if (VAT_JSON_ARRAY != vam->json_tree.type)
5211     {
5212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5213       vat_json_init_array (&vam->json_tree);
5214     }
5215   node = vat_json_array_add (&vam->json_tree);
5216
5217   vat_json_init_object (node);
5218   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5219   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5220 }
5221
5222 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5223 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5224 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5225 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5226 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5227 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5228 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5229 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5230 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5231 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5232
5233 /*
5234  * Generate boilerplate reply handlers, which
5235  * dig the return value out of the xxx_reply_t API message,
5236  * stick it into vam->retval, and set vam->result_ready
5237  *
5238  * Could also do this by pointing N message decode slots at
5239  * a single function, but that could break in subtle ways.
5240  */
5241
5242 #define foreach_standard_reply_retval_handler           \
5243 _(sw_interface_set_flags_reply)                         \
5244 _(sw_interface_add_del_address_reply)                   \
5245 _(sw_interface_set_rx_mode_reply)                       \
5246 _(sw_interface_set_rx_placement_reply)                  \
5247 _(sw_interface_set_table_reply)                         \
5248 _(sw_interface_set_mpls_enable_reply)                   \
5249 _(sw_interface_set_vpath_reply)                         \
5250 _(sw_interface_set_vxlan_bypass_reply)                  \
5251 _(sw_interface_set_geneve_bypass_reply)                 \
5252 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5253 _(sw_interface_set_l2_bridge_reply)                     \
5254 _(bridge_domain_add_del_reply)                          \
5255 _(sw_interface_set_l2_xconnect_reply)                   \
5256 _(l2fib_add_del_reply)                                  \
5257 _(l2fib_flush_int_reply)                                \
5258 _(l2fib_flush_bd_reply)                                 \
5259 _(ip_add_del_route_reply)                               \
5260 _(ip_table_add_del_reply)                               \
5261 _(ip_mroute_add_del_reply)                              \
5262 _(mpls_route_add_del_reply)                             \
5263 _(mpls_table_add_del_reply)                             \
5264 _(mpls_ip_bind_unbind_reply)                            \
5265 _(bier_route_add_del_reply)                             \
5266 _(bier_table_add_del_reply)                             \
5267 _(proxy_arp_add_del_reply)                              \
5268 _(proxy_arp_intfc_enable_disable_reply)                 \
5269 _(sw_interface_set_unnumbered_reply)                    \
5270 _(ip_neighbor_add_del_reply)                            \
5271 _(oam_add_del_reply)                                    \
5272 _(reset_fib_reply)                                      \
5273 _(dhcp_proxy_config_reply)                              \
5274 _(dhcp_proxy_set_vss_reply)                             \
5275 _(dhcp_client_config_reply)                             \
5276 _(set_ip_flow_hash_reply)                               \
5277 _(sw_interface_ip6_enable_disable_reply)                \
5278 _(ip6nd_proxy_add_del_reply)                            \
5279 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5280 _(sw_interface_ip6nd_ra_config_reply)                   \
5281 _(set_arp_neighbor_limit_reply)                         \
5282 _(l2_patch_add_del_reply)                               \
5283 _(sr_mpls_policy_add_reply)                             \
5284 _(sr_mpls_policy_mod_reply)                             \
5285 _(sr_mpls_policy_del_reply)                             \
5286 _(sr_policy_add_reply)                                  \
5287 _(sr_policy_mod_reply)                                  \
5288 _(sr_policy_del_reply)                                  \
5289 _(sr_localsid_add_del_reply)                            \
5290 _(sr_steering_add_del_reply)                            \
5291 _(classify_add_del_session_reply)                       \
5292 _(classify_set_interface_ip_table_reply)                \
5293 _(classify_set_interface_l2_tables_reply)               \
5294 _(l2tpv3_set_tunnel_cookies_reply)                      \
5295 _(l2tpv3_interface_enable_disable_reply)                \
5296 _(l2tpv3_set_lookup_key_reply)                          \
5297 _(l2_fib_clear_table_reply)                             \
5298 _(l2_interface_efp_filter_reply)                        \
5299 _(l2_interface_vlan_tag_rewrite_reply)                  \
5300 _(modify_vhost_user_if_reply)                           \
5301 _(delete_vhost_user_if_reply)                           \
5302 _(ip_probe_neighbor_reply)                              \
5303 _(ip_scan_neighbor_enable_disable_reply)                \
5304 _(want_ip4_arp_events_reply)                            \
5305 _(want_ip6_nd_events_reply)                             \
5306 _(want_l2_macs_events_reply)                            \
5307 _(input_acl_set_interface_reply)                        \
5308 _(ipsec_spd_add_del_reply)                              \
5309 _(ipsec_interface_add_del_spd_reply)                    \
5310 _(ipsec_spd_add_del_entry_reply)                        \
5311 _(ipsec_sad_add_del_entry_reply)                        \
5312 _(ipsec_sa_set_key_reply)                               \
5313 _(ipsec_tunnel_if_add_del_reply)                        \
5314 _(ipsec_tunnel_if_set_key_reply)                        \
5315 _(ipsec_tunnel_if_set_sa_reply)                         \
5316 _(ikev2_profile_add_del_reply)                          \
5317 _(ikev2_profile_set_auth_reply)                         \
5318 _(ikev2_profile_set_id_reply)                           \
5319 _(ikev2_profile_set_ts_reply)                           \
5320 _(ikev2_set_local_key_reply)                            \
5321 _(ikev2_set_responder_reply)                            \
5322 _(ikev2_set_ike_transforms_reply)                       \
5323 _(ikev2_set_esp_transforms_reply)                       \
5324 _(ikev2_set_sa_lifetime_reply)                          \
5325 _(ikev2_initiate_sa_init_reply)                         \
5326 _(ikev2_initiate_del_ike_sa_reply)                      \
5327 _(ikev2_initiate_del_child_sa_reply)                    \
5328 _(ikev2_initiate_rekey_child_sa_reply)                  \
5329 _(delete_loopback_reply)                                \
5330 _(bd_ip_mac_add_del_reply)                              \
5331 _(bd_ip_mac_flush_reply)                                \
5332 _(want_interface_events_reply)                          \
5333 _(cop_interface_enable_disable_reply)                   \
5334 _(cop_whitelist_enable_disable_reply)                   \
5335 _(sw_interface_clear_stats_reply)                       \
5336 _(ioam_enable_reply)                                    \
5337 _(ioam_disable_reply)                                   \
5338 _(one_add_del_locator_reply)                            \
5339 _(one_add_del_local_eid_reply)                          \
5340 _(one_add_del_remote_mapping_reply)                     \
5341 _(one_add_del_adjacency_reply)                          \
5342 _(one_add_del_map_resolver_reply)                       \
5343 _(one_add_del_map_server_reply)                         \
5344 _(one_enable_disable_reply)                             \
5345 _(one_rloc_probe_enable_disable_reply)                  \
5346 _(one_map_register_enable_disable_reply)                \
5347 _(one_map_register_set_ttl_reply)                       \
5348 _(one_set_transport_protocol_reply)                     \
5349 _(one_map_register_fallback_threshold_reply)            \
5350 _(one_pitr_set_locator_set_reply)                       \
5351 _(one_map_request_mode_reply)                           \
5352 _(one_add_del_map_request_itr_rlocs_reply)              \
5353 _(one_eid_table_add_del_map_reply)                      \
5354 _(one_use_petr_reply)                                   \
5355 _(one_stats_enable_disable_reply)                       \
5356 _(one_add_del_l2_arp_entry_reply)                       \
5357 _(one_add_del_ndp_entry_reply)                          \
5358 _(one_stats_flush_reply)                                \
5359 _(one_enable_disable_xtr_mode_reply)                    \
5360 _(one_enable_disable_pitr_mode_reply)                   \
5361 _(one_enable_disable_petr_mode_reply)                   \
5362 _(gpe_enable_disable_reply)                             \
5363 _(gpe_set_encap_mode_reply)                             \
5364 _(gpe_add_del_iface_reply)                              \
5365 _(gpe_add_del_native_fwd_rpath_reply)                   \
5366 _(af_packet_delete_reply)                               \
5367 _(policer_classify_set_interface_reply)                 \
5368 _(netmap_create_reply)                                  \
5369 _(netmap_delete_reply)                                  \
5370 _(set_ipfix_exporter_reply)                             \
5371 _(set_ipfix_classify_stream_reply)                      \
5372 _(ipfix_classify_table_add_del_reply)                   \
5373 _(flow_classify_set_interface_reply)                    \
5374 _(sw_interface_span_enable_disable_reply)               \
5375 _(pg_capture_reply)                                     \
5376 _(pg_enable_disable_reply)                              \
5377 _(ip_source_and_port_range_check_add_del_reply)         \
5378 _(ip_source_and_port_range_check_interface_add_del_reply)\
5379 _(delete_subif_reply)                                   \
5380 _(l2_interface_pbb_tag_rewrite_reply)                   \
5381 _(set_punt_reply)                                       \
5382 _(feature_enable_disable_reply)                         \
5383 _(sw_interface_tag_add_del_reply)                       \
5384 _(hw_interface_set_mtu_reply)                           \
5385 _(p2p_ethernet_add_reply)                               \
5386 _(p2p_ethernet_del_reply)                               \
5387 _(lldp_config_reply)                                    \
5388 _(sw_interface_set_lldp_reply)                          \
5389 _(tcp_configure_src_addresses_reply)                    \
5390 _(dns_enable_disable_reply)                             \
5391 _(dns_name_server_add_del_reply)                        \
5392 _(session_rule_add_del_reply)                           \
5393 _(ip_container_proxy_add_del_reply)                     \
5394 _(output_acl_set_interface_reply)                       \
5395 _(qos_record_enable_disable_reply)
5396
5397 #define _(n)                                    \
5398     static void vl_api_##n##_t_handler          \
5399     (vl_api_##n##_t * mp)                       \
5400     {                                           \
5401         vat_main_t * vam = &vat_main;           \
5402         i32 retval = ntohl(mp->retval);         \
5403         if (vam->async_mode) {                  \
5404             vam->async_errors += (retval < 0);  \
5405         } else {                                \
5406             vam->retval = retval;               \
5407             vam->result_ready = 1;              \
5408         }                                       \
5409     }
5410 foreach_standard_reply_retval_handler;
5411 #undef _
5412
5413 #define _(n)                                    \
5414     static void vl_api_##n##_t_handler_json     \
5415     (vl_api_##n##_t * mp)                       \
5416     {                                           \
5417         vat_main_t * vam = &vat_main;           \
5418         vat_json_node_t node;                   \
5419         vat_json_init_object(&node);            \
5420         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5421         vat_json_print(vam->ofp, &node);        \
5422         vam->retval = ntohl(mp->retval);        \
5423         vam->result_ready = 1;                  \
5424     }
5425 foreach_standard_reply_retval_handler;
5426 #undef _
5427
5428 /*
5429  * Table of message reply handlers, must include boilerplate handlers
5430  * we just generated
5431  */
5432
5433 #define foreach_vpe_api_reply_msg                                       \
5434 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5435 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5436 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5437 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5438 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5439 _(CLI_REPLY, cli_reply)                                                 \
5440 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5441 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5442   sw_interface_add_del_address_reply)                                   \
5443 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5444 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5445 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5446 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5447 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5448 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5449 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5450 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5451 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5452 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5453   sw_interface_set_l2_xconnect_reply)                                   \
5454 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5455   sw_interface_set_l2_bridge_reply)                                     \
5456 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5457 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5458 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5459 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5460 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5461 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5462 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5463 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5464 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5465 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5466 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5467 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5468 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5469 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5470 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5471 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5472 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5473 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5474 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5475 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5476 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5477 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5478 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5479 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5480 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5481 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5482 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5483 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5484 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5485 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5486 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5487 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5488 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5489 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5490   proxy_arp_intfc_enable_disable_reply)                                 \
5491 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5492 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5493   sw_interface_set_unnumbered_reply)                                    \
5494 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5495 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5496 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5497 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5498 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5499 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5500 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5501 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5502 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5503 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5504 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5505   sw_interface_ip6_enable_disable_reply)                                \
5506 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5507 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5508 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5509   sw_interface_ip6nd_ra_prefix_reply)                                   \
5510 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5511   sw_interface_ip6nd_ra_config_reply)                                   \
5512 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5513 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5514 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5515 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5516 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5517 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5518 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5519 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5520 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5521 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5522 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5523 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5524 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5525 classify_set_interface_ip_table_reply)                                  \
5526 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5527   classify_set_interface_l2_tables_reply)                               \
5528 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5529 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5530 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5531 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5532 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5533   l2tpv3_interface_enable_disable_reply)                                \
5534 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5535 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5536 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5537 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5538 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5539 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5540 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5541 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5542 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5543 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5544 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5545 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5546 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5547 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5548 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5549 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5550 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5551 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5552 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5553 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5554 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5555 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5556 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5557 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5558 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5559 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5560 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5561 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5562 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5563 _(L2_MACS_EVENT, l2_macs_event)                                         \
5564 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5565 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5566 _(IP_DETAILS, ip_details)                                               \
5567 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5568 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5569 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5570 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5571 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5572 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5573 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5574 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5575 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5576 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5577 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5578 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5579 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5580 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5581 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5582 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5583 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5584 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5585 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5586 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5587 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5588 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5589 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5590 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5591 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5592 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5593 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5594 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5595 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5596 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5597 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5598 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5599 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5600 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5601 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5602 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5603 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5604 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5605 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5606 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5607 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5608 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5609 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5610 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5611   one_map_register_enable_disable_reply)                                \
5612 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5613 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5614 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5615 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5616   one_map_register_fallback_threshold_reply)                            \
5617 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5618   one_rloc_probe_enable_disable_reply)                                  \
5619 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5620 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5621 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5622 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5623 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5624 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5625 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5626 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5627 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5628 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5629 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5630 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5631 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5632 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5633 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5634 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5635   show_one_stats_enable_disable_reply)                                  \
5636 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5637 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5638 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5639 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5640 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5641 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5642 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5643 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5644   one_enable_disable_pitr_mode_reply)                                   \
5645 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5646   one_enable_disable_petr_mode_reply)                                   \
5647 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5648 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5649 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5650 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5651 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5652 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5653 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5654 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5655 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5656 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5657 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5658 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5659   gpe_add_del_native_fwd_rpath_reply)                                   \
5660 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5661   gpe_fwd_entry_path_details)                                           \
5662 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5663 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5664   one_add_del_map_request_itr_rlocs_reply)                              \
5665 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5666   one_get_map_request_itr_rlocs_reply)                                  \
5667 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5668 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5669 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5670 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5671 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5672 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5673   show_one_map_register_state_reply)                                    \
5674 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5675 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5676   show_one_map_register_fallback_threshold_reply)                       \
5677 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5678 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5679 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5680 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5681 _(POLICER_DETAILS, policer_details)                                     \
5682 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5683 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5684 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5685 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5686 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5687 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5688 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5689 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5690 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5691 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5692 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5693 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5694 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5695 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5696 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5697 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5698 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5699 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5700 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5701 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5702 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5703 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5704 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5705 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5706 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5707  ip_source_and_port_range_check_add_del_reply)                          \
5708 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5709  ip_source_and_port_range_check_interface_add_del_reply)                \
5710 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5711 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5712 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5713 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5714 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5715 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5716 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5717 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5718 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5719 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5720 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5721 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5722 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5723 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5724 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5725 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5726 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5727 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5728 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5729 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5730 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5731 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5732 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5733 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5734 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5735 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5736 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5737 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5738
5739 #define foreach_standalone_reply_msg                                    \
5740 _(SW_INTERFACE_EVENT, sw_interface_event)
5741
5742 typedef struct
5743 {
5744   u8 *name;
5745   u32 value;
5746 } name_sort_t;
5747
5748 #define STR_VTR_OP_CASE(op)     \
5749     case L2_VTR_ ## op:         \
5750         return "" # op;
5751
5752 static const char *
5753 str_vtr_op (u32 vtr_op)
5754 {
5755   switch (vtr_op)
5756     {
5757       STR_VTR_OP_CASE (DISABLED);
5758       STR_VTR_OP_CASE (PUSH_1);
5759       STR_VTR_OP_CASE (PUSH_2);
5760       STR_VTR_OP_CASE (POP_1);
5761       STR_VTR_OP_CASE (POP_2);
5762       STR_VTR_OP_CASE (TRANSLATE_1_1);
5763       STR_VTR_OP_CASE (TRANSLATE_1_2);
5764       STR_VTR_OP_CASE (TRANSLATE_2_1);
5765       STR_VTR_OP_CASE (TRANSLATE_2_2);
5766     }
5767
5768   return "UNKNOWN";
5769 }
5770
5771 static int
5772 dump_sub_interface_table (vat_main_t * vam)
5773 {
5774   const sw_interface_subif_t *sub = NULL;
5775
5776   if (vam->json_output)
5777     {
5778       clib_warning
5779         ("JSON output supported only for VPE API calls and dump_stats_table");
5780       return -99;
5781     }
5782
5783   print (vam->ofp,
5784          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5785          "Interface", "sw_if_index",
5786          "sub id", "dot1ad", "tags", "outer id",
5787          "inner id", "exact", "default", "outer any", "inner any");
5788
5789   vec_foreach (sub, vam->sw_if_subif_table)
5790   {
5791     print (vam->ofp,
5792            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5793            sub->interface_name,
5794            sub->sw_if_index,
5795            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5796            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5797            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5798            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5799     if (sub->vtr_op != L2_VTR_DISABLED)
5800       {
5801         print (vam->ofp,
5802                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5803                "tag1: %d tag2: %d ]",
5804                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5805                sub->vtr_tag1, sub->vtr_tag2);
5806       }
5807   }
5808
5809   return 0;
5810 }
5811
5812 static int
5813 name_sort_cmp (void *a1, void *a2)
5814 {
5815   name_sort_t *n1 = a1;
5816   name_sort_t *n2 = a2;
5817
5818   return strcmp ((char *) n1->name, (char *) n2->name);
5819 }
5820
5821 static int
5822 dump_interface_table (vat_main_t * vam)
5823 {
5824   hash_pair_t *p;
5825   name_sort_t *nses = 0, *ns;
5826
5827   if (vam->json_output)
5828     {
5829       clib_warning
5830         ("JSON output supported only for VPE API calls and dump_stats_table");
5831       return -99;
5832     }
5833
5834   /* *INDENT-OFF* */
5835   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5836   ({
5837     vec_add2 (nses, ns, 1);
5838     ns->name = (u8 *)(p->key);
5839     ns->value = (u32) p->value[0];
5840   }));
5841   /* *INDENT-ON* */
5842
5843   vec_sort_with_function (nses, name_sort_cmp);
5844
5845   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5846   vec_foreach (ns, nses)
5847   {
5848     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5849   }
5850   vec_free (nses);
5851   return 0;
5852 }
5853
5854 static int
5855 dump_ip_table (vat_main_t * vam, int is_ipv6)
5856 {
5857   const ip_details_t *det = NULL;
5858   const ip_address_details_t *address = NULL;
5859   u32 i = ~0;
5860
5861   print (vam->ofp, "%-12s", "sw_if_index");
5862
5863   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5864   {
5865     i++;
5866     if (!det->present)
5867       {
5868         continue;
5869       }
5870     print (vam->ofp, "%-12d", i);
5871     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5872     if (!det->addr)
5873       {
5874         continue;
5875       }
5876     vec_foreach (address, det->addr)
5877     {
5878       print (vam->ofp,
5879              "            %-30U%-13d",
5880              is_ipv6 ? format_ip6_address : format_ip4_address,
5881              address->ip, address->prefix_length);
5882     }
5883   }
5884
5885   return 0;
5886 }
5887
5888 static int
5889 dump_ipv4_table (vat_main_t * vam)
5890 {
5891   if (vam->json_output)
5892     {
5893       clib_warning
5894         ("JSON output supported only for VPE API calls and dump_stats_table");
5895       return -99;
5896     }
5897
5898   return dump_ip_table (vam, 0);
5899 }
5900
5901 static int
5902 dump_ipv6_table (vat_main_t * vam)
5903 {
5904   if (vam->json_output)
5905     {
5906       clib_warning
5907         ("JSON output supported only for VPE API calls and dump_stats_table");
5908       return -99;
5909     }
5910
5911   return dump_ip_table (vam, 1);
5912 }
5913
5914 /*
5915  * Pass CLI buffers directly in the CLI_INBAND API message,
5916  * instead of an additional shared memory area.
5917  */
5918 static int
5919 exec_inband (vat_main_t * vam)
5920 {
5921   vl_api_cli_inband_t *mp;
5922   unformat_input_t *i = vam->input;
5923   int ret;
5924
5925   if (vec_len (i->buffer) == 0)
5926     return -1;
5927
5928   if (vam->exec_mode == 0 && unformat (i, "mode"))
5929     {
5930       vam->exec_mode = 1;
5931       return 0;
5932     }
5933   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5934     {
5935       vam->exec_mode = 0;
5936       return 0;
5937     }
5938
5939   /*
5940    * In order for the CLI command to work, it
5941    * must be a vector ending in \n, not a C-string ending
5942    * in \n\0.
5943    */
5944   u32 len = vec_len (vam->input->buffer);
5945   M2 (CLI_INBAND, mp, len);
5946   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5947
5948   S (mp);
5949   W (ret);
5950   /* json responses may or may not include a useful reply... */
5951   if (vec_len (vam->cmd_reply))
5952     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5953   return ret;
5954 }
5955
5956 int
5957 exec (vat_main_t * vam)
5958 {
5959   return exec_inband (vam);
5960 }
5961
5962 static int
5963 api_create_loopback (vat_main_t * vam)
5964 {
5965   unformat_input_t *i = vam->input;
5966   vl_api_create_loopback_t *mp;
5967   vl_api_create_loopback_instance_t *mp_lbi;
5968   u8 mac_address[6];
5969   u8 mac_set = 0;
5970   u8 is_specified = 0;
5971   u32 user_instance = 0;
5972   int ret;
5973
5974   clib_memset (mac_address, 0, sizeof (mac_address));
5975
5976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5977     {
5978       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5979         mac_set = 1;
5980       if (unformat (i, "instance %d", &user_instance))
5981         is_specified = 1;
5982       else
5983         break;
5984     }
5985
5986   if (is_specified)
5987     {
5988       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5989       mp_lbi->is_specified = is_specified;
5990       if (is_specified)
5991         mp_lbi->user_instance = htonl (user_instance);
5992       if (mac_set)
5993         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5994       S (mp_lbi);
5995     }
5996   else
5997     {
5998       /* Construct the API message */
5999       M (CREATE_LOOPBACK, mp);
6000       if (mac_set)
6001         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6002       S (mp);
6003     }
6004
6005   W (ret);
6006   return ret;
6007 }
6008
6009 static int
6010 api_delete_loopback (vat_main_t * vam)
6011 {
6012   unformat_input_t *i = vam->input;
6013   vl_api_delete_loopback_t *mp;
6014   u32 sw_if_index = ~0;
6015   int ret;
6016
6017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6018     {
6019       if (unformat (i, "sw_if_index %d", &sw_if_index))
6020         ;
6021       else
6022         break;
6023     }
6024
6025   if (sw_if_index == ~0)
6026     {
6027       errmsg ("missing sw_if_index");
6028       return -99;
6029     }
6030
6031   /* Construct the API message */
6032   M (DELETE_LOOPBACK, mp);
6033   mp->sw_if_index = ntohl (sw_if_index);
6034
6035   S (mp);
6036   W (ret);
6037   return ret;
6038 }
6039
6040 static int
6041 api_want_interface_events (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_want_interface_events_t *mp;
6045   int enable = -1;
6046   int ret;
6047
6048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6049     {
6050       if (unformat (i, "enable"))
6051         enable = 1;
6052       else if (unformat (i, "disable"))
6053         enable = 0;
6054       else
6055         break;
6056     }
6057
6058   if (enable == -1)
6059     {
6060       errmsg ("missing enable|disable");
6061       return -99;
6062     }
6063
6064   M (WANT_INTERFACE_EVENTS, mp);
6065   mp->enable_disable = enable;
6066
6067   vam->interface_event_display = enable;
6068
6069   S (mp);
6070   W (ret);
6071   return ret;
6072 }
6073
6074
6075 /* Note: non-static, called once to set up the initial intfc table */
6076 int
6077 api_sw_interface_dump (vat_main_t * vam)
6078 {
6079   vl_api_sw_interface_dump_t *mp;
6080   vl_api_control_ping_t *mp_ping;
6081   hash_pair_t *p;
6082   name_sort_t *nses = 0, *ns;
6083   sw_interface_subif_t *sub = NULL;
6084   int ret;
6085
6086   /* Toss the old name table */
6087   /* *INDENT-OFF* */
6088   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6089   ({
6090     vec_add2 (nses, ns, 1);
6091     ns->name = (u8 *)(p->key);
6092     ns->value = (u32) p->value[0];
6093   }));
6094   /* *INDENT-ON* */
6095
6096   hash_free (vam->sw_if_index_by_interface_name);
6097
6098   vec_foreach (ns, nses) vec_free (ns->name);
6099
6100   vec_free (nses);
6101
6102   vec_foreach (sub, vam->sw_if_subif_table)
6103   {
6104     vec_free (sub->interface_name);
6105   }
6106   vec_free (vam->sw_if_subif_table);
6107
6108   /* recreate the interface name hash table */
6109   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6110
6111   /*
6112    * Ask for all interface names. Otherwise, the epic catalog of
6113    * name filters becomes ridiculously long, and vat ends up needing
6114    * to be taught about new interface types.
6115    */
6116   M (SW_INTERFACE_DUMP, mp);
6117   S (mp);
6118
6119   /* Use a control ping for synchronization */
6120   MPING (CONTROL_PING, mp_ping);
6121   S (mp_ping);
6122
6123   W (ret);
6124   return ret;
6125 }
6126
6127 static int
6128 api_sw_interface_set_flags (vat_main_t * vam)
6129 {
6130   unformat_input_t *i = vam->input;
6131   vl_api_sw_interface_set_flags_t *mp;
6132   u32 sw_if_index;
6133   u8 sw_if_index_set = 0;
6134   u8 admin_up = 0;
6135   int ret;
6136
6137   /* Parse args required to build the message */
6138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6139     {
6140       if (unformat (i, "admin-up"))
6141         admin_up = 1;
6142       else if (unformat (i, "admin-down"))
6143         admin_up = 0;
6144       else
6145         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6146         sw_if_index_set = 1;
6147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6148         sw_if_index_set = 1;
6149       else
6150         break;
6151     }
6152
6153   if (sw_if_index_set == 0)
6154     {
6155       errmsg ("missing interface name or sw_if_index");
6156       return -99;
6157     }
6158
6159   /* Construct the API message */
6160   M (SW_INTERFACE_SET_FLAGS, mp);
6161   mp->sw_if_index = ntohl (sw_if_index);
6162   mp->admin_up_down = admin_up;
6163
6164   /* send it... */
6165   S (mp);
6166
6167   /* Wait for a reply, return the good/bad news... */
6168   W (ret);
6169   return ret;
6170 }
6171
6172 static int
6173 api_sw_interface_set_rx_mode (vat_main_t * vam)
6174 {
6175   unformat_input_t *i = vam->input;
6176   vl_api_sw_interface_set_rx_mode_t *mp;
6177   u32 sw_if_index;
6178   u8 sw_if_index_set = 0;
6179   int ret;
6180   u8 queue_id_valid = 0;
6181   u32 queue_id;
6182   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6183
6184   /* Parse args required to build the message */
6185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6186     {
6187       if (unformat (i, "queue %d", &queue_id))
6188         queue_id_valid = 1;
6189       else if (unformat (i, "polling"))
6190         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6191       else if (unformat (i, "interrupt"))
6192         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6193       else if (unformat (i, "adaptive"))
6194         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6195       else
6196         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6197         sw_if_index_set = 1;
6198       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6199         sw_if_index_set = 1;
6200       else
6201         break;
6202     }
6203
6204   if (sw_if_index_set == 0)
6205     {
6206       errmsg ("missing interface name or sw_if_index");
6207       return -99;
6208     }
6209   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6210     {
6211       errmsg ("missing rx-mode");
6212       return -99;
6213     }
6214
6215   /* Construct the API message */
6216   M (SW_INTERFACE_SET_RX_MODE, mp);
6217   mp->sw_if_index = ntohl (sw_if_index);
6218   mp->mode = mode;
6219   mp->queue_id_valid = queue_id_valid;
6220   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6221
6222   /* send it... */
6223   S (mp);
6224
6225   /* Wait for a reply, return the good/bad news... */
6226   W (ret);
6227   return ret;
6228 }
6229
6230 static int
6231 api_sw_interface_set_rx_placement (vat_main_t * vam)
6232 {
6233   unformat_input_t *i = vam->input;
6234   vl_api_sw_interface_set_rx_placement_t *mp;
6235   u32 sw_if_index;
6236   u8 sw_if_index_set = 0;
6237   int ret;
6238   u8 is_main = 0;
6239   u32 queue_id, thread_index;
6240
6241   /* Parse args required to build the message */
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "queue %d", &queue_id))
6245         ;
6246       else if (unformat (i, "main"))
6247         is_main = 1;
6248       else if (unformat (i, "worker %d", &thread_index))
6249         ;
6250       else
6251         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6252         sw_if_index_set = 1;
6253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6254         sw_if_index_set = 1;
6255       else
6256         break;
6257     }
6258
6259   if (sw_if_index_set == 0)
6260     {
6261       errmsg ("missing interface name or sw_if_index");
6262       return -99;
6263     }
6264
6265   if (is_main)
6266     thread_index = 0;
6267   /* Construct the API message */
6268   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6269   mp->sw_if_index = ntohl (sw_if_index);
6270   mp->worker_id = ntohl (thread_index);
6271   mp->queue_id = ntohl (queue_id);
6272   mp->is_main = is_main;
6273
6274   /* send it... */
6275   S (mp);
6276   /* Wait for a reply, return the good/bad news... */
6277   W (ret);
6278   return ret;
6279 }
6280
6281 static void vl_api_sw_interface_rx_placement_details_t_handler
6282   (vl_api_sw_interface_rx_placement_details_t * mp)
6283 {
6284   vat_main_t *vam = &vat_main;
6285   u32 worker_id = ntohl (mp->worker_id);
6286
6287   print (vam->ofp,
6288          "\n%-11d %-11s %-6d %-5d %-9s",
6289          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6290          worker_id, ntohl (mp->queue_id),
6291          (mp->mode ==
6292           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6293 }
6294
6295 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6296   (vl_api_sw_interface_rx_placement_details_t * mp)
6297 {
6298   vat_main_t *vam = &vat_main;
6299   vat_json_node_t *node = NULL;
6300
6301   if (VAT_JSON_ARRAY != vam->json_tree.type)
6302     {
6303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6304       vat_json_init_array (&vam->json_tree);
6305     }
6306   node = vat_json_array_add (&vam->json_tree);
6307
6308   vat_json_init_object (node);
6309   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6310   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6311   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6312   vat_json_object_add_uint (node, "mode", mp->mode);
6313 }
6314
6315 static int
6316 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6317 {
6318   unformat_input_t *i = vam->input;
6319   vl_api_sw_interface_rx_placement_dump_t *mp;
6320   vl_api_control_ping_t *mp_ping;
6321   int ret;
6322   u32 sw_if_index;
6323   u8 sw_if_index_set = 0;
6324
6325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6326     {
6327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6328         sw_if_index_set++;
6329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6330         sw_if_index_set++;
6331       else
6332         break;
6333     }
6334
6335   print (vam->ofp,
6336          "\n%-11s %-11s %-6s %-5s %-4s",
6337          "sw_if_index", "main/worker", "thread", "queue", "mode");
6338
6339   /* Dump Interface rx placement */
6340   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6341
6342   if (sw_if_index_set)
6343     mp->sw_if_index = htonl (sw_if_index);
6344   else
6345     mp->sw_if_index = ~0;
6346
6347   S (mp);
6348
6349   /* Use a control ping for synchronization */
6350   MPING (CONTROL_PING, mp_ping);
6351   S (mp_ping);
6352
6353   W (ret);
6354   return ret;
6355 }
6356
6357 static int
6358 api_sw_interface_clear_stats (vat_main_t * vam)
6359 {
6360   unformat_input_t *i = vam->input;
6361   vl_api_sw_interface_clear_stats_t *mp;
6362   u32 sw_if_index;
6363   u8 sw_if_index_set = 0;
6364   int ret;
6365
6366   /* Parse args required to build the message */
6367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6368     {
6369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6372         sw_if_index_set = 1;
6373       else
6374         break;
6375     }
6376
6377   /* Construct the API message */
6378   M (SW_INTERFACE_CLEAR_STATS, mp);
6379
6380   if (sw_if_index_set == 1)
6381     mp->sw_if_index = ntohl (sw_if_index);
6382   else
6383     mp->sw_if_index = ~0;
6384
6385   /* send it... */
6386   S (mp);
6387
6388   /* Wait for a reply, return the good/bad news... */
6389   W (ret);
6390   return ret;
6391 }
6392
6393 static int
6394 api_sw_interface_add_del_address (vat_main_t * vam)
6395 {
6396   unformat_input_t *i = vam->input;
6397   vl_api_sw_interface_add_del_address_t *mp;
6398   u32 sw_if_index;
6399   u8 sw_if_index_set = 0;
6400   u8 is_add = 1, del_all = 0;
6401   u32 address_length = 0;
6402   u8 v4_address_set = 0;
6403   u8 v6_address_set = 0;
6404   ip4_address_t v4address;
6405   ip6_address_t v6address;
6406   int ret;
6407
6408   /* Parse args required to build the message */
6409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6410     {
6411       if (unformat (i, "del-all"))
6412         del_all = 1;
6413       else if (unformat (i, "del"))
6414         is_add = 0;
6415       else
6416         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6417         sw_if_index_set = 1;
6418       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6419         sw_if_index_set = 1;
6420       else if (unformat (i, "%U/%d",
6421                          unformat_ip4_address, &v4address, &address_length))
6422         v4_address_set = 1;
6423       else if (unformat (i, "%U/%d",
6424                          unformat_ip6_address, &v6address, &address_length))
6425         v6_address_set = 1;
6426       else
6427         break;
6428     }
6429
6430   if (sw_if_index_set == 0)
6431     {
6432       errmsg ("missing interface name or sw_if_index");
6433       return -99;
6434     }
6435   if (v4_address_set && v6_address_set)
6436     {
6437       errmsg ("both v4 and v6 addresses set");
6438       return -99;
6439     }
6440   if (!v4_address_set && !v6_address_set && !del_all)
6441     {
6442       errmsg ("no addresses set");
6443       return -99;
6444     }
6445
6446   /* Construct the API message */
6447   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6448
6449   mp->sw_if_index = ntohl (sw_if_index);
6450   mp->is_add = is_add;
6451   mp->del_all = del_all;
6452   if (v6_address_set)
6453     {
6454       mp->is_ipv6 = 1;
6455       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6456     }
6457   else
6458     {
6459       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6460     }
6461   mp->address_length = address_length;
6462
6463   /* send it... */
6464   S (mp);
6465
6466   /* Wait for a reply, return good/bad news  */
6467   W (ret);
6468   return ret;
6469 }
6470
6471 static int
6472 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_sw_interface_set_mpls_enable_t *mp;
6476   u32 sw_if_index;
6477   u8 sw_if_index_set = 0;
6478   u8 enable = 1;
6479   int ret;
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6485         sw_if_index_set = 1;
6486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "disable"))
6489         enable = 0;
6490       else if (unformat (i, "dis"))
6491         enable = 0;
6492       else
6493         break;
6494     }
6495
6496   if (sw_if_index_set == 0)
6497     {
6498       errmsg ("missing interface name or sw_if_index");
6499       return -99;
6500     }
6501
6502   /* Construct the API message */
6503   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6504
6505   mp->sw_if_index = ntohl (sw_if_index);
6506   mp->enable = enable;
6507
6508   /* send it... */
6509   S (mp);
6510
6511   /* Wait for a reply... */
6512   W (ret);
6513   return ret;
6514 }
6515
6516 static int
6517 api_sw_interface_set_table (vat_main_t * vam)
6518 {
6519   unformat_input_t *i = vam->input;
6520   vl_api_sw_interface_set_table_t *mp;
6521   u32 sw_if_index, vrf_id = 0;
6522   u8 sw_if_index_set = 0;
6523   u8 is_ipv6 = 0;
6524   int ret;
6525
6526   /* Parse args required to build the message */
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "vrf %d", &vrf_id))
6534         ;
6535       else if (unformat (i, "ipv6"))
6536         is_ipv6 = 1;
6537       else
6538         break;
6539     }
6540
6541   if (sw_if_index_set == 0)
6542     {
6543       errmsg ("missing interface name or sw_if_index");
6544       return -99;
6545     }
6546
6547   /* Construct the API message */
6548   M (SW_INTERFACE_SET_TABLE, mp);
6549
6550   mp->sw_if_index = ntohl (sw_if_index);
6551   mp->is_ipv6 = is_ipv6;
6552   mp->vrf_id = ntohl (vrf_id);
6553
6554   /* send it... */
6555   S (mp);
6556
6557   /* Wait for a reply... */
6558   W (ret);
6559   return ret;
6560 }
6561
6562 static void vl_api_sw_interface_get_table_reply_t_handler
6563   (vl_api_sw_interface_get_table_reply_t * mp)
6564 {
6565   vat_main_t *vam = &vat_main;
6566
6567   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6568
6569   vam->retval = ntohl (mp->retval);
6570   vam->result_ready = 1;
6571
6572 }
6573
6574 static void vl_api_sw_interface_get_table_reply_t_handler_json
6575   (vl_api_sw_interface_get_table_reply_t * mp)
6576 {
6577   vat_main_t *vam = &vat_main;
6578   vat_json_node_t node;
6579
6580   vat_json_init_object (&node);
6581   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6582   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6583
6584   vat_json_print (vam->ofp, &node);
6585   vat_json_free (&node);
6586
6587   vam->retval = ntohl (mp->retval);
6588   vam->result_ready = 1;
6589 }
6590
6591 static int
6592 api_sw_interface_get_table (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_sw_interface_get_table_t *mp;
6596   u32 sw_if_index;
6597   u8 sw_if_index_set = 0;
6598   u8 is_ipv6 = 0;
6599   int ret;
6600
6601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6602     {
6603       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6604         sw_if_index_set = 1;
6605       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6606         sw_if_index_set = 1;
6607       else if (unformat (i, "ipv6"))
6608         is_ipv6 = 1;
6609       else
6610         break;
6611     }
6612
6613   if (sw_if_index_set == 0)
6614     {
6615       errmsg ("missing interface name or sw_if_index");
6616       return -99;
6617     }
6618
6619   M (SW_INTERFACE_GET_TABLE, mp);
6620   mp->sw_if_index = htonl (sw_if_index);
6621   mp->is_ipv6 = is_ipv6;
6622
6623   S (mp);
6624   W (ret);
6625   return ret;
6626 }
6627
6628 static int
6629 api_sw_interface_set_vpath (vat_main_t * vam)
6630 {
6631   unformat_input_t *i = vam->input;
6632   vl_api_sw_interface_set_vpath_t *mp;
6633   u32 sw_if_index = 0;
6634   u8 sw_if_index_set = 0;
6635   u8 is_enable = 0;
6636   int ret;
6637
6638   /* Parse args required to build the message */
6639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640     {
6641       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6642         sw_if_index_set = 1;
6643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6644         sw_if_index_set = 1;
6645       else if (unformat (i, "enable"))
6646         is_enable = 1;
6647       else if (unformat (i, "disable"))
6648         is_enable = 0;
6649       else
6650         break;
6651     }
6652
6653   if (sw_if_index_set == 0)
6654     {
6655       errmsg ("missing interface name or sw_if_index");
6656       return -99;
6657     }
6658
6659   /* Construct the API message */
6660   M (SW_INTERFACE_SET_VPATH, mp);
6661
6662   mp->sw_if_index = ntohl (sw_if_index);
6663   mp->enable = is_enable;
6664
6665   /* send it... */
6666   S (mp);
6667
6668   /* Wait for a reply... */
6669   W (ret);
6670   return ret;
6671 }
6672
6673 static int
6674 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6675 {
6676   unformat_input_t *i = vam->input;
6677   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6678   u32 sw_if_index = 0;
6679   u8 sw_if_index_set = 0;
6680   u8 is_enable = 1;
6681   u8 is_ipv6 = 0;
6682   int ret;
6683
6684   /* Parse args required to build the message */
6685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6686     {
6687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6688         sw_if_index_set = 1;
6689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6690         sw_if_index_set = 1;
6691       else if (unformat (i, "enable"))
6692         is_enable = 1;
6693       else if (unformat (i, "disable"))
6694         is_enable = 0;
6695       else if (unformat (i, "ip4"))
6696         is_ipv6 = 0;
6697       else if (unformat (i, "ip6"))
6698         is_ipv6 = 1;
6699       else
6700         break;
6701     }
6702
6703   if (sw_if_index_set == 0)
6704     {
6705       errmsg ("missing interface name or sw_if_index");
6706       return -99;
6707     }
6708
6709   /* Construct the API message */
6710   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6711
6712   mp->sw_if_index = ntohl (sw_if_index);
6713   mp->enable = is_enable;
6714   mp->is_ipv6 = is_ipv6;
6715
6716   /* send it... */
6717   S (mp);
6718
6719   /* Wait for a reply... */
6720   W (ret);
6721   return ret;
6722 }
6723
6724 static int
6725 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6726 {
6727   unformat_input_t *i = vam->input;
6728   vl_api_sw_interface_set_geneve_bypass_t *mp;
6729   u32 sw_if_index = 0;
6730   u8 sw_if_index_set = 0;
6731   u8 is_enable = 1;
6732   u8 is_ipv6 = 0;
6733   int ret;
6734
6735   /* Parse args required to build the message */
6736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6737     {
6738       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6739         sw_if_index_set = 1;
6740       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6741         sw_if_index_set = 1;
6742       else if (unformat (i, "enable"))
6743         is_enable = 1;
6744       else if (unformat (i, "disable"))
6745         is_enable = 0;
6746       else if (unformat (i, "ip4"))
6747         is_ipv6 = 0;
6748       else if (unformat (i, "ip6"))
6749         is_ipv6 = 1;
6750       else
6751         break;
6752     }
6753
6754   if (sw_if_index_set == 0)
6755     {
6756       errmsg ("missing interface name or sw_if_index");
6757       return -99;
6758     }
6759
6760   /* Construct the API message */
6761   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6762
6763   mp->sw_if_index = ntohl (sw_if_index);
6764   mp->enable = is_enable;
6765   mp->is_ipv6 = is_ipv6;
6766
6767   /* send it... */
6768   S (mp);
6769
6770   /* Wait for a reply... */
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_sw_interface_set_l2_xconnect_t *mp;
6780   u32 rx_sw_if_index;
6781   u8 rx_sw_if_index_set = 0;
6782   u32 tx_sw_if_index;
6783   u8 tx_sw_if_index_set = 0;
6784   u8 enable = 1;
6785   int ret;
6786
6787   /* Parse args required to build the message */
6788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6789     {
6790       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6791         rx_sw_if_index_set = 1;
6792       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6793         tx_sw_if_index_set = 1;
6794       else if (unformat (i, "rx"))
6795         {
6796           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6797             {
6798               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6799                             &rx_sw_if_index))
6800                 rx_sw_if_index_set = 1;
6801             }
6802           else
6803             break;
6804         }
6805       else if (unformat (i, "tx"))
6806         {
6807           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6808             {
6809               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6810                             &tx_sw_if_index))
6811                 tx_sw_if_index_set = 1;
6812             }
6813           else
6814             break;
6815         }
6816       else if (unformat (i, "enable"))
6817         enable = 1;
6818       else if (unformat (i, "disable"))
6819         enable = 0;
6820       else
6821         break;
6822     }
6823
6824   if (rx_sw_if_index_set == 0)
6825     {
6826       errmsg ("missing rx interface name or rx_sw_if_index");
6827       return -99;
6828     }
6829
6830   if (enable && (tx_sw_if_index_set == 0))
6831     {
6832       errmsg ("missing tx interface name or tx_sw_if_index");
6833       return -99;
6834     }
6835
6836   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6837
6838   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6839   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6840   mp->enable = enable;
6841
6842   S (mp);
6843   W (ret);
6844   return ret;
6845 }
6846
6847 static int
6848 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6849 {
6850   unformat_input_t *i = vam->input;
6851   vl_api_sw_interface_set_l2_bridge_t *mp;
6852   vl_api_l2_port_type_t port_type;
6853   u32 rx_sw_if_index;
6854   u8 rx_sw_if_index_set = 0;
6855   u32 bd_id;
6856   u8 bd_id_set = 0;
6857   u32 shg = 0;
6858   u8 enable = 1;
6859   int ret;
6860
6861   port_type = L2_API_PORT_TYPE_NORMAL;
6862
6863   /* Parse args required to build the message */
6864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6865     {
6866       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6867         rx_sw_if_index_set = 1;
6868       else if (unformat (i, "bd_id %d", &bd_id))
6869         bd_id_set = 1;
6870       else
6871         if (unformat
6872             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6873         rx_sw_if_index_set = 1;
6874       else if (unformat (i, "shg %d", &shg))
6875         ;
6876       else if (unformat (i, "bvi"))
6877         port_type = L2_API_PORT_TYPE_BVI;
6878       else if (unformat (i, "uu-fwd"))
6879         port_type = L2_API_PORT_TYPE_UU_FWD;
6880       else if (unformat (i, "enable"))
6881         enable = 1;
6882       else if (unformat (i, "disable"))
6883         enable = 0;
6884       else
6885         break;
6886     }
6887
6888   if (rx_sw_if_index_set == 0)
6889     {
6890       errmsg ("missing rx interface name or sw_if_index");
6891       return -99;
6892     }
6893
6894   if (enable && (bd_id_set == 0))
6895     {
6896       errmsg ("missing bridge domain");
6897       return -99;
6898     }
6899
6900   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6901
6902   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6903   mp->bd_id = ntohl (bd_id);
6904   mp->shg = (u8) shg;
6905   mp->port_type = ntohl (port_type);
6906   mp->enable = enable;
6907
6908   S (mp);
6909   W (ret);
6910   return ret;
6911 }
6912
6913 static int
6914 api_bridge_domain_dump (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_bridge_domain_dump_t *mp;
6918   vl_api_control_ping_t *mp_ping;
6919   u32 bd_id = ~0;
6920   int ret;
6921
6922   /* Parse args required to build the message */
6923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6924     {
6925       if (unformat (i, "bd_id %d", &bd_id))
6926         ;
6927       else
6928         break;
6929     }
6930
6931   M (BRIDGE_DOMAIN_DUMP, mp);
6932   mp->bd_id = ntohl (bd_id);
6933   S (mp);
6934
6935   /* Use a control ping for synchronization */
6936   MPING (CONTROL_PING, mp_ping);
6937   S (mp_ping);
6938
6939   W (ret);
6940   return ret;
6941 }
6942
6943 static int
6944 api_bridge_domain_add_del (vat_main_t * vam)
6945 {
6946   unformat_input_t *i = vam->input;
6947   vl_api_bridge_domain_add_del_t *mp;
6948   u32 bd_id = ~0;
6949   u8 is_add = 1;
6950   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6951   u8 *bd_tag = NULL;
6952   u32 mac_age = 0;
6953   int ret;
6954
6955   /* Parse args required to build the message */
6956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6957     {
6958       if (unformat (i, "bd_id %d", &bd_id))
6959         ;
6960       else if (unformat (i, "flood %d", &flood))
6961         ;
6962       else if (unformat (i, "uu-flood %d", &uu_flood))
6963         ;
6964       else if (unformat (i, "forward %d", &forward))
6965         ;
6966       else if (unformat (i, "learn %d", &learn))
6967         ;
6968       else if (unformat (i, "arp-term %d", &arp_term))
6969         ;
6970       else if (unformat (i, "mac-age %d", &mac_age))
6971         ;
6972       else if (unformat (i, "bd-tag %s", &bd_tag))
6973         ;
6974       else if (unformat (i, "del"))
6975         {
6976           is_add = 0;
6977           flood = uu_flood = forward = learn = 0;
6978         }
6979       else
6980         break;
6981     }
6982
6983   if (bd_id == ~0)
6984     {
6985       errmsg ("missing bridge domain");
6986       ret = -99;
6987       goto done;
6988     }
6989
6990   if (mac_age > 255)
6991     {
6992       errmsg ("mac age must be less than 256 ");
6993       ret = -99;
6994       goto done;
6995     }
6996
6997   if ((bd_tag) && (vec_len (bd_tag) > 63))
6998     {
6999       errmsg ("bd-tag cannot be longer than 63");
7000       ret = -99;
7001       goto done;
7002     }
7003
7004   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7005
7006   mp->bd_id = ntohl (bd_id);
7007   mp->flood = flood;
7008   mp->uu_flood = uu_flood;
7009   mp->forward = forward;
7010   mp->learn = learn;
7011   mp->arp_term = arp_term;
7012   mp->is_add = is_add;
7013   mp->mac_age = (u8) mac_age;
7014   if (bd_tag)
7015     {
7016       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7017       mp->bd_tag[vec_len (bd_tag)] = 0;
7018     }
7019   S (mp);
7020   W (ret);
7021
7022 done:
7023   vec_free (bd_tag);
7024   return ret;
7025 }
7026
7027 static int
7028 api_l2fib_flush_bd (vat_main_t * vam)
7029 {
7030   unformat_input_t *i = vam->input;
7031   vl_api_l2fib_flush_bd_t *mp;
7032   u32 bd_id = ~0;
7033   int ret;
7034
7035   /* Parse args required to build the message */
7036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7037     {
7038       if (unformat (i, "bd_id %d", &bd_id));
7039       else
7040         break;
7041     }
7042
7043   if (bd_id == ~0)
7044     {
7045       errmsg ("missing bridge domain");
7046       return -99;
7047     }
7048
7049   M (L2FIB_FLUSH_BD, mp);
7050
7051   mp->bd_id = htonl (bd_id);
7052
7053   S (mp);
7054   W (ret);
7055   return ret;
7056 }
7057
7058 static int
7059 api_l2fib_flush_int (vat_main_t * vam)
7060 {
7061   unformat_input_t *i = vam->input;
7062   vl_api_l2fib_flush_int_t *mp;
7063   u32 sw_if_index = ~0;
7064   int ret;
7065
7066   /* Parse args required to build the message */
7067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068     {
7069       if (unformat (i, "sw_if_index %d", &sw_if_index));
7070       else
7071         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7072       else
7073         break;
7074     }
7075
7076   if (sw_if_index == ~0)
7077     {
7078       errmsg ("missing interface name or sw_if_index");
7079       return -99;
7080     }
7081
7082   M (L2FIB_FLUSH_INT, mp);
7083
7084   mp->sw_if_index = ntohl (sw_if_index);
7085
7086   S (mp);
7087   W (ret);
7088   return ret;
7089 }
7090
7091 static int
7092 api_l2fib_add_del (vat_main_t * vam)
7093 {
7094   unformat_input_t *i = vam->input;
7095   vl_api_l2fib_add_del_t *mp;
7096   f64 timeout;
7097   u8 mac[6] = { 0 };
7098   u8 mac_set = 0;
7099   u32 bd_id;
7100   u8 bd_id_set = 0;
7101   u32 sw_if_index = 0;
7102   u8 sw_if_index_set = 0;
7103   u8 is_add = 1;
7104   u8 static_mac = 0;
7105   u8 filter_mac = 0;
7106   u8 bvi_mac = 0;
7107   int count = 1;
7108   f64 before = 0;
7109   int j;
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7115         mac_set = 1;
7116       else if (unformat (i, "bd_id %d", &bd_id))
7117         bd_id_set = 1;
7118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7119         sw_if_index_set = 1;
7120       else if (unformat (i, "sw_if"))
7121         {
7122           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123             {
7124               if (unformat
7125                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7126                 sw_if_index_set = 1;
7127             }
7128           else
7129             break;
7130         }
7131       else if (unformat (i, "static"))
7132         static_mac = 1;
7133       else if (unformat (i, "filter"))
7134         {
7135           filter_mac = 1;
7136           static_mac = 1;
7137         }
7138       else if (unformat (i, "bvi"))
7139         {
7140           bvi_mac = 1;
7141           static_mac = 1;
7142         }
7143       else if (unformat (i, "del"))
7144         is_add = 0;
7145       else if (unformat (i, "count %d", &count))
7146         ;
7147       else
7148         break;
7149     }
7150
7151   if (mac_set == 0)
7152     {
7153       errmsg ("missing mac address");
7154       return -99;
7155     }
7156
7157   if (bd_id_set == 0)
7158     {
7159       errmsg ("missing bridge domain");
7160       return -99;
7161     }
7162
7163   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7164     {
7165       errmsg ("missing interface name or sw_if_index");
7166       return -99;
7167     }
7168
7169   if (count > 1)
7170     {
7171       /* Turn on async mode */
7172       vam->async_mode = 1;
7173       vam->async_errors = 0;
7174       before = vat_time_now (vam);
7175     }
7176
7177   for (j = 0; j < count; j++)
7178     {
7179       M (L2FIB_ADD_DEL, mp);
7180
7181       clib_memcpy (mp->mac, mac, 6);
7182       mp->bd_id = ntohl (bd_id);
7183       mp->is_add = is_add;
7184       mp->sw_if_index = ntohl (sw_if_index);
7185
7186       if (is_add)
7187         {
7188           mp->static_mac = static_mac;
7189           mp->filter_mac = filter_mac;
7190           mp->bvi_mac = bvi_mac;
7191         }
7192       increment_mac_address (mac);
7193       /* send it... */
7194       S (mp);
7195     }
7196
7197   if (count > 1)
7198     {
7199       vl_api_control_ping_t *mp_ping;
7200       f64 after;
7201
7202       /* Shut off async mode */
7203       vam->async_mode = 0;
7204
7205       MPING (CONTROL_PING, mp_ping);
7206       S (mp_ping);
7207
7208       timeout = vat_time_now (vam) + 1.0;
7209       while (vat_time_now (vam) < timeout)
7210         if (vam->result_ready == 1)
7211           goto out;
7212       vam->retval = -99;
7213
7214     out:
7215       if (vam->retval == -99)
7216         errmsg ("timeout");
7217
7218       if (vam->async_errors > 0)
7219         {
7220           errmsg ("%d asynchronous errors", vam->async_errors);
7221           vam->retval = -98;
7222         }
7223       vam->async_errors = 0;
7224       after = vat_time_now (vam);
7225
7226       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7227              count, after - before, count / (after - before));
7228     }
7229   else
7230     {
7231       int ret;
7232
7233       /* Wait for a reply... */
7234       W (ret);
7235       return ret;
7236     }
7237   /* Return the good/bad news */
7238   return (vam->retval);
7239 }
7240
7241 static int
7242 api_bridge_domain_set_mac_age (vat_main_t * vam)
7243 {
7244   unformat_input_t *i = vam->input;
7245   vl_api_bridge_domain_set_mac_age_t *mp;
7246   u32 bd_id = ~0;
7247   u32 mac_age = 0;
7248   int ret;
7249
7250   /* Parse args required to build the message */
7251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7252     {
7253       if (unformat (i, "bd_id %d", &bd_id));
7254       else if (unformat (i, "mac-age %d", &mac_age));
7255       else
7256         break;
7257     }
7258
7259   if (bd_id == ~0)
7260     {
7261       errmsg ("missing bridge domain");
7262       return -99;
7263     }
7264
7265   if (mac_age > 255)
7266     {
7267       errmsg ("mac age must be less than 256 ");
7268       return -99;
7269     }
7270
7271   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7272
7273   mp->bd_id = htonl (bd_id);
7274   mp->mac_age = (u8) mac_age;
7275
7276   S (mp);
7277   W (ret);
7278   return ret;
7279 }
7280
7281 static int
7282 api_l2_flags (vat_main_t * vam)
7283 {
7284   unformat_input_t *i = vam->input;
7285   vl_api_l2_flags_t *mp;
7286   u32 sw_if_index;
7287   u32 flags = 0;
7288   u8 sw_if_index_set = 0;
7289   u8 is_set = 0;
7290   int ret;
7291
7292   /* Parse args required to build the message */
7293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (i, "sw_if_index %d", &sw_if_index))
7296         sw_if_index_set = 1;
7297       else if (unformat (i, "sw_if"))
7298         {
7299           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7300             {
7301               if (unformat
7302                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7303                 sw_if_index_set = 1;
7304             }
7305           else
7306             break;
7307         }
7308       else if (unformat (i, "learn"))
7309         flags |= L2_LEARN;
7310       else if (unformat (i, "forward"))
7311         flags |= L2_FWD;
7312       else if (unformat (i, "flood"))
7313         flags |= L2_FLOOD;
7314       else if (unformat (i, "uu-flood"))
7315         flags |= L2_UU_FLOOD;
7316       else if (unformat (i, "arp-term"))
7317         flags |= L2_ARP_TERM;
7318       else if (unformat (i, "off"))
7319         is_set = 0;
7320       else if (unformat (i, "disable"))
7321         is_set = 0;
7322       else
7323         break;
7324     }
7325
7326   if (sw_if_index_set == 0)
7327     {
7328       errmsg ("missing interface name or sw_if_index");
7329       return -99;
7330     }
7331
7332   M (L2_FLAGS, mp);
7333
7334   mp->sw_if_index = ntohl (sw_if_index);
7335   mp->feature_bitmap = ntohl (flags);
7336   mp->is_set = is_set;
7337
7338   S (mp);
7339   W (ret);
7340   return ret;
7341 }
7342
7343 static int
7344 api_bridge_flags (vat_main_t * vam)
7345 {
7346   unformat_input_t *i = vam->input;
7347   vl_api_bridge_flags_t *mp;
7348   u32 bd_id;
7349   u8 bd_id_set = 0;
7350   u8 is_set = 1;
7351   bd_flags_t flags = 0;
7352   int ret;
7353
7354   /* Parse args required to build the message */
7355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7356     {
7357       if (unformat (i, "bd_id %d", &bd_id))
7358         bd_id_set = 1;
7359       else if (unformat (i, "learn"))
7360         flags |= BRIDGE_API_FLAG_LEARN;
7361       else if (unformat (i, "forward"))
7362         flags |= BRIDGE_API_FLAG_FWD;
7363       else if (unformat (i, "flood"))
7364         flags |= BRIDGE_API_FLAG_FLOOD;
7365       else if (unformat (i, "uu-flood"))
7366         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7367       else if (unformat (i, "arp-term"))
7368         flags |= BRIDGE_API_FLAG_ARP_TERM;
7369       else if (unformat (i, "off"))
7370         is_set = 0;
7371       else if (unformat (i, "disable"))
7372         is_set = 0;
7373       else
7374         break;
7375     }
7376
7377   if (bd_id_set == 0)
7378     {
7379       errmsg ("missing bridge domain");
7380       return -99;
7381     }
7382
7383   M (BRIDGE_FLAGS, mp);
7384
7385   mp->bd_id = ntohl (bd_id);
7386   mp->flags = ntohl (flags);
7387   mp->is_set = is_set;
7388
7389   S (mp);
7390   W (ret);
7391   return ret;
7392 }
7393
7394 static int
7395 api_bd_ip_mac_add_del (vat_main_t * vam)
7396 {
7397   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7398   vl_api_mac_address_t mac = { 0 };
7399   unformat_input_t *i = vam->input;
7400   vl_api_bd_ip_mac_add_del_t *mp;
7401   ip46_type_t type;
7402   u32 bd_id;
7403   u8 is_ipv6 = 0;
7404   u8 is_add = 1;
7405   u8 bd_id_set = 0;
7406   u8 ip_set = 0;
7407   u8 mac_set = 0;
7408   u8 macaddr[6];
7409   int ret;
7410
7411
7412   /* Parse args required to build the message */
7413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7414     {
7415       if (unformat (i, "bd_id %d", &bd_id))
7416         {
7417           bd_id_set++;
7418         }
7419       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7420         {
7421           ip_set++;
7422         }
7423       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7424         {
7425           mac_set++;
7426         }
7427       else if (unformat (i, "del"))
7428         is_add = 0;
7429       else
7430         break;
7431     }
7432
7433   if (bd_id_set == 0)
7434     {
7435       errmsg ("missing bridge domain");
7436       return -99;
7437     }
7438   else if (ip_set == 0)
7439     {
7440       errmsg ("missing IP address");
7441       return -99;
7442     }
7443   else if (mac_set == 0)
7444     {
7445       errmsg ("missing MAC address");
7446       return -99;
7447     }
7448
7449   M (BD_IP_MAC_ADD_DEL, mp);
7450
7451   mp->bd_id = ntohl (bd_id);
7452   mp->is_add = is_add;
7453
7454   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7455   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7456
7457   S (mp);
7458   W (ret);
7459   return ret;
7460 }
7461
7462 static int
7463 api_bd_ip_mac_flush (vat_main_t * vam)
7464 {
7465   unformat_input_t *i = vam->input;
7466   vl_api_bd_ip_mac_flush_t *mp;
7467   u32 bd_id;
7468   u8 bd_id_set = 0;
7469   int ret;
7470
7471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7472     {
7473       if (unformat (i, "bd_id %d", &bd_id))
7474         {
7475           bd_id_set++;
7476         }
7477       else
7478         break;
7479     }
7480
7481   if (bd_id_set == 0)
7482     {
7483       errmsg ("missing bridge domain");
7484       return -99;
7485     }
7486
7487   M (BD_IP_MAC_FLUSH, mp);
7488
7489   mp->bd_id = ntohl (bd_id);
7490
7491   S (mp);
7492   W (ret);
7493   return ret;
7494 }
7495
7496 static void vl_api_bd_ip_mac_details_t_handler
7497   (vl_api_bd_ip_mac_details_t * mp)
7498 {
7499   vat_main_t *vam = &vat_main;
7500   u8 *ip = 0;
7501
7502   if (!mp->is_ipv6)
7503     ip =
7504       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7505   else
7506     ip =
7507       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7508
7509   print (vam->ofp,
7510          "\n%-5d %-7s %-20U %-30s",
7511          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7512          format_ethernet_address, mp->mac_address, ip);
7513
7514   vec_free (ip);
7515 }
7516
7517 static void vl_api_bd_ip_mac_details_t_handler_json
7518   (vl_api_bd_ip_mac_details_t * mp)
7519 {
7520   vat_main_t *vam = &vat_main;
7521   vat_json_node_t *node = NULL;
7522
7523   if (VAT_JSON_ARRAY != vam->json_tree.type)
7524     {
7525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7526       vat_json_init_array (&vam->json_tree);
7527     }
7528   node = vat_json_array_add (&vam->json_tree);
7529
7530   vat_json_init_object (node);
7531   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7532   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7533   vat_json_object_add_string_copy (node, "mac_address",
7534                                    format (0, "%U", format_ethernet_address,
7535                                            &mp->mac_address));
7536   u8 *ip = 0;
7537
7538   if (!mp->is_ipv6)
7539     ip =
7540       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7541   else
7542     ip =
7543       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7544   vat_json_object_add_string_copy (node, "ip_address", ip);
7545   vec_free (ip);
7546 }
7547
7548 static int
7549 api_bd_ip_mac_dump (vat_main_t * vam)
7550 {
7551   unformat_input_t *i = vam->input;
7552   vl_api_bd_ip_mac_dump_t *mp;
7553   vl_api_control_ping_t *mp_ping;
7554   int ret;
7555   u32 bd_id;
7556   u8 bd_id_set = 0;
7557
7558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7559     {
7560       if (unformat (i, "bd_id %d", &bd_id))
7561         {
7562           bd_id_set++;
7563         }
7564       else
7565         break;
7566     }
7567
7568   print (vam->ofp,
7569          "\n%-5s %-7s %-20s %-30s",
7570          "bd_id", "is_ipv6", "mac_address", "ip_address");
7571
7572   /* Dump Bridge Domain Ip to Mac entries */
7573   M (BD_IP_MAC_DUMP, mp);
7574
7575   if (bd_id_set)
7576     mp->bd_id = htonl (bd_id);
7577   else
7578     mp->bd_id = ~0;
7579
7580   S (mp);
7581
7582   /* Use a control ping for synchronization */
7583   MPING (CONTROL_PING, mp_ping);
7584   S (mp_ping);
7585
7586   W (ret);
7587   return ret;
7588 }
7589
7590 static int
7591 api_tap_connect (vat_main_t * vam)
7592 {
7593   unformat_input_t *i = vam->input;
7594   vl_api_tap_connect_t *mp;
7595   u8 mac_address[6];
7596   u8 random_mac = 1;
7597   u8 name_set = 0;
7598   u8 *tap_name;
7599   u8 *tag = 0;
7600   ip4_address_t ip4_address;
7601   u32 ip4_mask_width;
7602   int ip4_address_set = 0;
7603   ip6_address_t ip6_address;
7604   u32 ip6_mask_width;
7605   int ip6_address_set = 0;
7606   int ret;
7607
7608   clib_memset (mac_address, 0, sizeof (mac_address));
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7614         {
7615           random_mac = 0;
7616         }
7617       else if (unformat (i, "random-mac"))
7618         random_mac = 1;
7619       else if (unformat (i, "tapname %s", &tap_name))
7620         name_set = 1;
7621       else if (unformat (i, "tag %s", &tag))
7622         ;
7623       else if (unformat (i, "address %U/%d",
7624                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7625         ip4_address_set = 1;
7626       else if (unformat (i, "address %U/%d",
7627                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7628         ip6_address_set = 1;
7629       else
7630         break;
7631     }
7632
7633   if (name_set == 0)
7634     {
7635       errmsg ("missing tap name");
7636       return -99;
7637     }
7638   if (vec_len (tap_name) > 63)
7639     {
7640       errmsg ("tap name too long");
7641       return -99;
7642     }
7643   vec_add1 (tap_name, 0);
7644
7645   if (vec_len (tag) > 63)
7646     {
7647       errmsg ("tag too long");
7648       return -99;
7649     }
7650
7651   /* Construct the API message */
7652   M (TAP_CONNECT, mp);
7653
7654   mp->use_random_mac = random_mac;
7655   clib_memcpy (mp->mac_address, mac_address, 6);
7656   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7657   if (tag)
7658     clib_memcpy (mp->tag, tag, vec_len (tag));
7659
7660   if (ip4_address_set)
7661     {
7662       mp->ip4_address_set = 1;
7663       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7664       mp->ip4_mask_width = ip4_mask_width;
7665     }
7666   if (ip6_address_set)
7667     {
7668       mp->ip6_address_set = 1;
7669       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7670       mp->ip6_mask_width = ip6_mask_width;
7671     }
7672
7673   vec_free (tap_name);
7674   vec_free (tag);
7675
7676   /* send it... */
7677   S (mp);
7678
7679   /* Wait for a reply... */
7680   W (ret);
7681   return ret;
7682 }
7683
7684 static int
7685 api_tap_modify (vat_main_t * vam)
7686 {
7687   unformat_input_t *i = vam->input;
7688   vl_api_tap_modify_t *mp;
7689   u8 mac_address[6];
7690   u8 random_mac = 1;
7691   u8 name_set = 0;
7692   u8 *tap_name;
7693   u32 sw_if_index = ~0;
7694   u8 sw_if_index_set = 0;
7695   int ret;
7696
7697   clib_memset (mac_address, 0, sizeof (mac_address));
7698
7699   /* Parse args required to build the message */
7700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701     {
7702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7703         sw_if_index_set = 1;
7704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7705         sw_if_index_set = 1;
7706       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7707         {
7708           random_mac = 0;
7709         }
7710       else if (unformat (i, "random-mac"))
7711         random_mac = 1;
7712       else if (unformat (i, "tapname %s", &tap_name))
7713         name_set = 1;
7714       else
7715         break;
7716     }
7717
7718   if (sw_if_index_set == 0)
7719     {
7720       errmsg ("missing vpp interface name");
7721       return -99;
7722     }
7723   if (name_set == 0)
7724     {
7725       errmsg ("missing tap name");
7726       return -99;
7727     }
7728   if (vec_len (tap_name) > 63)
7729     {
7730       errmsg ("tap name too long");
7731     }
7732   vec_add1 (tap_name, 0);
7733
7734   /* Construct the API message */
7735   M (TAP_MODIFY, mp);
7736
7737   mp->use_random_mac = random_mac;
7738   mp->sw_if_index = ntohl (sw_if_index);
7739   clib_memcpy (mp->mac_address, mac_address, 6);
7740   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7741   vec_free (tap_name);
7742
7743   /* send it... */
7744   S (mp);
7745
7746   /* Wait for a reply... */
7747   W (ret);
7748   return ret;
7749 }
7750
7751 static int
7752 api_tap_delete (vat_main_t * vam)
7753 {
7754   unformat_input_t *i = vam->input;
7755   vl_api_tap_delete_t *mp;
7756   u32 sw_if_index = ~0;
7757   u8 sw_if_index_set = 0;
7758   int ret;
7759
7760   /* Parse args required to build the message */
7761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7762     {
7763       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7764         sw_if_index_set = 1;
7765       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7766         sw_if_index_set = 1;
7767       else
7768         break;
7769     }
7770
7771   if (sw_if_index_set == 0)
7772     {
7773       errmsg ("missing vpp interface name");
7774       return -99;
7775     }
7776
7777   /* Construct the API message */
7778   M (TAP_DELETE, mp);
7779
7780   mp->sw_if_index = ntohl (sw_if_index);
7781
7782   /* send it... */
7783   S (mp);
7784
7785   /* Wait for a reply... */
7786   W (ret);
7787   return ret;
7788 }
7789
7790 static int
7791 api_tap_create_v2 (vat_main_t * vam)
7792 {
7793   unformat_input_t *i = vam->input;
7794   vl_api_tap_create_v2_t *mp;
7795   u8 mac_address[6];
7796   u8 random_mac = 1;
7797   u32 id = ~0;
7798   u8 *host_if_name = 0;
7799   u8 *host_ns = 0;
7800   u8 host_mac_addr[6];
7801   u8 host_mac_addr_set = 0;
7802   u8 *host_bridge = 0;
7803   ip4_address_t host_ip4_addr;
7804   ip4_address_t host_ip4_gw;
7805   u8 host_ip4_gw_set = 0;
7806   u32 host_ip4_prefix_len = 0;
7807   ip6_address_t host_ip6_addr;
7808   ip6_address_t host_ip6_gw;
7809   u8 host_ip6_gw_set = 0;
7810   u32 host_ip6_prefix_len = 0;
7811   int ret;
7812   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7813
7814   clib_memset (mac_address, 0, sizeof (mac_address));
7815
7816   /* Parse args required to build the message */
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7820         {
7821           random_mac = 0;
7822         }
7823       else if (unformat (i, "id %u", &id))
7824         ;
7825       else if (unformat (i, "host-if-name %s", &host_if_name))
7826         ;
7827       else if (unformat (i, "host-ns %s", &host_ns))
7828         ;
7829       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7830                          host_mac_addr))
7831         host_mac_addr_set = 1;
7832       else if (unformat (i, "host-bridge %s", &host_bridge))
7833         ;
7834       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7835                          &host_ip4_addr, &host_ip4_prefix_len))
7836         ;
7837       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7838                          &host_ip6_addr, &host_ip6_prefix_len))
7839         ;
7840       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7841                          &host_ip4_gw))
7842         host_ip4_gw_set = 1;
7843       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7844                          &host_ip6_gw))
7845         host_ip6_gw_set = 1;
7846       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7847         ;
7848       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7849         ;
7850       else
7851         break;
7852     }
7853
7854   if (vec_len (host_if_name) > 63)
7855     {
7856       errmsg ("tap name too long. ");
7857       return -99;
7858     }
7859   if (vec_len (host_ns) > 63)
7860     {
7861       errmsg ("host name space too long. ");
7862       return -99;
7863     }
7864   if (vec_len (host_bridge) > 63)
7865     {
7866       errmsg ("host bridge name too long. ");
7867       return -99;
7868     }
7869   if (host_ip4_prefix_len > 32)
7870     {
7871       errmsg ("host ip4 prefix length not valid. ");
7872       return -99;
7873     }
7874   if (host_ip6_prefix_len > 128)
7875     {
7876       errmsg ("host ip6 prefix length not valid. ");
7877       return -99;
7878     }
7879   if (!is_pow2 (rx_ring_sz))
7880     {
7881       errmsg ("rx ring size must be power of 2. ");
7882       return -99;
7883     }
7884   if (rx_ring_sz > 32768)
7885     {
7886       errmsg ("rx ring size must be 32768 or lower. ");
7887       return -99;
7888     }
7889   if (!is_pow2 (tx_ring_sz))
7890     {
7891       errmsg ("tx ring size must be power of 2. ");
7892       return -99;
7893     }
7894   if (tx_ring_sz > 32768)
7895     {
7896       errmsg ("tx ring size must be 32768 or lower. ");
7897       return -99;
7898     }
7899
7900   /* Construct the API message */
7901   M (TAP_CREATE_V2, mp);
7902
7903   mp->use_random_mac = random_mac;
7904
7905   mp->id = ntohl (id);
7906   mp->host_namespace_set = host_ns != 0;
7907   mp->host_bridge_set = host_bridge != 0;
7908   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7909   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7910   mp->rx_ring_sz = ntohs (rx_ring_sz);
7911   mp->tx_ring_sz = ntohs (tx_ring_sz);
7912
7913   if (random_mac == 0)
7914     clib_memcpy (mp->mac_address, mac_address, 6);
7915   if (host_mac_addr_set)
7916     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7917   if (host_if_name)
7918     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7919   if (host_ns)
7920     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7921   if (host_bridge)
7922     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7923   if (host_ip4_prefix_len)
7924     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7925   if (host_ip6_prefix_len)
7926     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7927   if (host_ip4_gw_set)
7928     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7929   if (host_ip6_gw_set)
7930     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7931
7932   vec_free (host_ns);
7933   vec_free (host_if_name);
7934   vec_free (host_bridge);
7935
7936   /* send it... */
7937   S (mp);
7938
7939   /* Wait for a reply... */
7940   W (ret);
7941   return ret;
7942 }
7943
7944 static int
7945 api_tap_delete_v2 (vat_main_t * vam)
7946 {
7947   unformat_input_t *i = vam->input;
7948   vl_api_tap_delete_v2_t *mp;
7949   u32 sw_if_index = ~0;
7950   u8 sw_if_index_set = 0;
7951   int ret;
7952
7953   /* Parse args required to build the message */
7954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7955     {
7956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7957         sw_if_index_set = 1;
7958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7959         sw_if_index_set = 1;
7960       else
7961         break;
7962     }
7963
7964   if (sw_if_index_set == 0)
7965     {
7966       errmsg ("missing vpp interface name. ");
7967       return -99;
7968     }
7969
7970   /* Construct the API message */
7971   M (TAP_DELETE_V2, mp);
7972
7973   mp->sw_if_index = ntohl (sw_if_index);
7974
7975   /* send it... */
7976   S (mp);
7977
7978   /* Wait for a reply... */
7979   W (ret);
7980   return ret;
7981 }
7982
7983 uword
7984 unformat_pci_addr (unformat_input_t * input, va_list * args)
7985 {
7986   struct pci_addr_t
7987   {
7988     u16 domain;
7989     u8 bus;
7990     u8 slot:5;
7991     u8 function:3;
7992   } *addr;
7993   addr = va_arg (*args, struct pci_addr_t *);
7994   u32 x[4];
7995
7996   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7997     return 0;
7998
7999   addr->domain = x[0];
8000   addr->bus = x[1];
8001   addr->slot = x[2];
8002   addr->function = x[3];
8003
8004   return 1;
8005 }
8006
8007 static int
8008 api_virtio_pci_create (vat_main_t * vam)
8009 {
8010   unformat_input_t *i = vam->input;
8011   vl_api_virtio_pci_create_t *mp;
8012   u8 mac_address[6];
8013   u8 random_mac = 1;
8014   u32 pci_addr = 0;
8015   u64 features = (u64) ~ (0ULL);
8016   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8017   int ret;
8018
8019   clib_memset (mac_address, 0, sizeof (mac_address));
8020
8021   /* Parse args required to build the message */
8022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8023     {
8024       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8025         {
8026           random_mac = 0;
8027         }
8028       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
8029         ;
8030       else if (unformat (i, "features 0x%llx", &features))
8031         ;
8032       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
8033         ;
8034       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
8035         ;
8036       else
8037         break;
8038     }
8039
8040   if (pci_addr == 0)
8041     {
8042       errmsg ("pci address must be non zero. ");
8043       return -99;
8044     }
8045   if (!is_pow2 (rx_ring_sz))
8046     {
8047       errmsg ("rx ring size must be power of 2. ");
8048       return -99;
8049     }
8050   if (rx_ring_sz > 32768)
8051     {
8052       errmsg ("rx ring size must be 32768 or lower. ");
8053       return -99;
8054     }
8055   if (!is_pow2 (tx_ring_sz))
8056     {
8057       errmsg ("tx ring size must be power of 2. ");
8058       return -99;
8059     }
8060   if (tx_ring_sz > 32768)
8061     {
8062       errmsg ("tx ring size must be 32768 or lower. ");
8063       return -99;
8064     }
8065
8066   /* Construct the API message */
8067   M (VIRTIO_PCI_CREATE, mp);
8068
8069   mp->use_random_mac = random_mac;
8070
8071   mp->pci_addr = htonl (pci_addr);
8072   mp->features = clib_host_to_net_u64 (features);
8073   mp->rx_ring_sz = htons (rx_ring_sz);
8074   mp->tx_ring_sz = htons (tx_ring_sz);
8075
8076   if (random_mac == 0)
8077     clib_memcpy (mp->mac_address, mac_address, 6);
8078
8079   /* send it... */
8080   S (mp);
8081
8082   /* Wait for a reply... */
8083   W (ret);
8084   return ret;
8085 }
8086
8087 static int
8088 api_virtio_pci_delete (vat_main_t * vam)
8089 {
8090   unformat_input_t *i = vam->input;
8091   vl_api_virtio_pci_delete_t *mp;
8092   u32 sw_if_index = ~0;
8093   u8 sw_if_index_set = 0;
8094   int ret;
8095
8096   /* Parse args required to build the message */
8097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8098     {
8099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8100         sw_if_index_set = 1;
8101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8102         sw_if_index_set = 1;
8103       else
8104         break;
8105     }
8106
8107   if (sw_if_index_set == 0)
8108     {
8109       errmsg ("missing vpp interface name. ");
8110       return -99;
8111     }
8112
8113   /* Construct the API message */
8114   M (VIRTIO_PCI_DELETE, mp);
8115
8116   mp->sw_if_index = htonl (sw_if_index);
8117
8118   /* send it... */
8119   S (mp);
8120
8121   /* Wait for a reply... */
8122   W (ret);
8123   return ret;
8124 }
8125
8126 static int
8127 api_bond_create (vat_main_t * vam)
8128 {
8129   unformat_input_t *i = vam->input;
8130   vl_api_bond_create_t *mp;
8131   u8 mac_address[6];
8132   u8 custom_mac = 0;
8133   int ret;
8134   u8 mode;
8135   u8 lb;
8136   u8 mode_is_set = 0;
8137   u32 id = ~0;
8138
8139   clib_memset (mac_address, 0, sizeof (mac_address));
8140   lb = BOND_LB_L2;
8141
8142   /* Parse args required to build the message */
8143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8144     {
8145       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8146         mode_is_set = 1;
8147       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8148                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8149         ;
8150       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8151                          mac_address))
8152         custom_mac = 1;
8153       else if (unformat (i, "id %u", &id))
8154         ;
8155       else
8156         break;
8157     }
8158
8159   if (mode_is_set == 0)
8160     {
8161       errmsg ("Missing bond mode. ");
8162       return -99;
8163     }
8164
8165   /* Construct the API message */
8166   M (BOND_CREATE, mp);
8167
8168   mp->use_custom_mac = custom_mac;
8169
8170   mp->mode = mode;
8171   mp->lb = lb;
8172   mp->id = htonl (id);
8173
8174   if (custom_mac)
8175     clib_memcpy (mp->mac_address, mac_address, 6);
8176
8177   /* send it... */
8178   S (mp);
8179
8180   /* Wait for a reply... */
8181   W (ret);
8182   return ret;
8183 }
8184
8185 static int
8186 api_bond_delete (vat_main_t * vam)
8187 {
8188   unformat_input_t *i = vam->input;
8189   vl_api_bond_delete_t *mp;
8190   u32 sw_if_index = ~0;
8191   u8 sw_if_index_set = 0;
8192   int ret;
8193
8194   /* Parse args required to build the message */
8195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8196     {
8197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8198         sw_if_index_set = 1;
8199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8200         sw_if_index_set = 1;
8201       else
8202         break;
8203     }
8204
8205   if (sw_if_index_set == 0)
8206     {
8207       errmsg ("missing vpp interface name. ");
8208       return -99;
8209     }
8210
8211   /* Construct the API message */
8212   M (BOND_DELETE, mp);
8213
8214   mp->sw_if_index = ntohl (sw_if_index);
8215
8216   /* send it... */
8217   S (mp);
8218
8219   /* Wait for a reply... */
8220   W (ret);
8221   return ret;
8222 }
8223
8224 static int
8225 api_bond_enslave (vat_main_t * vam)
8226 {
8227   unformat_input_t *i = vam->input;
8228   vl_api_bond_enslave_t *mp;
8229   u32 bond_sw_if_index;
8230   int ret;
8231   u8 is_passive;
8232   u8 is_long_timeout;
8233   u32 bond_sw_if_index_is_set = 0;
8234   u32 sw_if_index;
8235   u8 sw_if_index_is_set = 0;
8236
8237   /* Parse args required to build the message */
8238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8239     {
8240       if (unformat (i, "sw_if_index %d", &sw_if_index))
8241         sw_if_index_is_set = 1;
8242       else if (unformat (i, "bond %u", &bond_sw_if_index))
8243         bond_sw_if_index_is_set = 1;
8244       else if (unformat (i, "passive %d", &is_passive))
8245         ;
8246       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8247         ;
8248       else
8249         break;
8250     }
8251
8252   if (bond_sw_if_index_is_set == 0)
8253     {
8254       errmsg ("Missing bond sw_if_index. ");
8255       return -99;
8256     }
8257   if (sw_if_index_is_set == 0)
8258     {
8259       errmsg ("Missing slave sw_if_index. ");
8260       return -99;
8261     }
8262
8263   /* Construct the API message */
8264   M (BOND_ENSLAVE, mp);
8265
8266   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8267   mp->sw_if_index = ntohl (sw_if_index);
8268   mp->is_long_timeout = is_long_timeout;
8269   mp->is_passive = is_passive;
8270
8271   /* send it... */
8272   S (mp);
8273
8274   /* Wait for a reply... */
8275   W (ret);
8276   return ret;
8277 }
8278
8279 static int
8280 api_bond_detach_slave (vat_main_t * vam)
8281 {
8282   unformat_input_t *i = vam->input;
8283   vl_api_bond_detach_slave_t *mp;
8284   u32 sw_if_index = ~0;
8285   u8 sw_if_index_set = 0;
8286   int ret;
8287
8288   /* Parse args required to build the message */
8289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8290     {
8291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8292         sw_if_index_set = 1;
8293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8294         sw_if_index_set = 1;
8295       else
8296         break;
8297     }
8298
8299   if (sw_if_index_set == 0)
8300     {
8301       errmsg ("missing vpp interface name. ");
8302       return -99;
8303     }
8304
8305   /* Construct the API message */
8306   M (BOND_DETACH_SLAVE, mp);
8307
8308   mp->sw_if_index = ntohl (sw_if_index);
8309
8310   /* send it... */
8311   S (mp);
8312
8313   /* Wait for a reply... */
8314   W (ret);
8315   return ret;
8316 }
8317
8318 static int
8319 api_ip_table_add_del (vat_main_t * vam)
8320 {
8321   unformat_input_t *i = vam->input;
8322   vl_api_ip_table_add_del_t *mp;
8323   u32 table_id = ~0;
8324   u8 is_ipv6 = 0;
8325   u8 is_add = 1;
8326   int ret = 0;
8327
8328   /* Parse args required to build the message */
8329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8330     {
8331       if (unformat (i, "ipv6"))
8332         is_ipv6 = 1;
8333       else if (unformat (i, "del"))
8334         is_add = 0;
8335       else if (unformat (i, "add"))
8336         is_add = 1;
8337       else if (unformat (i, "table %d", &table_id))
8338         ;
8339       else
8340         {
8341           clib_warning ("parse error '%U'", format_unformat_error, i);
8342           return -99;
8343         }
8344     }
8345
8346   if (~0 == table_id)
8347     {
8348       errmsg ("missing table-ID");
8349       return -99;
8350     }
8351
8352   /* Construct the API message */
8353   M (IP_TABLE_ADD_DEL, mp);
8354
8355   mp->table_id = ntohl (table_id);
8356   mp->is_ipv6 = is_ipv6;
8357   mp->is_add = is_add;
8358
8359   /* send it... */
8360   S (mp);
8361
8362   /* Wait for a reply... */
8363   W (ret);
8364
8365   return ret;
8366 }
8367
8368 static int
8369 api_ip_add_del_route (vat_main_t * vam)
8370 {
8371   unformat_input_t *i = vam->input;
8372   vl_api_ip_add_del_route_t *mp;
8373   u32 sw_if_index = ~0, vrf_id = 0;
8374   u8 is_ipv6 = 0;
8375   u8 is_local = 0, is_drop = 0;
8376   u8 is_unreach = 0, is_prohibit = 0;
8377   u8 is_add = 1;
8378   u32 next_hop_weight = 1;
8379   u8 is_multipath = 0;
8380   u8 address_set = 0;
8381   u8 address_length_set = 0;
8382   u32 next_hop_table_id = 0;
8383   u32 resolve_attempts = 0;
8384   u32 dst_address_length = 0;
8385   u8 next_hop_set = 0;
8386   ip4_address_t v4_dst_address, v4_next_hop_address;
8387   ip6_address_t v6_dst_address, v6_next_hop_address;
8388   int count = 1;
8389   int j;
8390   f64 before = 0;
8391   u32 random_add_del = 0;
8392   u32 *random_vector = 0;
8393   uword *random_hash;
8394   u32 random_seed = 0xdeaddabe;
8395   u32 classify_table_index = ~0;
8396   u8 is_classify = 0;
8397   u8 resolve_host = 0, resolve_attached = 0;
8398   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8399   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8400   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8401
8402   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8403   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8404   /* Parse args required to build the message */
8405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8406     {
8407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8408         ;
8409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8410         ;
8411       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8412         {
8413           address_set = 1;
8414           is_ipv6 = 0;
8415         }
8416       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8417         {
8418           address_set = 1;
8419           is_ipv6 = 1;
8420         }
8421       else if (unformat (i, "/%d", &dst_address_length))
8422         {
8423           address_length_set = 1;
8424         }
8425
8426       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8427                                          &v4_next_hop_address))
8428         {
8429           next_hop_set = 1;
8430         }
8431       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8432                                          &v6_next_hop_address))
8433         {
8434           next_hop_set = 1;
8435         }
8436       else
8437         if (unformat
8438             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8439         {
8440           next_hop_set = 1;
8441         }
8442       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8443         {
8444           next_hop_set = 1;
8445         }
8446       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8447         ;
8448       else if (unformat (i, "weight %d", &next_hop_weight))
8449         ;
8450       else if (unformat (i, "drop"))
8451         {
8452           is_drop = 1;
8453         }
8454       else if (unformat (i, "null-send-unreach"))
8455         {
8456           is_unreach = 1;
8457         }
8458       else if (unformat (i, "null-send-prohibit"))
8459         {
8460           is_prohibit = 1;
8461         }
8462       else if (unformat (i, "local"))
8463         {
8464           is_local = 1;
8465         }
8466       else if (unformat (i, "classify %d", &classify_table_index))
8467         {
8468           is_classify = 1;
8469         }
8470       else if (unformat (i, "del"))
8471         is_add = 0;
8472       else if (unformat (i, "add"))
8473         is_add = 1;
8474       else if (unformat (i, "resolve-via-host"))
8475         resolve_host = 1;
8476       else if (unformat (i, "resolve-via-attached"))
8477         resolve_attached = 1;
8478       else if (unformat (i, "multipath"))
8479         is_multipath = 1;
8480       else if (unformat (i, "vrf %d", &vrf_id))
8481         ;
8482       else if (unformat (i, "count %d", &count))
8483         ;
8484       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8485         ;
8486       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8487         ;
8488       else if (unformat (i, "out-label %d", &next_hop_out_label))
8489         {
8490           vl_api_fib_mpls_label_t fib_label = {
8491             .label = ntohl (next_hop_out_label),
8492             .ttl = 64,
8493             .exp = 0,
8494           };
8495           vec_add1 (next_hop_out_label_stack, fib_label);
8496         }
8497       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8498         ;
8499       else if (unformat (i, "random"))
8500         random_add_del = 1;
8501       else if (unformat (i, "seed %d", &random_seed))
8502         ;
8503       else
8504         {
8505           clib_warning ("parse error '%U'", format_unformat_error, i);
8506           return -99;
8507         }
8508     }
8509
8510   if (!next_hop_set && !is_drop && !is_local &&
8511       !is_classify && !is_unreach && !is_prohibit &&
8512       MPLS_LABEL_INVALID == next_hop_via_label)
8513     {
8514       errmsg
8515         ("next hop / local / drop / unreach / prohibit / classify not set");
8516       return -99;
8517     }
8518
8519   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8520     {
8521       errmsg ("next hop and next-hop via label set");
8522       return -99;
8523     }
8524   if (address_set == 0)
8525     {
8526       errmsg ("missing addresses");
8527       return -99;
8528     }
8529
8530   if (address_length_set == 0)
8531     {
8532       errmsg ("missing address length");
8533       return -99;
8534     }
8535
8536   /* Generate a pile of unique, random routes */
8537   if (random_add_del)
8538     {
8539       u32 this_random_address;
8540       random_hash = hash_create (count, sizeof (uword));
8541
8542       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8543       for (j = 0; j <= count; j++)
8544         {
8545           do
8546             {
8547               this_random_address = random_u32 (&random_seed);
8548               this_random_address =
8549                 clib_host_to_net_u32 (this_random_address);
8550             }
8551           while (hash_get (random_hash, this_random_address));
8552           vec_add1 (random_vector, this_random_address);
8553           hash_set (random_hash, this_random_address, 1);
8554         }
8555       hash_free (random_hash);
8556       v4_dst_address.as_u32 = random_vector[0];
8557     }
8558
8559   if (count > 1)
8560     {
8561       /* Turn on async mode */
8562       vam->async_mode = 1;
8563       vam->async_errors = 0;
8564       before = vat_time_now (vam);
8565     }
8566
8567   for (j = 0; j < count; j++)
8568     {
8569       /* Construct the API message */
8570       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8571           vec_len (next_hop_out_label_stack));
8572
8573       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8574       mp->table_id = ntohl (vrf_id);
8575
8576       mp->is_add = is_add;
8577       mp->is_drop = is_drop;
8578       mp->is_unreach = is_unreach;
8579       mp->is_prohibit = is_prohibit;
8580       mp->is_ipv6 = is_ipv6;
8581       mp->is_local = is_local;
8582       mp->is_classify = is_classify;
8583       mp->is_multipath = is_multipath;
8584       mp->is_resolve_host = resolve_host;
8585       mp->is_resolve_attached = resolve_attached;
8586       mp->next_hop_weight = next_hop_weight;
8587       mp->next_hop_preference = 0;
8588       mp->dst_address_length = dst_address_length;
8589       mp->next_hop_table_id = ntohl (next_hop_table_id);
8590       mp->classify_table_index = ntohl (classify_table_index);
8591       mp->next_hop_via_label = ntohl (next_hop_via_label);
8592       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8593       if (0 != mp->next_hop_n_out_labels)
8594         {
8595           memcpy (mp->next_hop_out_label_stack,
8596                   next_hop_out_label_stack,
8597                   (vec_len (next_hop_out_label_stack) *
8598                    sizeof (vl_api_fib_mpls_label_t)));
8599           vec_free (next_hop_out_label_stack);
8600         }
8601
8602       if (is_ipv6)
8603         {
8604           clib_memcpy (mp->dst_address, &v6_dst_address,
8605                        sizeof (v6_dst_address));
8606           if (next_hop_set)
8607             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8608                          sizeof (v6_next_hop_address));
8609           increment_v6_address (&v6_dst_address);
8610         }
8611       else
8612         {
8613           clib_memcpy (mp->dst_address, &v4_dst_address,
8614                        sizeof (v4_dst_address));
8615           if (next_hop_set)
8616             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8617                          sizeof (v4_next_hop_address));
8618           if (random_add_del)
8619             v4_dst_address.as_u32 = random_vector[j + 1];
8620           else
8621             increment_v4_address (&v4_dst_address);
8622         }
8623       /* send it... */
8624       S (mp);
8625       /* If we receive SIGTERM, stop now... */
8626       if (vam->do_exit)
8627         break;
8628     }
8629
8630   /* When testing multiple add/del ops, use a control-ping to sync */
8631   if (count > 1)
8632     {
8633       vl_api_control_ping_t *mp_ping;
8634       f64 after;
8635       f64 timeout;
8636
8637       /* Shut off async mode */
8638       vam->async_mode = 0;
8639
8640       MPING (CONTROL_PING, mp_ping);
8641       S (mp_ping);
8642
8643       timeout = vat_time_now (vam) + 1.0;
8644       while (vat_time_now (vam) < timeout)
8645         if (vam->result_ready == 1)
8646           goto out;
8647       vam->retval = -99;
8648
8649     out:
8650       if (vam->retval == -99)
8651         errmsg ("timeout");
8652
8653       if (vam->async_errors > 0)
8654         {
8655           errmsg ("%d asynchronous errors", vam->async_errors);
8656           vam->retval = -98;
8657         }
8658       vam->async_errors = 0;
8659       after = vat_time_now (vam);
8660
8661       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8662       if (j > 0)
8663         count = j;
8664
8665       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8666              count, after - before, count / (after - before));
8667     }
8668   else
8669     {
8670       int ret;
8671
8672       /* Wait for a reply... */
8673       W (ret);
8674       return ret;
8675     }
8676
8677   /* Return the good/bad news */
8678   return (vam->retval);
8679 }
8680
8681 static int
8682 api_ip_mroute_add_del (vat_main_t * vam)
8683 {
8684   unformat_input_t *i = vam->input;
8685   vl_api_ip_mroute_add_del_t *mp;
8686   u32 sw_if_index = ~0, vrf_id = 0;
8687   u8 is_ipv6 = 0;
8688   u8 is_local = 0;
8689   u8 is_add = 1;
8690   u8 address_set = 0;
8691   u32 grp_address_length = 0;
8692   ip4_address_t v4_grp_address, v4_src_address;
8693   ip6_address_t v6_grp_address, v6_src_address;
8694   mfib_itf_flags_t iflags = 0;
8695   mfib_entry_flags_t eflags = 0;
8696   int ret;
8697
8698   /* Parse args required to build the message */
8699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8700     {
8701       if (unformat (i, "sw_if_index %d", &sw_if_index))
8702         ;
8703       else if (unformat (i, "%U %U",
8704                          unformat_ip4_address, &v4_src_address,
8705                          unformat_ip4_address, &v4_grp_address))
8706         {
8707           grp_address_length = 64;
8708           address_set = 1;
8709           is_ipv6 = 0;
8710         }
8711       else if (unformat (i, "%U %U",
8712                          unformat_ip6_address, &v6_src_address,
8713                          unformat_ip6_address, &v6_grp_address))
8714         {
8715           grp_address_length = 256;
8716           address_set = 1;
8717           is_ipv6 = 1;
8718         }
8719       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8720         {
8721           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8722           grp_address_length = 32;
8723           address_set = 1;
8724           is_ipv6 = 0;
8725         }
8726       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8727         {
8728           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8729           grp_address_length = 128;
8730           address_set = 1;
8731           is_ipv6 = 1;
8732         }
8733       else if (unformat (i, "/%d", &grp_address_length))
8734         ;
8735       else if (unformat (i, "local"))
8736         {
8737           is_local = 1;
8738         }
8739       else if (unformat (i, "del"))
8740         is_add = 0;
8741       else if (unformat (i, "add"))
8742         is_add = 1;
8743       else if (unformat (i, "vrf %d", &vrf_id))
8744         ;
8745       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8746         ;
8747       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8748         ;
8749       else
8750         {
8751           clib_warning ("parse error '%U'", format_unformat_error, i);
8752           return -99;
8753         }
8754     }
8755
8756   if (address_set == 0)
8757     {
8758       errmsg ("missing addresses\n");
8759       return -99;
8760     }
8761
8762   /* Construct the API message */
8763   M (IP_MROUTE_ADD_DEL, mp);
8764
8765   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8766   mp->table_id = ntohl (vrf_id);
8767
8768   mp->is_add = is_add;
8769   mp->is_ipv6 = is_ipv6;
8770   mp->is_local = is_local;
8771   mp->itf_flags = ntohl (iflags);
8772   mp->entry_flags = ntohl (eflags);
8773   mp->grp_address_length = grp_address_length;
8774   mp->grp_address_length = ntohs (mp->grp_address_length);
8775
8776   if (is_ipv6)
8777     {
8778       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8779       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8780     }
8781   else
8782     {
8783       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8784       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8785
8786     }
8787
8788   /* send it... */
8789   S (mp);
8790   /* Wait for a reply... */
8791   W (ret);
8792   return ret;
8793 }
8794
8795 static int
8796 api_mpls_table_add_del (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   vl_api_mpls_table_add_del_t *mp;
8800   u32 table_id = ~0;
8801   u8 is_add = 1;
8802   int ret = 0;
8803
8804   /* Parse args required to build the message */
8805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8806     {
8807       if (unformat (i, "table %d", &table_id))
8808         ;
8809       else if (unformat (i, "del"))
8810         is_add = 0;
8811       else if (unformat (i, "add"))
8812         is_add = 1;
8813       else
8814         {
8815           clib_warning ("parse error '%U'", format_unformat_error, i);
8816           return -99;
8817         }
8818     }
8819
8820   if (~0 == table_id)
8821     {
8822       errmsg ("missing table-ID");
8823       return -99;
8824     }
8825
8826   /* Construct the API message */
8827   M (MPLS_TABLE_ADD_DEL, mp);
8828
8829   mp->mt_table_id = ntohl (table_id);
8830   mp->mt_is_add = is_add;
8831
8832   /* send it... */
8833   S (mp);
8834
8835   /* Wait for a reply... */
8836   W (ret);
8837
8838   return ret;
8839 }
8840
8841 static int
8842 api_mpls_route_add_del (vat_main_t * vam)
8843 {
8844   unformat_input_t *i = vam->input;
8845   vl_api_mpls_route_add_del_t *mp;
8846   u32 sw_if_index = ~0, table_id = 0;
8847   u8 is_add = 1;
8848   u32 next_hop_weight = 1;
8849   u8 is_multipath = 0;
8850   u32 next_hop_table_id = 0;
8851   u8 next_hop_set = 0;
8852   ip4_address_t v4_next_hop_address = {
8853     .as_u32 = 0,
8854   };
8855   ip6_address_t v6_next_hop_address = { {0} };
8856   int count = 1;
8857   int j;
8858   f64 before = 0;
8859   u32 classify_table_index = ~0;
8860   u8 is_classify = 0;
8861   u8 resolve_host = 0, resolve_attached = 0;
8862   u8 is_interface_rx = 0;
8863   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8864   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8865   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8866   mpls_label_t local_label = MPLS_LABEL_INVALID;
8867   u8 is_eos = 0;
8868   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8869
8870   /* Parse args required to build the message */
8871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8872     {
8873       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8874         ;
8875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8876         ;
8877       else if (unformat (i, "%d", &local_label))
8878         ;
8879       else if (unformat (i, "eos"))
8880         is_eos = 1;
8881       else if (unformat (i, "non-eos"))
8882         is_eos = 0;
8883       else if (unformat (i, "via %U", unformat_ip4_address,
8884                          &v4_next_hop_address))
8885         {
8886           next_hop_set = 1;
8887           next_hop_proto = DPO_PROTO_IP4;
8888         }
8889       else if (unformat (i, "via %U", unformat_ip6_address,
8890                          &v6_next_hop_address))
8891         {
8892           next_hop_set = 1;
8893           next_hop_proto = DPO_PROTO_IP6;
8894         }
8895       else if (unformat (i, "weight %d", &next_hop_weight))
8896         ;
8897       else if (unformat (i, "classify %d", &classify_table_index))
8898         {
8899           is_classify = 1;
8900         }
8901       else if (unformat (i, "del"))
8902         is_add = 0;
8903       else if (unformat (i, "add"))
8904         is_add = 1;
8905       else if (unformat (i, "resolve-via-host"))
8906         resolve_host = 1;
8907       else if (unformat (i, "resolve-via-attached"))
8908         resolve_attached = 1;
8909       else if (unformat (i, "multipath"))
8910         is_multipath = 1;
8911       else if (unformat (i, "count %d", &count))
8912         ;
8913       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8914         {
8915           next_hop_set = 1;
8916           next_hop_proto = DPO_PROTO_IP4;
8917         }
8918       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8919         {
8920           next_hop_set = 1;
8921           next_hop_proto = DPO_PROTO_IP6;
8922         }
8923       else
8924         if (unformat
8925             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8926              &sw_if_index))
8927         {
8928           next_hop_set = 1;
8929           next_hop_proto = DPO_PROTO_ETHERNET;
8930           is_interface_rx = 1;
8931         }
8932       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8933         {
8934           next_hop_set = 1;
8935           next_hop_proto = DPO_PROTO_ETHERNET;
8936           is_interface_rx = 1;
8937         }
8938       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8939         next_hop_set = 1;
8940       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8941         next_hop_set = 1;
8942       else if (unformat (i, "out-label %d", &next_hop_out_label))
8943         {
8944           vl_api_fib_mpls_label_t fib_label = {
8945             .label = ntohl (next_hop_out_label),
8946             .ttl = 64,
8947             .exp = 0,
8948           };
8949           vec_add1 (next_hop_out_label_stack, fib_label);
8950         }
8951       else
8952         {
8953           clib_warning ("parse error '%U'", format_unformat_error, i);
8954           return -99;
8955         }
8956     }
8957
8958   if (!next_hop_set && !is_classify)
8959     {
8960       errmsg ("next hop / classify not set");
8961       return -99;
8962     }
8963
8964   if (MPLS_LABEL_INVALID == local_label)
8965     {
8966       errmsg ("missing label");
8967       return -99;
8968     }
8969
8970   if (count > 1)
8971     {
8972       /* Turn on async mode */
8973       vam->async_mode = 1;
8974       vam->async_errors = 0;
8975       before = vat_time_now (vam);
8976     }
8977
8978   for (j = 0; j < count; j++)
8979     {
8980       /* Construct the API message */
8981       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8982           vec_len (next_hop_out_label_stack));
8983
8984       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8985       mp->mr_table_id = ntohl (table_id);
8986
8987       mp->mr_is_add = is_add;
8988       mp->mr_next_hop_proto = next_hop_proto;
8989       mp->mr_is_classify = is_classify;
8990       mp->mr_is_multipath = is_multipath;
8991       mp->mr_is_resolve_host = resolve_host;
8992       mp->mr_is_resolve_attached = resolve_attached;
8993       mp->mr_is_interface_rx = is_interface_rx;
8994       mp->mr_next_hop_weight = next_hop_weight;
8995       mp->mr_next_hop_preference = 0;
8996       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8997       mp->mr_classify_table_index = ntohl (classify_table_index);
8998       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8999       mp->mr_label = ntohl (local_label);
9000       mp->mr_eos = is_eos;
9001
9002       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9003       if (0 != mp->mr_next_hop_n_out_labels)
9004         {
9005           memcpy (mp->mr_next_hop_out_label_stack,
9006                   next_hop_out_label_stack,
9007                   vec_len (next_hop_out_label_stack) *
9008                   sizeof (vl_api_fib_mpls_label_t));
9009           vec_free (next_hop_out_label_stack);
9010         }
9011
9012       if (next_hop_set)
9013         {
9014           if (DPO_PROTO_IP4 == next_hop_proto)
9015             {
9016               clib_memcpy (mp->mr_next_hop,
9017                            &v4_next_hop_address,
9018                            sizeof (v4_next_hop_address));
9019             }
9020           else if (DPO_PROTO_IP6 == next_hop_proto)
9021
9022             {
9023               clib_memcpy (mp->mr_next_hop,
9024                            &v6_next_hop_address,
9025                            sizeof (v6_next_hop_address));
9026             }
9027         }
9028       local_label++;
9029
9030       /* send it... */
9031       S (mp);
9032       /* If we receive SIGTERM, stop now... */
9033       if (vam->do_exit)
9034         break;
9035     }
9036
9037   /* When testing multiple add/del ops, use a control-ping to sync */
9038   if (count > 1)
9039     {
9040       vl_api_control_ping_t *mp_ping;
9041       f64 after;
9042       f64 timeout;
9043
9044       /* Shut off async mode */
9045       vam->async_mode = 0;
9046
9047       MPING (CONTROL_PING, mp_ping);
9048       S (mp_ping);
9049
9050       timeout = vat_time_now (vam) + 1.0;
9051       while (vat_time_now (vam) < timeout)
9052         if (vam->result_ready == 1)
9053           goto out;
9054       vam->retval = -99;
9055
9056     out:
9057       if (vam->retval == -99)
9058         errmsg ("timeout");
9059
9060       if (vam->async_errors > 0)
9061         {
9062           errmsg ("%d asynchronous errors", vam->async_errors);
9063           vam->retval = -98;
9064         }
9065       vam->async_errors = 0;
9066       after = vat_time_now (vam);
9067
9068       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9069       if (j > 0)
9070         count = j;
9071
9072       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9073              count, after - before, count / (after - before));
9074     }
9075   else
9076     {
9077       int ret;
9078
9079       /* Wait for a reply... */
9080       W (ret);
9081       return ret;
9082     }
9083
9084   /* Return the good/bad news */
9085   return (vam->retval);
9086 }
9087
9088 static int
9089 api_mpls_ip_bind_unbind (vat_main_t * vam)
9090 {
9091   unformat_input_t *i = vam->input;
9092   vl_api_mpls_ip_bind_unbind_t *mp;
9093   u32 ip_table_id = 0;
9094   u8 is_bind = 1;
9095   u8 is_ip4 = 1;
9096   ip4_address_t v4_address;
9097   ip6_address_t v6_address;
9098   u32 address_length;
9099   u8 address_set = 0;
9100   mpls_label_t local_label = MPLS_LABEL_INVALID;
9101   int ret;
9102
9103   /* Parse args required to build the message */
9104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9105     {
9106       if (unformat (i, "%U/%d", unformat_ip4_address,
9107                     &v4_address, &address_length))
9108         {
9109           is_ip4 = 1;
9110           address_set = 1;
9111         }
9112       else if (unformat (i, "%U/%d", unformat_ip6_address,
9113                          &v6_address, &address_length))
9114         {
9115           is_ip4 = 0;
9116           address_set = 1;
9117         }
9118       else if (unformat (i, "%d", &local_label))
9119         ;
9120       else if (unformat (i, "table-id %d", &ip_table_id))
9121         ;
9122       else if (unformat (i, "unbind"))
9123         is_bind = 0;
9124       else if (unformat (i, "bind"))
9125         is_bind = 1;
9126       else
9127         {
9128           clib_warning ("parse error '%U'", format_unformat_error, i);
9129           return -99;
9130         }
9131     }
9132
9133   if (!address_set)
9134     {
9135       errmsg ("IP address not set");
9136       return -99;
9137     }
9138
9139   if (MPLS_LABEL_INVALID == local_label)
9140     {
9141       errmsg ("missing label");
9142       return -99;
9143     }
9144
9145   /* Construct the API message */
9146   M (MPLS_IP_BIND_UNBIND, mp);
9147
9148   mp->mb_is_bind = is_bind;
9149   mp->mb_is_ip4 = is_ip4;
9150   mp->mb_ip_table_id = ntohl (ip_table_id);
9151   mp->mb_mpls_table_id = 0;
9152   mp->mb_label = ntohl (local_label);
9153   mp->mb_address_length = address_length;
9154
9155   if (is_ip4)
9156     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9157   else
9158     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9159
9160   /* send it... */
9161   S (mp);
9162
9163   /* Wait for a reply... */
9164   W (ret);
9165   return ret;
9166 }
9167
9168 static int
9169 api_sr_mpls_policy_add (vat_main_t * vam)
9170 {
9171   unformat_input_t *i = vam->input;
9172   vl_api_sr_mpls_policy_add_t *mp;
9173   u32 bsid = 0;
9174   u32 weight = 1;
9175   u8 type = 0;
9176   u8 n_segments = 0;
9177   u32 sid;
9178   u32 *segments = NULL;
9179   int ret;
9180
9181   /* Parse args required to build the message */
9182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9183     {
9184       if (unformat (i, "bsid %d", &bsid))
9185         ;
9186       else if (unformat (i, "weight %d", &weight))
9187         ;
9188       else if (unformat (i, "spray"))
9189         type = 1;
9190       else if (unformat (i, "next %d", &sid))
9191         {
9192           n_segments += 1;
9193           vec_add1 (segments, htonl (sid));
9194         }
9195       else
9196         {
9197           clib_warning ("parse error '%U'", format_unformat_error, i);
9198           return -99;
9199         }
9200     }
9201
9202   if (bsid == 0)
9203     {
9204       errmsg ("bsid not set");
9205       return -99;
9206     }
9207
9208   if (n_segments == 0)
9209     {
9210       errmsg ("no sid in segment stack");
9211       return -99;
9212     }
9213
9214   /* Construct the API message */
9215   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9216
9217   mp->bsid = htonl (bsid);
9218   mp->weight = htonl (weight);
9219   mp->type = type;
9220   mp->n_segments = n_segments;
9221   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9222   vec_free (segments);
9223
9224   /* send it... */
9225   S (mp);
9226
9227   /* Wait for a reply... */
9228   W (ret);
9229   return ret;
9230 }
9231
9232 static int
9233 api_sr_mpls_policy_del (vat_main_t * vam)
9234 {
9235   unformat_input_t *i = vam->input;
9236   vl_api_sr_mpls_policy_del_t *mp;
9237   u32 bsid = 0;
9238   int ret;
9239
9240   /* Parse args required to build the message */
9241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9242     {
9243       if (unformat (i, "bsid %d", &bsid))
9244         ;
9245       else
9246         {
9247           clib_warning ("parse error '%U'", format_unformat_error, i);
9248           return -99;
9249         }
9250     }
9251
9252   if (bsid == 0)
9253     {
9254       errmsg ("bsid not set");
9255       return -99;
9256     }
9257
9258   /* Construct the API message */
9259   M (SR_MPLS_POLICY_DEL, mp);
9260
9261   mp->bsid = htonl (bsid);
9262
9263   /* send it... */
9264   S (mp);
9265
9266   /* Wait for a reply... */
9267   W (ret);
9268   return ret;
9269 }
9270
9271 static int
9272 api_bier_table_add_del (vat_main_t * vam)
9273 {
9274   unformat_input_t *i = vam->input;
9275   vl_api_bier_table_add_del_t *mp;
9276   u8 is_add = 1;
9277   u32 set = 0, sub_domain = 0, hdr_len = 3;
9278   mpls_label_t local_label = MPLS_LABEL_INVALID;
9279   int ret;
9280
9281   /* Parse args required to build the message */
9282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9283     {
9284       if (unformat (i, "sub-domain %d", &sub_domain))
9285         ;
9286       else if (unformat (i, "set %d", &set))
9287         ;
9288       else if (unformat (i, "label %d", &local_label))
9289         ;
9290       else if (unformat (i, "hdr-len %d", &hdr_len))
9291         ;
9292       else if (unformat (i, "add"))
9293         is_add = 1;
9294       else if (unformat (i, "del"))
9295         is_add = 0;
9296       else
9297         {
9298           clib_warning ("parse error '%U'", format_unformat_error, i);
9299           return -99;
9300         }
9301     }
9302
9303   if (MPLS_LABEL_INVALID == local_label)
9304     {
9305       errmsg ("missing label\n");
9306       return -99;
9307     }
9308
9309   /* Construct the API message */
9310   M (BIER_TABLE_ADD_DEL, mp);
9311
9312   mp->bt_is_add = is_add;
9313   mp->bt_label = ntohl (local_label);
9314   mp->bt_tbl_id.bt_set = set;
9315   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9316   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9317
9318   /* send it... */
9319   S (mp);
9320
9321   /* Wait for a reply... */
9322   W (ret);
9323
9324   return (ret);
9325 }
9326
9327 static int
9328 api_bier_route_add_del (vat_main_t * vam)
9329 {
9330   unformat_input_t *i = vam->input;
9331   vl_api_bier_route_add_del_t *mp;
9332   u8 is_add = 1;
9333   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9334   ip4_address_t v4_next_hop_address;
9335   ip6_address_t v6_next_hop_address;
9336   u8 next_hop_set = 0;
9337   u8 next_hop_proto_is_ip4 = 1;
9338   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9339   int ret;
9340
9341   /* Parse args required to build the message */
9342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9343     {
9344       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9345         {
9346           next_hop_proto_is_ip4 = 1;
9347           next_hop_set = 1;
9348         }
9349       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9350         {
9351           next_hop_proto_is_ip4 = 0;
9352           next_hop_set = 1;
9353         }
9354       if (unformat (i, "sub-domain %d", &sub_domain))
9355         ;
9356       else if (unformat (i, "set %d", &set))
9357         ;
9358       else if (unformat (i, "hdr-len %d", &hdr_len))
9359         ;
9360       else if (unformat (i, "bp %d", &bp))
9361         ;
9362       else if (unformat (i, "add"))
9363         is_add = 1;
9364       else if (unformat (i, "del"))
9365         is_add = 0;
9366       else if (unformat (i, "out-label %d", &next_hop_out_label))
9367         ;
9368       else
9369         {
9370           clib_warning ("parse error '%U'", format_unformat_error, i);
9371           return -99;
9372         }
9373     }
9374
9375   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9376     {
9377       errmsg ("next hop / label set\n");
9378       return -99;
9379     }
9380   if (0 == bp)
9381     {
9382       errmsg ("bit=position not set\n");
9383       return -99;
9384     }
9385
9386   /* Construct the API message */
9387   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9388
9389   mp->br_is_add = is_add;
9390   mp->br_tbl_id.bt_set = set;
9391   mp->br_tbl_id.bt_sub_domain = sub_domain;
9392   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9393   mp->br_bp = ntohs (bp);
9394   mp->br_n_paths = 1;
9395   mp->br_paths[0].n_labels = 1;
9396   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9397   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9398
9399   if (next_hop_proto_is_ip4)
9400     {
9401       clib_memcpy (mp->br_paths[0].next_hop,
9402                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9403     }
9404   else
9405     {
9406       clib_memcpy (mp->br_paths[0].next_hop,
9407                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9408     }
9409
9410   /* send it... */
9411   S (mp);
9412
9413   /* Wait for a reply... */
9414   W (ret);
9415
9416   return (ret);
9417 }
9418
9419 static int
9420 api_proxy_arp_add_del (vat_main_t * vam)
9421 {
9422   unformat_input_t *i = vam->input;
9423   vl_api_proxy_arp_add_del_t *mp;
9424   u32 vrf_id = 0;
9425   u8 is_add = 1;
9426   ip4_address_t lo, hi;
9427   u8 range_set = 0;
9428   int ret;
9429
9430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (i, "vrf %d", &vrf_id))
9433         ;
9434       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9435                          unformat_ip4_address, &hi))
9436         range_set = 1;
9437       else if (unformat (i, "del"))
9438         is_add = 0;
9439       else
9440         {
9441           clib_warning ("parse error '%U'", format_unformat_error, i);
9442           return -99;
9443         }
9444     }
9445
9446   if (range_set == 0)
9447     {
9448       errmsg ("address range not set");
9449       return -99;
9450     }
9451
9452   M (PROXY_ARP_ADD_DEL, mp);
9453
9454   mp->proxy.vrf_id = ntohl (vrf_id);
9455   mp->is_add = is_add;
9456   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9457   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9458
9459   S (mp);
9460   W (ret);
9461   return ret;
9462 }
9463
9464 static int
9465 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9466 {
9467   unformat_input_t *i = vam->input;
9468   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9469   u32 sw_if_index;
9470   u8 enable = 1;
9471   u8 sw_if_index_set = 0;
9472   int ret;
9473
9474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9475     {
9476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9477         sw_if_index_set = 1;
9478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9479         sw_if_index_set = 1;
9480       else if (unformat (i, "enable"))
9481         enable = 1;
9482       else if (unformat (i, "disable"))
9483         enable = 0;
9484       else
9485         {
9486           clib_warning ("parse error '%U'", format_unformat_error, i);
9487           return -99;
9488         }
9489     }
9490
9491   if (sw_if_index_set == 0)
9492     {
9493       errmsg ("missing interface name or sw_if_index");
9494       return -99;
9495     }
9496
9497   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9498
9499   mp->sw_if_index = ntohl (sw_if_index);
9500   mp->enable_disable = enable;
9501
9502   S (mp);
9503   W (ret);
9504   return ret;
9505 }
9506
9507 static int
9508 api_mpls_tunnel_add_del (vat_main_t * vam)
9509 {
9510   unformat_input_t *i = vam->input;
9511   vl_api_mpls_tunnel_add_del_t *mp;
9512
9513   u8 is_add = 1;
9514   u8 l2_only = 0;
9515   u32 sw_if_index = ~0;
9516   u32 next_hop_sw_if_index = ~0;
9517   u32 next_hop_proto_is_ip4 = 1;
9518
9519   u32 next_hop_table_id = 0;
9520   ip4_address_t v4_next_hop_address = {
9521     .as_u32 = 0,
9522   };
9523   ip6_address_t v6_next_hop_address = { {0} };
9524   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9525   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9526   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9527   int ret;
9528
9529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9530     {
9531       if (unformat (i, "add"))
9532         is_add = 1;
9533       else
9534         if (unformat
9535             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9536         is_add = 0;
9537       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9538         is_add = 0;
9539       else if (unformat (i, "via %U",
9540                          unformat_ip4_address, &v4_next_hop_address))
9541         {
9542           next_hop_proto_is_ip4 = 1;
9543         }
9544       else if (unformat (i, "via %U",
9545                          unformat_ip6_address, &v6_next_hop_address))
9546         {
9547           next_hop_proto_is_ip4 = 0;
9548         }
9549       else if (unformat (i, "via-label %d", &next_hop_via_label))
9550         ;
9551       else
9552         if (unformat
9553             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9554         ;
9555       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9556         ;
9557       else if (unformat (i, "l2-only"))
9558         l2_only = 1;
9559       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9560         ;
9561       else if (unformat (i, "out-label %d", &next_hop_out_label))
9562         {
9563           vl_api_fib_mpls_label_t fib_label = {
9564             .label = ntohl (next_hop_out_label),
9565             .ttl = 64,
9566             .exp = 0,
9567           };
9568           vec_add1 (next_hop_out_label_stack, fib_label);
9569         }
9570       else
9571         {
9572           clib_warning ("parse error '%U'", format_unformat_error, i);
9573           return -99;
9574         }
9575     }
9576
9577   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9578       vec_len (next_hop_out_label_stack));
9579
9580   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9581   mp->mt_sw_if_index = ntohl (sw_if_index);
9582   mp->mt_is_add = is_add;
9583   mp->mt_l2_only = l2_only;
9584   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9585   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9586   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9587   mp->mt_next_hop_weight = 1;
9588   mp->mt_next_hop_preference = 0;
9589
9590   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9591
9592   if (0 != mp->mt_next_hop_n_out_labels)
9593     {
9594       clib_memcpy (mp->mt_next_hop_out_label_stack,
9595                    next_hop_out_label_stack,
9596                    (vec_len (next_hop_out_label_stack) *
9597                     sizeof (vl_api_fib_mpls_label_t)));
9598       vec_free (next_hop_out_label_stack);
9599     }
9600
9601   if (next_hop_proto_is_ip4)
9602     {
9603       clib_memcpy (mp->mt_next_hop,
9604                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9605     }
9606   else
9607     {
9608       clib_memcpy (mp->mt_next_hop,
9609                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9610     }
9611
9612   S (mp);
9613   W (ret);
9614   return ret;
9615 }
9616
9617 static int
9618 api_sw_interface_set_unnumbered (vat_main_t * vam)
9619 {
9620   unformat_input_t *i = vam->input;
9621   vl_api_sw_interface_set_unnumbered_t *mp;
9622   u32 sw_if_index;
9623   u32 unnum_sw_index = ~0;
9624   u8 is_add = 1;
9625   u8 sw_if_index_set = 0;
9626   int ret;
9627
9628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9629     {
9630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9631         sw_if_index_set = 1;
9632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9633         sw_if_index_set = 1;
9634       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9635         ;
9636       else if (unformat (i, "del"))
9637         is_add = 0;
9638       else
9639         {
9640           clib_warning ("parse error '%U'", format_unformat_error, i);
9641           return -99;
9642         }
9643     }
9644
9645   if (sw_if_index_set == 0)
9646     {
9647       errmsg ("missing interface name or sw_if_index");
9648       return -99;
9649     }
9650
9651   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9652
9653   mp->sw_if_index = ntohl (sw_if_index);
9654   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9655   mp->is_add = is_add;
9656
9657   S (mp);
9658   W (ret);
9659   return ret;
9660 }
9661
9662 static int
9663 api_ip_neighbor_add_del (vat_main_t * vam)
9664 {
9665   unformat_input_t *i = vam->input;
9666   vl_api_ip_neighbor_add_del_t *mp;
9667   u32 sw_if_index;
9668   u8 sw_if_index_set = 0;
9669   u8 is_add = 1;
9670   u8 is_static = 0;
9671   u8 is_no_fib_entry = 0;
9672   u8 mac_address[6];
9673   u8 mac_set = 0;
9674   u8 v4_address_set = 0;
9675   u8 v6_address_set = 0;
9676   ip4_address_t v4address;
9677   ip6_address_t v6address;
9678   int ret;
9679
9680   clib_memset (mac_address, 0, sizeof (mac_address));
9681
9682   /* Parse args required to build the message */
9683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9684     {
9685       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9686         {
9687           mac_set = 1;
9688         }
9689       else if (unformat (i, "del"))
9690         is_add = 0;
9691       else
9692         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9693         sw_if_index_set = 1;
9694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9695         sw_if_index_set = 1;
9696       else if (unformat (i, "is_static"))
9697         is_static = 1;
9698       else if (unformat (i, "no-fib-entry"))
9699         is_no_fib_entry = 1;
9700       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9701         v4_address_set = 1;
9702       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9703         v6_address_set = 1;
9704       else
9705         {
9706           clib_warning ("parse error '%U'", format_unformat_error, i);
9707           return -99;
9708         }
9709     }
9710
9711   if (sw_if_index_set == 0)
9712     {
9713       errmsg ("missing interface name or sw_if_index");
9714       return -99;
9715     }
9716   if (v4_address_set && v6_address_set)
9717     {
9718       errmsg ("both v4 and v6 addresses set");
9719       return -99;
9720     }
9721   if (!v4_address_set && !v6_address_set)
9722     {
9723       errmsg ("no address set");
9724       return -99;
9725     }
9726
9727   /* Construct the API message */
9728   M (IP_NEIGHBOR_ADD_DEL, mp);
9729
9730   mp->sw_if_index = ntohl (sw_if_index);
9731   mp->is_add = is_add;
9732   mp->is_static = is_static;
9733   mp->is_no_adj_fib = is_no_fib_entry;
9734   if (mac_set)
9735     clib_memcpy (mp->mac_address, mac_address, 6);
9736   if (v6_address_set)
9737     {
9738       mp->is_ipv6 = 1;
9739       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9740     }
9741   else
9742     {
9743       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9744       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9745     }
9746
9747   /* send it... */
9748   S (mp);
9749
9750   /* Wait for a reply, return good/bad news  */
9751   W (ret);
9752   return ret;
9753 }
9754
9755 static int
9756 api_create_vlan_subif (vat_main_t * vam)
9757 {
9758   unformat_input_t *i = vam->input;
9759   vl_api_create_vlan_subif_t *mp;
9760   u32 sw_if_index;
9761   u8 sw_if_index_set = 0;
9762   u32 vlan_id;
9763   u8 vlan_id_set = 0;
9764   int ret;
9765
9766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9767     {
9768       if (unformat (i, "sw_if_index %d", &sw_if_index))
9769         sw_if_index_set = 1;
9770       else
9771         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9772         sw_if_index_set = 1;
9773       else if (unformat (i, "vlan %d", &vlan_id))
9774         vlan_id_set = 1;
9775       else
9776         {
9777           clib_warning ("parse error '%U'", format_unformat_error, i);
9778           return -99;
9779         }
9780     }
9781
9782   if (sw_if_index_set == 0)
9783     {
9784       errmsg ("missing interface name or sw_if_index");
9785       return -99;
9786     }
9787
9788   if (vlan_id_set == 0)
9789     {
9790       errmsg ("missing vlan_id");
9791       return -99;
9792     }
9793   M (CREATE_VLAN_SUBIF, mp);
9794
9795   mp->sw_if_index = ntohl (sw_if_index);
9796   mp->vlan_id = ntohl (vlan_id);
9797
9798   S (mp);
9799   W (ret);
9800   return ret;
9801 }
9802
9803 #define foreach_create_subif_bit                \
9804 _(no_tags)                                      \
9805 _(one_tag)                                      \
9806 _(two_tags)                                     \
9807 _(dot1ad)                                       \
9808 _(exact_match)                                  \
9809 _(default_sub)                                  \
9810 _(outer_vlan_id_any)                            \
9811 _(inner_vlan_id_any)
9812
9813 static int
9814 api_create_subif (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   vl_api_create_subif_t *mp;
9818   u32 sw_if_index;
9819   u8 sw_if_index_set = 0;
9820   u32 sub_id;
9821   u8 sub_id_set = 0;
9822   u32 no_tags = 0;
9823   u32 one_tag = 0;
9824   u32 two_tags = 0;
9825   u32 dot1ad = 0;
9826   u32 exact_match = 0;
9827   u32 default_sub = 0;
9828   u32 outer_vlan_id_any = 0;
9829   u32 inner_vlan_id_any = 0;
9830   u32 tmp;
9831   u16 outer_vlan_id = 0;
9832   u16 inner_vlan_id = 0;
9833   int ret;
9834
9835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836     {
9837       if (unformat (i, "sw_if_index %d", &sw_if_index))
9838         sw_if_index_set = 1;
9839       else
9840         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9841         sw_if_index_set = 1;
9842       else if (unformat (i, "sub_id %d", &sub_id))
9843         sub_id_set = 1;
9844       else if (unformat (i, "outer_vlan_id %d", &tmp))
9845         outer_vlan_id = tmp;
9846       else if (unformat (i, "inner_vlan_id %d", &tmp))
9847         inner_vlan_id = tmp;
9848
9849 #define _(a) else if (unformat (i, #a)) a = 1 ;
9850       foreach_create_subif_bit
9851 #undef _
9852         else
9853         {
9854           clib_warning ("parse error '%U'", format_unformat_error, i);
9855           return -99;
9856         }
9857     }
9858
9859   if (sw_if_index_set == 0)
9860     {
9861       errmsg ("missing interface name or sw_if_index");
9862       return -99;
9863     }
9864
9865   if (sub_id_set == 0)
9866     {
9867       errmsg ("missing sub_id");
9868       return -99;
9869     }
9870   M (CREATE_SUBIF, mp);
9871
9872   mp->sw_if_index = ntohl (sw_if_index);
9873   mp->sub_id = ntohl (sub_id);
9874
9875 #define _(a) mp->a = a;
9876   foreach_create_subif_bit;
9877 #undef _
9878
9879   mp->outer_vlan_id = ntohs (outer_vlan_id);
9880   mp->inner_vlan_id = ntohs (inner_vlan_id);
9881
9882   S (mp);
9883   W (ret);
9884   return ret;
9885 }
9886
9887 static int
9888 api_oam_add_del (vat_main_t * vam)
9889 {
9890   unformat_input_t *i = vam->input;
9891   vl_api_oam_add_del_t *mp;
9892   u32 vrf_id = 0;
9893   u8 is_add = 1;
9894   ip4_address_t src, dst;
9895   u8 src_set = 0;
9896   u8 dst_set = 0;
9897   int ret;
9898
9899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9900     {
9901       if (unformat (i, "vrf %d", &vrf_id))
9902         ;
9903       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9904         src_set = 1;
9905       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9906         dst_set = 1;
9907       else if (unformat (i, "del"))
9908         is_add = 0;
9909       else
9910         {
9911           clib_warning ("parse error '%U'", format_unformat_error, i);
9912           return -99;
9913         }
9914     }
9915
9916   if (src_set == 0)
9917     {
9918       errmsg ("missing src addr");
9919       return -99;
9920     }
9921
9922   if (dst_set == 0)
9923     {
9924       errmsg ("missing dst addr");
9925       return -99;
9926     }
9927
9928   M (OAM_ADD_DEL, mp);
9929
9930   mp->vrf_id = ntohl (vrf_id);
9931   mp->is_add = is_add;
9932   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9933   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9934
9935   S (mp);
9936   W (ret);
9937   return ret;
9938 }
9939
9940 static int
9941 api_reset_fib (vat_main_t * vam)
9942 {
9943   unformat_input_t *i = vam->input;
9944   vl_api_reset_fib_t *mp;
9945   u32 vrf_id = 0;
9946   u8 is_ipv6 = 0;
9947   u8 vrf_id_set = 0;
9948
9949   int ret;
9950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9951     {
9952       if (unformat (i, "vrf %d", &vrf_id))
9953         vrf_id_set = 1;
9954       else if (unformat (i, "ipv6"))
9955         is_ipv6 = 1;
9956       else
9957         {
9958           clib_warning ("parse error '%U'", format_unformat_error, i);
9959           return -99;
9960         }
9961     }
9962
9963   if (vrf_id_set == 0)
9964     {
9965       errmsg ("missing vrf id");
9966       return -99;
9967     }
9968
9969   M (RESET_FIB, mp);
9970
9971   mp->vrf_id = ntohl (vrf_id);
9972   mp->is_ipv6 = is_ipv6;
9973
9974   S (mp);
9975   W (ret);
9976   return ret;
9977 }
9978
9979 static int
9980 api_dhcp_proxy_config (vat_main_t * vam)
9981 {
9982   unformat_input_t *i = vam->input;
9983   vl_api_dhcp_proxy_config_t *mp;
9984   u32 rx_vrf_id = 0;
9985   u32 server_vrf_id = 0;
9986   u8 is_add = 1;
9987   u8 v4_address_set = 0;
9988   u8 v6_address_set = 0;
9989   ip4_address_t v4address;
9990   ip6_address_t v6address;
9991   u8 v4_src_address_set = 0;
9992   u8 v6_src_address_set = 0;
9993   ip4_address_t v4srcaddress;
9994   ip6_address_t v6srcaddress;
9995   int ret;
9996
9997   /* Parse args required to build the message */
9998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9999     {
10000       if (unformat (i, "del"))
10001         is_add = 0;
10002       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10003         ;
10004       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10005         ;
10006       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10007         v4_address_set = 1;
10008       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10009         v6_address_set = 1;
10010       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10011         v4_src_address_set = 1;
10012       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10013         v6_src_address_set = 1;
10014       else
10015         break;
10016     }
10017
10018   if (v4_address_set && v6_address_set)
10019     {
10020       errmsg ("both v4 and v6 server addresses set");
10021       return -99;
10022     }
10023   if (!v4_address_set && !v6_address_set)
10024     {
10025       errmsg ("no server addresses set");
10026       return -99;
10027     }
10028
10029   if (v4_src_address_set && v6_src_address_set)
10030     {
10031       errmsg ("both v4 and v6  src addresses set");
10032       return -99;
10033     }
10034   if (!v4_src_address_set && !v6_src_address_set)
10035     {
10036       errmsg ("no src addresses set");
10037       return -99;
10038     }
10039
10040   if (!(v4_src_address_set && v4_address_set) &&
10041       !(v6_src_address_set && v6_address_set))
10042     {
10043       errmsg ("no matching server and src addresses set");
10044       return -99;
10045     }
10046
10047   /* Construct the API message */
10048   M (DHCP_PROXY_CONFIG, mp);
10049
10050   mp->is_add = is_add;
10051   mp->rx_vrf_id = ntohl (rx_vrf_id);
10052   mp->server_vrf_id = ntohl (server_vrf_id);
10053   if (v6_address_set)
10054     {
10055       mp->is_ipv6 = 1;
10056       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10057       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10058     }
10059   else
10060     {
10061       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10062       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10063     }
10064
10065   /* send it... */
10066   S (mp);
10067
10068   /* Wait for a reply, return good/bad news  */
10069   W (ret);
10070   return ret;
10071 }
10072
10073 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10074 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10075
10076 static void
10077 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10078 {
10079   vat_main_t *vam = &vat_main;
10080   u32 i, count = mp->count;
10081   vl_api_dhcp_server_t *s;
10082
10083   if (mp->is_ipv6)
10084     print (vam->ofp,
10085            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10086            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10087            ntohl (mp->rx_vrf_id),
10088            format_ip6_address, mp->dhcp_src_address,
10089            mp->vss_type, mp->vss_vpn_ascii_id,
10090            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10091   else
10092     print (vam->ofp,
10093            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10094            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10095            ntohl (mp->rx_vrf_id),
10096            format_ip4_address, mp->dhcp_src_address,
10097            mp->vss_type, mp->vss_vpn_ascii_id,
10098            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10099
10100   for (i = 0; i < count; i++)
10101     {
10102       s = &mp->servers[i];
10103
10104       if (mp->is_ipv6)
10105         print (vam->ofp,
10106                " Server Table-ID %d, Server Address %U",
10107                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10108       else
10109         print (vam->ofp,
10110                " Server Table-ID %d, Server Address %U",
10111                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10112     }
10113 }
10114
10115 static void vl_api_dhcp_proxy_details_t_handler_json
10116   (vl_api_dhcp_proxy_details_t * mp)
10117 {
10118   vat_main_t *vam = &vat_main;
10119   vat_json_node_t *node = NULL;
10120   u32 i, count = mp->count;
10121   struct in_addr ip4;
10122   struct in6_addr ip6;
10123   vl_api_dhcp_server_t *s;
10124
10125   if (VAT_JSON_ARRAY != vam->json_tree.type)
10126     {
10127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10128       vat_json_init_array (&vam->json_tree);
10129     }
10130   node = vat_json_array_add (&vam->json_tree);
10131
10132   vat_json_init_object (node);
10133   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10134   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10135                              sizeof (mp->vss_type));
10136   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10137                                    mp->vss_vpn_ascii_id);
10138   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10139   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10140
10141   if (mp->is_ipv6)
10142     {
10143       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10144       vat_json_object_add_ip6 (node, "src_address", ip6);
10145     }
10146   else
10147     {
10148       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10149       vat_json_object_add_ip4 (node, "src_address", ip4);
10150     }
10151
10152   for (i = 0; i < count; i++)
10153     {
10154       s = &mp->servers[i];
10155
10156       vat_json_object_add_uint (node, "server-table-id",
10157                                 ntohl (s->server_vrf_id));
10158
10159       if (mp->is_ipv6)
10160         {
10161           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10162           vat_json_object_add_ip4 (node, "src_address", ip4);
10163         }
10164       else
10165         {
10166           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10167           vat_json_object_add_ip6 (node, "server_address", ip6);
10168         }
10169     }
10170 }
10171
10172 static int
10173 api_dhcp_proxy_dump (vat_main_t * vam)
10174 {
10175   unformat_input_t *i = vam->input;
10176   vl_api_control_ping_t *mp_ping;
10177   vl_api_dhcp_proxy_dump_t *mp;
10178   u8 is_ipv6 = 0;
10179   int ret;
10180
10181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10182     {
10183       if (unformat (i, "ipv6"))
10184         is_ipv6 = 1;
10185       else
10186         {
10187           clib_warning ("parse error '%U'", format_unformat_error, i);
10188           return -99;
10189         }
10190     }
10191
10192   M (DHCP_PROXY_DUMP, mp);
10193
10194   mp->is_ip6 = is_ipv6;
10195   S (mp);
10196
10197   /* Use a control ping for synchronization */
10198   MPING (CONTROL_PING, mp_ping);
10199   S (mp_ping);
10200
10201   W (ret);
10202   return ret;
10203 }
10204
10205 static int
10206 api_dhcp_proxy_set_vss (vat_main_t * vam)
10207 {
10208   unformat_input_t *i = vam->input;
10209   vl_api_dhcp_proxy_set_vss_t *mp;
10210   u8 is_ipv6 = 0;
10211   u8 is_add = 1;
10212   u32 tbl_id = ~0;
10213   u8 vss_type = VSS_TYPE_DEFAULT;
10214   u8 *vpn_ascii_id = 0;
10215   u32 oui = 0;
10216   u32 fib_id = 0;
10217   int ret;
10218
10219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (i, "tbl_id %d", &tbl_id))
10222         ;
10223       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10224         vss_type = VSS_TYPE_ASCII;
10225       else if (unformat (i, "fib_id %d", &fib_id))
10226         vss_type = VSS_TYPE_VPN_ID;
10227       else if (unformat (i, "oui %d", &oui))
10228         vss_type = VSS_TYPE_VPN_ID;
10229       else if (unformat (i, "ipv6"))
10230         is_ipv6 = 1;
10231       else if (unformat (i, "del"))
10232         is_add = 0;
10233       else
10234         break;
10235     }
10236
10237   if (tbl_id == ~0)
10238     {
10239       errmsg ("missing tbl_id ");
10240       vec_free (vpn_ascii_id);
10241       return -99;
10242     }
10243
10244   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10245     {
10246       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10247       vec_free (vpn_ascii_id);
10248       return -99;
10249     }
10250
10251   M (DHCP_PROXY_SET_VSS, mp);
10252   mp->tbl_id = ntohl (tbl_id);
10253   mp->vss_type = vss_type;
10254   if (vpn_ascii_id)
10255     {
10256       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10257       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10258     }
10259   mp->vpn_index = ntohl (fib_id);
10260   mp->oui = ntohl (oui);
10261   mp->is_ipv6 = is_ipv6;
10262   mp->is_add = is_add;
10263
10264   S (mp);
10265   W (ret);
10266
10267   vec_free (vpn_ascii_id);
10268   return ret;
10269 }
10270
10271 static int
10272 api_dhcp_client_config (vat_main_t * vam)
10273 {
10274   unformat_input_t *i = vam->input;
10275   vl_api_dhcp_client_config_t *mp;
10276   u32 sw_if_index;
10277   u8 sw_if_index_set = 0;
10278   u8 is_add = 1;
10279   u8 *hostname = 0;
10280   u8 disable_event = 0;
10281   int ret;
10282
10283   /* Parse args required to build the message */
10284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10285     {
10286       if (unformat (i, "del"))
10287         is_add = 0;
10288       else
10289         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10290         sw_if_index_set = 1;
10291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10292         sw_if_index_set = 1;
10293       else if (unformat (i, "hostname %s", &hostname))
10294         ;
10295       else if (unformat (i, "disable_event"))
10296         disable_event = 1;
10297       else
10298         break;
10299     }
10300
10301   if (sw_if_index_set == 0)
10302     {
10303       errmsg ("missing interface name or sw_if_index");
10304       return -99;
10305     }
10306
10307   if (vec_len (hostname) > 63)
10308     {
10309       errmsg ("hostname too long");
10310     }
10311   vec_add1 (hostname, 0);
10312
10313   /* Construct the API message */
10314   M (DHCP_CLIENT_CONFIG, mp);
10315
10316   mp->is_add = is_add;
10317   mp->client.sw_if_index = htonl (sw_if_index);
10318   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10319   vec_free (hostname);
10320   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10321   mp->client.pid = htonl (getpid ());
10322
10323   /* send it... */
10324   S (mp);
10325
10326   /* Wait for a reply, return good/bad news  */
10327   W (ret);
10328   return ret;
10329 }
10330
10331 static int
10332 api_set_ip_flow_hash (vat_main_t * vam)
10333 {
10334   unformat_input_t *i = vam->input;
10335   vl_api_set_ip_flow_hash_t *mp;
10336   u32 vrf_id = 0;
10337   u8 is_ipv6 = 0;
10338   u8 vrf_id_set = 0;
10339   u8 src = 0;
10340   u8 dst = 0;
10341   u8 sport = 0;
10342   u8 dport = 0;
10343   u8 proto = 0;
10344   u8 reverse = 0;
10345   int ret;
10346
10347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10348     {
10349       if (unformat (i, "vrf %d", &vrf_id))
10350         vrf_id_set = 1;
10351       else if (unformat (i, "ipv6"))
10352         is_ipv6 = 1;
10353       else if (unformat (i, "src"))
10354         src = 1;
10355       else if (unformat (i, "dst"))
10356         dst = 1;
10357       else if (unformat (i, "sport"))
10358         sport = 1;
10359       else if (unformat (i, "dport"))
10360         dport = 1;
10361       else if (unformat (i, "proto"))
10362         proto = 1;
10363       else if (unformat (i, "reverse"))
10364         reverse = 1;
10365
10366       else
10367         {
10368           clib_warning ("parse error '%U'", format_unformat_error, i);
10369           return -99;
10370         }
10371     }
10372
10373   if (vrf_id_set == 0)
10374     {
10375       errmsg ("missing vrf id");
10376       return -99;
10377     }
10378
10379   M (SET_IP_FLOW_HASH, mp);
10380   mp->src = src;
10381   mp->dst = dst;
10382   mp->sport = sport;
10383   mp->dport = dport;
10384   mp->proto = proto;
10385   mp->reverse = reverse;
10386   mp->vrf_id = ntohl (vrf_id);
10387   mp->is_ipv6 = is_ipv6;
10388
10389   S (mp);
10390   W (ret);
10391   return ret;
10392 }
10393
10394 static int
10395 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10396 {
10397   unformat_input_t *i = vam->input;
10398   vl_api_sw_interface_ip6_enable_disable_t *mp;
10399   u32 sw_if_index;
10400   u8 sw_if_index_set = 0;
10401   u8 enable = 0;
10402   int ret;
10403
10404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10407         sw_if_index_set = 1;
10408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10409         sw_if_index_set = 1;
10410       else if (unformat (i, "enable"))
10411         enable = 1;
10412       else if (unformat (i, "disable"))
10413         enable = 0;
10414       else
10415         {
10416           clib_warning ("parse error '%U'", format_unformat_error, i);
10417           return -99;
10418         }
10419     }
10420
10421   if (sw_if_index_set == 0)
10422     {
10423       errmsg ("missing interface name or sw_if_index");
10424       return -99;
10425     }
10426
10427   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10428
10429   mp->sw_if_index = ntohl (sw_if_index);
10430   mp->enable = enable;
10431
10432   S (mp);
10433   W (ret);
10434   return ret;
10435 }
10436
10437 static int
10438 api_ip6nd_proxy_add_del (vat_main_t * vam)
10439 {
10440   unformat_input_t *i = vam->input;
10441   vl_api_ip6nd_proxy_add_del_t *mp;
10442   u32 sw_if_index = ~0;
10443   u8 v6_address_set = 0;
10444   ip6_address_t v6address;
10445   u8 is_del = 0;
10446   int ret;
10447
10448   /* Parse args required to build the message */
10449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10452         ;
10453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10454         ;
10455       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10456         v6_address_set = 1;
10457       if (unformat (i, "del"))
10458         is_del = 1;
10459       else
10460         {
10461           clib_warning ("parse error '%U'", format_unformat_error, i);
10462           return -99;
10463         }
10464     }
10465
10466   if (sw_if_index == ~0)
10467     {
10468       errmsg ("missing interface name or sw_if_index");
10469       return -99;
10470     }
10471   if (!v6_address_set)
10472     {
10473       errmsg ("no address set");
10474       return -99;
10475     }
10476
10477   /* Construct the API message */
10478   M (IP6ND_PROXY_ADD_DEL, mp);
10479
10480   mp->is_del = is_del;
10481   mp->sw_if_index = ntohl (sw_if_index);
10482   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10483
10484   /* send it... */
10485   S (mp);
10486
10487   /* Wait for a reply, return good/bad news  */
10488   W (ret);
10489   return ret;
10490 }
10491
10492 static int
10493 api_ip6nd_proxy_dump (vat_main_t * vam)
10494 {
10495   vl_api_ip6nd_proxy_dump_t *mp;
10496   vl_api_control_ping_t *mp_ping;
10497   int ret;
10498
10499   M (IP6ND_PROXY_DUMP, mp);
10500
10501   S (mp);
10502
10503   /* Use a control ping for synchronization */
10504   MPING (CONTROL_PING, mp_ping);
10505   S (mp_ping);
10506
10507   W (ret);
10508   return ret;
10509 }
10510
10511 static void vl_api_ip6nd_proxy_details_t_handler
10512   (vl_api_ip6nd_proxy_details_t * mp)
10513 {
10514   vat_main_t *vam = &vat_main;
10515
10516   print (vam->ofp, "host %U sw_if_index %d",
10517          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10518 }
10519
10520 static void vl_api_ip6nd_proxy_details_t_handler_json
10521   (vl_api_ip6nd_proxy_details_t * mp)
10522 {
10523   vat_main_t *vam = &vat_main;
10524   struct in6_addr ip6;
10525   vat_json_node_t *node = NULL;
10526
10527   if (VAT_JSON_ARRAY != vam->json_tree.type)
10528     {
10529       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10530       vat_json_init_array (&vam->json_tree);
10531     }
10532   node = vat_json_array_add (&vam->json_tree);
10533
10534   vat_json_init_object (node);
10535   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10536
10537   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10538   vat_json_object_add_ip6 (node, "host", ip6);
10539 }
10540
10541 static int
10542 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10543 {
10544   unformat_input_t *i = vam->input;
10545   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10546   u32 sw_if_index;
10547   u8 sw_if_index_set = 0;
10548   u32 address_length = 0;
10549   u8 v6_address_set = 0;
10550   ip6_address_t v6address;
10551   u8 use_default = 0;
10552   u8 no_advertise = 0;
10553   u8 off_link = 0;
10554   u8 no_autoconfig = 0;
10555   u8 no_onlink = 0;
10556   u8 is_no = 0;
10557   u32 val_lifetime = 0;
10558   u32 pref_lifetime = 0;
10559   int ret;
10560
10561   /* Parse args required to build the message */
10562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10565         sw_if_index_set = 1;
10566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10567         sw_if_index_set = 1;
10568       else if (unformat (i, "%U/%d",
10569                          unformat_ip6_address, &v6address, &address_length))
10570         v6_address_set = 1;
10571       else if (unformat (i, "val_life %d", &val_lifetime))
10572         ;
10573       else if (unformat (i, "pref_life %d", &pref_lifetime))
10574         ;
10575       else if (unformat (i, "def"))
10576         use_default = 1;
10577       else if (unformat (i, "noadv"))
10578         no_advertise = 1;
10579       else if (unformat (i, "offl"))
10580         off_link = 1;
10581       else if (unformat (i, "noauto"))
10582         no_autoconfig = 1;
10583       else if (unformat (i, "nolink"))
10584         no_onlink = 1;
10585       else if (unformat (i, "isno"))
10586         is_no = 1;
10587       else
10588         {
10589           clib_warning ("parse error '%U'", format_unformat_error, i);
10590           return -99;
10591         }
10592     }
10593
10594   if (sw_if_index_set == 0)
10595     {
10596       errmsg ("missing interface name or sw_if_index");
10597       return -99;
10598     }
10599   if (!v6_address_set)
10600     {
10601       errmsg ("no address set");
10602       return -99;
10603     }
10604
10605   /* Construct the API message */
10606   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10607
10608   mp->sw_if_index = ntohl (sw_if_index);
10609   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10610   mp->address_length = address_length;
10611   mp->use_default = use_default;
10612   mp->no_advertise = no_advertise;
10613   mp->off_link = off_link;
10614   mp->no_autoconfig = no_autoconfig;
10615   mp->no_onlink = no_onlink;
10616   mp->is_no = is_no;
10617   mp->val_lifetime = ntohl (val_lifetime);
10618   mp->pref_lifetime = ntohl (pref_lifetime);
10619
10620   /* send it... */
10621   S (mp);
10622
10623   /* Wait for a reply, return good/bad news  */
10624   W (ret);
10625   return ret;
10626 }
10627
10628 static int
10629 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10630 {
10631   unformat_input_t *i = vam->input;
10632   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10633   u32 sw_if_index;
10634   u8 sw_if_index_set = 0;
10635   u8 suppress = 0;
10636   u8 managed = 0;
10637   u8 other = 0;
10638   u8 ll_option = 0;
10639   u8 send_unicast = 0;
10640   u8 cease = 0;
10641   u8 is_no = 0;
10642   u8 default_router = 0;
10643   u32 max_interval = 0;
10644   u32 min_interval = 0;
10645   u32 lifetime = 0;
10646   u32 initial_count = 0;
10647   u32 initial_interval = 0;
10648   int ret;
10649
10650
10651   /* Parse args required to build the message */
10652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10653     {
10654       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10655         sw_if_index_set = 1;
10656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10657         sw_if_index_set = 1;
10658       else if (unformat (i, "maxint %d", &max_interval))
10659         ;
10660       else if (unformat (i, "minint %d", &min_interval))
10661         ;
10662       else if (unformat (i, "life %d", &lifetime))
10663         ;
10664       else if (unformat (i, "count %d", &initial_count))
10665         ;
10666       else if (unformat (i, "interval %d", &initial_interval))
10667         ;
10668       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10669         suppress = 1;
10670       else if (unformat (i, "managed"))
10671         managed = 1;
10672       else if (unformat (i, "other"))
10673         other = 1;
10674       else if (unformat (i, "ll"))
10675         ll_option = 1;
10676       else if (unformat (i, "send"))
10677         send_unicast = 1;
10678       else if (unformat (i, "cease"))
10679         cease = 1;
10680       else if (unformat (i, "isno"))
10681         is_no = 1;
10682       else if (unformat (i, "def"))
10683         default_router = 1;
10684       else
10685         {
10686           clib_warning ("parse error '%U'", format_unformat_error, i);
10687           return -99;
10688         }
10689     }
10690
10691   if (sw_if_index_set == 0)
10692     {
10693       errmsg ("missing interface name or sw_if_index");
10694       return -99;
10695     }
10696
10697   /* Construct the API message */
10698   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10699
10700   mp->sw_if_index = ntohl (sw_if_index);
10701   mp->max_interval = ntohl (max_interval);
10702   mp->min_interval = ntohl (min_interval);
10703   mp->lifetime = ntohl (lifetime);
10704   mp->initial_count = ntohl (initial_count);
10705   mp->initial_interval = ntohl (initial_interval);
10706   mp->suppress = suppress;
10707   mp->managed = managed;
10708   mp->other = other;
10709   mp->ll_option = ll_option;
10710   mp->send_unicast = send_unicast;
10711   mp->cease = cease;
10712   mp->is_no = is_no;
10713   mp->default_router = default_router;
10714
10715   /* send it... */
10716   S (mp);
10717
10718   /* Wait for a reply, return good/bad news  */
10719   W (ret);
10720   return ret;
10721 }
10722
10723 static int
10724 api_set_arp_neighbor_limit (vat_main_t * vam)
10725 {
10726   unformat_input_t *i = vam->input;
10727   vl_api_set_arp_neighbor_limit_t *mp;
10728   u32 arp_nbr_limit;
10729   u8 limit_set = 0;
10730   u8 is_ipv6 = 0;
10731   int ret;
10732
10733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10734     {
10735       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10736         limit_set = 1;
10737       else if (unformat (i, "ipv6"))
10738         is_ipv6 = 1;
10739       else
10740         {
10741           clib_warning ("parse error '%U'", format_unformat_error, i);
10742           return -99;
10743         }
10744     }
10745
10746   if (limit_set == 0)
10747     {
10748       errmsg ("missing limit value");
10749       return -99;
10750     }
10751
10752   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10753
10754   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10755   mp->is_ipv6 = is_ipv6;
10756
10757   S (mp);
10758   W (ret);
10759   return ret;
10760 }
10761
10762 static int
10763 api_l2_patch_add_del (vat_main_t * vam)
10764 {
10765   unformat_input_t *i = vam->input;
10766   vl_api_l2_patch_add_del_t *mp;
10767   u32 rx_sw_if_index;
10768   u8 rx_sw_if_index_set = 0;
10769   u32 tx_sw_if_index;
10770   u8 tx_sw_if_index_set = 0;
10771   u8 is_add = 1;
10772   int ret;
10773
10774   /* Parse args required to build the message */
10775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10776     {
10777       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10778         rx_sw_if_index_set = 1;
10779       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10780         tx_sw_if_index_set = 1;
10781       else if (unformat (i, "rx"))
10782         {
10783           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10784             {
10785               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10786                             &rx_sw_if_index))
10787                 rx_sw_if_index_set = 1;
10788             }
10789           else
10790             break;
10791         }
10792       else if (unformat (i, "tx"))
10793         {
10794           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10795             {
10796               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10797                             &tx_sw_if_index))
10798                 tx_sw_if_index_set = 1;
10799             }
10800           else
10801             break;
10802         }
10803       else if (unformat (i, "del"))
10804         is_add = 0;
10805       else
10806         break;
10807     }
10808
10809   if (rx_sw_if_index_set == 0)
10810     {
10811       errmsg ("missing rx interface name or rx_sw_if_index");
10812       return -99;
10813     }
10814
10815   if (tx_sw_if_index_set == 0)
10816     {
10817       errmsg ("missing tx interface name or tx_sw_if_index");
10818       return -99;
10819     }
10820
10821   M (L2_PATCH_ADD_DEL, mp);
10822
10823   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10824   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10825   mp->is_add = is_add;
10826
10827   S (mp);
10828   W (ret);
10829   return ret;
10830 }
10831
10832 u8 is_del;
10833 u8 localsid_addr[16];
10834 u8 end_psp;
10835 u8 behavior;
10836 u32 sw_if_index;
10837 u32 vlan_index;
10838 u32 fib_table;
10839 u8 nh_addr[16];
10840
10841 static int
10842 api_sr_localsid_add_del (vat_main_t * vam)
10843 {
10844   unformat_input_t *i = vam->input;
10845   vl_api_sr_localsid_add_del_t *mp;
10846
10847   u8 is_del;
10848   ip6_address_t localsid;
10849   u8 end_psp = 0;
10850   u8 behavior = ~0;
10851   u32 sw_if_index;
10852   u32 fib_table = ~(u32) 0;
10853   ip6_address_t nh_addr6;
10854   ip4_address_t nh_addr4;
10855   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10856   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10857
10858   bool nexthop_set = 0;
10859
10860   int ret;
10861
10862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10863     {
10864       if (unformat (i, "del"))
10865         is_del = 1;
10866       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10867       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10868         nexthop_set = 1;
10869       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10870         nexthop_set = 1;
10871       else if (unformat (i, "behavior %u", &behavior));
10872       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10873       else if (unformat (i, "fib-table %u", &fib_table));
10874       else if (unformat (i, "end.psp %u", &behavior));
10875       else
10876         break;
10877     }
10878
10879   M (SR_LOCALSID_ADD_DEL, mp);
10880
10881   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10882   if (nexthop_set)
10883     {
10884       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10885       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10886     }
10887   mp->behavior = behavior;
10888   mp->sw_if_index = ntohl (sw_if_index);
10889   mp->fib_table = ntohl (fib_table);
10890   mp->end_psp = end_psp;
10891   mp->is_del = is_del;
10892
10893   S (mp);
10894   W (ret);
10895   return ret;
10896 }
10897
10898 static int
10899 api_ioam_enable (vat_main_t * vam)
10900 {
10901   unformat_input_t *input = vam->input;
10902   vl_api_ioam_enable_t *mp;
10903   u32 id = 0;
10904   int has_trace_option = 0;
10905   int has_pot_option = 0;
10906   int has_seqno_option = 0;
10907   int has_analyse_option = 0;
10908   int ret;
10909
10910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10911     {
10912       if (unformat (input, "trace"))
10913         has_trace_option = 1;
10914       else if (unformat (input, "pot"))
10915         has_pot_option = 1;
10916       else if (unformat (input, "seqno"))
10917         has_seqno_option = 1;
10918       else if (unformat (input, "analyse"))
10919         has_analyse_option = 1;
10920       else
10921         break;
10922     }
10923   M (IOAM_ENABLE, mp);
10924   mp->id = htons (id);
10925   mp->seqno = has_seqno_option;
10926   mp->analyse = has_analyse_option;
10927   mp->pot_enable = has_pot_option;
10928   mp->trace_enable = has_trace_option;
10929
10930   S (mp);
10931   W (ret);
10932   return ret;
10933 }
10934
10935
10936 static int
10937 api_ioam_disable (vat_main_t * vam)
10938 {
10939   vl_api_ioam_disable_t *mp;
10940   int ret;
10941
10942   M (IOAM_DISABLE, mp);
10943   S (mp);
10944   W (ret);
10945   return ret;
10946 }
10947
10948 #define foreach_tcp_proto_field                 \
10949 _(src_port)                                     \
10950 _(dst_port)
10951
10952 #define foreach_udp_proto_field                 \
10953 _(src_port)                                     \
10954 _(dst_port)
10955
10956 #define foreach_ip4_proto_field                 \
10957 _(src_address)                                  \
10958 _(dst_address)                                  \
10959 _(tos)                                          \
10960 _(length)                                       \
10961 _(fragment_id)                                  \
10962 _(ttl)                                          \
10963 _(protocol)                                     \
10964 _(checksum)
10965
10966 typedef struct
10967 {
10968   u16 src_port, dst_port;
10969 } tcpudp_header_t;
10970
10971 #if VPP_API_TEST_BUILTIN == 0
10972 uword
10973 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10974 {
10975   u8 **maskp = va_arg (*args, u8 **);
10976   u8 *mask = 0;
10977   u8 found_something = 0;
10978   tcp_header_t *tcp;
10979
10980 #define _(a) u8 a=0;
10981   foreach_tcp_proto_field;
10982 #undef _
10983
10984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10985     {
10986       if (0);
10987 #define _(a) else if (unformat (input, #a)) a=1;
10988       foreach_tcp_proto_field
10989 #undef _
10990         else
10991         break;
10992     }
10993
10994 #define _(a) found_something += a;
10995   foreach_tcp_proto_field;
10996 #undef _
10997
10998   if (found_something == 0)
10999     return 0;
11000
11001   vec_validate (mask, sizeof (*tcp) - 1);
11002
11003   tcp = (tcp_header_t *) mask;
11004
11005 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11006   foreach_tcp_proto_field;
11007 #undef _
11008
11009   *maskp = mask;
11010   return 1;
11011 }
11012
11013 uword
11014 unformat_udp_mask (unformat_input_t * input, va_list * args)
11015 {
11016   u8 **maskp = va_arg (*args, u8 **);
11017   u8 *mask = 0;
11018   u8 found_something = 0;
11019   udp_header_t *udp;
11020
11021 #define _(a) u8 a=0;
11022   foreach_udp_proto_field;
11023 #undef _
11024
11025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11026     {
11027       if (0);
11028 #define _(a) else if (unformat (input, #a)) a=1;
11029       foreach_udp_proto_field
11030 #undef _
11031         else
11032         break;
11033     }
11034
11035 #define _(a) found_something += a;
11036   foreach_udp_proto_field;
11037 #undef _
11038
11039   if (found_something == 0)
11040     return 0;
11041
11042   vec_validate (mask, sizeof (*udp) - 1);
11043
11044   udp = (udp_header_t *) mask;
11045
11046 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11047   foreach_udp_proto_field;
11048 #undef _
11049
11050   *maskp = mask;
11051   return 1;
11052 }
11053
11054 uword
11055 unformat_l4_mask (unformat_input_t * input, va_list * args)
11056 {
11057   u8 **maskp = va_arg (*args, u8 **);
11058   u16 src_port = 0, dst_port = 0;
11059   tcpudp_header_t *tcpudp;
11060
11061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11062     {
11063       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11064         return 1;
11065       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11066         return 1;
11067       else if (unformat (input, "src_port"))
11068         src_port = 0xFFFF;
11069       else if (unformat (input, "dst_port"))
11070         dst_port = 0xFFFF;
11071       else
11072         return 0;
11073     }
11074
11075   if (!src_port && !dst_port)
11076     return 0;
11077
11078   u8 *mask = 0;
11079   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11080
11081   tcpudp = (tcpudp_header_t *) mask;
11082   tcpudp->src_port = src_port;
11083   tcpudp->dst_port = dst_port;
11084
11085   *maskp = mask;
11086
11087   return 1;
11088 }
11089
11090 uword
11091 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11092 {
11093   u8 **maskp = va_arg (*args, u8 **);
11094   u8 *mask = 0;
11095   u8 found_something = 0;
11096   ip4_header_t *ip;
11097
11098 #define _(a) u8 a=0;
11099   foreach_ip4_proto_field;
11100 #undef _
11101   u8 version = 0;
11102   u8 hdr_length = 0;
11103
11104
11105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11106     {
11107       if (unformat (input, "version"))
11108         version = 1;
11109       else if (unformat (input, "hdr_length"))
11110         hdr_length = 1;
11111       else if (unformat (input, "src"))
11112         src_address = 1;
11113       else if (unformat (input, "dst"))
11114         dst_address = 1;
11115       else if (unformat (input, "proto"))
11116         protocol = 1;
11117
11118 #define _(a) else if (unformat (input, #a)) a=1;
11119       foreach_ip4_proto_field
11120 #undef _
11121         else
11122         break;
11123     }
11124
11125 #define _(a) found_something += a;
11126   foreach_ip4_proto_field;
11127 #undef _
11128
11129   if (found_something == 0)
11130     return 0;
11131
11132   vec_validate (mask, sizeof (*ip) - 1);
11133
11134   ip = (ip4_header_t *) mask;
11135
11136 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11137   foreach_ip4_proto_field;
11138 #undef _
11139
11140   ip->ip_version_and_header_length = 0;
11141
11142   if (version)
11143     ip->ip_version_and_header_length |= 0xF0;
11144
11145   if (hdr_length)
11146     ip->ip_version_and_header_length |= 0x0F;
11147
11148   *maskp = mask;
11149   return 1;
11150 }
11151
11152 #define foreach_ip6_proto_field                 \
11153 _(src_address)                                  \
11154 _(dst_address)                                  \
11155 _(payload_length)                               \
11156 _(hop_limit)                                    \
11157 _(protocol)
11158
11159 uword
11160 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11161 {
11162   u8 **maskp = va_arg (*args, u8 **);
11163   u8 *mask = 0;
11164   u8 found_something = 0;
11165   ip6_header_t *ip;
11166   u32 ip_version_traffic_class_and_flow_label;
11167
11168 #define _(a) u8 a=0;
11169   foreach_ip6_proto_field;
11170 #undef _
11171   u8 version = 0;
11172   u8 traffic_class = 0;
11173   u8 flow_label = 0;
11174
11175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (input, "version"))
11178         version = 1;
11179       else if (unformat (input, "traffic-class"))
11180         traffic_class = 1;
11181       else if (unformat (input, "flow-label"))
11182         flow_label = 1;
11183       else if (unformat (input, "src"))
11184         src_address = 1;
11185       else if (unformat (input, "dst"))
11186         dst_address = 1;
11187       else if (unformat (input, "proto"))
11188         protocol = 1;
11189
11190 #define _(a) else if (unformat (input, #a)) a=1;
11191       foreach_ip6_proto_field
11192 #undef _
11193         else
11194         break;
11195     }
11196
11197 #define _(a) found_something += a;
11198   foreach_ip6_proto_field;
11199 #undef _
11200
11201   if (found_something == 0)
11202     return 0;
11203
11204   vec_validate (mask, sizeof (*ip) - 1);
11205
11206   ip = (ip6_header_t *) mask;
11207
11208 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11209   foreach_ip6_proto_field;
11210 #undef _
11211
11212   ip_version_traffic_class_and_flow_label = 0;
11213
11214   if (version)
11215     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11216
11217   if (traffic_class)
11218     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11219
11220   if (flow_label)
11221     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11222
11223   ip->ip_version_traffic_class_and_flow_label =
11224     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11225
11226   *maskp = mask;
11227   return 1;
11228 }
11229
11230 uword
11231 unformat_l3_mask (unformat_input_t * input, va_list * args)
11232 {
11233   u8 **maskp = va_arg (*args, u8 **);
11234
11235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11236     {
11237       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11238         return 1;
11239       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11240         return 1;
11241       else
11242         break;
11243     }
11244   return 0;
11245 }
11246
11247 uword
11248 unformat_l2_mask (unformat_input_t * input, va_list * args)
11249 {
11250   u8 **maskp = va_arg (*args, u8 **);
11251   u8 *mask = 0;
11252   u8 src = 0;
11253   u8 dst = 0;
11254   u8 proto = 0;
11255   u8 tag1 = 0;
11256   u8 tag2 = 0;
11257   u8 ignore_tag1 = 0;
11258   u8 ignore_tag2 = 0;
11259   u8 cos1 = 0;
11260   u8 cos2 = 0;
11261   u8 dot1q = 0;
11262   u8 dot1ad = 0;
11263   int len = 14;
11264
11265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11266     {
11267       if (unformat (input, "src"))
11268         src = 1;
11269       else if (unformat (input, "dst"))
11270         dst = 1;
11271       else if (unformat (input, "proto"))
11272         proto = 1;
11273       else if (unformat (input, "tag1"))
11274         tag1 = 1;
11275       else if (unformat (input, "tag2"))
11276         tag2 = 1;
11277       else if (unformat (input, "ignore-tag1"))
11278         ignore_tag1 = 1;
11279       else if (unformat (input, "ignore-tag2"))
11280         ignore_tag2 = 1;
11281       else if (unformat (input, "cos1"))
11282         cos1 = 1;
11283       else if (unformat (input, "cos2"))
11284         cos2 = 1;
11285       else if (unformat (input, "dot1q"))
11286         dot1q = 1;
11287       else if (unformat (input, "dot1ad"))
11288         dot1ad = 1;
11289       else
11290         break;
11291     }
11292   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11293        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11294     return 0;
11295
11296   if (tag1 || ignore_tag1 || cos1 || dot1q)
11297     len = 18;
11298   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11299     len = 22;
11300
11301   vec_validate (mask, len - 1);
11302
11303   if (dst)
11304     clib_memset (mask, 0xff, 6);
11305
11306   if (src)
11307     clib_memset (mask + 6, 0xff, 6);
11308
11309   if (tag2 || dot1ad)
11310     {
11311       /* inner vlan tag */
11312       if (tag2)
11313         {
11314           mask[19] = 0xff;
11315           mask[18] = 0x0f;
11316         }
11317       if (cos2)
11318         mask[18] |= 0xe0;
11319       if (proto)
11320         mask[21] = mask[20] = 0xff;
11321       if (tag1)
11322         {
11323           mask[15] = 0xff;
11324           mask[14] = 0x0f;
11325         }
11326       if (cos1)
11327         mask[14] |= 0xe0;
11328       *maskp = mask;
11329       return 1;
11330     }
11331   if (tag1 | dot1q)
11332     {
11333       if (tag1)
11334         {
11335           mask[15] = 0xff;
11336           mask[14] = 0x0f;
11337         }
11338       if (cos1)
11339         mask[14] |= 0xe0;
11340       if (proto)
11341         mask[16] = mask[17] = 0xff;
11342
11343       *maskp = mask;
11344       return 1;
11345     }
11346   if (cos2)
11347     mask[18] |= 0xe0;
11348   if (cos1)
11349     mask[14] |= 0xe0;
11350   if (proto)
11351     mask[12] = mask[13] = 0xff;
11352
11353   *maskp = mask;
11354   return 1;
11355 }
11356
11357 uword
11358 unformat_classify_mask (unformat_input_t * input, va_list * args)
11359 {
11360   u8 **maskp = va_arg (*args, u8 **);
11361   u32 *skipp = va_arg (*args, u32 *);
11362   u32 *matchp = va_arg (*args, u32 *);
11363   u32 match;
11364   u8 *mask = 0;
11365   u8 *l2 = 0;
11366   u8 *l3 = 0;
11367   u8 *l4 = 0;
11368   int i;
11369
11370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11373         ;
11374       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11375         ;
11376       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11377         ;
11378       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11379         ;
11380       else
11381         break;
11382     }
11383
11384   if (l4 && !l3)
11385     {
11386       vec_free (mask);
11387       vec_free (l2);
11388       vec_free (l4);
11389       return 0;
11390     }
11391
11392   if (mask || l2 || l3 || l4)
11393     {
11394       if (l2 || l3 || l4)
11395         {
11396           /* "With a free Ethernet header in every package" */
11397           if (l2 == 0)
11398             vec_validate (l2, 13);
11399           mask = l2;
11400           if (vec_len (l3))
11401             {
11402               vec_append (mask, l3);
11403               vec_free (l3);
11404             }
11405           if (vec_len (l4))
11406             {
11407               vec_append (mask, l4);
11408               vec_free (l4);
11409             }
11410         }
11411
11412       /* Scan forward looking for the first significant mask octet */
11413       for (i = 0; i < vec_len (mask); i++)
11414         if (mask[i])
11415           break;
11416
11417       /* compute (skip, match) params */
11418       *skipp = i / sizeof (u32x4);
11419       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11420
11421       /* Pad mask to an even multiple of the vector size */
11422       while (vec_len (mask) % sizeof (u32x4))
11423         vec_add1 (mask, 0);
11424
11425       match = vec_len (mask) / sizeof (u32x4);
11426
11427       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11428         {
11429           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11430           if (*tmp || *(tmp + 1))
11431             break;
11432           match--;
11433         }
11434       if (match == 0)
11435         clib_warning ("BUG: match 0");
11436
11437       _vec_len (mask) = match * sizeof (u32x4);
11438
11439       *matchp = match;
11440       *maskp = mask;
11441
11442       return 1;
11443     }
11444
11445   return 0;
11446 }
11447 #endif /* VPP_API_TEST_BUILTIN */
11448
11449 #define foreach_l2_next                         \
11450 _(drop, DROP)                                   \
11451 _(ethernet, ETHERNET_INPUT)                     \
11452 _(ip4, IP4_INPUT)                               \
11453 _(ip6, IP6_INPUT)
11454
11455 uword
11456 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11457 {
11458   u32 *miss_next_indexp = va_arg (*args, u32 *);
11459   u32 next_index = 0;
11460   u32 tmp;
11461
11462 #define _(n,N) \
11463   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11464   foreach_l2_next;
11465 #undef _
11466
11467   if (unformat (input, "%d", &tmp))
11468     {
11469       next_index = tmp;
11470       goto out;
11471     }
11472
11473   return 0;
11474
11475 out:
11476   *miss_next_indexp = next_index;
11477   return 1;
11478 }
11479
11480 #define foreach_ip_next                         \
11481 _(drop, DROP)                                   \
11482 _(local, LOCAL)                                 \
11483 _(rewrite, REWRITE)
11484
11485 uword
11486 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11487 {
11488   u32 *miss_next_indexp = va_arg (*args, u32 *);
11489   u32 next_index = 0;
11490   u32 tmp;
11491
11492 #define _(n,N) \
11493   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11494   foreach_ip_next;
11495 #undef _
11496
11497   if (unformat (input, "%d", &tmp))
11498     {
11499       next_index = tmp;
11500       goto out;
11501     }
11502
11503   return 0;
11504
11505 out:
11506   *miss_next_indexp = next_index;
11507   return 1;
11508 }
11509
11510 #define foreach_acl_next                        \
11511 _(deny, DENY)
11512
11513 uword
11514 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11515 {
11516   u32 *miss_next_indexp = va_arg (*args, u32 *);
11517   u32 next_index = 0;
11518   u32 tmp;
11519
11520 #define _(n,N) \
11521   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11522   foreach_acl_next;
11523 #undef _
11524
11525   if (unformat (input, "permit"))
11526     {
11527       next_index = ~0;
11528       goto out;
11529     }
11530   else if (unformat (input, "%d", &tmp))
11531     {
11532       next_index = tmp;
11533       goto out;
11534     }
11535
11536   return 0;
11537
11538 out:
11539   *miss_next_indexp = next_index;
11540   return 1;
11541 }
11542
11543 uword
11544 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11545 {
11546   u32 *r = va_arg (*args, u32 *);
11547
11548   if (unformat (input, "conform-color"))
11549     *r = POLICE_CONFORM;
11550   else if (unformat (input, "exceed-color"))
11551     *r = POLICE_EXCEED;
11552   else
11553     return 0;
11554
11555   return 1;
11556 }
11557
11558 static int
11559 api_classify_add_del_table (vat_main_t * vam)
11560 {
11561   unformat_input_t *i = vam->input;
11562   vl_api_classify_add_del_table_t *mp;
11563
11564   u32 nbuckets = 2;
11565   u32 skip = ~0;
11566   u32 match = ~0;
11567   int is_add = 1;
11568   int del_chain = 0;
11569   u32 table_index = ~0;
11570   u32 next_table_index = ~0;
11571   u32 miss_next_index = ~0;
11572   u32 memory_size = 32 << 20;
11573   u8 *mask = 0;
11574   u32 current_data_flag = 0;
11575   int current_data_offset = 0;
11576   int ret;
11577
11578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (i, "del"))
11581         is_add = 0;
11582       else if (unformat (i, "del-chain"))
11583         {
11584           is_add = 0;
11585           del_chain = 1;
11586         }
11587       else if (unformat (i, "buckets %d", &nbuckets))
11588         ;
11589       else if (unformat (i, "memory_size %d", &memory_size))
11590         ;
11591       else if (unformat (i, "skip %d", &skip))
11592         ;
11593       else if (unformat (i, "match %d", &match))
11594         ;
11595       else if (unformat (i, "table %d", &table_index))
11596         ;
11597       else if (unformat (i, "mask %U", unformat_classify_mask,
11598                          &mask, &skip, &match))
11599         ;
11600       else if (unformat (i, "next-table %d", &next_table_index))
11601         ;
11602       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11603                          &miss_next_index))
11604         ;
11605       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11606                          &miss_next_index))
11607         ;
11608       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11609                          &miss_next_index))
11610         ;
11611       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11612         ;
11613       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11614         ;
11615       else
11616         break;
11617     }
11618
11619   if (is_add && mask == 0)
11620     {
11621       errmsg ("Mask required");
11622       return -99;
11623     }
11624
11625   if (is_add && skip == ~0)
11626     {
11627       errmsg ("skip count required");
11628       return -99;
11629     }
11630
11631   if (is_add && match == ~0)
11632     {
11633       errmsg ("match count required");
11634       return -99;
11635     }
11636
11637   if (!is_add && table_index == ~0)
11638     {
11639       errmsg ("table index required for delete");
11640       return -99;
11641     }
11642
11643   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11644
11645   mp->is_add = is_add;
11646   mp->del_chain = del_chain;
11647   mp->table_index = ntohl (table_index);
11648   mp->nbuckets = ntohl (nbuckets);
11649   mp->memory_size = ntohl (memory_size);
11650   mp->skip_n_vectors = ntohl (skip);
11651   mp->match_n_vectors = ntohl (match);
11652   mp->next_table_index = ntohl (next_table_index);
11653   mp->miss_next_index = ntohl (miss_next_index);
11654   mp->current_data_flag = ntohl (current_data_flag);
11655   mp->current_data_offset = ntohl (current_data_offset);
11656   mp->mask_len = ntohl (vec_len (mask));
11657   clib_memcpy (mp->mask, mask, vec_len (mask));
11658
11659   vec_free (mask);
11660
11661   S (mp);
11662   W (ret);
11663   return ret;
11664 }
11665
11666 #if VPP_API_TEST_BUILTIN == 0
11667 uword
11668 unformat_l4_match (unformat_input_t * input, va_list * args)
11669 {
11670   u8 **matchp = va_arg (*args, u8 **);
11671
11672   u8 *proto_header = 0;
11673   int src_port = 0;
11674   int dst_port = 0;
11675
11676   tcpudp_header_t h;
11677
11678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (input, "src_port %d", &src_port))
11681         ;
11682       else if (unformat (input, "dst_port %d", &dst_port))
11683         ;
11684       else
11685         return 0;
11686     }
11687
11688   h.src_port = clib_host_to_net_u16 (src_port);
11689   h.dst_port = clib_host_to_net_u16 (dst_port);
11690   vec_validate (proto_header, sizeof (h) - 1);
11691   memcpy (proto_header, &h, sizeof (h));
11692
11693   *matchp = proto_header;
11694
11695   return 1;
11696 }
11697
11698 uword
11699 unformat_ip4_match (unformat_input_t * input, va_list * args)
11700 {
11701   u8 **matchp = va_arg (*args, u8 **);
11702   u8 *match = 0;
11703   ip4_header_t *ip;
11704   int version = 0;
11705   u32 version_val;
11706   int hdr_length = 0;
11707   u32 hdr_length_val;
11708   int src = 0, dst = 0;
11709   ip4_address_t src_val, dst_val;
11710   int proto = 0;
11711   u32 proto_val;
11712   int tos = 0;
11713   u32 tos_val;
11714   int length = 0;
11715   u32 length_val;
11716   int fragment_id = 0;
11717   u32 fragment_id_val;
11718   int ttl = 0;
11719   int ttl_val;
11720   int checksum = 0;
11721   u32 checksum_val;
11722
11723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11724     {
11725       if (unformat (input, "version %d", &version_val))
11726         version = 1;
11727       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11728         hdr_length = 1;
11729       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11730         src = 1;
11731       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11732         dst = 1;
11733       else if (unformat (input, "proto %d", &proto_val))
11734         proto = 1;
11735       else if (unformat (input, "tos %d", &tos_val))
11736         tos = 1;
11737       else if (unformat (input, "length %d", &length_val))
11738         length = 1;
11739       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11740         fragment_id = 1;
11741       else if (unformat (input, "ttl %d", &ttl_val))
11742         ttl = 1;
11743       else if (unformat (input, "checksum %d", &checksum_val))
11744         checksum = 1;
11745       else
11746         break;
11747     }
11748
11749   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11750       + ttl + checksum == 0)
11751     return 0;
11752
11753   /*
11754    * Aligned because we use the real comparison functions
11755    */
11756   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11757
11758   ip = (ip4_header_t *) match;
11759
11760   /* These are realistically matched in practice */
11761   if (src)
11762     ip->src_address.as_u32 = src_val.as_u32;
11763
11764   if (dst)
11765     ip->dst_address.as_u32 = dst_val.as_u32;
11766
11767   if (proto)
11768     ip->protocol = proto_val;
11769
11770
11771   /* These are not, but they're included for completeness */
11772   if (version)
11773     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11774
11775   if (hdr_length)
11776     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11777
11778   if (tos)
11779     ip->tos = tos_val;
11780
11781   if (length)
11782     ip->length = clib_host_to_net_u16 (length_val);
11783
11784   if (ttl)
11785     ip->ttl = ttl_val;
11786
11787   if (checksum)
11788     ip->checksum = clib_host_to_net_u16 (checksum_val);
11789
11790   *matchp = match;
11791   return 1;
11792 }
11793
11794 uword
11795 unformat_ip6_match (unformat_input_t * input, va_list * args)
11796 {
11797   u8 **matchp = va_arg (*args, u8 **);
11798   u8 *match = 0;
11799   ip6_header_t *ip;
11800   int version = 0;
11801   u32 version_val;
11802   u8 traffic_class = 0;
11803   u32 traffic_class_val = 0;
11804   u8 flow_label = 0;
11805   u8 flow_label_val;
11806   int src = 0, dst = 0;
11807   ip6_address_t src_val, dst_val;
11808   int proto = 0;
11809   u32 proto_val;
11810   int payload_length = 0;
11811   u32 payload_length_val;
11812   int hop_limit = 0;
11813   int hop_limit_val;
11814   u32 ip_version_traffic_class_and_flow_label;
11815
11816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11817     {
11818       if (unformat (input, "version %d", &version_val))
11819         version = 1;
11820       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11821         traffic_class = 1;
11822       else if (unformat (input, "flow_label %d", &flow_label_val))
11823         flow_label = 1;
11824       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11825         src = 1;
11826       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11827         dst = 1;
11828       else if (unformat (input, "proto %d", &proto_val))
11829         proto = 1;
11830       else if (unformat (input, "payload_length %d", &payload_length_val))
11831         payload_length = 1;
11832       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11833         hop_limit = 1;
11834       else
11835         break;
11836     }
11837
11838   if (version + traffic_class + flow_label + src + dst + proto +
11839       payload_length + hop_limit == 0)
11840     return 0;
11841
11842   /*
11843    * Aligned because we use the real comparison functions
11844    */
11845   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11846
11847   ip = (ip6_header_t *) match;
11848
11849   if (src)
11850     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11851
11852   if (dst)
11853     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11854
11855   if (proto)
11856     ip->protocol = proto_val;
11857
11858   ip_version_traffic_class_and_flow_label = 0;
11859
11860   if (version)
11861     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11862
11863   if (traffic_class)
11864     ip_version_traffic_class_and_flow_label |=
11865       (traffic_class_val & 0xFF) << 20;
11866
11867   if (flow_label)
11868     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11869
11870   ip->ip_version_traffic_class_and_flow_label =
11871     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11872
11873   if (payload_length)
11874     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11875
11876   if (hop_limit)
11877     ip->hop_limit = hop_limit_val;
11878
11879   *matchp = match;
11880   return 1;
11881 }
11882
11883 uword
11884 unformat_l3_match (unformat_input_t * input, va_list * args)
11885 {
11886   u8 **matchp = va_arg (*args, u8 **);
11887
11888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11889     {
11890       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11891         return 1;
11892       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11893         return 1;
11894       else
11895         break;
11896     }
11897   return 0;
11898 }
11899
11900 uword
11901 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11902 {
11903   u8 *tagp = va_arg (*args, u8 *);
11904   u32 tag;
11905
11906   if (unformat (input, "%d", &tag))
11907     {
11908       tagp[0] = (tag >> 8) & 0x0F;
11909       tagp[1] = tag & 0xFF;
11910       return 1;
11911     }
11912
11913   return 0;
11914 }
11915
11916 uword
11917 unformat_l2_match (unformat_input_t * input, va_list * args)
11918 {
11919   u8 **matchp = va_arg (*args, u8 **);
11920   u8 *match = 0;
11921   u8 src = 0;
11922   u8 src_val[6];
11923   u8 dst = 0;
11924   u8 dst_val[6];
11925   u8 proto = 0;
11926   u16 proto_val;
11927   u8 tag1 = 0;
11928   u8 tag1_val[2];
11929   u8 tag2 = 0;
11930   u8 tag2_val[2];
11931   int len = 14;
11932   u8 ignore_tag1 = 0;
11933   u8 ignore_tag2 = 0;
11934   u8 cos1 = 0;
11935   u8 cos2 = 0;
11936   u32 cos1_val = 0;
11937   u32 cos2_val = 0;
11938
11939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11940     {
11941       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11942         src = 1;
11943       else
11944         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11945         dst = 1;
11946       else if (unformat (input, "proto %U",
11947                          unformat_ethernet_type_host_byte_order, &proto_val))
11948         proto = 1;
11949       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11950         tag1 = 1;
11951       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11952         tag2 = 1;
11953       else if (unformat (input, "ignore-tag1"))
11954         ignore_tag1 = 1;
11955       else if (unformat (input, "ignore-tag2"))
11956         ignore_tag2 = 1;
11957       else if (unformat (input, "cos1 %d", &cos1_val))
11958         cos1 = 1;
11959       else if (unformat (input, "cos2 %d", &cos2_val))
11960         cos2 = 1;
11961       else
11962         break;
11963     }
11964   if ((src + dst + proto + tag1 + tag2 +
11965        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11966     return 0;
11967
11968   if (tag1 || ignore_tag1 || cos1)
11969     len = 18;
11970   if (tag2 || ignore_tag2 || cos2)
11971     len = 22;
11972
11973   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11974
11975   if (dst)
11976     clib_memcpy (match, dst_val, 6);
11977
11978   if (src)
11979     clib_memcpy (match + 6, src_val, 6);
11980
11981   if (tag2)
11982     {
11983       /* inner vlan tag */
11984       match[19] = tag2_val[1];
11985       match[18] = tag2_val[0];
11986       if (cos2)
11987         match[18] |= (cos2_val & 0x7) << 5;
11988       if (proto)
11989         {
11990           match[21] = proto_val & 0xff;
11991           match[20] = proto_val >> 8;
11992         }
11993       if (tag1)
11994         {
11995           match[15] = tag1_val[1];
11996           match[14] = tag1_val[0];
11997         }
11998       if (cos1)
11999         match[14] |= (cos1_val & 0x7) << 5;
12000       *matchp = match;
12001       return 1;
12002     }
12003   if (tag1)
12004     {
12005       match[15] = tag1_val[1];
12006       match[14] = tag1_val[0];
12007       if (proto)
12008         {
12009           match[17] = proto_val & 0xff;
12010           match[16] = proto_val >> 8;
12011         }
12012       if (cos1)
12013         match[14] |= (cos1_val & 0x7) << 5;
12014
12015       *matchp = match;
12016       return 1;
12017     }
12018   if (cos2)
12019     match[18] |= (cos2_val & 0x7) << 5;
12020   if (cos1)
12021     match[14] |= (cos1_val & 0x7) << 5;
12022   if (proto)
12023     {
12024       match[13] = proto_val & 0xff;
12025       match[12] = proto_val >> 8;
12026     }
12027
12028   *matchp = match;
12029   return 1;
12030 }
12031
12032 uword
12033 unformat_qos_source (unformat_input_t * input, va_list * args)
12034 {
12035   int *qs = va_arg (*args, int *);
12036
12037   if (unformat (input, "ip"))
12038     *qs = QOS_SOURCE_IP;
12039   else if (unformat (input, "mpls"))
12040     *qs = QOS_SOURCE_MPLS;
12041   else if (unformat (input, "ext"))
12042     *qs = QOS_SOURCE_EXT;
12043   else if (unformat (input, "vlan"))
12044     *qs = QOS_SOURCE_VLAN;
12045   else
12046     return 0;
12047
12048   return 1;
12049 }
12050 #endif
12051
12052 uword
12053 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12054 {
12055   u8 **matchp = va_arg (*args, u8 **);
12056   u32 skip_n_vectors = va_arg (*args, u32);
12057   u32 match_n_vectors = va_arg (*args, u32);
12058
12059   u8 *match = 0;
12060   u8 *l2 = 0;
12061   u8 *l3 = 0;
12062   u8 *l4 = 0;
12063
12064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12065     {
12066       if (unformat (input, "hex %U", unformat_hex_string, &match))
12067         ;
12068       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12069         ;
12070       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12071         ;
12072       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12073         ;
12074       else
12075         break;
12076     }
12077
12078   if (l4 && !l3)
12079     {
12080       vec_free (match);
12081       vec_free (l2);
12082       vec_free (l4);
12083       return 0;
12084     }
12085
12086   if (match || l2 || l3 || l4)
12087     {
12088       if (l2 || l3 || l4)
12089         {
12090           /* "Win a free Ethernet header in every packet" */
12091           if (l2 == 0)
12092             vec_validate_aligned (l2, 13, sizeof (u32x4));
12093           match = l2;
12094           if (vec_len (l3))
12095             {
12096               vec_append_aligned (match, l3, sizeof (u32x4));
12097               vec_free (l3);
12098             }
12099           if (vec_len (l4))
12100             {
12101               vec_append_aligned (match, l4, sizeof (u32x4));
12102               vec_free (l4);
12103             }
12104         }
12105
12106       /* Make sure the vector is big enough even if key is all 0's */
12107       vec_validate_aligned
12108         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12109          sizeof (u32x4));
12110
12111       /* Set size, include skipped vectors */
12112       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12113
12114       *matchp = match;
12115
12116       return 1;
12117     }
12118
12119   return 0;
12120 }
12121
12122 static int
12123 api_classify_add_del_session (vat_main_t * vam)
12124 {
12125   unformat_input_t *i = vam->input;
12126   vl_api_classify_add_del_session_t *mp;
12127   int is_add = 1;
12128   u32 table_index = ~0;
12129   u32 hit_next_index = ~0;
12130   u32 opaque_index = ~0;
12131   u8 *match = 0;
12132   i32 advance = 0;
12133   u32 skip_n_vectors = 0;
12134   u32 match_n_vectors = 0;
12135   u32 action = 0;
12136   u32 metadata = 0;
12137   int ret;
12138
12139   /*
12140    * Warning: you have to supply skip_n and match_n
12141    * because the API client cant simply look at the classify
12142    * table object.
12143    */
12144
12145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12146     {
12147       if (unformat (i, "del"))
12148         is_add = 0;
12149       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12150                          &hit_next_index))
12151         ;
12152       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12153                          &hit_next_index))
12154         ;
12155       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12156                          &hit_next_index))
12157         ;
12158       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12159         ;
12160       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12161         ;
12162       else if (unformat (i, "opaque-index %d", &opaque_index))
12163         ;
12164       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12165         ;
12166       else if (unformat (i, "match_n %d", &match_n_vectors))
12167         ;
12168       else if (unformat (i, "match %U", api_unformat_classify_match,
12169                          &match, skip_n_vectors, match_n_vectors))
12170         ;
12171       else if (unformat (i, "advance %d", &advance))
12172         ;
12173       else if (unformat (i, "table-index %d", &table_index))
12174         ;
12175       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12176         action = 1;
12177       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12178         action = 2;
12179       else if (unformat (i, "action %d", &action))
12180         ;
12181       else if (unformat (i, "metadata %d", &metadata))
12182         ;
12183       else
12184         break;
12185     }
12186
12187   if (table_index == ~0)
12188     {
12189       errmsg ("Table index required");
12190       return -99;
12191     }
12192
12193   if (is_add && match == 0)
12194     {
12195       errmsg ("Match value required");
12196       return -99;
12197     }
12198
12199   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12200
12201   mp->is_add = is_add;
12202   mp->table_index = ntohl (table_index);
12203   mp->hit_next_index = ntohl (hit_next_index);
12204   mp->opaque_index = ntohl (opaque_index);
12205   mp->advance = ntohl (advance);
12206   mp->action = action;
12207   mp->metadata = ntohl (metadata);
12208   mp->match_len = ntohl (vec_len (match));
12209   clib_memcpy (mp->match, match, vec_len (match));
12210   vec_free (match);
12211
12212   S (mp);
12213   W (ret);
12214   return ret;
12215 }
12216
12217 static int
12218 api_classify_set_interface_ip_table (vat_main_t * vam)
12219 {
12220   unformat_input_t *i = vam->input;
12221   vl_api_classify_set_interface_ip_table_t *mp;
12222   u32 sw_if_index;
12223   int sw_if_index_set;
12224   u32 table_index = ~0;
12225   u8 is_ipv6 = 0;
12226   int ret;
12227
12228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12229     {
12230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12231         sw_if_index_set = 1;
12232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12233         sw_if_index_set = 1;
12234       else if (unformat (i, "table %d", &table_index))
12235         ;
12236       else
12237         {
12238           clib_warning ("parse error '%U'", format_unformat_error, i);
12239           return -99;
12240         }
12241     }
12242
12243   if (sw_if_index_set == 0)
12244     {
12245       errmsg ("missing interface name or sw_if_index");
12246       return -99;
12247     }
12248
12249
12250   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12251
12252   mp->sw_if_index = ntohl (sw_if_index);
12253   mp->table_index = ntohl (table_index);
12254   mp->is_ipv6 = is_ipv6;
12255
12256   S (mp);
12257   W (ret);
12258   return ret;
12259 }
12260
12261 static int
12262 api_classify_set_interface_l2_tables (vat_main_t * vam)
12263 {
12264   unformat_input_t *i = vam->input;
12265   vl_api_classify_set_interface_l2_tables_t *mp;
12266   u32 sw_if_index;
12267   int sw_if_index_set;
12268   u32 ip4_table_index = ~0;
12269   u32 ip6_table_index = ~0;
12270   u32 other_table_index = ~0;
12271   u32 is_input = 1;
12272   int ret;
12273
12274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12275     {
12276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12277         sw_if_index_set = 1;
12278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12279         sw_if_index_set = 1;
12280       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12281         ;
12282       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12283         ;
12284       else if (unformat (i, "other-table %d", &other_table_index))
12285         ;
12286       else if (unformat (i, "is-input %d", &is_input))
12287         ;
12288       else
12289         {
12290           clib_warning ("parse error '%U'", format_unformat_error, i);
12291           return -99;
12292         }
12293     }
12294
12295   if (sw_if_index_set == 0)
12296     {
12297       errmsg ("missing interface name or sw_if_index");
12298       return -99;
12299     }
12300
12301
12302   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12303
12304   mp->sw_if_index = ntohl (sw_if_index);
12305   mp->ip4_table_index = ntohl (ip4_table_index);
12306   mp->ip6_table_index = ntohl (ip6_table_index);
12307   mp->other_table_index = ntohl (other_table_index);
12308   mp->is_input = (u8) is_input;
12309
12310   S (mp);
12311   W (ret);
12312   return ret;
12313 }
12314
12315 static int
12316 api_set_ipfix_exporter (vat_main_t * vam)
12317 {
12318   unformat_input_t *i = vam->input;
12319   vl_api_set_ipfix_exporter_t *mp;
12320   ip4_address_t collector_address;
12321   u8 collector_address_set = 0;
12322   u32 collector_port = ~0;
12323   ip4_address_t src_address;
12324   u8 src_address_set = 0;
12325   u32 vrf_id = ~0;
12326   u32 path_mtu = ~0;
12327   u32 template_interval = ~0;
12328   u8 udp_checksum = 0;
12329   int ret;
12330
12331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12332     {
12333       if (unformat (i, "collector_address %U", unformat_ip4_address,
12334                     &collector_address))
12335         collector_address_set = 1;
12336       else if (unformat (i, "collector_port %d", &collector_port))
12337         ;
12338       else if (unformat (i, "src_address %U", unformat_ip4_address,
12339                          &src_address))
12340         src_address_set = 1;
12341       else if (unformat (i, "vrf_id %d", &vrf_id))
12342         ;
12343       else if (unformat (i, "path_mtu %d", &path_mtu))
12344         ;
12345       else if (unformat (i, "template_interval %d", &template_interval))
12346         ;
12347       else if (unformat (i, "udp_checksum"))
12348         udp_checksum = 1;
12349       else
12350         break;
12351     }
12352
12353   if (collector_address_set == 0)
12354     {
12355       errmsg ("collector_address required");
12356       return -99;
12357     }
12358
12359   if (src_address_set == 0)
12360     {
12361       errmsg ("src_address required");
12362       return -99;
12363     }
12364
12365   M (SET_IPFIX_EXPORTER, mp);
12366
12367   memcpy (mp->collector_address, collector_address.data,
12368           sizeof (collector_address.data));
12369   mp->collector_port = htons ((u16) collector_port);
12370   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12371   mp->vrf_id = htonl (vrf_id);
12372   mp->path_mtu = htonl (path_mtu);
12373   mp->template_interval = htonl (template_interval);
12374   mp->udp_checksum = udp_checksum;
12375
12376   S (mp);
12377   W (ret);
12378   return ret;
12379 }
12380
12381 static int
12382 api_set_ipfix_classify_stream (vat_main_t * vam)
12383 {
12384   unformat_input_t *i = vam->input;
12385   vl_api_set_ipfix_classify_stream_t *mp;
12386   u32 domain_id = 0;
12387   u32 src_port = UDP_DST_PORT_ipfix;
12388   int ret;
12389
12390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12391     {
12392       if (unformat (i, "domain %d", &domain_id))
12393         ;
12394       else if (unformat (i, "src_port %d", &src_port))
12395         ;
12396       else
12397         {
12398           errmsg ("unknown input `%U'", format_unformat_error, i);
12399           return -99;
12400         }
12401     }
12402
12403   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12404
12405   mp->domain_id = htonl (domain_id);
12406   mp->src_port = htons ((u16) src_port);
12407
12408   S (mp);
12409   W (ret);
12410   return ret;
12411 }
12412
12413 static int
12414 api_ipfix_classify_table_add_del (vat_main_t * vam)
12415 {
12416   unformat_input_t *i = vam->input;
12417   vl_api_ipfix_classify_table_add_del_t *mp;
12418   int is_add = -1;
12419   u32 classify_table_index = ~0;
12420   u8 ip_version = 0;
12421   u8 transport_protocol = 255;
12422   int ret;
12423
12424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12425     {
12426       if (unformat (i, "add"))
12427         is_add = 1;
12428       else if (unformat (i, "del"))
12429         is_add = 0;
12430       else if (unformat (i, "table %d", &classify_table_index))
12431         ;
12432       else if (unformat (i, "ip4"))
12433         ip_version = 4;
12434       else if (unformat (i, "ip6"))
12435         ip_version = 6;
12436       else if (unformat (i, "tcp"))
12437         transport_protocol = 6;
12438       else if (unformat (i, "udp"))
12439         transport_protocol = 17;
12440       else
12441         {
12442           errmsg ("unknown input `%U'", format_unformat_error, i);
12443           return -99;
12444         }
12445     }
12446
12447   if (is_add == -1)
12448     {
12449       errmsg ("expecting: add|del");
12450       return -99;
12451     }
12452   if (classify_table_index == ~0)
12453     {
12454       errmsg ("classifier table not specified");
12455       return -99;
12456     }
12457   if (ip_version == 0)
12458     {
12459       errmsg ("IP version not specified");
12460       return -99;
12461     }
12462
12463   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12464
12465   mp->is_add = is_add;
12466   mp->table_id = htonl (classify_table_index);
12467   mp->ip_version = ip_version;
12468   mp->transport_protocol = transport_protocol;
12469
12470   S (mp);
12471   W (ret);
12472   return ret;
12473 }
12474
12475 static int
12476 api_get_node_index (vat_main_t * vam)
12477 {
12478   unformat_input_t *i = vam->input;
12479   vl_api_get_node_index_t *mp;
12480   u8 *name = 0;
12481   int ret;
12482
12483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12484     {
12485       if (unformat (i, "node %s", &name))
12486         ;
12487       else
12488         break;
12489     }
12490   if (name == 0)
12491     {
12492       errmsg ("node name required");
12493       return -99;
12494     }
12495   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12496     {
12497       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12498       return -99;
12499     }
12500
12501   M (GET_NODE_INDEX, mp);
12502   clib_memcpy (mp->node_name, name, vec_len (name));
12503   vec_free (name);
12504
12505   S (mp);
12506   W (ret);
12507   return ret;
12508 }
12509
12510 static int
12511 api_get_next_index (vat_main_t * vam)
12512 {
12513   unformat_input_t *i = vam->input;
12514   vl_api_get_next_index_t *mp;
12515   u8 *node_name = 0, *next_node_name = 0;
12516   int ret;
12517
12518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12519     {
12520       if (unformat (i, "node-name %s", &node_name))
12521         ;
12522       else if (unformat (i, "next-node-name %s", &next_node_name))
12523         break;
12524     }
12525
12526   if (node_name == 0)
12527     {
12528       errmsg ("node name required");
12529       return -99;
12530     }
12531   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12532     {
12533       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12534       return -99;
12535     }
12536
12537   if (next_node_name == 0)
12538     {
12539       errmsg ("next node name required");
12540       return -99;
12541     }
12542   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12543     {
12544       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12545       return -99;
12546     }
12547
12548   M (GET_NEXT_INDEX, mp);
12549   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12550   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12551   vec_free (node_name);
12552   vec_free (next_node_name);
12553
12554   S (mp);
12555   W (ret);
12556   return ret;
12557 }
12558
12559 static int
12560 api_add_node_next (vat_main_t * vam)
12561 {
12562   unformat_input_t *i = vam->input;
12563   vl_api_add_node_next_t *mp;
12564   u8 *name = 0;
12565   u8 *next = 0;
12566   int ret;
12567
12568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12569     {
12570       if (unformat (i, "node %s", &name))
12571         ;
12572       else if (unformat (i, "next %s", &next))
12573         ;
12574       else
12575         break;
12576     }
12577   if (name == 0)
12578     {
12579       errmsg ("node name required");
12580       return -99;
12581     }
12582   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12583     {
12584       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12585       return -99;
12586     }
12587   if (next == 0)
12588     {
12589       errmsg ("next node required");
12590       return -99;
12591     }
12592   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12593     {
12594       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12595       return -99;
12596     }
12597
12598   M (ADD_NODE_NEXT, mp);
12599   clib_memcpy (mp->node_name, name, vec_len (name));
12600   clib_memcpy (mp->next_name, next, vec_len (next));
12601   vec_free (name);
12602   vec_free (next);
12603
12604   S (mp);
12605   W (ret);
12606   return ret;
12607 }
12608
12609 static int
12610 api_l2tpv3_create_tunnel (vat_main_t * vam)
12611 {
12612   unformat_input_t *i = vam->input;
12613   ip6_address_t client_address, our_address;
12614   int client_address_set = 0;
12615   int our_address_set = 0;
12616   u32 local_session_id = 0;
12617   u32 remote_session_id = 0;
12618   u64 local_cookie = 0;
12619   u64 remote_cookie = 0;
12620   u8 l2_sublayer_present = 0;
12621   vl_api_l2tpv3_create_tunnel_t *mp;
12622   int ret;
12623
12624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12625     {
12626       if (unformat (i, "client_address %U", unformat_ip6_address,
12627                     &client_address))
12628         client_address_set = 1;
12629       else if (unformat (i, "our_address %U", unformat_ip6_address,
12630                          &our_address))
12631         our_address_set = 1;
12632       else if (unformat (i, "local_session_id %d", &local_session_id))
12633         ;
12634       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12635         ;
12636       else if (unformat (i, "local_cookie %lld", &local_cookie))
12637         ;
12638       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12639         ;
12640       else if (unformat (i, "l2-sublayer-present"))
12641         l2_sublayer_present = 1;
12642       else
12643         break;
12644     }
12645
12646   if (client_address_set == 0)
12647     {
12648       errmsg ("client_address required");
12649       return -99;
12650     }
12651
12652   if (our_address_set == 0)
12653     {
12654       errmsg ("our_address required");
12655       return -99;
12656     }
12657
12658   M (L2TPV3_CREATE_TUNNEL, mp);
12659
12660   clib_memcpy (mp->client_address, client_address.as_u8,
12661                sizeof (mp->client_address));
12662
12663   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12664
12665   mp->local_session_id = ntohl (local_session_id);
12666   mp->remote_session_id = ntohl (remote_session_id);
12667   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12668   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12669   mp->l2_sublayer_present = l2_sublayer_present;
12670   mp->is_ipv6 = 1;
12671
12672   S (mp);
12673   W (ret);
12674   return ret;
12675 }
12676
12677 static int
12678 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12679 {
12680   unformat_input_t *i = vam->input;
12681   u32 sw_if_index;
12682   u8 sw_if_index_set = 0;
12683   u64 new_local_cookie = 0;
12684   u64 new_remote_cookie = 0;
12685   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12686   int ret;
12687
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12691         sw_if_index_set = 1;
12692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12693         sw_if_index_set = 1;
12694       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12695         ;
12696       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12697         ;
12698       else
12699         break;
12700     }
12701
12702   if (sw_if_index_set == 0)
12703     {
12704       errmsg ("missing interface name or sw_if_index");
12705       return -99;
12706     }
12707
12708   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12709
12710   mp->sw_if_index = ntohl (sw_if_index);
12711   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12712   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12713
12714   S (mp);
12715   W (ret);
12716   return ret;
12717 }
12718
12719 static int
12720 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12721 {
12722   unformat_input_t *i = vam->input;
12723   vl_api_l2tpv3_interface_enable_disable_t *mp;
12724   u32 sw_if_index;
12725   u8 sw_if_index_set = 0;
12726   u8 enable_disable = 1;
12727   int ret;
12728
12729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12730     {
12731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12732         sw_if_index_set = 1;
12733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12734         sw_if_index_set = 1;
12735       else if (unformat (i, "enable"))
12736         enable_disable = 1;
12737       else if (unformat (i, "disable"))
12738         enable_disable = 0;
12739       else
12740         break;
12741     }
12742
12743   if (sw_if_index_set == 0)
12744     {
12745       errmsg ("missing interface name or sw_if_index");
12746       return -99;
12747     }
12748
12749   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12750
12751   mp->sw_if_index = ntohl (sw_if_index);
12752   mp->enable_disable = enable_disable;
12753
12754   S (mp);
12755   W (ret);
12756   return ret;
12757 }
12758
12759 static int
12760 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12761 {
12762   unformat_input_t *i = vam->input;
12763   vl_api_l2tpv3_set_lookup_key_t *mp;
12764   u8 key = ~0;
12765   int ret;
12766
12767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12768     {
12769       if (unformat (i, "lookup_v6_src"))
12770         key = L2T_LOOKUP_SRC_ADDRESS;
12771       else if (unformat (i, "lookup_v6_dst"))
12772         key = L2T_LOOKUP_DST_ADDRESS;
12773       else if (unformat (i, "lookup_session_id"))
12774         key = L2T_LOOKUP_SESSION_ID;
12775       else
12776         break;
12777     }
12778
12779   if (key == (u8) ~ 0)
12780     {
12781       errmsg ("l2tp session lookup key unset");
12782       return -99;
12783     }
12784
12785   M (L2TPV3_SET_LOOKUP_KEY, mp);
12786
12787   mp->key = key;
12788
12789   S (mp);
12790   W (ret);
12791   return ret;
12792 }
12793
12794 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12795   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12796 {
12797   vat_main_t *vam = &vat_main;
12798
12799   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12800          format_ip6_address, mp->our_address,
12801          format_ip6_address, mp->client_address,
12802          clib_net_to_host_u32 (mp->sw_if_index));
12803
12804   print (vam->ofp,
12805          "   local cookies %016llx %016llx remote cookie %016llx",
12806          clib_net_to_host_u64 (mp->local_cookie[0]),
12807          clib_net_to_host_u64 (mp->local_cookie[1]),
12808          clib_net_to_host_u64 (mp->remote_cookie));
12809
12810   print (vam->ofp, "   local session-id %d remote session-id %d",
12811          clib_net_to_host_u32 (mp->local_session_id),
12812          clib_net_to_host_u32 (mp->remote_session_id));
12813
12814   print (vam->ofp, "   l2 specific sublayer %s\n",
12815          mp->l2_sublayer_present ? "preset" : "absent");
12816
12817 }
12818
12819 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12820   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12821 {
12822   vat_main_t *vam = &vat_main;
12823   vat_json_node_t *node = NULL;
12824   struct in6_addr addr;
12825
12826   if (VAT_JSON_ARRAY != vam->json_tree.type)
12827     {
12828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12829       vat_json_init_array (&vam->json_tree);
12830     }
12831   node = vat_json_array_add (&vam->json_tree);
12832
12833   vat_json_init_object (node);
12834
12835   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12836   vat_json_object_add_ip6 (node, "our_address", addr);
12837   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12838   vat_json_object_add_ip6 (node, "client_address", addr);
12839
12840   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12841   vat_json_init_array (lc);
12842   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12843   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12844   vat_json_object_add_uint (node, "remote_cookie",
12845                             clib_net_to_host_u64 (mp->remote_cookie));
12846
12847   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12848   vat_json_object_add_uint (node, "local_session_id",
12849                             clib_net_to_host_u32 (mp->local_session_id));
12850   vat_json_object_add_uint (node, "remote_session_id",
12851                             clib_net_to_host_u32 (mp->remote_session_id));
12852   vat_json_object_add_string_copy (node, "l2_sublayer",
12853                                    mp->l2_sublayer_present ? (u8 *) "present"
12854                                    : (u8 *) "absent");
12855 }
12856
12857 static int
12858 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12859 {
12860   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12861   vl_api_control_ping_t *mp_ping;
12862   int ret;
12863
12864   /* Get list of l2tpv3-tunnel interfaces */
12865   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12866   S (mp);
12867
12868   /* Use a control ping for synchronization */
12869   MPING (CONTROL_PING, mp_ping);
12870   S (mp_ping);
12871
12872   W (ret);
12873   return ret;
12874 }
12875
12876
12877 static void vl_api_sw_interface_tap_details_t_handler
12878   (vl_api_sw_interface_tap_details_t * mp)
12879 {
12880   vat_main_t *vam = &vat_main;
12881
12882   print (vam->ofp, "%-16s %d",
12883          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12884 }
12885
12886 static void vl_api_sw_interface_tap_details_t_handler_json
12887   (vl_api_sw_interface_tap_details_t * mp)
12888 {
12889   vat_main_t *vam = &vat_main;
12890   vat_json_node_t *node = NULL;
12891
12892   if (VAT_JSON_ARRAY != vam->json_tree.type)
12893     {
12894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12895       vat_json_init_array (&vam->json_tree);
12896     }
12897   node = vat_json_array_add (&vam->json_tree);
12898
12899   vat_json_init_object (node);
12900   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12901   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12902 }
12903
12904 static int
12905 api_sw_interface_tap_dump (vat_main_t * vam)
12906 {
12907   vl_api_sw_interface_tap_dump_t *mp;
12908   vl_api_control_ping_t *mp_ping;
12909   int ret;
12910
12911   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12912   /* Get list of tap interfaces */
12913   M (SW_INTERFACE_TAP_DUMP, mp);
12914   S (mp);
12915
12916   /* Use a control ping for synchronization */
12917   MPING (CONTROL_PING, mp_ping);
12918   S (mp_ping);
12919
12920   W (ret);
12921   return ret;
12922 }
12923
12924 static void vl_api_sw_interface_tap_v2_details_t_handler
12925   (vl_api_sw_interface_tap_v2_details_t * mp)
12926 {
12927   vat_main_t *vam = &vat_main;
12928
12929   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12930                     mp->host_ip4_prefix_len);
12931   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12932                     mp->host_ip6_prefix_len);
12933
12934   print (vam->ofp,
12935          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12936          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12937          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12938          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12939          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12940
12941   vec_free (ip4);
12942   vec_free (ip6);
12943 }
12944
12945 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12946   (vl_api_sw_interface_tap_v2_details_t * mp)
12947 {
12948   vat_main_t *vam = &vat_main;
12949   vat_json_node_t *node = NULL;
12950
12951   if (VAT_JSON_ARRAY != vam->json_tree.type)
12952     {
12953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12954       vat_json_init_array (&vam->json_tree);
12955     }
12956   node = vat_json_array_add (&vam->json_tree);
12957
12958   vat_json_init_object (node);
12959   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12960   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12961   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12962   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12963   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12964   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12965   vat_json_object_add_string_copy (node, "host_mac_addr",
12966                                    format (0, "%U", format_ethernet_address,
12967                                            &mp->host_mac_addr));
12968   vat_json_object_add_string_copy (node, "host_namespace",
12969                                    mp->host_namespace);
12970   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12971   vat_json_object_add_string_copy (node, "host_ip4_addr",
12972                                    format (0, "%U/%d", format_ip4_address,
12973                                            mp->host_ip4_addr,
12974                                            mp->host_ip4_prefix_len));
12975   vat_json_object_add_string_copy (node, "host_ip6_addr",
12976                                    format (0, "%U/%d", format_ip6_address,
12977                                            mp->host_ip6_addr,
12978                                            mp->host_ip6_prefix_len));
12979
12980 }
12981
12982 static int
12983 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12984 {
12985   vl_api_sw_interface_tap_v2_dump_t *mp;
12986   vl_api_control_ping_t *mp_ping;
12987   int ret;
12988
12989   print (vam->ofp,
12990          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12991          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12992          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12993          "host_ip6_addr");
12994
12995   /* Get list of tap interfaces */
12996   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12997   S (mp);
12998
12999   /* Use a control ping for synchronization */
13000   MPING (CONTROL_PING, mp_ping);
13001   S (mp_ping);
13002
13003   W (ret);
13004   return ret;
13005 }
13006
13007 static void vl_api_sw_interface_virtio_pci_details_t_handler
13008   (vl_api_sw_interface_virtio_pci_details_t * mp)
13009 {
13010   vat_main_t *vam = &vat_main;
13011
13012   typedef union
13013   {
13014     struct
13015     {
13016       u16 domain;
13017       u8 bus;
13018       u8 slot:5;
13019       u8 function:3;
13020     };
13021     u32 as_u32;
13022   } pci_addr_t;
13023   pci_addr_t addr;
13024   addr.as_u32 = ntohl (mp->pci_addr);
13025   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
13026                          addr.slot, addr.function);
13027
13028   print (vam->ofp,
13029          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
13030          pci_addr, ntohl (mp->sw_if_index),
13031          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13032          format_ethernet_address, mp->mac_addr,
13033          clib_net_to_host_u64 (mp->features));
13034   vec_free (pci_addr);
13035 }
13036
13037 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
13038   (vl_api_sw_interface_virtio_pci_details_t * mp)
13039 {
13040   vat_main_t *vam = &vat_main;
13041   vat_json_node_t *node = NULL;
13042
13043   if (VAT_JSON_ARRAY != vam->json_tree.type)
13044     {
13045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13046       vat_json_init_array (&vam->json_tree);
13047     }
13048   node = vat_json_array_add (&vam->json_tree);
13049
13050   vat_json_init_object (node);
13051   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
13052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13053   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13054   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13055   vat_json_object_add_uint (node, "features",
13056                             clib_net_to_host_u64 (mp->features));
13057   vat_json_object_add_string_copy (node, "mac_addr",
13058                                    format (0, "%U", format_ethernet_address,
13059                                            &mp->mac_addr));
13060 }
13061
13062 static int
13063 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
13064 {
13065   vl_api_sw_interface_virtio_pci_dump_t *mp;
13066   vl_api_control_ping_t *mp_ping;
13067   int ret;
13068
13069   print (vam->ofp,
13070          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
13071          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
13072          "mac_addr", "features");
13073
13074   /* Get list of tap interfaces */
13075   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
13076   S (mp);
13077
13078   /* Use a control ping for synchronization */
13079   MPING (CONTROL_PING, mp_ping);
13080   S (mp_ping);
13081
13082   W (ret);
13083   return ret;
13084 }
13085
13086 static int
13087 api_vxlan_offload_rx (vat_main_t * vam)
13088 {
13089   unformat_input_t *line_input = vam->input;
13090   vl_api_vxlan_offload_rx_t *mp;
13091   u32 hw_if_index = ~0, rx_if_index = ~0;
13092   u8 is_add = 1;
13093   int ret;
13094
13095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13096     {
13097       if (unformat (line_input, "del"))
13098         is_add = 0;
13099       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13100                          &hw_if_index))
13101         ;
13102       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13103         ;
13104       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13105                          &rx_if_index))
13106         ;
13107       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13108         ;
13109       else
13110         {
13111           errmsg ("parse error '%U'", format_unformat_error, line_input);
13112           return -99;
13113         }
13114     }
13115
13116   if (hw_if_index == ~0)
13117     {
13118       errmsg ("no hw interface");
13119       return -99;
13120     }
13121
13122   if (rx_if_index == ~0)
13123     {
13124       errmsg ("no rx tunnel");
13125       return -99;
13126     }
13127
13128   M (VXLAN_OFFLOAD_RX, mp);
13129
13130   mp->hw_if_index = ntohl (hw_if_index);
13131   mp->sw_if_index = ntohl (rx_if_index);
13132   mp->enable = is_add;
13133
13134   S (mp);
13135   W (ret);
13136   return ret;
13137 }
13138
13139 static uword unformat_vxlan_decap_next
13140   (unformat_input_t * input, va_list * args)
13141 {
13142   u32 *result = va_arg (*args, u32 *);
13143   u32 tmp;
13144
13145   if (unformat (input, "l2"))
13146     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13147   else if (unformat (input, "%d", &tmp))
13148     *result = tmp;
13149   else
13150     return 0;
13151   return 1;
13152 }
13153
13154 static int
13155 api_vxlan_add_del_tunnel (vat_main_t * vam)
13156 {
13157   unformat_input_t *line_input = vam->input;
13158   vl_api_vxlan_add_del_tunnel_t *mp;
13159   ip46_address_t src, dst;
13160   u8 is_add = 1;
13161   u8 ipv4_set = 0, ipv6_set = 0;
13162   u8 src_set = 0;
13163   u8 dst_set = 0;
13164   u8 grp_set = 0;
13165   u32 instance = ~0;
13166   u32 mcast_sw_if_index = ~0;
13167   u32 encap_vrf_id = 0;
13168   u32 decap_next_index = ~0;
13169   u32 vni = 0;
13170   int ret;
13171
13172   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13173   clib_memset (&src, 0, sizeof src);
13174   clib_memset (&dst, 0, sizeof dst);
13175
13176   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13177     {
13178       if (unformat (line_input, "del"))
13179         is_add = 0;
13180       else if (unformat (line_input, "instance %d", &instance))
13181         ;
13182       else
13183         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13184         {
13185           ipv4_set = 1;
13186           src_set = 1;
13187         }
13188       else
13189         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13190         {
13191           ipv4_set = 1;
13192           dst_set = 1;
13193         }
13194       else
13195         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13196         {
13197           ipv6_set = 1;
13198           src_set = 1;
13199         }
13200       else
13201         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13202         {
13203           ipv6_set = 1;
13204           dst_set = 1;
13205         }
13206       else if (unformat (line_input, "group %U %U",
13207                          unformat_ip4_address, &dst.ip4,
13208                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13209         {
13210           grp_set = dst_set = 1;
13211           ipv4_set = 1;
13212         }
13213       else if (unformat (line_input, "group %U",
13214                          unformat_ip4_address, &dst.ip4))
13215         {
13216           grp_set = dst_set = 1;
13217           ipv4_set = 1;
13218         }
13219       else if (unformat (line_input, "group %U %U",
13220                          unformat_ip6_address, &dst.ip6,
13221                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13222         {
13223           grp_set = dst_set = 1;
13224           ipv6_set = 1;
13225         }
13226       else if (unformat (line_input, "group %U",
13227                          unformat_ip6_address, &dst.ip6))
13228         {
13229           grp_set = dst_set = 1;
13230           ipv6_set = 1;
13231         }
13232       else
13233         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13234         ;
13235       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13236         ;
13237       else if (unformat (line_input, "decap-next %U",
13238                          unformat_vxlan_decap_next, &decap_next_index))
13239         ;
13240       else if (unformat (line_input, "vni %d", &vni))
13241         ;
13242       else
13243         {
13244           errmsg ("parse error '%U'", format_unformat_error, line_input);
13245           return -99;
13246         }
13247     }
13248
13249   if (src_set == 0)
13250     {
13251       errmsg ("tunnel src address not specified");
13252       return -99;
13253     }
13254   if (dst_set == 0)
13255     {
13256       errmsg ("tunnel dst address not specified");
13257       return -99;
13258     }
13259
13260   if (grp_set && !ip46_address_is_multicast (&dst))
13261     {
13262       errmsg ("tunnel group address not multicast");
13263       return -99;
13264     }
13265   if (grp_set && mcast_sw_if_index == ~0)
13266     {
13267       errmsg ("tunnel nonexistent multicast device");
13268       return -99;
13269     }
13270   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13271     {
13272       errmsg ("tunnel dst address must be unicast");
13273       return -99;
13274     }
13275
13276
13277   if (ipv4_set && ipv6_set)
13278     {
13279       errmsg ("both IPv4 and IPv6 addresses specified");
13280       return -99;
13281     }
13282
13283   if ((vni == 0) || (vni >> 24))
13284     {
13285       errmsg ("vni not specified or out of range");
13286       return -99;
13287     }
13288
13289   M (VXLAN_ADD_DEL_TUNNEL, mp);
13290
13291   if (ipv6_set)
13292     {
13293       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13294       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13295     }
13296   else
13297     {
13298       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13299       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13300     }
13301
13302   mp->instance = htonl (instance);
13303   mp->encap_vrf_id = ntohl (encap_vrf_id);
13304   mp->decap_next_index = ntohl (decap_next_index);
13305   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13306   mp->vni = ntohl (vni);
13307   mp->is_add = is_add;
13308   mp->is_ipv6 = ipv6_set;
13309
13310   S (mp);
13311   W (ret);
13312   return ret;
13313 }
13314
13315 static void vl_api_vxlan_tunnel_details_t_handler
13316   (vl_api_vxlan_tunnel_details_t * mp)
13317 {
13318   vat_main_t *vam = &vat_main;
13319   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13320   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13321
13322   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13323          ntohl (mp->sw_if_index),
13324          ntohl (mp->instance),
13325          format_ip46_address, &src, IP46_TYPE_ANY,
13326          format_ip46_address, &dst, IP46_TYPE_ANY,
13327          ntohl (mp->encap_vrf_id),
13328          ntohl (mp->decap_next_index), ntohl (mp->vni),
13329          ntohl (mp->mcast_sw_if_index));
13330 }
13331
13332 static void vl_api_vxlan_tunnel_details_t_handler_json
13333   (vl_api_vxlan_tunnel_details_t * mp)
13334 {
13335   vat_main_t *vam = &vat_main;
13336   vat_json_node_t *node = NULL;
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", ntohl (mp->sw_if_index));
13347
13348   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13349
13350   if (mp->is_ipv6)
13351     {
13352       struct in6_addr ip6;
13353
13354       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13355       vat_json_object_add_ip6 (node, "src_address", ip6);
13356       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13357       vat_json_object_add_ip6 (node, "dst_address", ip6);
13358     }
13359   else
13360     {
13361       struct in_addr ip4;
13362
13363       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13364       vat_json_object_add_ip4 (node, "src_address", ip4);
13365       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13366       vat_json_object_add_ip4 (node, "dst_address", ip4);
13367     }
13368   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13369   vat_json_object_add_uint (node, "decap_next_index",
13370                             ntohl (mp->decap_next_index));
13371   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13372   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13373   vat_json_object_add_uint (node, "mcast_sw_if_index",
13374                             ntohl (mp->mcast_sw_if_index));
13375 }
13376
13377 static int
13378 api_vxlan_tunnel_dump (vat_main_t * vam)
13379 {
13380   unformat_input_t *i = vam->input;
13381   vl_api_vxlan_tunnel_dump_t *mp;
13382   vl_api_control_ping_t *mp_ping;
13383   u32 sw_if_index;
13384   u8 sw_if_index_set = 0;
13385   int ret;
13386
13387   /* Parse args required to build the message */
13388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (i, "sw_if_index %d", &sw_if_index))
13391         sw_if_index_set = 1;
13392       else
13393         break;
13394     }
13395
13396   if (sw_if_index_set == 0)
13397     {
13398       sw_if_index = ~0;
13399     }
13400
13401   if (!vam->json_output)
13402     {
13403       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13404              "sw_if_index", "instance", "src_address", "dst_address",
13405              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13406     }
13407
13408   /* Get list of vxlan-tunnel interfaces */
13409   M (VXLAN_TUNNEL_DUMP, mp);
13410
13411   mp->sw_if_index = htonl (sw_if_index);
13412
13413   S (mp);
13414
13415   /* Use a control ping for synchronization */
13416   MPING (CONTROL_PING, mp_ping);
13417   S (mp_ping);
13418
13419   W (ret);
13420   return ret;
13421 }
13422
13423 static uword unformat_geneve_decap_next
13424   (unformat_input_t * input, va_list * args)
13425 {
13426   u32 *result = va_arg (*args, u32 *);
13427   u32 tmp;
13428
13429   if (unformat (input, "l2"))
13430     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13431   else if (unformat (input, "%d", &tmp))
13432     *result = tmp;
13433   else
13434     return 0;
13435   return 1;
13436 }
13437
13438 static int
13439 api_geneve_add_del_tunnel (vat_main_t * vam)
13440 {
13441   unformat_input_t *line_input = vam->input;
13442   vl_api_geneve_add_del_tunnel_t *mp;
13443   ip46_address_t src, dst;
13444   u8 is_add = 1;
13445   u8 ipv4_set = 0, ipv6_set = 0;
13446   u8 src_set = 0;
13447   u8 dst_set = 0;
13448   u8 grp_set = 0;
13449   u32 mcast_sw_if_index = ~0;
13450   u32 encap_vrf_id = 0;
13451   u32 decap_next_index = ~0;
13452   u32 vni = 0;
13453   int ret;
13454
13455   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13456   clib_memset (&src, 0, sizeof src);
13457   clib_memset (&dst, 0, sizeof dst);
13458
13459   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13460     {
13461       if (unformat (line_input, "del"))
13462         is_add = 0;
13463       else
13464         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13465         {
13466           ipv4_set = 1;
13467           src_set = 1;
13468         }
13469       else
13470         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13471         {
13472           ipv4_set = 1;
13473           dst_set = 1;
13474         }
13475       else
13476         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13477         {
13478           ipv6_set = 1;
13479           src_set = 1;
13480         }
13481       else
13482         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13483         {
13484           ipv6_set = 1;
13485           dst_set = 1;
13486         }
13487       else if (unformat (line_input, "group %U %U",
13488                          unformat_ip4_address, &dst.ip4,
13489                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13490         {
13491           grp_set = dst_set = 1;
13492           ipv4_set = 1;
13493         }
13494       else if (unformat (line_input, "group %U",
13495                          unformat_ip4_address, &dst.ip4))
13496         {
13497           grp_set = dst_set = 1;
13498           ipv4_set = 1;
13499         }
13500       else if (unformat (line_input, "group %U %U",
13501                          unformat_ip6_address, &dst.ip6,
13502                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13503         {
13504           grp_set = dst_set = 1;
13505           ipv6_set = 1;
13506         }
13507       else if (unformat (line_input, "group %U",
13508                          unformat_ip6_address, &dst.ip6))
13509         {
13510           grp_set = dst_set = 1;
13511           ipv6_set = 1;
13512         }
13513       else
13514         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13515         ;
13516       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13517         ;
13518       else if (unformat (line_input, "decap-next %U",
13519                          unformat_geneve_decap_next, &decap_next_index))
13520         ;
13521       else if (unformat (line_input, "vni %d", &vni))
13522         ;
13523       else
13524         {
13525           errmsg ("parse error '%U'", format_unformat_error, line_input);
13526           return -99;
13527         }
13528     }
13529
13530   if (src_set == 0)
13531     {
13532       errmsg ("tunnel src address not specified");
13533       return -99;
13534     }
13535   if (dst_set == 0)
13536     {
13537       errmsg ("tunnel dst address not specified");
13538       return -99;
13539     }
13540
13541   if (grp_set && !ip46_address_is_multicast (&dst))
13542     {
13543       errmsg ("tunnel group address not multicast");
13544       return -99;
13545     }
13546   if (grp_set && mcast_sw_if_index == ~0)
13547     {
13548       errmsg ("tunnel nonexistent multicast device");
13549       return -99;
13550     }
13551   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13552     {
13553       errmsg ("tunnel dst address must be unicast");
13554       return -99;
13555     }
13556
13557
13558   if (ipv4_set && ipv6_set)
13559     {
13560       errmsg ("both IPv4 and IPv6 addresses specified");
13561       return -99;
13562     }
13563
13564   if ((vni == 0) || (vni >> 24))
13565     {
13566       errmsg ("vni not specified or out of range");
13567       return -99;
13568     }
13569
13570   M (GENEVE_ADD_DEL_TUNNEL, mp);
13571
13572   if (ipv6_set)
13573     {
13574       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13575       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13576     }
13577   else
13578     {
13579       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13580       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13581     }
13582   mp->encap_vrf_id = ntohl (encap_vrf_id);
13583   mp->decap_next_index = ntohl (decap_next_index);
13584   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13585   mp->vni = ntohl (vni);
13586   mp->is_add = is_add;
13587   mp->is_ipv6 = ipv6_set;
13588
13589   S (mp);
13590   W (ret);
13591   return ret;
13592 }
13593
13594 static void vl_api_geneve_tunnel_details_t_handler
13595   (vl_api_geneve_tunnel_details_t * mp)
13596 {
13597   vat_main_t *vam = &vat_main;
13598   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13599   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13600
13601   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13602          ntohl (mp->sw_if_index),
13603          format_ip46_address, &src, IP46_TYPE_ANY,
13604          format_ip46_address, &dst, IP46_TYPE_ANY,
13605          ntohl (mp->encap_vrf_id),
13606          ntohl (mp->decap_next_index), ntohl (mp->vni),
13607          ntohl (mp->mcast_sw_if_index));
13608 }
13609
13610 static void vl_api_geneve_tunnel_details_t_handler_json
13611   (vl_api_geneve_tunnel_details_t * mp)
13612 {
13613   vat_main_t *vam = &vat_main;
13614   vat_json_node_t *node = NULL;
13615
13616   if (VAT_JSON_ARRAY != vam->json_tree.type)
13617     {
13618       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13619       vat_json_init_array (&vam->json_tree);
13620     }
13621   node = vat_json_array_add (&vam->json_tree);
13622
13623   vat_json_init_object (node);
13624   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13625   if (mp->is_ipv6)
13626     {
13627       struct in6_addr ip6;
13628
13629       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13630       vat_json_object_add_ip6 (node, "src_address", ip6);
13631       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13632       vat_json_object_add_ip6 (node, "dst_address", ip6);
13633     }
13634   else
13635     {
13636       struct in_addr ip4;
13637
13638       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13639       vat_json_object_add_ip4 (node, "src_address", ip4);
13640       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13641       vat_json_object_add_ip4 (node, "dst_address", ip4);
13642     }
13643   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13644   vat_json_object_add_uint (node, "decap_next_index",
13645                             ntohl (mp->decap_next_index));
13646   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13647   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13648   vat_json_object_add_uint (node, "mcast_sw_if_index",
13649                             ntohl (mp->mcast_sw_if_index));
13650 }
13651
13652 static int
13653 api_geneve_tunnel_dump (vat_main_t * vam)
13654 {
13655   unformat_input_t *i = vam->input;
13656   vl_api_geneve_tunnel_dump_t *mp;
13657   vl_api_control_ping_t *mp_ping;
13658   u32 sw_if_index;
13659   u8 sw_if_index_set = 0;
13660   int ret;
13661
13662   /* Parse args required to build the message */
13663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13664     {
13665       if (unformat (i, "sw_if_index %d", &sw_if_index))
13666         sw_if_index_set = 1;
13667       else
13668         break;
13669     }
13670
13671   if (sw_if_index_set == 0)
13672     {
13673       sw_if_index = ~0;
13674     }
13675
13676   if (!vam->json_output)
13677     {
13678       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13679              "sw_if_index", "local_address", "remote_address",
13680              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13681     }
13682
13683   /* Get list of geneve-tunnel interfaces */
13684   M (GENEVE_TUNNEL_DUMP, mp);
13685
13686   mp->sw_if_index = htonl (sw_if_index);
13687
13688   S (mp);
13689
13690   /* Use a control ping for synchronization */
13691   M (CONTROL_PING, mp_ping);
13692   S (mp_ping);
13693
13694   W (ret);
13695   return ret;
13696 }
13697
13698 static int
13699 api_gre_add_del_tunnel (vat_main_t * vam)
13700 {
13701   unformat_input_t *line_input = vam->input;
13702   vl_api_gre_add_del_tunnel_t *mp;
13703   ip4_address_t src4, dst4;
13704   ip6_address_t src6, dst6;
13705   u8 is_add = 1;
13706   u8 ipv4_set = 0;
13707   u8 ipv6_set = 0;
13708   u8 t_type = GRE_TUNNEL_TYPE_L3;
13709   u8 src_set = 0;
13710   u8 dst_set = 0;
13711   u32 outer_fib_id = 0;
13712   u32 session_id = 0;
13713   u32 instance = ~0;
13714   int ret;
13715
13716   clib_memset (&src4, 0, sizeof src4);
13717   clib_memset (&dst4, 0, sizeof dst4);
13718   clib_memset (&src6, 0, sizeof src6);
13719   clib_memset (&dst6, 0, sizeof dst6);
13720
13721   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13722     {
13723       if (unformat (line_input, "del"))
13724         is_add = 0;
13725       else if (unformat (line_input, "instance %d", &instance))
13726         ;
13727       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13728         {
13729           src_set = 1;
13730           ipv4_set = 1;
13731         }
13732       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13733         {
13734           dst_set = 1;
13735           ipv4_set = 1;
13736         }
13737       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13738         {
13739           src_set = 1;
13740           ipv6_set = 1;
13741         }
13742       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13743         {
13744           dst_set = 1;
13745           ipv6_set = 1;
13746         }
13747       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13748         ;
13749       else if (unformat (line_input, "teb"))
13750         t_type = GRE_TUNNEL_TYPE_TEB;
13751       else if (unformat (line_input, "erspan %d", &session_id))
13752         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13753       else
13754         {
13755           errmsg ("parse error '%U'", format_unformat_error, line_input);
13756           return -99;
13757         }
13758     }
13759
13760   if (src_set == 0)
13761     {
13762       errmsg ("tunnel src address not specified");
13763       return -99;
13764     }
13765   if (dst_set == 0)
13766     {
13767       errmsg ("tunnel dst address not specified");
13768       return -99;
13769     }
13770   if (ipv4_set && ipv6_set)
13771     {
13772       errmsg ("both IPv4 and IPv6 addresses specified");
13773       return -99;
13774     }
13775
13776
13777   M (GRE_ADD_DEL_TUNNEL, mp);
13778
13779   if (ipv4_set)
13780     {
13781       clib_memcpy (&mp->src_address, &src4, 4);
13782       clib_memcpy (&mp->dst_address, &dst4, 4);
13783     }
13784   else
13785     {
13786       clib_memcpy (&mp->src_address, &src6, 16);
13787       clib_memcpy (&mp->dst_address, &dst6, 16);
13788     }
13789   mp->instance = htonl (instance);
13790   mp->outer_fib_id = htonl (outer_fib_id);
13791   mp->is_add = is_add;
13792   mp->session_id = htons ((u16) session_id);
13793   mp->tunnel_type = t_type;
13794   mp->is_ipv6 = ipv6_set;
13795
13796   S (mp);
13797   W (ret);
13798   return ret;
13799 }
13800
13801 static void vl_api_gre_tunnel_details_t_handler
13802   (vl_api_gre_tunnel_details_t * mp)
13803 {
13804   vat_main_t *vam = &vat_main;
13805   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13806   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13807
13808   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13809          ntohl (mp->sw_if_index),
13810          ntohl (mp->instance),
13811          format_ip46_address, &src, IP46_TYPE_ANY,
13812          format_ip46_address, &dst, IP46_TYPE_ANY,
13813          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13814 }
13815
13816 static void vl_api_gre_tunnel_details_t_handler_json
13817   (vl_api_gre_tunnel_details_t * mp)
13818 {
13819   vat_main_t *vam = &vat_main;
13820   vat_json_node_t *node = NULL;
13821   struct in_addr ip4;
13822   struct in6_addr ip6;
13823
13824   if (VAT_JSON_ARRAY != vam->json_tree.type)
13825     {
13826       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13827       vat_json_init_array (&vam->json_tree);
13828     }
13829   node = vat_json_array_add (&vam->json_tree);
13830
13831   vat_json_init_object (node);
13832   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13833   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13834   if (!mp->is_ipv6)
13835     {
13836       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13837       vat_json_object_add_ip4 (node, "src_address", ip4);
13838       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13839       vat_json_object_add_ip4 (node, "dst_address", ip4);
13840     }
13841   else
13842     {
13843       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13844       vat_json_object_add_ip6 (node, "src_address", ip6);
13845       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13846       vat_json_object_add_ip6 (node, "dst_address", ip6);
13847     }
13848   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13849   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13850   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13851   vat_json_object_add_uint (node, "session_id", mp->session_id);
13852 }
13853
13854 static int
13855 api_gre_tunnel_dump (vat_main_t * vam)
13856 {
13857   unformat_input_t *i = vam->input;
13858   vl_api_gre_tunnel_dump_t *mp;
13859   vl_api_control_ping_t *mp_ping;
13860   u32 sw_if_index;
13861   u8 sw_if_index_set = 0;
13862   int ret;
13863
13864   /* Parse args required to build the message */
13865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13866     {
13867       if (unformat (i, "sw_if_index %d", &sw_if_index))
13868         sw_if_index_set = 1;
13869       else
13870         break;
13871     }
13872
13873   if (sw_if_index_set == 0)
13874     {
13875       sw_if_index = ~0;
13876     }
13877
13878   if (!vam->json_output)
13879     {
13880       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13881              "sw_if_index", "instance", "src_address", "dst_address",
13882              "tunnel_type", "outer_fib_id", "session_id");
13883     }
13884
13885   /* Get list of gre-tunnel interfaces */
13886   M (GRE_TUNNEL_DUMP, mp);
13887
13888   mp->sw_if_index = htonl (sw_if_index);
13889
13890   S (mp);
13891
13892   /* Use a control ping for synchronization */
13893   MPING (CONTROL_PING, mp_ping);
13894   S (mp_ping);
13895
13896   W (ret);
13897   return ret;
13898 }
13899
13900 static int
13901 api_l2_fib_clear_table (vat_main_t * vam)
13902 {
13903 //  unformat_input_t * i = vam->input;
13904   vl_api_l2_fib_clear_table_t *mp;
13905   int ret;
13906
13907   M (L2_FIB_CLEAR_TABLE, mp);
13908
13909   S (mp);
13910   W (ret);
13911   return ret;
13912 }
13913
13914 static int
13915 api_l2_interface_efp_filter (vat_main_t * vam)
13916 {
13917   unformat_input_t *i = vam->input;
13918   vl_api_l2_interface_efp_filter_t *mp;
13919   u32 sw_if_index;
13920   u8 enable = 1;
13921   u8 sw_if_index_set = 0;
13922   int ret;
13923
13924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13925     {
13926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13927         sw_if_index_set = 1;
13928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13929         sw_if_index_set = 1;
13930       else if (unformat (i, "enable"))
13931         enable = 1;
13932       else if (unformat (i, "disable"))
13933         enable = 0;
13934       else
13935         {
13936           clib_warning ("parse error '%U'", format_unformat_error, i);
13937           return -99;
13938         }
13939     }
13940
13941   if (sw_if_index_set == 0)
13942     {
13943       errmsg ("missing sw_if_index");
13944       return -99;
13945     }
13946
13947   M (L2_INTERFACE_EFP_FILTER, mp);
13948
13949   mp->sw_if_index = ntohl (sw_if_index);
13950   mp->enable_disable = enable;
13951
13952   S (mp);
13953   W (ret);
13954   return ret;
13955 }
13956
13957 #define foreach_vtr_op                          \
13958 _("disable",  L2_VTR_DISABLED)                  \
13959 _("push-1",  L2_VTR_PUSH_1)                     \
13960 _("push-2",  L2_VTR_PUSH_2)                     \
13961 _("pop-1",  L2_VTR_POP_1)                       \
13962 _("pop-2",  L2_VTR_POP_2)                       \
13963 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13964 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13965 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13966 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13967
13968 static int
13969 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13970 {
13971   unformat_input_t *i = vam->input;
13972   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13973   u32 sw_if_index;
13974   u8 sw_if_index_set = 0;
13975   u8 vtr_op_set = 0;
13976   u32 vtr_op = 0;
13977   u32 push_dot1q = 1;
13978   u32 tag1 = ~0;
13979   u32 tag2 = ~0;
13980   int ret;
13981
13982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13983     {
13984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13985         sw_if_index_set = 1;
13986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13987         sw_if_index_set = 1;
13988       else if (unformat (i, "vtr_op %d", &vtr_op))
13989         vtr_op_set = 1;
13990 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13991       foreach_vtr_op
13992 #undef _
13993         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13994         ;
13995       else if (unformat (i, "tag1 %d", &tag1))
13996         ;
13997       else if (unformat (i, "tag2 %d", &tag2))
13998         ;
13999       else
14000         {
14001           clib_warning ("parse error '%U'", format_unformat_error, i);
14002           return -99;
14003         }
14004     }
14005
14006   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14007     {
14008       errmsg ("missing vtr operation or sw_if_index");
14009       return -99;
14010     }
14011
14012   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14013   mp->sw_if_index = ntohl (sw_if_index);
14014   mp->vtr_op = ntohl (vtr_op);
14015   mp->push_dot1q = ntohl (push_dot1q);
14016   mp->tag1 = ntohl (tag1);
14017   mp->tag2 = ntohl (tag2);
14018
14019   S (mp);
14020   W (ret);
14021   return ret;
14022 }
14023
14024 static int
14025 api_create_vhost_user_if (vat_main_t * vam)
14026 {
14027   unformat_input_t *i = vam->input;
14028   vl_api_create_vhost_user_if_t *mp;
14029   u8 *file_name;
14030   u8 is_server = 0;
14031   u8 file_name_set = 0;
14032   u32 custom_dev_instance = ~0;
14033   u8 hwaddr[6];
14034   u8 use_custom_mac = 0;
14035   u8 disable_mrg_rxbuf = 0;
14036   u8 disable_indirect_desc = 0;
14037   u8 *tag = 0;
14038   int ret;
14039
14040   /* Shut up coverity */
14041   clib_memset (hwaddr, 0, sizeof (hwaddr));
14042
14043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14044     {
14045       if (unformat (i, "socket %s", &file_name))
14046         {
14047           file_name_set = 1;
14048         }
14049       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14050         ;
14051       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14052         use_custom_mac = 1;
14053       else if (unformat (i, "server"))
14054         is_server = 1;
14055       else if (unformat (i, "disable_mrg_rxbuf"))
14056         disable_mrg_rxbuf = 1;
14057       else if (unformat (i, "disable_indirect_desc"))
14058         disable_indirect_desc = 1;
14059       else if (unformat (i, "tag %s", &tag))
14060         ;
14061       else
14062         break;
14063     }
14064
14065   if (file_name_set == 0)
14066     {
14067       errmsg ("missing socket file name");
14068       return -99;
14069     }
14070
14071   if (vec_len (file_name) > 255)
14072     {
14073       errmsg ("socket file name too long");
14074       return -99;
14075     }
14076   vec_add1 (file_name, 0);
14077
14078   M (CREATE_VHOST_USER_IF, mp);
14079
14080   mp->is_server = is_server;
14081   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14082   mp->disable_indirect_desc = disable_indirect_desc;
14083   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14084   vec_free (file_name);
14085   if (custom_dev_instance != ~0)
14086     {
14087       mp->renumber = 1;
14088       mp->custom_dev_instance = ntohl (custom_dev_instance);
14089     }
14090
14091   mp->use_custom_mac = use_custom_mac;
14092   clib_memcpy (mp->mac_address, hwaddr, 6);
14093   if (tag)
14094     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14095   vec_free (tag);
14096
14097   S (mp);
14098   W (ret);
14099   return ret;
14100 }
14101
14102 static int
14103 api_modify_vhost_user_if (vat_main_t * vam)
14104 {
14105   unformat_input_t *i = vam->input;
14106   vl_api_modify_vhost_user_if_t *mp;
14107   u8 *file_name;
14108   u8 is_server = 0;
14109   u8 file_name_set = 0;
14110   u32 custom_dev_instance = ~0;
14111   u8 sw_if_index_set = 0;
14112   u32 sw_if_index = (u32) ~ 0;
14113   int ret;
14114
14115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14116     {
14117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14118         sw_if_index_set = 1;
14119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14120         sw_if_index_set = 1;
14121       else if (unformat (i, "socket %s", &file_name))
14122         {
14123           file_name_set = 1;
14124         }
14125       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14126         ;
14127       else if (unformat (i, "server"))
14128         is_server = 1;
14129       else
14130         break;
14131     }
14132
14133   if (sw_if_index_set == 0)
14134     {
14135       errmsg ("missing sw_if_index or interface name");
14136       return -99;
14137     }
14138
14139   if (file_name_set == 0)
14140     {
14141       errmsg ("missing socket file name");
14142       return -99;
14143     }
14144
14145   if (vec_len (file_name) > 255)
14146     {
14147       errmsg ("socket file name too long");
14148       return -99;
14149     }
14150   vec_add1 (file_name, 0);
14151
14152   M (MODIFY_VHOST_USER_IF, mp);
14153
14154   mp->sw_if_index = ntohl (sw_if_index);
14155   mp->is_server = is_server;
14156   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14157   vec_free (file_name);
14158   if (custom_dev_instance != ~0)
14159     {
14160       mp->renumber = 1;
14161       mp->custom_dev_instance = ntohl (custom_dev_instance);
14162     }
14163
14164   S (mp);
14165   W (ret);
14166   return ret;
14167 }
14168
14169 static int
14170 api_delete_vhost_user_if (vat_main_t * vam)
14171 {
14172   unformat_input_t *i = vam->input;
14173   vl_api_delete_vhost_user_if_t *mp;
14174   u32 sw_if_index = ~0;
14175   u8 sw_if_index_set = 0;
14176   int ret;
14177
14178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14179     {
14180       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14181         sw_if_index_set = 1;
14182       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14183         sw_if_index_set = 1;
14184       else
14185         break;
14186     }
14187
14188   if (sw_if_index_set == 0)
14189     {
14190       errmsg ("missing sw_if_index or interface name");
14191       return -99;
14192     }
14193
14194
14195   M (DELETE_VHOST_USER_IF, mp);
14196
14197   mp->sw_if_index = ntohl (sw_if_index);
14198
14199   S (mp);
14200   W (ret);
14201   return ret;
14202 }
14203
14204 static void vl_api_sw_interface_vhost_user_details_t_handler
14205   (vl_api_sw_interface_vhost_user_details_t * mp)
14206 {
14207   vat_main_t *vam = &vat_main;
14208
14209   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14210          (char *) mp->interface_name,
14211          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14212          clib_net_to_host_u64 (mp->features), mp->is_server,
14213          ntohl (mp->num_regions), (char *) mp->sock_filename);
14214   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14215 }
14216
14217 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14218   (vl_api_sw_interface_vhost_user_details_t * mp)
14219 {
14220   vat_main_t *vam = &vat_main;
14221   vat_json_node_t *node = NULL;
14222
14223   if (VAT_JSON_ARRAY != vam->json_tree.type)
14224     {
14225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14226       vat_json_init_array (&vam->json_tree);
14227     }
14228   node = vat_json_array_add (&vam->json_tree);
14229
14230   vat_json_init_object (node);
14231   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14232   vat_json_object_add_string_copy (node, "interface_name",
14233                                    mp->interface_name);
14234   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14235                             ntohl (mp->virtio_net_hdr_sz));
14236   vat_json_object_add_uint (node, "features",
14237                             clib_net_to_host_u64 (mp->features));
14238   vat_json_object_add_uint (node, "is_server", mp->is_server);
14239   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14240   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14241   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14242 }
14243
14244 static int
14245 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14246 {
14247   vl_api_sw_interface_vhost_user_dump_t *mp;
14248   vl_api_control_ping_t *mp_ping;
14249   int ret;
14250   print (vam->ofp,
14251          "Interface name            idx hdr_sz features server regions filename");
14252
14253   /* Get list of vhost-user interfaces */
14254   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14255   S (mp);
14256
14257   /* Use a control ping for synchronization */
14258   MPING (CONTROL_PING, mp_ping);
14259   S (mp_ping);
14260
14261   W (ret);
14262   return ret;
14263 }
14264
14265 static int
14266 api_show_version (vat_main_t * vam)
14267 {
14268   vl_api_show_version_t *mp;
14269   int ret;
14270
14271   M (SHOW_VERSION, mp);
14272
14273   S (mp);
14274   W (ret);
14275   return ret;
14276 }
14277
14278
14279 static int
14280 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14281 {
14282   unformat_input_t *line_input = vam->input;
14283   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14284   ip4_address_t local4, remote4;
14285   ip6_address_t local6, remote6;
14286   u8 is_add = 1;
14287   u8 ipv4_set = 0, ipv6_set = 0;
14288   u8 local_set = 0;
14289   u8 remote_set = 0;
14290   u8 grp_set = 0;
14291   u32 mcast_sw_if_index = ~0;
14292   u32 encap_vrf_id = 0;
14293   u32 decap_vrf_id = 0;
14294   u8 protocol = ~0;
14295   u32 vni;
14296   u8 vni_set = 0;
14297   int ret;
14298
14299   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14300   clib_memset (&local4, 0, sizeof local4);
14301   clib_memset (&remote4, 0, sizeof remote4);
14302   clib_memset (&local6, 0, sizeof local6);
14303   clib_memset (&remote6, 0, sizeof remote6);
14304
14305   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14306     {
14307       if (unformat (line_input, "del"))
14308         is_add = 0;
14309       else if (unformat (line_input, "local %U",
14310                          unformat_ip4_address, &local4))
14311         {
14312           local_set = 1;
14313           ipv4_set = 1;
14314         }
14315       else if (unformat (line_input, "remote %U",
14316                          unformat_ip4_address, &remote4))
14317         {
14318           remote_set = 1;
14319           ipv4_set = 1;
14320         }
14321       else if (unformat (line_input, "local %U",
14322                          unformat_ip6_address, &local6))
14323         {
14324           local_set = 1;
14325           ipv6_set = 1;
14326         }
14327       else if (unformat (line_input, "remote %U",
14328                          unformat_ip6_address, &remote6))
14329         {
14330           remote_set = 1;
14331           ipv6_set = 1;
14332         }
14333       else if (unformat (line_input, "group %U %U",
14334                          unformat_ip4_address, &remote4,
14335                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14336         {
14337           grp_set = remote_set = 1;
14338           ipv4_set = 1;
14339         }
14340       else if (unformat (line_input, "group %U",
14341                          unformat_ip4_address, &remote4))
14342         {
14343           grp_set = remote_set = 1;
14344           ipv4_set = 1;
14345         }
14346       else if (unformat (line_input, "group %U %U",
14347                          unformat_ip6_address, &remote6,
14348                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14349         {
14350           grp_set = remote_set = 1;
14351           ipv6_set = 1;
14352         }
14353       else if (unformat (line_input, "group %U",
14354                          unformat_ip6_address, &remote6))
14355         {
14356           grp_set = remote_set = 1;
14357           ipv6_set = 1;
14358         }
14359       else
14360         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14361         ;
14362       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14363         ;
14364       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14365         ;
14366       else if (unformat (line_input, "vni %d", &vni))
14367         vni_set = 1;
14368       else if (unformat (line_input, "next-ip4"))
14369         protocol = 1;
14370       else if (unformat (line_input, "next-ip6"))
14371         protocol = 2;
14372       else if (unformat (line_input, "next-ethernet"))
14373         protocol = 3;
14374       else if (unformat (line_input, "next-nsh"))
14375         protocol = 4;
14376       else
14377         {
14378           errmsg ("parse error '%U'", format_unformat_error, line_input);
14379           return -99;
14380         }
14381     }
14382
14383   if (local_set == 0)
14384     {
14385       errmsg ("tunnel local address not specified");
14386       return -99;
14387     }
14388   if (remote_set == 0)
14389     {
14390       errmsg ("tunnel remote address not specified");
14391       return -99;
14392     }
14393   if (grp_set && mcast_sw_if_index == ~0)
14394     {
14395       errmsg ("tunnel nonexistent multicast device");
14396       return -99;
14397     }
14398   if (ipv4_set && ipv6_set)
14399     {
14400       errmsg ("both IPv4 and IPv6 addresses specified");
14401       return -99;
14402     }
14403
14404   if (vni_set == 0)
14405     {
14406       errmsg ("vni not specified");
14407       return -99;
14408     }
14409
14410   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14411
14412
14413   if (ipv6_set)
14414     {
14415       clib_memcpy (&mp->local, &local6, sizeof (local6));
14416       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14417     }
14418   else
14419     {
14420       clib_memcpy (&mp->local, &local4, sizeof (local4));
14421       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14422     }
14423
14424   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14425   mp->encap_vrf_id = ntohl (encap_vrf_id);
14426   mp->decap_vrf_id = ntohl (decap_vrf_id);
14427   mp->protocol = protocol;
14428   mp->vni = ntohl (vni);
14429   mp->is_add = is_add;
14430   mp->is_ipv6 = ipv6_set;
14431
14432   S (mp);
14433   W (ret);
14434   return ret;
14435 }
14436
14437 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14438   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14439 {
14440   vat_main_t *vam = &vat_main;
14441   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14442   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14443
14444   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14445          ntohl (mp->sw_if_index),
14446          format_ip46_address, &local, IP46_TYPE_ANY,
14447          format_ip46_address, &remote, IP46_TYPE_ANY,
14448          ntohl (mp->vni), mp->protocol,
14449          ntohl (mp->mcast_sw_if_index),
14450          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14451 }
14452
14453
14454 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14455   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14456 {
14457   vat_main_t *vam = &vat_main;
14458   vat_json_node_t *node = NULL;
14459   struct in_addr ip4;
14460   struct in6_addr ip6;
14461
14462   if (VAT_JSON_ARRAY != vam->json_tree.type)
14463     {
14464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14465       vat_json_init_array (&vam->json_tree);
14466     }
14467   node = vat_json_array_add (&vam->json_tree);
14468
14469   vat_json_init_object (node);
14470   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14471   if (mp->is_ipv6)
14472     {
14473       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14474       vat_json_object_add_ip6 (node, "local", ip6);
14475       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14476       vat_json_object_add_ip6 (node, "remote", ip6);
14477     }
14478   else
14479     {
14480       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14481       vat_json_object_add_ip4 (node, "local", ip4);
14482       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14483       vat_json_object_add_ip4 (node, "remote", ip4);
14484     }
14485   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14486   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14487   vat_json_object_add_uint (node, "mcast_sw_if_index",
14488                             ntohl (mp->mcast_sw_if_index));
14489   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14490   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14491   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14492 }
14493
14494 static int
14495 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14496 {
14497   unformat_input_t *i = vam->input;
14498   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14499   vl_api_control_ping_t *mp_ping;
14500   u32 sw_if_index;
14501   u8 sw_if_index_set = 0;
14502   int ret;
14503
14504   /* Parse args required to build the message */
14505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14506     {
14507       if (unformat (i, "sw_if_index %d", &sw_if_index))
14508         sw_if_index_set = 1;
14509       else
14510         break;
14511     }
14512
14513   if (sw_if_index_set == 0)
14514     {
14515       sw_if_index = ~0;
14516     }
14517
14518   if (!vam->json_output)
14519     {
14520       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14521              "sw_if_index", "local", "remote", "vni",
14522              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14523     }
14524
14525   /* Get list of vxlan-tunnel interfaces */
14526   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14527
14528   mp->sw_if_index = htonl (sw_if_index);
14529
14530   S (mp);
14531
14532   /* Use a control ping for synchronization */
14533   MPING (CONTROL_PING, mp_ping);
14534   S (mp_ping);
14535
14536   W (ret);
14537   return ret;
14538 }
14539
14540 static void vl_api_l2_fib_table_details_t_handler
14541   (vl_api_l2_fib_table_details_t * mp)
14542 {
14543   vat_main_t *vam = &vat_main;
14544
14545   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14546          "       %d       %d     %d",
14547          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14548          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14549          mp->bvi_mac);
14550 }
14551
14552 static void vl_api_l2_fib_table_details_t_handler_json
14553   (vl_api_l2_fib_table_details_t * mp)
14554 {
14555   vat_main_t *vam = &vat_main;
14556   vat_json_node_t *node = NULL;
14557
14558   if (VAT_JSON_ARRAY != vam->json_tree.type)
14559     {
14560       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14561       vat_json_init_array (&vam->json_tree);
14562     }
14563   node = vat_json_array_add (&vam->json_tree);
14564
14565   vat_json_init_object (node);
14566   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14567   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14568   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14569   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14570   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14571   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14572 }
14573
14574 static int
14575 api_l2_fib_table_dump (vat_main_t * vam)
14576 {
14577   unformat_input_t *i = vam->input;
14578   vl_api_l2_fib_table_dump_t *mp;
14579   vl_api_control_ping_t *mp_ping;
14580   u32 bd_id;
14581   u8 bd_id_set = 0;
14582   int ret;
14583
14584   /* Parse args required to build the message */
14585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14586     {
14587       if (unformat (i, "bd_id %d", &bd_id))
14588         bd_id_set = 1;
14589       else
14590         break;
14591     }
14592
14593   if (bd_id_set == 0)
14594     {
14595       errmsg ("missing bridge domain");
14596       return -99;
14597     }
14598
14599   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14600
14601   /* Get list of l2 fib entries */
14602   M (L2_FIB_TABLE_DUMP, mp);
14603
14604   mp->bd_id = ntohl (bd_id);
14605   S (mp);
14606
14607   /* Use a control ping for synchronization */
14608   MPING (CONTROL_PING, mp_ping);
14609   S (mp_ping);
14610
14611   W (ret);
14612   return ret;
14613 }
14614
14615
14616 static int
14617 api_interface_name_renumber (vat_main_t * vam)
14618 {
14619   unformat_input_t *line_input = vam->input;
14620   vl_api_interface_name_renumber_t *mp;
14621   u32 sw_if_index = ~0;
14622   u32 new_show_dev_instance = ~0;
14623   int ret;
14624
14625   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14626     {
14627       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14628                     &sw_if_index))
14629         ;
14630       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14631         ;
14632       else if (unformat (line_input, "new_show_dev_instance %d",
14633                          &new_show_dev_instance))
14634         ;
14635       else
14636         break;
14637     }
14638
14639   if (sw_if_index == ~0)
14640     {
14641       errmsg ("missing interface name or sw_if_index");
14642       return -99;
14643     }
14644
14645   if (new_show_dev_instance == ~0)
14646     {
14647       errmsg ("missing new_show_dev_instance");
14648       return -99;
14649     }
14650
14651   M (INTERFACE_NAME_RENUMBER, mp);
14652
14653   mp->sw_if_index = ntohl (sw_if_index);
14654   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14655
14656   S (mp);
14657   W (ret);
14658   return ret;
14659 }
14660
14661 static int
14662 api_ip_probe_neighbor (vat_main_t * vam)
14663 {
14664   unformat_input_t *i = vam->input;
14665   vl_api_ip_probe_neighbor_t *mp;
14666   u8 int_set = 0;
14667   u8 adr_set = 0;
14668   u8 is_ipv6 = 0;
14669   u8 dst_adr[16];
14670   u32 sw_if_index;
14671   int ret;
14672
14673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14674     {
14675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14676         int_set = 1;
14677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14678         int_set = 1;
14679       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14680         adr_set = 1;
14681       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14682         {
14683           adr_set = 1;
14684           is_ipv6 = 1;
14685         }
14686       else
14687         break;
14688     }
14689
14690   if (int_set == 0)
14691     {
14692       errmsg ("missing interface");
14693       return -99;
14694     }
14695
14696   if (adr_set == 0)
14697     {
14698       errmsg ("missing addresses");
14699       return -99;
14700     }
14701
14702   M (IP_PROBE_NEIGHBOR, mp);
14703
14704   mp->sw_if_index = ntohl (sw_if_index);
14705   mp->is_ipv6 = is_ipv6;
14706   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14707
14708   S (mp);
14709   W (ret);
14710   return ret;
14711 }
14712
14713 static int
14714 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14715 {
14716   unformat_input_t *i = vam->input;
14717   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14718   u8 mode = IP_SCAN_V46_NEIGHBORS;
14719   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14720   int ret;
14721
14722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14723     {
14724       if (unformat (i, "ip4"))
14725         mode = IP_SCAN_V4_NEIGHBORS;
14726       else if (unformat (i, "ip6"))
14727         mode = IP_SCAN_V6_NEIGHBORS;
14728       if (unformat (i, "both"))
14729         mode = IP_SCAN_V46_NEIGHBORS;
14730       else if (unformat (i, "disable"))
14731         mode = IP_SCAN_DISABLED;
14732       else if (unformat (i, "interval %d", &interval))
14733         ;
14734       else if (unformat (i, "max-time %d", &time))
14735         ;
14736       else if (unformat (i, "max-update %d", &update))
14737         ;
14738       else if (unformat (i, "delay %d", &delay))
14739         ;
14740       else if (unformat (i, "stale %d", &stale))
14741         ;
14742       else
14743         break;
14744     }
14745
14746   if (interval > 255)
14747     {
14748       errmsg ("interval cannot exceed 255 minutes.");
14749       return -99;
14750     }
14751   if (time > 255)
14752     {
14753       errmsg ("max-time cannot exceed 255 usec.");
14754       return -99;
14755     }
14756   if (update > 255)
14757     {
14758       errmsg ("max-update cannot exceed 255.");
14759       return -99;
14760     }
14761   if (delay > 255)
14762     {
14763       errmsg ("delay cannot exceed 255 msec.");
14764       return -99;
14765     }
14766   if (stale > 255)
14767     {
14768       errmsg ("stale cannot exceed 255 minutes.");
14769       return -99;
14770     }
14771
14772   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14773   mp->mode = mode;
14774   mp->scan_interval = interval;
14775   mp->max_proc_time = time;
14776   mp->max_update = update;
14777   mp->scan_int_delay = delay;
14778   mp->stale_threshold = stale;
14779
14780   S (mp);
14781   W (ret);
14782   return ret;
14783 }
14784
14785 static int
14786 api_want_ip4_arp_events (vat_main_t * vam)
14787 {
14788   unformat_input_t *line_input = vam->input;
14789   vl_api_want_ip4_arp_events_t *mp;
14790   ip4_address_t address;
14791   int address_set = 0;
14792   u32 enable_disable = 1;
14793   int ret;
14794
14795   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14796     {
14797       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14798         address_set = 1;
14799       else if (unformat (line_input, "del"))
14800         enable_disable = 0;
14801       else
14802         break;
14803     }
14804
14805   if (address_set == 0)
14806     {
14807       errmsg ("missing addresses");
14808       return -99;
14809     }
14810
14811   M (WANT_IP4_ARP_EVENTS, mp);
14812   mp->enable_disable = enable_disable;
14813   mp->pid = htonl (getpid ());
14814   mp->address = address.as_u32;
14815
14816   S (mp);
14817   W (ret);
14818   return ret;
14819 }
14820
14821 static int
14822 api_want_ip6_nd_events (vat_main_t * vam)
14823 {
14824   unformat_input_t *line_input = vam->input;
14825   vl_api_want_ip6_nd_events_t *mp;
14826   ip6_address_t address;
14827   int address_set = 0;
14828   u32 enable_disable = 1;
14829   int ret;
14830
14831   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14832     {
14833       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14834         address_set = 1;
14835       else if (unformat (line_input, "del"))
14836         enable_disable = 0;
14837       else
14838         break;
14839     }
14840
14841   if (address_set == 0)
14842     {
14843       errmsg ("missing addresses");
14844       return -99;
14845     }
14846
14847   M (WANT_IP6_ND_EVENTS, mp);
14848   mp->enable_disable = enable_disable;
14849   mp->pid = htonl (getpid ());
14850   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14851
14852   S (mp);
14853   W (ret);
14854   return ret;
14855 }
14856
14857 static int
14858 api_want_l2_macs_events (vat_main_t * vam)
14859 {
14860   unformat_input_t *line_input = vam->input;
14861   vl_api_want_l2_macs_events_t *mp;
14862   u8 enable_disable = 1;
14863   u32 scan_delay = 0;
14864   u32 max_macs_in_event = 0;
14865   u32 learn_limit = 0;
14866   int ret;
14867
14868   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14869     {
14870       if (unformat (line_input, "learn-limit %d", &learn_limit))
14871         ;
14872       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14873         ;
14874       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14875         ;
14876       else if (unformat (line_input, "disable"))
14877         enable_disable = 0;
14878       else
14879         break;
14880     }
14881
14882   M (WANT_L2_MACS_EVENTS, mp);
14883   mp->enable_disable = enable_disable;
14884   mp->pid = htonl (getpid ());
14885   mp->learn_limit = htonl (learn_limit);
14886   mp->scan_delay = (u8) scan_delay;
14887   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14888   S (mp);
14889   W (ret);
14890   return ret;
14891 }
14892
14893 static int
14894 api_input_acl_set_interface (vat_main_t * vam)
14895 {
14896   unformat_input_t *i = vam->input;
14897   vl_api_input_acl_set_interface_t *mp;
14898   u32 sw_if_index;
14899   int sw_if_index_set;
14900   u32 ip4_table_index = ~0;
14901   u32 ip6_table_index = ~0;
14902   u32 l2_table_index = ~0;
14903   u8 is_add = 1;
14904   int ret;
14905
14906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14907     {
14908       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14909         sw_if_index_set = 1;
14910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14911         sw_if_index_set = 1;
14912       else if (unformat (i, "del"))
14913         is_add = 0;
14914       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14915         ;
14916       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14917         ;
14918       else if (unformat (i, "l2-table %d", &l2_table_index))
14919         ;
14920       else
14921         {
14922           clib_warning ("parse error '%U'", format_unformat_error, i);
14923           return -99;
14924         }
14925     }
14926
14927   if (sw_if_index_set == 0)
14928     {
14929       errmsg ("missing interface name or sw_if_index");
14930       return -99;
14931     }
14932
14933   M (INPUT_ACL_SET_INTERFACE, mp);
14934
14935   mp->sw_if_index = ntohl (sw_if_index);
14936   mp->ip4_table_index = ntohl (ip4_table_index);
14937   mp->ip6_table_index = ntohl (ip6_table_index);
14938   mp->l2_table_index = ntohl (l2_table_index);
14939   mp->is_add = is_add;
14940
14941   S (mp);
14942   W (ret);
14943   return ret;
14944 }
14945
14946 static int
14947 api_output_acl_set_interface (vat_main_t * vam)
14948 {
14949   unformat_input_t *i = vam->input;
14950   vl_api_output_acl_set_interface_t *mp;
14951   u32 sw_if_index;
14952   int sw_if_index_set;
14953   u32 ip4_table_index = ~0;
14954   u32 ip6_table_index = ~0;
14955   u32 l2_table_index = ~0;
14956   u8 is_add = 1;
14957   int ret;
14958
14959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14960     {
14961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14962         sw_if_index_set = 1;
14963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14964         sw_if_index_set = 1;
14965       else if (unformat (i, "del"))
14966         is_add = 0;
14967       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14968         ;
14969       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14970         ;
14971       else if (unformat (i, "l2-table %d", &l2_table_index))
14972         ;
14973       else
14974         {
14975           clib_warning ("parse error '%U'", format_unformat_error, i);
14976           return -99;
14977         }
14978     }
14979
14980   if (sw_if_index_set == 0)
14981     {
14982       errmsg ("missing interface name or sw_if_index");
14983       return -99;
14984     }
14985
14986   M (OUTPUT_ACL_SET_INTERFACE, mp);
14987
14988   mp->sw_if_index = ntohl (sw_if_index);
14989   mp->ip4_table_index = ntohl (ip4_table_index);
14990   mp->ip6_table_index = ntohl (ip6_table_index);
14991   mp->l2_table_index = ntohl (l2_table_index);
14992   mp->is_add = is_add;
14993
14994   S (mp);
14995   W (ret);
14996   return ret;
14997 }
14998
14999 static int
15000 api_ip_address_dump (vat_main_t * vam)
15001 {
15002   unformat_input_t *i = vam->input;
15003   vl_api_ip_address_dump_t *mp;
15004   vl_api_control_ping_t *mp_ping;
15005   u32 sw_if_index = ~0;
15006   u8 sw_if_index_set = 0;
15007   u8 ipv4_set = 0;
15008   u8 ipv6_set = 0;
15009   int ret;
15010
15011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15012     {
15013       if (unformat (i, "sw_if_index %d", &sw_if_index))
15014         sw_if_index_set = 1;
15015       else
15016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15017         sw_if_index_set = 1;
15018       else if (unformat (i, "ipv4"))
15019         ipv4_set = 1;
15020       else if (unformat (i, "ipv6"))
15021         ipv6_set = 1;
15022       else
15023         break;
15024     }
15025
15026   if (ipv4_set && ipv6_set)
15027     {
15028       errmsg ("ipv4 and ipv6 flags cannot be both set");
15029       return -99;
15030     }
15031
15032   if ((!ipv4_set) && (!ipv6_set))
15033     {
15034       errmsg ("no ipv4 nor ipv6 flag set");
15035       return -99;
15036     }
15037
15038   if (sw_if_index_set == 0)
15039     {
15040       errmsg ("missing interface name or sw_if_index");
15041       return -99;
15042     }
15043
15044   vam->current_sw_if_index = sw_if_index;
15045   vam->is_ipv6 = ipv6_set;
15046
15047   M (IP_ADDRESS_DUMP, mp);
15048   mp->sw_if_index = ntohl (sw_if_index);
15049   mp->is_ipv6 = ipv6_set;
15050   S (mp);
15051
15052   /* Use a control ping for synchronization */
15053   MPING (CONTROL_PING, mp_ping);
15054   S (mp_ping);
15055
15056   W (ret);
15057   return ret;
15058 }
15059
15060 static int
15061 api_ip_dump (vat_main_t * vam)
15062 {
15063   vl_api_ip_dump_t *mp;
15064   vl_api_control_ping_t *mp_ping;
15065   unformat_input_t *in = vam->input;
15066   int ipv4_set = 0;
15067   int ipv6_set = 0;
15068   int is_ipv6;
15069   int i;
15070   int ret;
15071
15072   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15073     {
15074       if (unformat (in, "ipv4"))
15075         ipv4_set = 1;
15076       else if (unformat (in, "ipv6"))
15077         ipv6_set = 1;
15078       else
15079         break;
15080     }
15081
15082   if (ipv4_set && ipv6_set)
15083     {
15084       errmsg ("ipv4 and ipv6 flags cannot be both set");
15085       return -99;
15086     }
15087
15088   if ((!ipv4_set) && (!ipv6_set))
15089     {
15090       errmsg ("no ipv4 nor ipv6 flag set");
15091       return -99;
15092     }
15093
15094   is_ipv6 = ipv6_set;
15095   vam->is_ipv6 = is_ipv6;
15096
15097   /* free old data */
15098   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15099     {
15100       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15101     }
15102   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15103
15104   M (IP_DUMP, mp);
15105   mp->is_ipv6 = ipv6_set;
15106   S (mp);
15107
15108   /* Use a control ping for synchronization */
15109   MPING (CONTROL_PING, mp_ping);
15110   S (mp_ping);
15111
15112   W (ret);
15113   return ret;
15114 }
15115
15116 static int
15117 api_ipsec_spd_add_del (vat_main_t * vam)
15118 {
15119   unformat_input_t *i = vam->input;
15120   vl_api_ipsec_spd_add_del_t *mp;
15121   u32 spd_id = ~0;
15122   u8 is_add = 1;
15123   int ret;
15124
15125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15126     {
15127       if (unformat (i, "spd_id %d", &spd_id))
15128         ;
15129       else if (unformat (i, "del"))
15130         is_add = 0;
15131       else
15132         {
15133           clib_warning ("parse error '%U'", format_unformat_error, i);
15134           return -99;
15135         }
15136     }
15137   if (spd_id == ~0)
15138     {
15139       errmsg ("spd_id must be set");
15140       return -99;
15141     }
15142
15143   M (IPSEC_SPD_ADD_DEL, mp);
15144
15145   mp->spd_id = ntohl (spd_id);
15146   mp->is_add = is_add;
15147
15148   S (mp);
15149   W (ret);
15150   return ret;
15151 }
15152
15153 static int
15154 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15155 {
15156   unformat_input_t *i = vam->input;
15157   vl_api_ipsec_interface_add_del_spd_t *mp;
15158   u32 sw_if_index;
15159   u8 sw_if_index_set = 0;
15160   u32 spd_id = (u32) ~ 0;
15161   u8 is_add = 1;
15162   int ret;
15163
15164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15165     {
15166       if (unformat (i, "del"))
15167         is_add = 0;
15168       else if (unformat (i, "spd_id %d", &spd_id))
15169         ;
15170       else
15171         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15172         sw_if_index_set = 1;
15173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15174         sw_if_index_set = 1;
15175       else
15176         {
15177           clib_warning ("parse error '%U'", format_unformat_error, i);
15178           return -99;
15179         }
15180
15181     }
15182
15183   if (spd_id == (u32) ~ 0)
15184     {
15185       errmsg ("spd_id must be set");
15186       return -99;
15187     }
15188
15189   if (sw_if_index_set == 0)
15190     {
15191       errmsg ("missing interface name or sw_if_index");
15192       return -99;
15193     }
15194
15195   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15196
15197   mp->spd_id = ntohl (spd_id);
15198   mp->sw_if_index = ntohl (sw_if_index);
15199   mp->is_add = is_add;
15200
15201   S (mp);
15202   W (ret);
15203   return ret;
15204 }
15205
15206 static int
15207 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15208 {
15209   unformat_input_t *i = vam->input;
15210   vl_api_ipsec_spd_add_del_entry_t *mp;
15211   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15212   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15213   i32 priority = 0;
15214   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15215   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15216   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15217   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15218   int ret;
15219
15220   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15221   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15222   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15223   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15224   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15225   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15226
15227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15228     {
15229       if (unformat (i, "del"))
15230         is_add = 0;
15231       if (unformat (i, "outbound"))
15232         is_outbound = 1;
15233       if (unformat (i, "inbound"))
15234         is_outbound = 0;
15235       else if (unformat (i, "spd_id %d", &spd_id))
15236         ;
15237       else if (unformat (i, "sa_id %d", &sa_id))
15238         ;
15239       else if (unformat (i, "priority %d", &priority))
15240         ;
15241       else if (unformat (i, "protocol %d", &protocol))
15242         ;
15243       else if (unformat (i, "lport_start %d", &lport_start))
15244         ;
15245       else if (unformat (i, "lport_stop %d", &lport_stop))
15246         ;
15247       else if (unformat (i, "rport_start %d", &rport_start))
15248         ;
15249       else if (unformat (i, "rport_stop %d", &rport_stop))
15250         ;
15251       else
15252         if (unformat
15253             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15254         {
15255           is_ipv6 = 0;
15256           is_ip_any = 0;
15257         }
15258       else
15259         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15260         {
15261           is_ipv6 = 0;
15262           is_ip_any = 0;
15263         }
15264       else
15265         if (unformat
15266             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15267         {
15268           is_ipv6 = 0;
15269           is_ip_any = 0;
15270         }
15271       else
15272         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15273         {
15274           is_ipv6 = 0;
15275           is_ip_any = 0;
15276         }
15277       else
15278         if (unformat
15279             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15280         {
15281           is_ipv6 = 1;
15282           is_ip_any = 0;
15283         }
15284       else
15285         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15286         {
15287           is_ipv6 = 1;
15288           is_ip_any = 0;
15289         }
15290       else
15291         if (unformat
15292             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15293         {
15294           is_ipv6 = 1;
15295           is_ip_any = 0;
15296         }
15297       else
15298         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15299         {
15300           is_ipv6 = 1;
15301           is_ip_any = 0;
15302         }
15303       else
15304         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15305         {
15306           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15307             {
15308               clib_warning ("unsupported action: 'resolve'");
15309               return -99;
15310             }
15311         }
15312       else
15313         {
15314           clib_warning ("parse error '%U'", format_unformat_error, i);
15315           return -99;
15316         }
15317
15318     }
15319
15320   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15321
15322   mp->spd_id = ntohl (spd_id);
15323   mp->priority = ntohl (priority);
15324   mp->is_outbound = is_outbound;
15325
15326   mp->is_ipv6 = is_ipv6;
15327   if (is_ipv6 || is_ip_any)
15328     {
15329       clib_memcpy (mp->remote_address_start, &raddr6_start,
15330                    sizeof (ip6_address_t));
15331       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15332                    sizeof (ip6_address_t));
15333       clib_memcpy (mp->local_address_start, &laddr6_start,
15334                    sizeof (ip6_address_t));
15335       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15336                    sizeof (ip6_address_t));
15337     }
15338   else
15339     {
15340       clib_memcpy (mp->remote_address_start, &raddr4_start,
15341                    sizeof (ip4_address_t));
15342       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15343                    sizeof (ip4_address_t));
15344       clib_memcpy (mp->local_address_start, &laddr4_start,
15345                    sizeof (ip4_address_t));
15346       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15347                    sizeof (ip4_address_t));
15348     }
15349   mp->protocol = (u8) protocol;
15350   mp->local_port_start = ntohs ((u16) lport_start);
15351   mp->local_port_stop = ntohs ((u16) lport_stop);
15352   mp->remote_port_start = ntohs ((u16) rport_start);
15353   mp->remote_port_stop = ntohs ((u16) rport_stop);
15354   mp->policy = (u8) policy;
15355   mp->sa_id = ntohl (sa_id);
15356   mp->is_add = is_add;
15357   mp->is_ip_any = is_ip_any;
15358   S (mp);
15359   W (ret);
15360   return ret;
15361 }
15362
15363 static int
15364 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15365 {
15366   unformat_input_t *i = vam->input;
15367   vl_api_ipsec_sad_add_del_entry_t *mp;
15368   u32 sad_id = 0, spi = 0;
15369   u8 *ck = 0, *ik = 0;
15370   u8 is_add = 1;
15371
15372   u8 protocol = IPSEC_PROTOCOL_AH;
15373   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15374   u32 crypto_alg = 0, integ_alg = 0;
15375   ip4_address_t tun_src4;
15376   ip4_address_t tun_dst4;
15377   ip6_address_t tun_src6;
15378   ip6_address_t tun_dst6;
15379   int ret;
15380
15381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15382     {
15383       if (unformat (i, "del"))
15384         is_add = 0;
15385       else if (unformat (i, "sad_id %d", &sad_id))
15386         ;
15387       else if (unformat (i, "spi %d", &spi))
15388         ;
15389       else if (unformat (i, "esp"))
15390         protocol = IPSEC_PROTOCOL_ESP;
15391       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15392         {
15393           is_tunnel = 1;
15394           is_tunnel_ipv6 = 0;
15395         }
15396       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15397         {
15398           is_tunnel = 1;
15399           is_tunnel_ipv6 = 0;
15400         }
15401       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15402         {
15403           is_tunnel = 1;
15404           is_tunnel_ipv6 = 1;
15405         }
15406       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15407         {
15408           is_tunnel = 1;
15409           is_tunnel_ipv6 = 1;
15410         }
15411       else
15412         if (unformat
15413             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15414         {
15415           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15416             {
15417               clib_warning ("unsupported crypto-alg: '%U'",
15418                             format_ipsec_crypto_alg, crypto_alg);
15419               return -99;
15420             }
15421         }
15422       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15423         ;
15424       else
15425         if (unformat
15426             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15427         {
15428           if (integ_alg >= IPSEC_INTEG_N_ALG)
15429             {
15430               clib_warning ("unsupported integ-alg: '%U'",
15431                             format_ipsec_integ_alg, integ_alg);
15432               return -99;
15433             }
15434         }
15435       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15436         ;
15437       else
15438         {
15439           clib_warning ("parse error '%U'", format_unformat_error, i);
15440           return -99;
15441         }
15442
15443     }
15444
15445   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15446
15447   mp->sad_id = ntohl (sad_id);
15448   mp->is_add = is_add;
15449   mp->protocol = protocol;
15450   mp->spi = ntohl (spi);
15451   mp->is_tunnel = is_tunnel;
15452   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15453   mp->crypto_algorithm = crypto_alg;
15454   mp->integrity_algorithm = integ_alg;
15455   mp->crypto_key_length = vec_len (ck);
15456   mp->integrity_key_length = vec_len (ik);
15457
15458   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15459     mp->crypto_key_length = sizeof (mp->crypto_key);
15460
15461   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15462     mp->integrity_key_length = sizeof (mp->integrity_key);
15463
15464   if (ck)
15465     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15466   if (ik)
15467     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15468
15469   if (is_tunnel)
15470     {
15471       if (is_tunnel_ipv6)
15472         {
15473           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15474                        sizeof (ip6_address_t));
15475           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15476                        sizeof (ip6_address_t));
15477         }
15478       else
15479         {
15480           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15481                        sizeof (ip4_address_t));
15482           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15483                        sizeof (ip4_address_t));
15484         }
15485     }
15486
15487   S (mp);
15488   W (ret);
15489   return ret;
15490 }
15491
15492 static int
15493 api_ipsec_sa_set_key (vat_main_t * vam)
15494 {
15495   unformat_input_t *i = vam->input;
15496   vl_api_ipsec_sa_set_key_t *mp;
15497   u32 sa_id;
15498   u8 *ck = 0, *ik = 0;
15499   int ret;
15500
15501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15502     {
15503       if (unformat (i, "sa_id %d", &sa_id))
15504         ;
15505       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15506         ;
15507       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15508         ;
15509       else
15510         {
15511           clib_warning ("parse error '%U'", format_unformat_error, i);
15512           return -99;
15513         }
15514     }
15515
15516   M (IPSEC_SA_SET_KEY, mp);
15517
15518   mp->sa_id = ntohl (sa_id);
15519   mp->crypto_key_length = vec_len (ck);
15520   mp->integrity_key_length = vec_len (ik);
15521
15522   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15523     mp->crypto_key_length = sizeof (mp->crypto_key);
15524
15525   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15526     mp->integrity_key_length = sizeof (mp->integrity_key);
15527
15528   if (ck)
15529     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15530   if (ik)
15531     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15532
15533   S (mp);
15534   W (ret);
15535   return ret;
15536 }
15537
15538 static int
15539 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15540 {
15541   unformat_input_t *i = vam->input;
15542   vl_api_ipsec_tunnel_if_add_del_t *mp;
15543   u32 local_spi = 0, remote_spi = 0;
15544   u32 crypto_alg = 0, integ_alg = 0;
15545   u8 *lck = NULL, *rck = NULL;
15546   u8 *lik = NULL, *rik = NULL;
15547   ip4_address_t local_ip = { {0} };
15548   ip4_address_t remote_ip = { {0} };
15549   u8 is_add = 1;
15550   u8 esn = 0;
15551   u8 anti_replay = 0;
15552   u8 renumber = 0;
15553   u32 instance = ~0;
15554   int ret;
15555
15556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15557     {
15558       if (unformat (i, "del"))
15559         is_add = 0;
15560       else if (unformat (i, "esn"))
15561         esn = 1;
15562       else if (unformat (i, "anti_replay"))
15563         anti_replay = 1;
15564       else if (unformat (i, "local_spi %d", &local_spi))
15565         ;
15566       else if (unformat (i, "remote_spi %d", &remote_spi))
15567         ;
15568       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15569         ;
15570       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15571         ;
15572       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15573         ;
15574       else
15575         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15576         ;
15577       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15578         ;
15579       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15580         ;
15581       else
15582         if (unformat
15583             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15584         {
15585           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15586             {
15587               errmsg ("unsupported crypto-alg: '%U'\n",
15588                       format_ipsec_crypto_alg, crypto_alg);
15589               return -99;
15590             }
15591         }
15592       else
15593         if (unformat
15594             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15595         {
15596           if (integ_alg >= IPSEC_INTEG_N_ALG)
15597             {
15598               errmsg ("unsupported integ-alg: '%U'\n",
15599                       format_ipsec_integ_alg, integ_alg);
15600               return -99;
15601             }
15602         }
15603       else if (unformat (i, "instance %u", &instance))
15604         renumber = 1;
15605       else
15606         {
15607           errmsg ("parse error '%U'\n", format_unformat_error, i);
15608           return -99;
15609         }
15610     }
15611
15612   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15613
15614   mp->is_add = is_add;
15615   mp->esn = esn;
15616   mp->anti_replay = anti_replay;
15617
15618   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15619   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15620
15621   mp->local_spi = htonl (local_spi);
15622   mp->remote_spi = htonl (remote_spi);
15623   mp->crypto_alg = (u8) crypto_alg;
15624
15625   mp->local_crypto_key_len = 0;
15626   if (lck)
15627     {
15628       mp->local_crypto_key_len = vec_len (lck);
15629       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15630         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15631       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15632     }
15633
15634   mp->remote_crypto_key_len = 0;
15635   if (rck)
15636     {
15637       mp->remote_crypto_key_len = vec_len (rck);
15638       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15639         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15640       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15641     }
15642
15643   mp->integ_alg = (u8) integ_alg;
15644
15645   mp->local_integ_key_len = 0;
15646   if (lik)
15647     {
15648       mp->local_integ_key_len = vec_len (lik);
15649       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15650         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15651       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15652     }
15653
15654   mp->remote_integ_key_len = 0;
15655   if (rik)
15656     {
15657       mp->remote_integ_key_len = vec_len (rik);
15658       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15659         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15660       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15661     }
15662
15663   if (renumber)
15664     {
15665       mp->renumber = renumber;
15666       mp->show_instance = ntohl (instance);
15667     }
15668
15669   S (mp);
15670   W (ret);
15671   return ret;
15672 }
15673
15674 static void
15675 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15676 {
15677   vat_main_t *vam = &vat_main;
15678
15679   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15680          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15681          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15682          "tunnel_src_addr %U tunnel_dst_addr %U "
15683          "salt %u seq_outbound %lu last_seq_inbound %lu "
15684          "replay_window %lu total_data_size %lu\n",
15685          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15686          mp->protocol,
15687          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15688          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15689          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15690          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15691          mp->tunnel_src_addr,
15692          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15693          mp->tunnel_dst_addr,
15694          ntohl (mp->salt),
15695          clib_net_to_host_u64 (mp->seq_outbound),
15696          clib_net_to_host_u64 (mp->last_seq_inbound),
15697          clib_net_to_host_u64 (mp->replay_window),
15698          clib_net_to_host_u64 (mp->total_data_size));
15699 }
15700
15701 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15702 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15703
15704 static void vl_api_ipsec_sa_details_t_handler_json
15705   (vl_api_ipsec_sa_details_t * mp)
15706 {
15707   vat_main_t *vam = &vat_main;
15708   vat_json_node_t *node = NULL;
15709   struct in_addr src_ip4, dst_ip4;
15710   struct in6_addr src_ip6, dst_ip6;
15711
15712   if (VAT_JSON_ARRAY != vam->json_tree.type)
15713     {
15714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15715       vat_json_init_array (&vam->json_tree);
15716     }
15717   node = vat_json_array_add (&vam->json_tree);
15718
15719   vat_json_init_object (node);
15720   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15721   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15722   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15723   vat_json_object_add_uint (node, "proto", mp->protocol);
15724   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15725   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15726   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15727   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15728   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15729   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15730   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15731                              mp->crypto_key_len);
15732   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15733                              mp->integ_key_len);
15734   if (mp->is_tunnel_ip6)
15735     {
15736       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15737       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15738       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15739       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15740     }
15741   else
15742     {
15743       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15744       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15745       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15746       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15747     }
15748   vat_json_object_add_uint (node, "replay_window",
15749                             clib_net_to_host_u64 (mp->replay_window));
15750   vat_json_object_add_uint (node, "total_data_size",
15751                             clib_net_to_host_u64 (mp->total_data_size));
15752
15753 }
15754
15755 static int
15756 api_ipsec_sa_dump (vat_main_t * vam)
15757 {
15758   unformat_input_t *i = vam->input;
15759   vl_api_ipsec_sa_dump_t *mp;
15760   vl_api_control_ping_t *mp_ping;
15761   u32 sa_id = ~0;
15762   int ret;
15763
15764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15765     {
15766       if (unformat (i, "sa_id %d", &sa_id))
15767         ;
15768       else
15769         {
15770           clib_warning ("parse error '%U'", format_unformat_error, i);
15771           return -99;
15772         }
15773     }
15774
15775   M (IPSEC_SA_DUMP, mp);
15776
15777   mp->sa_id = ntohl (sa_id);
15778
15779   S (mp);
15780
15781   /* Use a control ping for synchronization */
15782   M (CONTROL_PING, mp_ping);
15783   S (mp_ping);
15784
15785   W (ret);
15786   return ret;
15787 }
15788
15789 static int
15790 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15791 {
15792   unformat_input_t *i = vam->input;
15793   vl_api_ipsec_tunnel_if_set_key_t *mp;
15794   u32 sw_if_index = ~0;
15795   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15796   u8 *key = 0;
15797   u32 alg = ~0;
15798   int ret;
15799
15800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15801     {
15802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15803         ;
15804       else
15805         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15806         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15807       else
15808         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15809         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15810       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15811         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15812       else
15813         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15814         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15815       else if (unformat (i, "%U", unformat_hex_string, &key))
15816         ;
15817       else
15818         {
15819           clib_warning ("parse error '%U'", format_unformat_error, i);
15820           return -99;
15821         }
15822     }
15823
15824   if (sw_if_index == ~0)
15825     {
15826       errmsg ("interface must be specified");
15827       return -99;
15828     }
15829
15830   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15831     {
15832       errmsg ("key type must be specified");
15833       return -99;
15834     }
15835
15836   if (alg == ~0)
15837     {
15838       errmsg ("algorithm must be specified");
15839       return -99;
15840     }
15841
15842   if (vec_len (key) == 0)
15843     {
15844       errmsg ("key must be specified");
15845       return -99;
15846     }
15847
15848   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15849
15850   mp->sw_if_index = htonl (sw_if_index);
15851   mp->alg = alg;
15852   mp->key_type = key_type;
15853   mp->key_len = vec_len (key);
15854   clib_memcpy (mp->key, key, vec_len (key));
15855
15856   S (mp);
15857   W (ret);
15858
15859   return ret;
15860 }
15861
15862 static int
15863 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15864 {
15865   unformat_input_t *i = vam->input;
15866   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15867   u32 sw_if_index = ~0;
15868   u32 sa_id = ~0;
15869   u8 is_outbound = (u8) ~ 0;
15870   int ret;
15871
15872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15873     {
15874       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15875         ;
15876       else if (unformat (i, "sa_id %d", &sa_id))
15877         ;
15878       else if (unformat (i, "outbound"))
15879         is_outbound = 1;
15880       else if (unformat (i, "inbound"))
15881         is_outbound = 0;
15882       else
15883         {
15884           clib_warning ("parse error '%U'", format_unformat_error, i);
15885           return -99;
15886         }
15887     }
15888
15889   if (sw_if_index == ~0)
15890     {
15891       errmsg ("interface must be specified");
15892       return -99;
15893     }
15894
15895   if (sa_id == ~0)
15896     {
15897       errmsg ("SA ID must be specified");
15898       return -99;
15899     }
15900
15901   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15902
15903   mp->sw_if_index = htonl (sw_if_index);
15904   mp->sa_id = htonl (sa_id);
15905   mp->is_outbound = is_outbound;
15906
15907   S (mp);
15908   W (ret);
15909
15910   return ret;
15911 }
15912
15913 static int
15914 api_ikev2_profile_add_del (vat_main_t * vam)
15915 {
15916   unformat_input_t *i = vam->input;
15917   vl_api_ikev2_profile_add_del_t *mp;
15918   u8 is_add = 1;
15919   u8 *name = 0;
15920   int ret;
15921
15922   const char *valid_chars = "a-zA-Z0-9_";
15923
15924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15925     {
15926       if (unformat (i, "del"))
15927         is_add = 0;
15928       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15929         vec_add1 (name, 0);
15930       else
15931         {
15932           errmsg ("parse error '%U'", format_unformat_error, i);
15933           return -99;
15934         }
15935     }
15936
15937   if (!vec_len (name))
15938     {
15939       errmsg ("profile name must be specified");
15940       return -99;
15941     }
15942
15943   if (vec_len (name) > 64)
15944     {
15945       errmsg ("profile name too long");
15946       return -99;
15947     }
15948
15949   M (IKEV2_PROFILE_ADD_DEL, mp);
15950
15951   clib_memcpy (mp->name, name, vec_len (name));
15952   mp->is_add = is_add;
15953   vec_free (name);
15954
15955   S (mp);
15956   W (ret);
15957   return ret;
15958 }
15959
15960 static int
15961 api_ikev2_profile_set_auth (vat_main_t * vam)
15962 {
15963   unformat_input_t *i = vam->input;
15964   vl_api_ikev2_profile_set_auth_t *mp;
15965   u8 *name = 0;
15966   u8 *data = 0;
15967   u32 auth_method = 0;
15968   u8 is_hex = 0;
15969   int ret;
15970
15971   const char *valid_chars = "a-zA-Z0-9_";
15972
15973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15976         vec_add1 (name, 0);
15977       else if (unformat (i, "auth_method %U",
15978                          unformat_ikev2_auth_method, &auth_method))
15979         ;
15980       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15981         is_hex = 1;
15982       else if (unformat (i, "auth_data %v", &data))
15983         ;
15984       else
15985         {
15986           errmsg ("parse error '%U'", format_unformat_error, i);
15987           return -99;
15988         }
15989     }
15990
15991   if (!vec_len (name))
15992     {
15993       errmsg ("profile name must be specified");
15994       return -99;
15995     }
15996
15997   if (vec_len (name) > 64)
15998     {
15999       errmsg ("profile name too long");
16000       return -99;
16001     }
16002
16003   if (!vec_len (data))
16004     {
16005       errmsg ("auth_data must be specified");
16006       return -99;
16007     }
16008
16009   if (!auth_method)
16010     {
16011       errmsg ("auth_method must be specified");
16012       return -99;
16013     }
16014
16015   M (IKEV2_PROFILE_SET_AUTH, mp);
16016
16017   mp->is_hex = is_hex;
16018   mp->auth_method = (u8) auth_method;
16019   mp->data_len = vec_len (data);
16020   clib_memcpy (mp->name, name, vec_len (name));
16021   clib_memcpy (mp->data, data, vec_len (data));
16022   vec_free (name);
16023   vec_free (data);
16024
16025   S (mp);
16026   W (ret);
16027   return ret;
16028 }
16029
16030 static int
16031 api_ikev2_profile_set_id (vat_main_t * vam)
16032 {
16033   unformat_input_t *i = vam->input;
16034   vl_api_ikev2_profile_set_id_t *mp;
16035   u8 *name = 0;
16036   u8 *data = 0;
16037   u8 is_local = 0;
16038   u32 id_type = 0;
16039   ip4_address_t ip4;
16040   int ret;
16041
16042   const char *valid_chars = "a-zA-Z0-9_";
16043
16044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16045     {
16046       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16047         vec_add1 (name, 0);
16048       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16049         ;
16050       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16051         {
16052           data = vec_new (u8, 4);
16053           clib_memcpy (data, ip4.as_u8, 4);
16054         }
16055       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16056         ;
16057       else if (unformat (i, "id_data %v", &data))
16058         ;
16059       else if (unformat (i, "local"))
16060         is_local = 1;
16061       else if (unformat (i, "remote"))
16062         is_local = 0;
16063       else
16064         {
16065           errmsg ("parse error '%U'", format_unformat_error, i);
16066           return -99;
16067         }
16068     }
16069
16070   if (!vec_len (name))
16071     {
16072       errmsg ("profile name must be specified");
16073       return -99;
16074     }
16075
16076   if (vec_len (name) > 64)
16077     {
16078       errmsg ("profile name too long");
16079       return -99;
16080     }
16081
16082   if (!vec_len (data))
16083     {
16084       errmsg ("id_data must be specified");
16085       return -99;
16086     }
16087
16088   if (!id_type)
16089     {
16090       errmsg ("id_type must be specified");
16091       return -99;
16092     }
16093
16094   M (IKEV2_PROFILE_SET_ID, mp);
16095
16096   mp->is_local = is_local;
16097   mp->id_type = (u8) id_type;
16098   mp->data_len = vec_len (data);
16099   clib_memcpy (mp->name, name, vec_len (name));
16100   clib_memcpy (mp->data, data, vec_len (data));
16101   vec_free (name);
16102   vec_free (data);
16103
16104   S (mp);
16105   W (ret);
16106   return ret;
16107 }
16108
16109 static int
16110 api_ikev2_profile_set_ts (vat_main_t * vam)
16111 {
16112   unformat_input_t *i = vam->input;
16113   vl_api_ikev2_profile_set_ts_t *mp;
16114   u8 *name = 0;
16115   u8 is_local = 0;
16116   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16117   ip4_address_t start_addr, end_addr;
16118
16119   const char *valid_chars = "a-zA-Z0-9_";
16120   int ret;
16121
16122   start_addr.as_u32 = 0;
16123   end_addr.as_u32 = (u32) ~ 0;
16124
16125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16126     {
16127       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16128         vec_add1 (name, 0);
16129       else if (unformat (i, "protocol %d", &proto))
16130         ;
16131       else if (unformat (i, "start_port %d", &start_port))
16132         ;
16133       else if (unformat (i, "end_port %d", &end_port))
16134         ;
16135       else
16136         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16137         ;
16138       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16139         ;
16140       else if (unformat (i, "local"))
16141         is_local = 1;
16142       else if (unformat (i, "remote"))
16143         is_local = 0;
16144       else
16145         {
16146           errmsg ("parse error '%U'", format_unformat_error, i);
16147           return -99;
16148         }
16149     }
16150
16151   if (!vec_len (name))
16152     {
16153       errmsg ("profile name must be specified");
16154       return -99;
16155     }
16156
16157   if (vec_len (name) > 64)
16158     {
16159       errmsg ("profile name too long");
16160       return -99;
16161     }
16162
16163   M (IKEV2_PROFILE_SET_TS, mp);
16164
16165   mp->is_local = is_local;
16166   mp->proto = (u8) proto;
16167   mp->start_port = (u16) start_port;
16168   mp->end_port = (u16) end_port;
16169   mp->start_addr = start_addr.as_u32;
16170   mp->end_addr = end_addr.as_u32;
16171   clib_memcpy (mp->name, name, vec_len (name));
16172   vec_free (name);
16173
16174   S (mp);
16175   W (ret);
16176   return ret;
16177 }
16178
16179 static int
16180 api_ikev2_set_local_key (vat_main_t * vam)
16181 {
16182   unformat_input_t *i = vam->input;
16183   vl_api_ikev2_set_local_key_t *mp;
16184   u8 *file = 0;
16185   int ret;
16186
16187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16188     {
16189       if (unformat (i, "file %v", &file))
16190         vec_add1 (file, 0);
16191       else
16192         {
16193           errmsg ("parse error '%U'", format_unformat_error, i);
16194           return -99;
16195         }
16196     }
16197
16198   if (!vec_len (file))
16199     {
16200       errmsg ("RSA key file must be specified");
16201       return -99;
16202     }
16203
16204   if (vec_len (file) > 256)
16205     {
16206       errmsg ("file name too long");
16207       return -99;
16208     }
16209
16210   M (IKEV2_SET_LOCAL_KEY, mp);
16211
16212   clib_memcpy (mp->key_file, file, vec_len (file));
16213   vec_free (file);
16214
16215   S (mp);
16216   W (ret);
16217   return ret;
16218 }
16219
16220 static int
16221 api_ikev2_set_responder (vat_main_t * vam)
16222 {
16223   unformat_input_t *i = vam->input;
16224   vl_api_ikev2_set_responder_t *mp;
16225   int ret;
16226   u8 *name = 0;
16227   u32 sw_if_index = ~0;
16228   ip4_address_t address;
16229
16230   const char *valid_chars = "a-zA-Z0-9_";
16231
16232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat
16235           (i, "%U interface %d address %U", unformat_token, valid_chars,
16236            &name, &sw_if_index, unformat_ip4_address, &address))
16237         vec_add1 (name, 0);
16238       else
16239         {
16240           errmsg ("parse error '%U'", format_unformat_error, i);
16241           return -99;
16242         }
16243     }
16244
16245   if (!vec_len (name))
16246     {
16247       errmsg ("profile name must be specified");
16248       return -99;
16249     }
16250
16251   if (vec_len (name) > 64)
16252     {
16253       errmsg ("profile name too long");
16254       return -99;
16255     }
16256
16257   M (IKEV2_SET_RESPONDER, mp);
16258
16259   clib_memcpy (mp->name, name, vec_len (name));
16260   vec_free (name);
16261
16262   mp->sw_if_index = sw_if_index;
16263   clib_memcpy (mp->address, &address, sizeof (address));
16264
16265   S (mp);
16266   W (ret);
16267   return ret;
16268 }
16269
16270 static int
16271 api_ikev2_set_ike_transforms (vat_main_t * vam)
16272 {
16273   unformat_input_t *i = vam->input;
16274   vl_api_ikev2_set_ike_transforms_t *mp;
16275   int ret;
16276   u8 *name = 0;
16277   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16278
16279   const char *valid_chars = "a-zA-Z0-9_";
16280
16281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16282     {
16283       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16284                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16285         vec_add1 (name, 0);
16286       else
16287         {
16288           errmsg ("parse error '%U'", format_unformat_error, i);
16289           return -99;
16290         }
16291     }
16292
16293   if (!vec_len (name))
16294     {
16295       errmsg ("profile name must be specified");
16296       return -99;
16297     }
16298
16299   if (vec_len (name) > 64)
16300     {
16301       errmsg ("profile name too long");
16302       return -99;
16303     }
16304
16305   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16306
16307   clib_memcpy (mp->name, name, vec_len (name));
16308   vec_free (name);
16309   mp->crypto_alg = crypto_alg;
16310   mp->crypto_key_size = crypto_key_size;
16311   mp->integ_alg = integ_alg;
16312   mp->dh_group = dh_group;
16313
16314   S (mp);
16315   W (ret);
16316   return ret;
16317 }
16318
16319
16320 static int
16321 api_ikev2_set_esp_transforms (vat_main_t * vam)
16322 {
16323   unformat_input_t *i = vam->input;
16324   vl_api_ikev2_set_esp_transforms_t *mp;
16325   int ret;
16326   u8 *name = 0;
16327   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16328
16329   const char *valid_chars = "a-zA-Z0-9_";
16330
16331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16332     {
16333       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16334                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16335         vec_add1 (name, 0);
16336       else
16337         {
16338           errmsg ("parse error '%U'", format_unformat_error, i);
16339           return -99;
16340         }
16341     }
16342
16343   if (!vec_len (name))
16344     {
16345       errmsg ("profile name must be specified");
16346       return -99;
16347     }
16348
16349   if (vec_len (name) > 64)
16350     {
16351       errmsg ("profile name too long");
16352       return -99;
16353     }
16354
16355   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16356
16357   clib_memcpy (mp->name, name, vec_len (name));
16358   vec_free (name);
16359   mp->crypto_alg = crypto_alg;
16360   mp->crypto_key_size = crypto_key_size;
16361   mp->integ_alg = integ_alg;
16362   mp->dh_group = dh_group;
16363
16364   S (mp);
16365   W (ret);
16366   return ret;
16367 }
16368
16369 static int
16370 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16371 {
16372   unformat_input_t *i = vam->input;
16373   vl_api_ikev2_set_sa_lifetime_t *mp;
16374   int ret;
16375   u8 *name = 0;
16376   u64 lifetime, lifetime_maxdata;
16377   u32 lifetime_jitter, handover;
16378
16379   const char *valid_chars = "a-zA-Z0-9_";
16380
16381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16382     {
16383       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16384                     &lifetime, &lifetime_jitter, &handover,
16385                     &lifetime_maxdata))
16386         vec_add1 (name, 0);
16387       else
16388         {
16389           errmsg ("parse error '%U'", format_unformat_error, i);
16390           return -99;
16391         }
16392     }
16393
16394   if (!vec_len (name))
16395     {
16396       errmsg ("profile name must be specified");
16397       return -99;
16398     }
16399
16400   if (vec_len (name) > 64)
16401     {
16402       errmsg ("profile name too long");
16403       return -99;
16404     }
16405
16406   M (IKEV2_SET_SA_LIFETIME, mp);
16407
16408   clib_memcpy (mp->name, name, vec_len (name));
16409   vec_free (name);
16410   mp->lifetime = lifetime;
16411   mp->lifetime_jitter = lifetime_jitter;
16412   mp->handover = handover;
16413   mp->lifetime_maxdata = lifetime_maxdata;
16414
16415   S (mp);
16416   W (ret);
16417   return ret;
16418 }
16419
16420 static int
16421 api_ikev2_initiate_sa_init (vat_main_t * vam)
16422 {
16423   unformat_input_t *i = vam->input;
16424   vl_api_ikev2_initiate_sa_init_t *mp;
16425   int ret;
16426   u8 *name = 0;
16427
16428   const char *valid_chars = "a-zA-Z0-9_";
16429
16430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16431     {
16432       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16433         vec_add1 (name, 0);
16434       else
16435         {
16436           errmsg ("parse error '%U'", format_unformat_error, i);
16437           return -99;
16438         }
16439     }
16440
16441   if (!vec_len (name))
16442     {
16443       errmsg ("profile name must be specified");
16444       return -99;
16445     }
16446
16447   if (vec_len (name) > 64)
16448     {
16449       errmsg ("profile name too long");
16450       return -99;
16451     }
16452
16453   M (IKEV2_INITIATE_SA_INIT, mp);
16454
16455   clib_memcpy (mp->name, name, vec_len (name));
16456   vec_free (name);
16457
16458   S (mp);
16459   W (ret);
16460   return ret;
16461 }
16462
16463 static int
16464 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16465 {
16466   unformat_input_t *i = vam->input;
16467   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16468   int ret;
16469   u64 ispi;
16470
16471
16472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16473     {
16474       if (unformat (i, "%lx", &ispi))
16475         ;
16476       else
16477         {
16478           errmsg ("parse error '%U'", format_unformat_error, i);
16479           return -99;
16480         }
16481     }
16482
16483   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16484
16485   mp->ispi = ispi;
16486
16487   S (mp);
16488   W (ret);
16489   return ret;
16490 }
16491
16492 static int
16493 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16494 {
16495   unformat_input_t *i = vam->input;
16496   vl_api_ikev2_initiate_del_child_sa_t *mp;
16497   int ret;
16498   u32 ispi;
16499
16500
16501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16502     {
16503       if (unformat (i, "%x", &ispi))
16504         ;
16505       else
16506         {
16507           errmsg ("parse error '%U'", format_unformat_error, i);
16508           return -99;
16509         }
16510     }
16511
16512   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16513
16514   mp->ispi = ispi;
16515
16516   S (mp);
16517   W (ret);
16518   return ret;
16519 }
16520
16521 static int
16522 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16523 {
16524   unformat_input_t *i = vam->input;
16525   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16526   int ret;
16527   u32 ispi;
16528
16529
16530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16531     {
16532       if (unformat (i, "%x", &ispi))
16533         ;
16534       else
16535         {
16536           errmsg ("parse error '%U'", format_unformat_error, i);
16537           return -99;
16538         }
16539     }
16540
16541   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16542
16543   mp->ispi = ispi;
16544
16545   S (mp);
16546   W (ret);
16547   return ret;
16548 }
16549
16550 static int
16551 api_get_first_msg_id (vat_main_t * vam)
16552 {
16553   vl_api_get_first_msg_id_t *mp;
16554   unformat_input_t *i = vam->input;
16555   u8 *name;
16556   u8 name_set = 0;
16557   int ret;
16558
16559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16560     {
16561       if (unformat (i, "client %s", &name))
16562         name_set = 1;
16563       else
16564         break;
16565     }
16566
16567   if (name_set == 0)
16568     {
16569       errmsg ("missing client name");
16570       return -99;
16571     }
16572   vec_add1 (name, 0);
16573
16574   if (vec_len (name) > 63)
16575     {
16576       errmsg ("client name too long");
16577       return -99;
16578     }
16579
16580   M (GET_FIRST_MSG_ID, mp);
16581   clib_memcpy (mp->name, name, vec_len (name));
16582   S (mp);
16583   W (ret);
16584   return ret;
16585 }
16586
16587 static int
16588 api_cop_interface_enable_disable (vat_main_t * vam)
16589 {
16590   unformat_input_t *line_input = vam->input;
16591   vl_api_cop_interface_enable_disable_t *mp;
16592   u32 sw_if_index = ~0;
16593   u8 enable_disable = 1;
16594   int ret;
16595
16596   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16597     {
16598       if (unformat (line_input, "disable"))
16599         enable_disable = 0;
16600       if (unformat (line_input, "enable"))
16601         enable_disable = 1;
16602       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16603                          vam, &sw_if_index))
16604         ;
16605       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16606         ;
16607       else
16608         break;
16609     }
16610
16611   if (sw_if_index == ~0)
16612     {
16613       errmsg ("missing interface name or sw_if_index");
16614       return -99;
16615     }
16616
16617   /* Construct the API message */
16618   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16619   mp->sw_if_index = ntohl (sw_if_index);
16620   mp->enable_disable = enable_disable;
16621
16622   /* send it... */
16623   S (mp);
16624   /* Wait for the reply */
16625   W (ret);
16626   return ret;
16627 }
16628
16629 static int
16630 api_cop_whitelist_enable_disable (vat_main_t * vam)
16631 {
16632   unformat_input_t *line_input = vam->input;
16633   vl_api_cop_whitelist_enable_disable_t *mp;
16634   u32 sw_if_index = ~0;
16635   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16636   u32 fib_id = 0;
16637   int ret;
16638
16639   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16640     {
16641       if (unformat (line_input, "ip4"))
16642         ip4 = 1;
16643       else if (unformat (line_input, "ip6"))
16644         ip6 = 1;
16645       else if (unformat (line_input, "default"))
16646         default_cop = 1;
16647       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16648                          vam, &sw_if_index))
16649         ;
16650       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16651         ;
16652       else if (unformat (line_input, "fib-id %d", &fib_id))
16653         ;
16654       else
16655         break;
16656     }
16657
16658   if (sw_if_index == ~0)
16659     {
16660       errmsg ("missing interface name or sw_if_index");
16661       return -99;
16662     }
16663
16664   /* Construct the API message */
16665   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16666   mp->sw_if_index = ntohl (sw_if_index);
16667   mp->fib_id = ntohl (fib_id);
16668   mp->ip4 = ip4;
16669   mp->ip6 = ip6;
16670   mp->default_cop = default_cop;
16671
16672   /* send it... */
16673   S (mp);
16674   /* Wait for the reply */
16675   W (ret);
16676   return ret;
16677 }
16678
16679 static int
16680 api_get_node_graph (vat_main_t * vam)
16681 {
16682   vl_api_get_node_graph_t *mp;
16683   int ret;
16684
16685   M (GET_NODE_GRAPH, mp);
16686
16687   /* send it... */
16688   S (mp);
16689   /* Wait for the reply */
16690   W (ret);
16691   return ret;
16692 }
16693
16694 /* *INDENT-OFF* */
16695 /** Used for parsing LISP eids */
16696 typedef CLIB_PACKED(struct{
16697   u8 addr[16];   /**< eid address */
16698   u32 len;       /**< prefix length if IP */
16699   u8 type;      /**< type of eid */
16700 }) lisp_eid_vat_t;
16701 /* *INDENT-ON* */
16702
16703 static uword
16704 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16705 {
16706   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16707
16708   clib_memset (a, 0, sizeof (a[0]));
16709
16710   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16711     {
16712       a->type = 0;              /* ipv4 type */
16713     }
16714   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16715     {
16716       a->type = 1;              /* ipv6 type */
16717     }
16718   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16719     {
16720       a->type = 2;              /* mac type */
16721     }
16722   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16723     {
16724       a->type = 3;              /* NSH type */
16725       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16726       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16727     }
16728   else
16729     {
16730       return 0;
16731     }
16732
16733   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16734     {
16735       return 0;
16736     }
16737
16738   return 1;
16739 }
16740
16741 static int
16742 lisp_eid_size_vat (u8 type)
16743 {
16744   switch (type)
16745     {
16746     case 0:
16747       return 4;
16748     case 1:
16749       return 16;
16750     case 2:
16751       return 6;
16752     case 3:
16753       return 5;
16754     }
16755   return 0;
16756 }
16757
16758 static void
16759 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16760 {
16761   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16762 }
16763
16764 static int
16765 api_one_add_del_locator_set (vat_main_t * vam)
16766 {
16767   unformat_input_t *input = vam->input;
16768   vl_api_one_add_del_locator_set_t *mp;
16769   u8 is_add = 1;
16770   u8 *locator_set_name = NULL;
16771   u8 locator_set_name_set = 0;
16772   vl_api_local_locator_t locator, *locators = 0;
16773   u32 sw_if_index, priority, weight;
16774   u32 data_len = 0;
16775
16776   int ret;
16777   /* Parse args required to build the message */
16778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16779     {
16780       if (unformat (input, "del"))
16781         {
16782           is_add = 0;
16783         }
16784       else if (unformat (input, "locator-set %s", &locator_set_name))
16785         {
16786           locator_set_name_set = 1;
16787         }
16788       else if (unformat (input, "sw_if_index %u p %u w %u",
16789                          &sw_if_index, &priority, &weight))
16790         {
16791           locator.sw_if_index = htonl (sw_if_index);
16792           locator.priority = priority;
16793           locator.weight = weight;
16794           vec_add1 (locators, locator);
16795         }
16796       else
16797         if (unformat
16798             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16799              &sw_if_index, &priority, &weight))
16800         {
16801           locator.sw_if_index = htonl (sw_if_index);
16802           locator.priority = priority;
16803           locator.weight = weight;
16804           vec_add1 (locators, locator);
16805         }
16806       else
16807         break;
16808     }
16809
16810   if (locator_set_name_set == 0)
16811     {
16812       errmsg ("missing locator-set name");
16813       vec_free (locators);
16814       return -99;
16815     }
16816
16817   if (vec_len (locator_set_name) > 64)
16818     {
16819       errmsg ("locator-set name too long");
16820       vec_free (locator_set_name);
16821       vec_free (locators);
16822       return -99;
16823     }
16824   vec_add1 (locator_set_name, 0);
16825
16826   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16827
16828   /* Construct the API message */
16829   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16830
16831   mp->is_add = is_add;
16832   clib_memcpy (mp->locator_set_name, locator_set_name,
16833                vec_len (locator_set_name));
16834   vec_free (locator_set_name);
16835
16836   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16837   if (locators)
16838     clib_memcpy (mp->locators, locators, data_len);
16839   vec_free (locators);
16840
16841   /* send it... */
16842   S (mp);
16843
16844   /* Wait for a reply... */
16845   W (ret);
16846   return ret;
16847 }
16848
16849 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16850
16851 static int
16852 api_one_add_del_locator (vat_main_t * vam)
16853 {
16854   unformat_input_t *input = vam->input;
16855   vl_api_one_add_del_locator_t *mp;
16856   u32 tmp_if_index = ~0;
16857   u32 sw_if_index = ~0;
16858   u8 sw_if_index_set = 0;
16859   u8 sw_if_index_if_name_set = 0;
16860   u32 priority = ~0;
16861   u8 priority_set = 0;
16862   u32 weight = ~0;
16863   u8 weight_set = 0;
16864   u8 is_add = 1;
16865   u8 *locator_set_name = NULL;
16866   u8 locator_set_name_set = 0;
16867   int ret;
16868
16869   /* Parse args required to build the message */
16870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16871     {
16872       if (unformat (input, "del"))
16873         {
16874           is_add = 0;
16875         }
16876       else if (unformat (input, "locator-set %s", &locator_set_name))
16877         {
16878           locator_set_name_set = 1;
16879         }
16880       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16881                          &tmp_if_index))
16882         {
16883           sw_if_index_if_name_set = 1;
16884           sw_if_index = tmp_if_index;
16885         }
16886       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16887         {
16888           sw_if_index_set = 1;
16889           sw_if_index = tmp_if_index;
16890         }
16891       else if (unformat (input, "p %d", &priority))
16892         {
16893           priority_set = 1;
16894         }
16895       else if (unformat (input, "w %d", &weight))
16896         {
16897           weight_set = 1;
16898         }
16899       else
16900         break;
16901     }
16902
16903   if (locator_set_name_set == 0)
16904     {
16905       errmsg ("missing locator-set name");
16906       return -99;
16907     }
16908
16909   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16910     {
16911       errmsg ("missing sw_if_index");
16912       vec_free (locator_set_name);
16913       return -99;
16914     }
16915
16916   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16917     {
16918       errmsg ("cannot use both params interface name and sw_if_index");
16919       vec_free (locator_set_name);
16920       return -99;
16921     }
16922
16923   if (priority_set == 0)
16924     {
16925       errmsg ("missing locator-set priority");
16926       vec_free (locator_set_name);
16927       return -99;
16928     }
16929
16930   if (weight_set == 0)
16931     {
16932       errmsg ("missing locator-set weight");
16933       vec_free (locator_set_name);
16934       return -99;
16935     }
16936
16937   if (vec_len (locator_set_name) > 64)
16938     {
16939       errmsg ("locator-set name too long");
16940       vec_free (locator_set_name);
16941       return -99;
16942     }
16943   vec_add1 (locator_set_name, 0);
16944
16945   /* Construct the API message */
16946   M (ONE_ADD_DEL_LOCATOR, mp);
16947
16948   mp->is_add = is_add;
16949   mp->sw_if_index = ntohl (sw_if_index);
16950   mp->priority = priority;
16951   mp->weight = weight;
16952   clib_memcpy (mp->locator_set_name, locator_set_name,
16953                vec_len (locator_set_name));
16954   vec_free (locator_set_name);
16955
16956   /* send it... */
16957   S (mp);
16958
16959   /* Wait for a reply... */
16960   W (ret);
16961   return ret;
16962 }
16963
16964 #define api_lisp_add_del_locator api_one_add_del_locator
16965
16966 uword
16967 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16968 {
16969   u32 *key_id = va_arg (*args, u32 *);
16970   u8 *s = 0;
16971
16972   if (unformat (input, "%s", &s))
16973     {
16974       if (!strcmp ((char *) s, "sha1"))
16975         key_id[0] = HMAC_SHA_1_96;
16976       else if (!strcmp ((char *) s, "sha256"))
16977         key_id[0] = HMAC_SHA_256_128;
16978       else
16979         {
16980           clib_warning ("invalid key_id: '%s'", s);
16981           key_id[0] = HMAC_NO_KEY;
16982         }
16983     }
16984   else
16985     return 0;
16986
16987   vec_free (s);
16988   return 1;
16989 }
16990
16991 static int
16992 api_one_add_del_local_eid (vat_main_t * vam)
16993 {
16994   unformat_input_t *input = vam->input;
16995   vl_api_one_add_del_local_eid_t *mp;
16996   u8 is_add = 1;
16997   u8 eid_set = 0;
16998   lisp_eid_vat_t _eid, *eid = &_eid;
16999   u8 *locator_set_name = 0;
17000   u8 locator_set_name_set = 0;
17001   u32 vni = 0;
17002   u16 key_id = 0;
17003   u8 *key = 0;
17004   int ret;
17005
17006   /* Parse args required to build the message */
17007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17008     {
17009       if (unformat (input, "del"))
17010         {
17011           is_add = 0;
17012         }
17013       else if (unformat (input, "vni %d", &vni))
17014         {
17015           ;
17016         }
17017       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17018         {
17019           eid_set = 1;
17020         }
17021       else if (unformat (input, "locator-set %s", &locator_set_name))
17022         {
17023           locator_set_name_set = 1;
17024         }
17025       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17026         ;
17027       else if (unformat (input, "secret-key %_%v%_", &key))
17028         ;
17029       else
17030         break;
17031     }
17032
17033   if (locator_set_name_set == 0)
17034     {
17035       errmsg ("missing locator-set name");
17036       return -99;
17037     }
17038
17039   if (0 == eid_set)
17040     {
17041       errmsg ("EID address not set!");
17042       vec_free (locator_set_name);
17043       return -99;
17044     }
17045
17046   if (key && (0 == key_id))
17047     {
17048       errmsg ("invalid key_id!");
17049       return -99;
17050     }
17051
17052   if (vec_len (key) > 64)
17053     {
17054       errmsg ("key too long");
17055       vec_free (key);
17056       return -99;
17057     }
17058
17059   if (vec_len (locator_set_name) > 64)
17060     {
17061       errmsg ("locator-set name too long");
17062       vec_free (locator_set_name);
17063       return -99;
17064     }
17065   vec_add1 (locator_set_name, 0);
17066
17067   /* Construct the API message */
17068   M (ONE_ADD_DEL_LOCAL_EID, mp);
17069
17070   mp->is_add = is_add;
17071   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17072   mp->eid_type = eid->type;
17073   mp->prefix_len = eid->len;
17074   mp->vni = clib_host_to_net_u32 (vni);
17075   mp->key_id = clib_host_to_net_u16 (key_id);
17076   clib_memcpy (mp->locator_set_name, locator_set_name,
17077                vec_len (locator_set_name));
17078   clib_memcpy (mp->key, key, vec_len (key));
17079
17080   vec_free (locator_set_name);
17081   vec_free (key);
17082
17083   /* send it... */
17084   S (mp);
17085
17086   /* Wait for a reply... */
17087   W (ret);
17088   return ret;
17089 }
17090
17091 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17092
17093 static int
17094 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17095 {
17096   u32 dp_table = 0, vni = 0;;
17097   unformat_input_t *input = vam->input;
17098   vl_api_gpe_add_del_fwd_entry_t *mp;
17099   u8 is_add = 1;
17100   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17101   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17102   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17103   u32 action = ~0, w;
17104   ip4_address_t rmt_rloc4, lcl_rloc4;
17105   ip6_address_t rmt_rloc6, lcl_rloc6;
17106   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17107   int ret;
17108
17109   clib_memset (&rloc, 0, sizeof (rloc));
17110
17111   /* Parse args required to build the message */
17112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17113     {
17114       if (unformat (input, "del"))
17115         is_add = 0;
17116       else if (unformat (input, "add"))
17117         is_add = 1;
17118       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17119         {
17120           rmt_eid_set = 1;
17121         }
17122       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17123         {
17124           lcl_eid_set = 1;
17125         }
17126       else if (unformat (input, "vrf %d", &dp_table))
17127         ;
17128       else if (unformat (input, "bd %d", &dp_table))
17129         ;
17130       else if (unformat (input, "vni %d", &vni))
17131         ;
17132       else if (unformat (input, "w %d", &w))
17133         {
17134           if (!curr_rloc)
17135             {
17136               errmsg ("No RLOC configured for setting priority/weight!");
17137               return -99;
17138             }
17139           curr_rloc->weight = w;
17140         }
17141       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17142                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17143         {
17144           rloc.is_ip4 = 1;
17145
17146           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17147           rloc.weight = 0;
17148           vec_add1 (lcl_locs, rloc);
17149
17150           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17151           vec_add1 (rmt_locs, rloc);
17152           /* weight saved in rmt loc */
17153           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17154         }
17155       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17156                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17157         {
17158           rloc.is_ip4 = 0;
17159           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17160           rloc.weight = 0;
17161           vec_add1 (lcl_locs, rloc);
17162
17163           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17164           vec_add1 (rmt_locs, rloc);
17165           /* weight saved in rmt loc */
17166           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17167         }
17168       else if (unformat (input, "action %d", &action))
17169         {
17170           ;
17171         }
17172       else
17173         {
17174           clib_warning ("parse error '%U'", format_unformat_error, input);
17175           return -99;
17176         }
17177     }
17178
17179   if (!rmt_eid_set)
17180     {
17181       errmsg ("remote eid addresses not set");
17182       return -99;
17183     }
17184
17185   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17186     {
17187       errmsg ("eid types don't match");
17188       return -99;
17189     }
17190
17191   if (0 == rmt_locs && (u32) ~ 0 == action)
17192     {
17193       errmsg ("action not set for negative mapping");
17194       return -99;
17195     }
17196
17197   /* Construct the API message */
17198   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17199       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17200
17201   mp->is_add = is_add;
17202   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17203   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17204   mp->eid_type = rmt_eid->type;
17205   mp->dp_table = clib_host_to_net_u32 (dp_table);
17206   mp->vni = clib_host_to_net_u32 (vni);
17207   mp->rmt_len = rmt_eid->len;
17208   mp->lcl_len = lcl_eid->len;
17209   mp->action = action;
17210
17211   if (0 != rmt_locs && 0 != lcl_locs)
17212     {
17213       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17214       clib_memcpy (mp->locs, lcl_locs,
17215                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17216
17217       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17218       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17219                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17220     }
17221   vec_free (lcl_locs);
17222   vec_free (rmt_locs);
17223
17224   /* send it... */
17225   S (mp);
17226
17227   /* Wait for a reply... */
17228   W (ret);
17229   return ret;
17230 }
17231
17232 static int
17233 api_one_add_del_map_server (vat_main_t * vam)
17234 {
17235   unformat_input_t *input = vam->input;
17236   vl_api_one_add_del_map_server_t *mp;
17237   u8 is_add = 1;
17238   u8 ipv4_set = 0;
17239   u8 ipv6_set = 0;
17240   ip4_address_t ipv4;
17241   ip6_address_t ipv6;
17242   int ret;
17243
17244   /* Parse args required to build the message */
17245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17246     {
17247       if (unformat (input, "del"))
17248         {
17249           is_add = 0;
17250         }
17251       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17252         {
17253           ipv4_set = 1;
17254         }
17255       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17256         {
17257           ipv6_set = 1;
17258         }
17259       else
17260         break;
17261     }
17262
17263   if (ipv4_set && ipv6_set)
17264     {
17265       errmsg ("both eid v4 and v6 addresses set");
17266       return -99;
17267     }
17268
17269   if (!ipv4_set && !ipv6_set)
17270     {
17271       errmsg ("eid addresses not set");
17272       return -99;
17273     }
17274
17275   /* Construct the API message */
17276   M (ONE_ADD_DEL_MAP_SERVER, mp);
17277
17278   mp->is_add = is_add;
17279   if (ipv6_set)
17280     {
17281       mp->is_ipv6 = 1;
17282       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17283     }
17284   else
17285     {
17286       mp->is_ipv6 = 0;
17287       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17288     }
17289
17290   /* send it... */
17291   S (mp);
17292
17293   /* Wait for a reply... */
17294   W (ret);
17295   return ret;
17296 }
17297
17298 #define api_lisp_add_del_map_server api_one_add_del_map_server
17299
17300 static int
17301 api_one_add_del_map_resolver (vat_main_t * vam)
17302 {
17303   unformat_input_t *input = vam->input;
17304   vl_api_one_add_del_map_resolver_t *mp;
17305   u8 is_add = 1;
17306   u8 ipv4_set = 0;
17307   u8 ipv6_set = 0;
17308   ip4_address_t ipv4;
17309   ip6_address_t ipv6;
17310   int ret;
17311
17312   /* Parse args required to build the message */
17313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17314     {
17315       if (unformat (input, "del"))
17316         {
17317           is_add = 0;
17318         }
17319       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17320         {
17321           ipv4_set = 1;
17322         }
17323       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17324         {
17325           ipv6_set = 1;
17326         }
17327       else
17328         break;
17329     }
17330
17331   if (ipv4_set && ipv6_set)
17332     {
17333       errmsg ("both eid v4 and v6 addresses set");
17334       return -99;
17335     }
17336
17337   if (!ipv4_set && !ipv6_set)
17338     {
17339       errmsg ("eid addresses not set");
17340       return -99;
17341     }
17342
17343   /* Construct the API message */
17344   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17345
17346   mp->is_add = is_add;
17347   if (ipv6_set)
17348     {
17349       mp->is_ipv6 = 1;
17350       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17351     }
17352   else
17353     {
17354       mp->is_ipv6 = 0;
17355       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17356     }
17357
17358   /* send it... */
17359   S (mp);
17360
17361   /* Wait for a reply... */
17362   W (ret);
17363   return ret;
17364 }
17365
17366 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17367
17368 static int
17369 api_lisp_gpe_enable_disable (vat_main_t * vam)
17370 {
17371   unformat_input_t *input = vam->input;
17372   vl_api_gpe_enable_disable_t *mp;
17373   u8 is_set = 0;
17374   u8 is_en = 1;
17375   int ret;
17376
17377   /* Parse args required to build the message */
17378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17379     {
17380       if (unformat (input, "enable"))
17381         {
17382           is_set = 1;
17383           is_en = 1;
17384         }
17385       else if (unformat (input, "disable"))
17386         {
17387           is_set = 1;
17388           is_en = 0;
17389         }
17390       else
17391         break;
17392     }
17393
17394   if (is_set == 0)
17395     {
17396       errmsg ("Value not set");
17397       return -99;
17398     }
17399
17400   /* Construct the API message */
17401   M (GPE_ENABLE_DISABLE, mp);
17402
17403   mp->is_en = is_en;
17404
17405   /* send it... */
17406   S (mp);
17407
17408   /* Wait for a reply... */
17409   W (ret);
17410   return ret;
17411 }
17412
17413 static int
17414 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17415 {
17416   unformat_input_t *input = vam->input;
17417   vl_api_one_rloc_probe_enable_disable_t *mp;
17418   u8 is_set = 0;
17419   u8 is_en = 0;
17420   int ret;
17421
17422   /* Parse args required to build the message */
17423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17424     {
17425       if (unformat (input, "enable"))
17426         {
17427           is_set = 1;
17428           is_en = 1;
17429         }
17430       else if (unformat (input, "disable"))
17431         is_set = 1;
17432       else
17433         break;
17434     }
17435
17436   if (!is_set)
17437     {
17438       errmsg ("Value not set");
17439       return -99;
17440     }
17441
17442   /* Construct the API message */
17443   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17444
17445   mp->is_enabled = is_en;
17446
17447   /* send it... */
17448   S (mp);
17449
17450   /* Wait for a reply... */
17451   W (ret);
17452   return ret;
17453 }
17454
17455 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17456
17457 static int
17458 api_one_map_register_enable_disable (vat_main_t * vam)
17459 {
17460   unformat_input_t *input = vam->input;
17461   vl_api_one_map_register_enable_disable_t *mp;
17462   u8 is_set = 0;
17463   u8 is_en = 0;
17464   int ret;
17465
17466   /* Parse args required to build the message */
17467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17468     {
17469       if (unformat (input, "enable"))
17470         {
17471           is_set = 1;
17472           is_en = 1;
17473         }
17474       else if (unformat (input, "disable"))
17475         is_set = 1;
17476       else
17477         break;
17478     }
17479
17480   if (!is_set)
17481     {
17482       errmsg ("Value not set");
17483       return -99;
17484     }
17485
17486   /* Construct the API message */
17487   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17488
17489   mp->is_enabled = is_en;
17490
17491   /* send it... */
17492   S (mp);
17493
17494   /* Wait for a reply... */
17495   W (ret);
17496   return ret;
17497 }
17498
17499 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17500
17501 static int
17502 api_one_enable_disable (vat_main_t * vam)
17503 {
17504   unformat_input_t *input = vam->input;
17505   vl_api_one_enable_disable_t *mp;
17506   u8 is_set = 0;
17507   u8 is_en = 0;
17508   int ret;
17509
17510   /* Parse args required to build the message */
17511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17512     {
17513       if (unformat (input, "enable"))
17514         {
17515           is_set = 1;
17516           is_en = 1;
17517         }
17518       else if (unformat (input, "disable"))
17519         {
17520           is_set = 1;
17521         }
17522       else
17523         break;
17524     }
17525
17526   if (!is_set)
17527     {
17528       errmsg ("Value not set");
17529       return -99;
17530     }
17531
17532   /* Construct the API message */
17533   M (ONE_ENABLE_DISABLE, mp);
17534
17535   mp->is_en = is_en;
17536
17537   /* send it... */
17538   S (mp);
17539
17540   /* Wait for a reply... */
17541   W (ret);
17542   return ret;
17543 }
17544
17545 #define api_lisp_enable_disable api_one_enable_disable
17546
17547 static int
17548 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17549 {
17550   unformat_input_t *input = vam->input;
17551   vl_api_one_enable_disable_xtr_mode_t *mp;
17552   u8 is_set = 0;
17553   u8 is_en = 0;
17554   int ret;
17555
17556   /* Parse args required to build the message */
17557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17558     {
17559       if (unformat (input, "enable"))
17560         {
17561           is_set = 1;
17562           is_en = 1;
17563         }
17564       else if (unformat (input, "disable"))
17565         {
17566           is_set = 1;
17567         }
17568       else
17569         break;
17570     }
17571
17572   if (!is_set)
17573     {
17574       errmsg ("Value not set");
17575       return -99;
17576     }
17577
17578   /* Construct the API message */
17579   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17580
17581   mp->is_en = is_en;
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_show_xtr_mode (vat_main_t * vam)
17593 {
17594   vl_api_one_show_xtr_mode_t *mp;
17595   int ret;
17596
17597   /* Construct the API message */
17598   M (ONE_SHOW_XTR_MODE, mp);
17599
17600   /* send it... */
17601   S (mp);
17602
17603   /* Wait for a reply... */
17604   W (ret);
17605   return ret;
17606 }
17607
17608 static int
17609 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17610 {
17611   unformat_input_t *input = vam->input;
17612   vl_api_one_enable_disable_pitr_mode_t *mp;
17613   u8 is_set = 0;
17614   u8 is_en = 0;
17615   int ret;
17616
17617   /* Parse args required to build the message */
17618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17619     {
17620       if (unformat (input, "enable"))
17621         {
17622           is_set = 1;
17623           is_en = 1;
17624         }
17625       else if (unformat (input, "disable"))
17626         {
17627           is_set = 1;
17628         }
17629       else
17630         break;
17631     }
17632
17633   if (!is_set)
17634     {
17635       errmsg ("Value not set");
17636       return -99;
17637     }
17638
17639   /* Construct the API message */
17640   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17641
17642   mp->is_en = is_en;
17643
17644   /* send it... */
17645   S (mp);
17646
17647   /* Wait for a reply... */
17648   W (ret);
17649   return ret;
17650 }
17651
17652 static int
17653 api_one_show_pitr_mode (vat_main_t * vam)
17654 {
17655   vl_api_one_show_pitr_mode_t *mp;
17656   int ret;
17657
17658   /* Construct the API message */
17659   M (ONE_SHOW_PITR_MODE, mp);
17660
17661   /* send it... */
17662   S (mp);
17663
17664   /* Wait for a reply... */
17665   W (ret);
17666   return ret;
17667 }
17668
17669 static int
17670 api_one_enable_disable_petr_mode (vat_main_t * vam)
17671 {
17672   unformat_input_t *input = vam->input;
17673   vl_api_one_enable_disable_petr_mode_t *mp;
17674   u8 is_set = 0;
17675   u8 is_en = 0;
17676   int ret;
17677
17678   /* Parse args required to build the message */
17679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17680     {
17681       if (unformat (input, "enable"))
17682         {
17683           is_set = 1;
17684           is_en = 1;
17685         }
17686       else if (unformat (input, "disable"))
17687         {
17688           is_set = 1;
17689         }
17690       else
17691         break;
17692     }
17693
17694   if (!is_set)
17695     {
17696       errmsg ("Value not set");
17697       return -99;
17698     }
17699
17700   /* Construct the API message */
17701   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17702
17703   mp->is_en = is_en;
17704
17705   /* send it... */
17706   S (mp);
17707
17708   /* Wait for a reply... */
17709   W (ret);
17710   return ret;
17711 }
17712
17713 static int
17714 api_one_show_petr_mode (vat_main_t * vam)
17715 {
17716   vl_api_one_show_petr_mode_t *mp;
17717   int ret;
17718
17719   /* Construct the API message */
17720   M (ONE_SHOW_PETR_MODE, mp);
17721
17722   /* send it... */
17723   S (mp);
17724
17725   /* Wait for a reply... */
17726   W (ret);
17727   return ret;
17728 }
17729
17730 static int
17731 api_show_one_map_register_state (vat_main_t * vam)
17732 {
17733   vl_api_show_one_map_register_state_t *mp;
17734   int ret;
17735
17736   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17737
17738   /* send */
17739   S (mp);
17740
17741   /* wait for reply */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 #define api_show_lisp_map_register_state api_show_one_map_register_state
17747
17748 static int
17749 api_show_one_rloc_probe_state (vat_main_t * vam)
17750 {
17751   vl_api_show_one_rloc_probe_state_t *mp;
17752   int ret;
17753
17754   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17755
17756   /* send */
17757   S (mp);
17758
17759   /* wait for reply */
17760   W (ret);
17761   return ret;
17762 }
17763
17764 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17765
17766 static int
17767 api_one_add_del_ndp_entry (vat_main_t * vam)
17768 {
17769   vl_api_one_add_del_ndp_entry_t *mp;
17770   unformat_input_t *input = vam->input;
17771   u8 is_add = 1;
17772   u8 mac_set = 0;
17773   u8 bd_set = 0;
17774   u8 ip_set = 0;
17775   u8 mac[6] = { 0, };
17776   u8 ip6[16] = { 0, };
17777   u32 bd = ~0;
17778   int ret;
17779
17780   /* Parse args required to build the message */
17781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17782     {
17783       if (unformat (input, "del"))
17784         is_add = 0;
17785       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17786         mac_set = 1;
17787       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17788         ip_set = 1;
17789       else if (unformat (input, "bd %d", &bd))
17790         bd_set = 1;
17791       else
17792         {
17793           errmsg ("parse error '%U'", format_unformat_error, input);
17794           return -99;
17795         }
17796     }
17797
17798   if (!bd_set || !ip_set || (!mac_set && is_add))
17799     {
17800       errmsg ("Missing BD, IP or MAC!");
17801       return -99;
17802     }
17803
17804   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17805   mp->is_add = is_add;
17806   clib_memcpy (mp->mac, mac, 6);
17807   mp->bd = clib_host_to_net_u32 (bd);
17808   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17809
17810   /* send */
17811   S (mp);
17812
17813   /* wait for reply */
17814   W (ret);
17815   return ret;
17816 }
17817
17818 static int
17819 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17820 {
17821   vl_api_one_add_del_l2_arp_entry_t *mp;
17822   unformat_input_t *input = vam->input;
17823   u8 is_add = 1;
17824   u8 mac_set = 0;
17825   u8 bd_set = 0;
17826   u8 ip_set = 0;
17827   u8 mac[6] = { 0, };
17828   u32 ip4 = 0, bd = ~0;
17829   int ret;
17830
17831   /* Parse args required to build the message */
17832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17833     {
17834       if (unformat (input, "del"))
17835         is_add = 0;
17836       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17837         mac_set = 1;
17838       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17839         ip_set = 1;
17840       else if (unformat (input, "bd %d", &bd))
17841         bd_set = 1;
17842       else
17843         {
17844           errmsg ("parse error '%U'", format_unformat_error, input);
17845           return -99;
17846         }
17847     }
17848
17849   if (!bd_set || !ip_set || (!mac_set && is_add))
17850     {
17851       errmsg ("Missing BD, IP or MAC!");
17852       return -99;
17853     }
17854
17855   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17856   mp->is_add = is_add;
17857   clib_memcpy (mp->mac, mac, 6);
17858   mp->bd = clib_host_to_net_u32 (bd);
17859   mp->ip4 = ip4;
17860
17861   /* send */
17862   S (mp);
17863
17864   /* wait for reply */
17865   W (ret);
17866   return ret;
17867 }
17868
17869 static int
17870 api_one_ndp_bd_get (vat_main_t * vam)
17871 {
17872   vl_api_one_ndp_bd_get_t *mp;
17873   int ret;
17874
17875   M (ONE_NDP_BD_GET, mp);
17876
17877   /* send */
17878   S (mp);
17879
17880   /* wait for reply */
17881   W (ret);
17882   return ret;
17883 }
17884
17885 static int
17886 api_one_ndp_entries_get (vat_main_t * vam)
17887 {
17888   vl_api_one_ndp_entries_get_t *mp;
17889   unformat_input_t *input = vam->input;
17890   u8 bd_set = 0;
17891   u32 bd = ~0;
17892   int ret;
17893
17894   /* Parse args required to build the message */
17895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17896     {
17897       if (unformat (input, "bd %d", &bd))
17898         bd_set = 1;
17899       else
17900         {
17901           errmsg ("parse error '%U'", format_unformat_error, input);
17902           return -99;
17903         }
17904     }
17905
17906   if (!bd_set)
17907     {
17908       errmsg ("Expected bridge domain!");
17909       return -99;
17910     }
17911
17912   M (ONE_NDP_ENTRIES_GET, mp);
17913   mp->bd = clib_host_to_net_u32 (bd);
17914
17915   /* send */
17916   S (mp);
17917
17918   /* wait for reply */
17919   W (ret);
17920   return ret;
17921 }
17922
17923 static int
17924 api_one_l2_arp_bd_get (vat_main_t * vam)
17925 {
17926   vl_api_one_l2_arp_bd_get_t *mp;
17927   int ret;
17928
17929   M (ONE_L2_ARP_BD_GET, mp);
17930
17931   /* send */
17932   S (mp);
17933
17934   /* wait for reply */
17935   W (ret);
17936   return ret;
17937 }
17938
17939 static int
17940 api_one_l2_arp_entries_get (vat_main_t * vam)
17941 {
17942   vl_api_one_l2_arp_entries_get_t *mp;
17943   unformat_input_t *input = vam->input;
17944   u8 bd_set = 0;
17945   u32 bd = ~0;
17946   int ret;
17947
17948   /* Parse args required to build the message */
17949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17950     {
17951       if (unformat (input, "bd %d", &bd))
17952         bd_set = 1;
17953       else
17954         {
17955           errmsg ("parse error '%U'", format_unformat_error, input);
17956           return -99;
17957         }
17958     }
17959
17960   if (!bd_set)
17961     {
17962       errmsg ("Expected bridge domain!");
17963       return -99;
17964     }
17965
17966   M (ONE_L2_ARP_ENTRIES_GET, mp);
17967   mp->bd = clib_host_to_net_u32 (bd);
17968
17969   /* send */
17970   S (mp);
17971
17972   /* wait for reply */
17973   W (ret);
17974   return ret;
17975 }
17976
17977 static int
17978 api_one_stats_enable_disable (vat_main_t * vam)
17979 {
17980   vl_api_one_stats_enable_disable_t *mp;
17981   unformat_input_t *input = vam->input;
17982   u8 is_set = 0;
17983   u8 is_en = 0;
17984   int ret;
17985
17986   /* Parse args required to build the message */
17987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17988     {
17989       if (unformat (input, "enable"))
17990         {
17991           is_set = 1;
17992           is_en = 1;
17993         }
17994       else if (unformat (input, "disable"))
17995         {
17996           is_set = 1;
17997         }
17998       else
17999         break;
18000     }
18001
18002   if (!is_set)
18003     {
18004       errmsg ("Value not set");
18005       return -99;
18006     }
18007
18008   M (ONE_STATS_ENABLE_DISABLE, mp);
18009   mp->is_en = is_en;
18010
18011   /* send */
18012   S (mp);
18013
18014   /* wait for reply */
18015   W (ret);
18016   return ret;
18017 }
18018
18019 static int
18020 api_show_one_stats_enable_disable (vat_main_t * vam)
18021 {
18022   vl_api_show_one_stats_enable_disable_t *mp;
18023   int ret;
18024
18025   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18026
18027   /* send */
18028   S (mp);
18029
18030   /* wait for reply */
18031   W (ret);
18032   return ret;
18033 }
18034
18035 static int
18036 api_show_one_map_request_mode (vat_main_t * vam)
18037 {
18038   vl_api_show_one_map_request_mode_t *mp;
18039   int ret;
18040
18041   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18042
18043   /* send */
18044   S (mp);
18045
18046   /* wait for reply */
18047   W (ret);
18048   return ret;
18049 }
18050
18051 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18052
18053 static int
18054 api_one_map_request_mode (vat_main_t * vam)
18055 {
18056   unformat_input_t *input = vam->input;
18057   vl_api_one_map_request_mode_t *mp;
18058   u8 mode = 0;
18059   int ret;
18060
18061   /* Parse args required to build the message */
18062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18063     {
18064       if (unformat (input, "dst-only"))
18065         mode = 0;
18066       else if (unformat (input, "src-dst"))
18067         mode = 1;
18068       else
18069         {
18070           errmsg ("parse error '%U'", format_unformat_error, input);
18071           return -99;
18072         }
18073     }
18074
18075   M (ONE_MAP_REQUEST_MODE, mp);
18076
18077   mp->mode = mode;
18078
18079   /* send */
18080   S (mp);
18081
18082   /* wait for reply */
18083   W (ret);
18084   return ret;
18085 }
18086
18087 #define api_lisp_map_request_mode api_one_map_request_mode
18088
18089 /**
18090  * Enable/disable ONE proxy ITR.
18091  *
18092  * @param vam vpp API test context
18093  * @return return code
18094  */
18095 static int
18096 api_one_pitr_set_locator_set (vat_main_t * vam)
18097 {
18098   u8 ls_name_set = 0;
18099   unformat_input_t *input = vam->input;
18100   vl_api_one_pitr_set_locator_set_t *mp;
18101   u8 is_add = 1;
18102   u8 *ls_name = 0;
18103   int ret;
18104
18105   /* Parse args required to build the message */
18106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18107     {
18108       if (unformat (input, "del"))
18109         is_add = 0;
18110       else if (unformat (input, "locator-set %s", &ls_name))
18111         ls_name_set = 1;
18112       else
18113         {
18114           errmsg ("parse error '%U'", format_unformat_error, input);
18115           return -99;
18116         }
18117     }
18118
18119   if (!ls_name_set)
18120     {
18121       errmsg ("locator-set name not set!");
18122       return -99;
18123     }
18124
18125   M (ONE_PITR_SET_LOCATOR_SET, mp);
18126
18127   mp->is_add = is_add;
18128   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18129   vec_free (ls_name);
18130
18131   /* send */
18132   S (mp);
18133
18134   /* wait for reply */
18135   W (ret);
18136   return ret;
18137 }
18138
18139 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18140
18141 static int
18142 api_one_nsh_set_locator_set (vat_main_t * vam)
18143 {
18144   u8 ls_name_set = 0;
18145   unformat_input_t *input = vam->input;
18146   vl_api_one_nsh_set_locator_set_t *mp;
18147   u8 is_add = 1;
18148   u8 *ls_name = 0;
18149   int ret;
18150
18151   /* Parse args required to build the message */
18152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18153     {
18154       if (unformat (input, "del"))
18155         is_add = 0;
18156       else if (unformat (input, "ls %s", &ls_name))
18157         ls_name_set = 1;
18158       else
18159         {
18160           errmsg ("parse error '%U'", format_unformat_error, input);
18161           return -99;
18162         }
18163     }
18164
18165   if (!ls_name_set && is_add)
18166     {
18167       errmsg ("locator-set name not set!");
18168       return -99;
18169     }
18170
18171   M (ONE_NSH_SET_LOCATOR_SET, mp);
18172
18173   mp->is_add = is_add;
18174   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18175   vec_free (ls_name);
18176
18177   /* send */
18178   S (mp);
18179
18180   /* wait for reply */
18181   W (ret);
18182   return ret;
18183 }
18184
18185 static int
18186 api_show_one_pitr (vat_main_t * vam)
18187 {
18188   vl_api_show_one_pitr_t *mp;
18189   int ret;
18190
18191   if (!vam->json_output)
18192     {
18193       print (vam->ofp, "%=20s", "lisp status:");
18194     }
18195
18196   M (SHOW_ONE_PITR, mp);
18197   /* send it... */
18198   S (mp);
18199
18200   /* Wait for a reply... */
18201   W (ret);
18202   return ret;
18203 }
18204
18205 #define api_show_lisp_pitr api_show_one_pitr
18206
18207 static int
18208 api_one_use_petr (vat_main_t * vam)
18209 {
18210   unformat_input_t *input = vam->input;
18211   vl_api_one_use_petr_t *mp;
18212   u8 is_add = 0;
18213   ip_address_t ip;
18214   int ret;
18215
18216   clib_memset (&ip, 0, sizeof (ip));
18217
18218   /* Parse args required to build the message */
18219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18220     {
18221       if (unformat (input, "disable"))
18222         is_add = 0;
18223       else
18224         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18225         {
18226           is_add = 1;
18227           ip_addr_version (&ip) = IP4;
18228         }
18229       else
18230         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18231         {
18232           is_add = 1;
18233           ip_addr_version (&ip) = IP6;
18234         }
18235       else
18236         {
18237           errmsg ("parse error '%U'", format_unformat_error, input);
18238           return -99;
18239         }
18240     }
18241
18242   M (ONE_USE_PETR, mp);
18243
18244   mp->is_add = is_add;
18245   if (is_add)
18246     {
18247       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18248       if (mp->is_ip4)
18249         clib_memcpy (mp->address, &ip, 4);
18250       else
18251         clib_memcpy (mp->address, &ip, 16);
18252     }
18253
18254   /* send */
18255   S (mp);
18256
18257   /* wait for reply */
18258   W (ret);
18259   return ret;
18260 }
18261
18262 #define api_lisp_use_petr api_one_use_petr
18263
18264 static int
18265 api_show_one_nsh_mapping (vat_main_t * vam)
18266 {
18267   vl_api_show_one_use_petr_t *mp;
18268   int ret;
18269
18270   if (!vam->json_output)
18271     {
18272       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18273     }
18274
18275   M (SHOW_ONE_NSH_MAPPING, mp);
18276   /* send it... */
18277   S (mp);
18278
18279   /* Wait for a reply... */
18280   W (ret);
18281   return ret;
18282 }
18283
18284 static int
18285 api_show_one_use_petr (vat_main_t * vam)
18286 {
18287   vl_api_show_one_use_petr_t *mp;
18288   int ret;
18289
18290   if (!vam->json_output)
18291     {
18292       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18293     }
18294
18295   M (SHOW_ONE_USE_PETR, mp);
18296   /* send it... */
18297   S (mp);
18298
18299   /* Wait for a reply... */
18300   W (ret);
18301   return ret;
18302 }
18303
18304 #define api_show_lisp_use_petr api_show_one_use_petr
18305
18306 /**
18307  * Add/delete mapping between vni and vrf
18308  */
18309 static int
18310 api_one_eid_table_add_del_map (vat_main_t * vam)
18311 {
18312   unformat_input_t *input = vam->input;
18313   vl_api_one_eid_table_add_del_map_t *mp;
18314   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18315   u32 vni, vrf, bd_index;
18316   int ret;
18317
18318   /* Parse args required to build the message */
18319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18320     {
18321       if (unformat (input, "del"))
18322         is_add = 0;
18323       else if (unformat (input, "vrf %d", &vrf))
18324         vrf_set = 1;
18325       else if (unformat (input, "bd_index %d", &bd_index))
18326         bd_index_set = 1;
18327       else if (unformat (input, "vni %d", &vni))
18328         vni_set = 1;
18329       else
18330         break;
18331     }
18332
18333   if (!vni_set || (!vrf_set && !bd_index_set))
18334     {
18335       errmsg ("missing arguments!");
18336       return -99;
18337     }
18338
18339   if (vrf_set && bd_index_set)
18340     {
18341       errmsg ("error: both vrf and bd entered!");
18342       return -99;
18343     }
18344
18345   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18346
18347   mp->is_add = is_add;
18348   mp->vni = htonl (vni);
18349   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18350   mp->is_l2 = bd_index_set;
18351
18352   /* send */
18353   S (mp);
18354
18355   /* wait for reply */
18356   W (ret);
18357   return ret;
18358 }
18359
18360 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18361
18362 uword
18363 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18364 {
18365   u32 *action = va_arg (*args, u32 *);
18366   u8 *s = 0;
18367
18368   if (unformat (input, "%s", &s))
18369     {
18370       if (!strcmp ((char *) s, "no-action"))
18371         action[0] = 0;
18372       else if (!strcmp ((char *) s, "natively-forward"))
18373         action[0] = 1;
18374       else if (!strcmp ((char *) s, "send-map-request"))
18375         action[0] = 2;
18376       else if (!strcmp ((char *) s, "drop"))
18377         action[0] = 3;
18378       else
18379         {
18380           clib_warning ("invalid action: '%s'", s);
18381           action[0] = 3;
18382         }
18383     }
18384   else
18385     return 0;
18386
18387   vec_free (s);
18388   return 1;
18389 }
18390
18391 /**
18392  * Add/del remote mapping to/from ONE control plane
18393  *
18394  * @param vam vpp API test context
18395  * @return return code
18396  */
18397 static int
18398 api_one_add_del_remote_mapping (vat_main_t * vam)
18399 {
18400   unformat_input_t *input = vam->input;
18401   vl_api_one_add_del_remote_mapping_t *mp;
18402   u32 vni = 0;
18403   lisp_eid_vat_t _eid, *eid = &_eid;
18404   lisp_eid_vat_t _seid, *seid = &_seid;
18405   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18406   u32 action = ~0, p, w, data_len;
18407   ip4_address_t rloc4;
18408   ip6_address_t rloc6;
18409   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18410   int ret;
18411
18412   clib_memset (&rloc, 0, sizeof (rloc));
18413
18414   /* Parse args required to build the message */
18415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18416     {
18417       if (unformat (input, "del-all"))
18418         {
18419           del_all = 1;
18420         }
18421       else if (unformat (input, "del"))
18422         {
18423           is_add = 0;
18424         }
18425       else if (unformat (input, "add"))
18426         {
18427           is_add = 1;
18428         }
18429       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18430         {
18431           eid_set = 1;
18432         }
18433       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18434         {
18435           seid_set = 1;
18436         }
18437       else if (unformat (input, "vni %d", &vni))
18438         {
18439           ;
18440         }
18441       else if (unformat (input, "p %d w %d", &p, &w))
18442         {
18443           if (!curr_rloc)
18444             {
18445               errmsg ("No RLOC configured for setting priority/weight!");
18446               return -99;
18447             }
18448           curr_rloc->priority = p;
18449           curr_rloc->weight = w;
18450         }
18451       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18452         {
18453           rloc.is_ip4 = 1;
18454           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18455           vec_add1 (rlocs, rloc);
18456           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18457         }
18458       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18459         {
18460           rloc.is_ip4 = 0;
18461           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18462           vec_add1 (rlocs, rloc);
18463           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18464         }
18465       else if (unformat (input, "action %U",
18466                          unformat_negative_mapping_action, &action))
18467         {
18468           ;
18469         }
18470       else
18471         {
18472           clib_warning ("parse error '%U'", format_unformat_error, input);
18473           return -99;
18474         }
18475     }
18476
18477   if (0 == eid_set)
18478     {
18479       errmsg ("missing params!");
18480       return -99;
18481     }
18482
18483   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18484     {
18485       errmsg ("no action set for negative map-reply!");
18486       return -99;
18487     }
18488
18489   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18490
18491   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18492   mp->is_add = is_add;
18493   mp->vni = htonl (vni);
18494   mp->action = (u8) action;
18495   mp->is_src_dst = seid_set;
18496   mp->eid_len = eid->len;
18497   mp->seid_len = seid->len;
18498   mp->del_all = del_all;
18499   mp->eid_type = eid->type;
18500   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18501   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18502
18503   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18504   clib_memcpy (mp->rlocs, rlocs, data_len);
18505   vec_free (rlocs);
18506
18507   /* send it... */
18508   S (mp);
18509
18510   /* Wait for a reply... */
18511   W (ret);
18512   return ret;
18513 }
18514
18515 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18516
18517 /**
18518  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18519  * forwarding entries in data-plane accordingly.
18520  *
18521  * @param vam vpp API test context
18522  * @return return code
18523  */
18524 static int
18525 api_one_add_del_adjacency (vat_main_t * vam)
18526 {
18527   unformat_input_t *input = vam->input;
18528   vl_api_one_add_del_adjacency_t *mp;
18529   u32 vni = 0;
18530   ip4_address_t leid4, reid4;
18531   ip6_address_t leid6, reid6;
18532   u8 reid_mac[6] = { 0 };
18533   u8 leid_mac[6] = { 0 };
18534   u8 reid_type, leid_type;
18535   u32 leid_len = 0, reid_len = 0, len;
18536   u8 is_add = 1;
18537   int ret;
18538
18539   leid_type = reid_type = (u8) ~ 0;
18540
18541   /* Parse args required to build the message */
18542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18543     {
18544       if (unformat (input, "del"))
18545         {
18546           is_add = 0;
18547         }
18548       else if (unformat (input, "add"))
18549         {
18550           is_add = 1;
18551         }
18552       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18553                          &reid4, &len))
18554         {
18555           reid_type = 0;        /* ipv4 */
18556           reid_len = len;
18557         }
18558       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18559                          &reid6, &len))
18560         {
18561           reid_type = 1;        /* ipv6 */
18562           reid_len = len;
18563         }
18564       else if (unformat (input, "reid %U", unformat_ethernet_address,
18565                          reid_mac))
18566         {
18567           reid_type = 2;        /* mac */
18568         }
18569       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18570                          &leid4, &len))
18571         {
18572           leid_type = 0;        /* ipv4 */
18573           leid_len = len;
18574         }
18575       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18576                          &leid6, &len))
18577         {
18578           leid_type = 1;        /* ipv6 */
18579           leid_len = len;
18580         }
18581       else if (unformat (input, "leid %U", unformat_ethernet_address,
18582                          leid_mac))
18583         {
18584           leid_type = 2;        /* mac */
18585         }
18586       else if (unformat (input, "vni %d", &vni))
18587         {
18588           ;
18589         }
18590       else
18591         {
18592           errmsg ("parse error '%U'", format_unformat_error, input);
18593           return -99;
18594         }
18595     }
18596
18597   if ((u8) ~ 0 == reid_type)
18598     {
18599       errmsg ("missing params!");
18600       return -99;
18601     }
18602
18603   if (leid_type != reid_type)
18604     {
18605       errmsg ("remote and local EIDs are of different types!");
18606       return -99;
18607     }
18608
18609   M (ONE_ADD_DEL_ADJACENCY, mp);
18610   mp->is_add = is_add;
18611   mp->vni = htonl (vni);
18612   mp->leid_len = leid_len;
18613   mp->reid_len = reid_len;
18614   mp->eid_type = reid_type;
18615
18616   switch (mp->eid_type)
18617     {
18618     case 0:
18619       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18620       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18621       break;
18622     case 1:
18623       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18624       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18625       break;
18626     case 2:
18627       clib_memcpy (mp->leid, leid_mac, 6);
18628       clib_memcpy (mp->reid, reid_mac, 6);
18629       break;
18630     default:
18631       errmsg ("unknown EID type %d!", mp->eid_type);
18632       return 0;
18633     }
18634
18635   /* send it... */
18636   S (mp);
18637
18638   /* Wait for a reply... */
18639   W (ret);
18640   return ret;
18641 }
18642
18643 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18644
18645 uword
18646 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18647 {
18648   u32 *mode = va_arg (*args, u32 *);
18649
18650   if (unformat (input, "lisp"))
18651     *mode = 0;
18652   else if (unformat (input, "vxlan"))
18653     *mode = 1;
18654   else
18655     return 0;
18656
18657   return 1;
18658 }
18659
18660 static int
18661 api_gpe_get_encap_mode (vat_main_t * vam)
18662 {
18663   vl_api_gpe_get_encap_mode_t *mp;
18664   int ret;
18665
18666   /* Construct the API message */
18667   M (GPE_GET_ENCAP_MODE, mp);
18668
18669   /* send it... */
18670   S (mp);
18671
18672   /* Wait for a reply... */
18673   W (ret);
18674   return ret;
18675 }
18676
18677 static int
18678 api_gpe_set_encap_mode (vat_main_t * vam)
18679 {
18680   unformat_input_t *input = vam->input;
18681   vl_api_gpe_set_encap_mode_t *mp;
18682   int ret;
18683   u32 mode = 0;
18684
18685   /* Parse args required to build the message */
18686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18687     {
18688       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18689         ;
18690       else
18691         break;
18692     }
18693
18694   /* Construct the API message */
18695   M (GPE_SET_ENCAP_MODE, mp);
18696
18697   mp->mode = mode;
18698
18699   /* send it... */
18700   S (mp);
18701
18702   /* Wait for a reply... */
18703   W (ret);
18704   return ret;
18705 }
18706
18707 static int
18708 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18709 {
18710   unformat_input_t *input = vam->input;
18711   vl_api_gpe_add_del_iface_t *mp;
18712   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18713   u32 dp_table = 0, vni = 0;
18714   int ret;
18715
18716   /* Parse args required to build the message */
18717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18718     {
18719       if (unformat (input, "up"))
18720         {
18721           action_set = 1;
18722           is_add = 1;
18723         }
18724       else if (unformat (input, "down"))
18725         {
18726           action_set = 1;
18727           is_add = 0;
18728         }
18729       else if (unformat (input, "table_id %d", &dp_table))
18730         {
18731           dp_table_set = 1;
18732         }
18733       else if (unformat (input, "bd_id %d", &dp_table))
18734         {
18735           dp_table_set = 1;
18736           is_l2 = 1;
18737         }
18738       else if (unformat (input, "vni %d", &vni))
18739         {
18740           vni_set = 1;
18741         }
18742       else
18743         break;
18744     }
18745
18746   if (action_set == 0)
18747     {
18748       errmsg ("Action not set");
18749       return -99;
18750     }
18751   if (dp_table_set == 0 || vni_set == 0)
18752     {
18753       errmsg ("vni and dp_table must be set");
18754       return -99;
18755     }
18756
18757   /* Construct the API message */
18758   M (GPE_ADD_DEL_IFACE, mp);
18759
18760   mp->is_add = is_add;
18761   mp->dp_table = clib_host_to_net_u32 (dp_table);
18762   mp->is_l2 = is_l2;
18763   mp->vni = clib_host_to_net_u32 (vni);
18764
18765   /* send it... */
18766   S (mp);
18767
18768   /* Wait for a reply... */
18769   W (ret);
18770   return ret;
18771 }
18772
18773 static int
18774 api_one_map_register_fallback_threshold (vat_main_t * vam)
18775 {
18776   unformat_input_t *input = vam->input;
18777   vl_api_one_map_register_fallback_threshold_t *mp;
18778   u32 value = 0;
18779   u8 is_set = 0;
18780   int ret;
18781
18782   /* Parse args required to build the message */
18783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18784     {
18785       if (unformat (input, "%u", &value))
18786         is_set = 1;
18787       else
18788         {
18789           clib_warning ("parse error '%U'", format_unformat_error, input);
18790           return -99;
18791         }
18792     }
18793
18794   if (!is_set)
18795     {
18796       errmsg ("fallback threshold value is missing!");
18797       return -99;
18798     }
18799
18800   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18801   mp->value = clib_host_to_net_u32 (value);
18802
18803   /* send it... */
18804   S (mp);
18805
18806   /* Wait for a reply... */
18807   W (ret);
18808   return ret;
18809 }
18810
18811 static int
18812 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18813 {
18814   vl_api_show_one_map_register_fallback_threshold_t *mp;
18815   int ret;
18816
18817   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18818
18819   /* send it... */
18820   S (mp);
18821
18822   /* Wait for a reply... */
18823   W (ret);
18824   return ret;
18825 }
18826
18827 uword
18828 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18829 {
18830   u32 *proto = va_arg (*args, u32 *);
18831
18832   if (unformat (input, "udp"))
18833     *proto = 1;
18834   else if (unformat (input, "api"))
18835     *proto = 2;
18836   else
18837     return 0;
18838
18839   return 1;
18840 }
18841
18842 static int
18843 api_one_set_transport_protocol (vat_main_t * vam)
18844 {
18845   unformat_input_t *input = vam->input;
18846   vl_api_one_set_transport_protocol_t *mp;
18847   u8 is_set = 0;
18848   u32 protocol = 0;
18849   int ret;
18850
18851   /* Parse args required to build the message */
18852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18853     {
18854       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18855         is_set = 1;
18856       else
18857         {
18858           clib_warning ("parse error '%U'", format_unformat_error, input);
18859           return -99;
18860         }
18861     }
18862
18863   if (!is_set)
18864     {
18865       errmsg ("Transport protocol missing!");
18866       return -99;
18867     }
18868
18869   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18870   mp->protocol = (u8) protocol;
18871
18872   /* send it... */
18873   S (mp);
18874
18875   /* Wait for a reply... */
18876   W (ret);
18877   return ret;
18878 }
18879
18880 static int
18881 api_one_get_transport_protocol (vat_main_t * vam)
18882 {
18883   vl_api_one_get_transport_protocol_t *mp;
18884   int ret;
18885
18886   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18887
18888   /* send it... */
18889   S (mp);
18890
18891   /* Wait for a reply... */
18892   W (ret);
18893   return ret;
18894 }
18895
18896 static int
18897 api_one_map_register_set_ttl (vat_main_t * vam)
18898 {
18899   unformat_input_t *input = vam->input;
18900   vl_api_one_map_register_set_ttl_t *mp;
18901   u32 ttl = 0;
18902   u8 is_set = 0;
18903   int ret;
18904
18905   /* Parse args required to build the message */
18906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18907     {
18908       if (unformat (input, "%u", &ttl))
18909         is_set = 1;
18910       else
18911         {
18912           clib_warning ("parse error '%U'", format_unformat_error, input);
18913           return -99;
18914         }
18915     }
18916
18917   if (!is_set)
18918     {
18919       errmsg ("TTL value missing!");
18920       return -99;
18921     }
18922
18923   M (ONE_MAP_REGISTER_SET_TTL, mp);
18924   mp->ttl = clib_host_to_net_u32 (ttl);
18925
18926   /* send it... */
18927   S (mp);
18928
18929   /* Wait for a reply... */
18930   W (ret);
18931   return ret;
18932 }
18933
18934 static int
18935 api_show_one_map_register_ttl (vat_main_t * vam)
18936 {
18937   vl_api_show_one_map_register_ttl_t *mp;
18938   int ret;
18939
18940   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18941
18942   /* send it... */
18943   S (mp);
18944
18945   /* Wait for a reply... */
18946   W (ret);
18947   return ret;
18948 }
18949
18950 /**
18951  * Add/del map request itr rlocs from ONE control plane and updates
18952  *
18953  * @param vam vpp API test context
18954  * @return return code
18955  */
18956 static int
18957 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18958 {
18959   unformat_input_t *input = vam->input;
18960   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18961   u8 *locator_set_name = 0;
18962   u8 locator_set_name_set = 0;
18963   u8 is_add = 1;
18964   int ret;
18965
18966   /* Parse args required to build the message */
18967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18968     {
18969       if (unformat (input, "del"))
18970         {
18971           is_add = 0;
18972         }
18973       else if (unformat (input, "%_%v%_", &locator_set_name))
18974         {
18975           locator_set_name_set = 1;
18976         }
18977       else
18978         {
18979           clib_warning ("parse error '%U'", format_unformat_error, input);
18980           return -99;
18981         }
18982     }
18983
18984   if (is_add && !locator_set_name_set)
18985     {
18986       errmsg ("itr-rloc is not set!");
18987       return -99;
18988     }
18989
18990   if (is_add && vec_len (locator_set_name) > 64)
18991     {
18992       errmsg ("itr-rloc locator-set name too long");
18993       vec_free (locator_set_name);
18994       return -99;
18995     }
18996
18997   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18998   mp->is_add = is_add;
18999   if (is_add)
19000     {
19001       clib_memcpy (mp->locator_set_name, locator_set_name,
19002                    vec_len (locator_set_name));
19003     }
19004   else
19005     {
19006       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19007     }
19008   vec_free (locator_set_name);
19009
19010   /* send it... */
19011   S (mp);
19012
19013   /* Wait for a reply... */
19014   W (ret);
19015   return ret;
19016 }
19017
19018 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19019
19020 static int
19021 api_one_locator_dump (vat_main_t * vam)
19022 {
19023   unformat_input_t *input = vam->input;
19024   vl_api_one_locator_dump_t *mp;
19025   vl_api_control_ping_t *mp_ping;
19026   u8 is_index_set = 0, is_name_set = 0;
19027   u8 *ls_name = 0;
19028   u32 ls_index = ~0;
19029   int ret;
19030
19031   /* Parse args required to build the message */
19032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19033     {
19034       if (unformat (input, "ls_name %_%v%_", &ls_name))
19035         {
19036           is_name_set = 1;
19037         }
19038       else if (unformat (input, "ls_index %d", &ls_index))
19039         {
19040           is_index_set = 1;
19041         }
19042       else
19043         {
19044           errmsg ("parse error '%U'", format_unformat_error, input);
19045           return -99;
19046         }
19047     }
19048
19049   if (!is_index_set && !is_name_set)
19050     {
19051       errmsg ("error: expected one of index or name!");
19052       return -99;
19053     }
19054
19055   if (is_index_set && is_name_set)
19056     {
19057       errmsg ("error: only one param expected!");
19058       return -99;
19059     }
19060
19061   if (vec_len (ls_name) > 62)
19062     {
19063       errmsg ("error: locator set name too long!");
19064       return -99;
19065     }
19066
19067   if (!vam->json_output)
19068     {
19069       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19070     }
19071
19072   M (ONE_LOCATOR_DUMP, mp);
19073   mp->is_index_set = is_index_set;
19074
19075   if (is_index_set)
19076     mp->ls_index = clib_host_to_net_u32 (ls_index);
19077   else
19078     {
19079       vec_add1 (ls_name, 0);
19080       strncpy ((char *) mp->ls_name, (char *) ls_name,
19081                sizeof (mp->ls_name) - 1);
19082     }
19083
19084   /* send it... */
19085   S (mp);
19086
19087   /* Use a control ping for synchronization */
19088   MPING (CONTROL_PING, mp_ping);
19089   S (mp_ping);
19090
19091   /* Wait for a reply... */
19092   W (ret);
19093   return ret;
19094 }
19095
19096 #define api_lisp_locator_dump api_one_locator_dump
19097
19098 static int
19099 api_one_locator_set_dump (vat_main_t * vam)
19100 {
19101   vl_api_one_locator_set_dump_t *mp;
19102   vl_api_control_ping_t *mp_ping;
19103   unformat_input_t *input = vam->input;
19104   u8 filter = 0;
19105   int ret;
19106
19107   /* Parse args required to build the message */
19108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19109     {
19110       if (unformat (input, "local"))
19111         {
19112           filter = 1;
19113         }
19114       else if (unformat (input, "remote"))
19115         {
19116           filter = 2;
19117         }
19118       else
19119         {
19120           errmsg ("parse error '%U'", format_unformat_error, input);
19121           return -99;
19122         }
19123     }
19124
19125   if (!vam->json_output)
19126     {
19127       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19128     }
19129
19130   M (ONE_LOCATOR_SET_DUMP, mp);
19131
19132   mp->filter = filter;
19133
19134   /* send it... */
19135   S (mp);
19136
19137   /* Use a control ping for synchronization */
19138   MPING (CONTROL_PING, mp_ping);
19139   S (mp_ping);
19140
19141   /* Wait for a reply... */
19142   W (ret);
19143   return ret;
19144 }
19145
19146 #define api_lisp_locator_set_dump api_one_locator_set_dump
19147
19148 static int
19149 api_one_eid_table_map_dump (vat_main_t * vam)
19150 {
19151   u8 is_l2 = 0;
19152   u8 mode_set = 0;
19153   unformat_input_t *input = vam->input;
19154   vl_api_one_eid_table_map_dump_t *mp;
19155   vl_api_control_ping_t *mp_ping;
19156   int ret;
19157
19158   /* Parse args required to build the message */
19159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19160     {
19161       if (unformat (input, "l2"))
19162         {
19163           is_l2 = 1;
19164           mode_set = 1;
19165         }
19166       else if (unformat (input, "l3"))
19167         {
19168           is_l2 = 0;
19169           mode_set = 1;
19170         }
19171       else
19172         {
19173           errmsg ("parse error '%U'", format_unformat_error, input);
19174           return -99;
19175         }
19176     }
19177
19178   if (!mode_set)
19179     {
19180       errmsg ("expected one of 'l2' or 'l3' parameter!");
19181       return -99;
19182     }
19183
19184   if (!vam->json_output)
19185     {
19186       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19187     }
19188
19189   M (ONE_EID_TABLE_MAP_DUMP, mp);
19190   mp->is_l2 = is_l2;
19191
19192   /* send it... */
19193   S (mp);
19194
19195   /* Use a control ping for synchronization */
19196   MPING (CONTROL_PING, mp_ping);
19197   S (mp_ping);
19198
19199   /* Wait for a reply... */
19200   W (ret);
19201   return ret;
19202 }
19203
19204 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19205
19206 static int
19207 api_one_eid_table_vni_dump (vat_main_t * vam)
19208 {
19209   vl_api_one_eid_table_vni_dump_t *mp;
19210   vl_api_control_ping_t *mp_ping;
19211   int ret;
19212
19213   if (!vam->json_output)
19214     {
19215       print (vam->ofp, "VNI");
19216     }
19217
19218   M (ONE_EID_TABLE_VNI_DUMP, mp);
19219
19220   /* send it... */
19221   S (mp);
19222
19223   /* Use a control ping for synchronization */
19224   MPING (CONTROL_PING, mp_ping);
19225   S (mp_ping);
19226
19227   /* Wait for a reply... */
19228   W (ret);
19229   return ret;
19230 }
19231
19232 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19233
19234 static int
19235 api_one_eid_table_dump (vat_main_t * vam)
19236 {
19237   unformat_input_t *i = vam->input;
19238   vl_api_one_eid_table_dump_t *mp;
19239   vl_api_control_ping_t *mp_ping;
19240   struct in_addr ip4;
19241   struct in6_addr ip6;
19242   u8 mac[6];
19243   u8 eid_type = ~0, eid_set = 0;
19244   u32 prefix_length = ~0, t, vni = 0;
19245   u8 filter = 0;
19246   int ret;
19247   lisp_nsh_api_t nsh;
19248
19249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19250     {
19251       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19252         {
19253           eid_set = 1;
19254           eid_type = 0;
19255           prefix_length = t;
19256         }
19257       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19258         {
19259           eid_set = 1;
19260           eid_type = 1;
19261           prefix_length = t;
19262         }
19263       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19264         {
19265           eid_set = 1;
19266           eid_type = 2;
19267         }
19268       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19269         {
19270           eid_set = 1;
19271           eid_type = 3;
19272         }
19273       else if (unformat (i, "vni %d", &t))
19274         {
19275           vni = t;
19276         }
19277       else if (unformat (i, "local"))
19278         {
19279           filter = 1;
19280         }
19281       else if (unformat (i, "remote"))
19282         {
19283           filter = 2;
19284         }
19285       else
19286         {
19287           errmsg ("parse error '%U'", format_unformat_error, i);
19288           return -99;
19289         }
19290     }
19291
19292   if (!vam->json_output)
19293     {
19294       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19295              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19296     }
19297
19298   M (ONE_EID_TABLE_DUMP, mp);
19299
19300   mp->filter = filter;
19301   if (eid_set)
19302     {
19303       mp->eid_set = 1;
19304       mp->vni = htonl (vni);
19305       mp->eid_type = eid_type;
19306       switch (eid_type)
19307         {
19308         case 0:
19309           mp->prefix_length = prefix_length;
19310           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19311           break;
19312         case 1:
19313           mp->prefix_length = prefix_length;
19314           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19315           break;
19316         case 2:
19317           clib_memcpy (mp->eid, mac, sizeof (mac));
19318           break;
19319         case 3:
19320           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19321           break;
19322         default:
19323           errmsg ("unknown EID type %d!", eid_type);
19324           return -99;
19325         }
19326     }
19327
19328   /* send it... */
19329   S (mp);
19330
19331   /* Use a control ping for synchronization */
19332   MPING (CONTROL_PING, mp_ping);
19333   S (mp_ping);
19334
19335   /* Wait for a reply... */
19336   W (ret);
19337   return ret;
19338 }
19339
19340 #define api_lisp_eid_table_dump api_one_eid_table_dump
19341
19342 static int
19343 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19344 {
19345   unformat_input_t *i = vam->input;
19346   vl_api_gpe_fwd_entries_get_t *mp;
19347   u8 vni_set = 0;
19348   u32 vni = ~0;
19349   int ret;
19350
19351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19352     {
19353       if (unformat (i, "vni %d", &vni))
19354         {
19355           vni_set = 1;
19356         }
19357       else
19358         {
19359           errmsg ("parse error '%U'", format_unformat_error, i);
19360           return -99;
19361         }
19362     }
19363
19364   if (!vni_set)
19365     {
19366       errmsg ("vni not set!");
19367       return -99;
19368     }
19369
19370   if (!vam->json_output)
19371     {
19372       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19373              "leid", "reid");
19374     }
19375
19376   M (GPE_FWD_ENTRIES_GET, mp);
19377   mp->vni = clib_host_to_net_u32 (vni);
19378
19379   /* send it... */
19380   S (mp);
19381
19382   /* Wait for a reply... */
19383   W (ret);
19384   return ret;
19385 }
19386
19387 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19388 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19389 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19390 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19391 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19392 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19393 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19394 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19395
19396 static int
19397 api_one_adjacencies_get (vat_main_t * vam)
19398 {
19399   unformat_input_t *i = vam->input;
19400   vl_api_one_adjacencies_get_t *mp;
19401   u8 vni_set = 0;
19402   u32 vni = ~0;
19403   int ret;
19404
19405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19406     {
19407       if (unformat (i, "vni %d", &vni))
19408         {
19409           vni_set = 1;
19410         }
19411       else
19412         {
19413           errmsg ("parse error '%U'", format_unformat_error, i);
19414           return -99;
19415         }
19416     }
19417
19418   if (!vni_set)
19419     {
19420       errmsg ("vni not set!");
19421       return -99;
19422     }
19423
19424   if (!vam->json_output)
19425     {
19426       print (vam->ofp, "%s %40s", "leid", "reid");
19427     }
19428
19429   M (ONE_ADJACENCIES_GET, mp);
19430   mp->vni = clib_host_to_net_u32 (vni);
19431
19432   /* send it... */
19433   S (mp);
19434
19435   /* Wait for a reply... */
19436   W (ret);
19437   return ret;
19438 }
19439
19440 #define api_lisp_adjacencies_get api_one_adjacencies_get
19441
19442 static int
19443 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19444 {
19445   unformat_input_t *i = vam->input;
19446   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19447   int ret;
19448   u8 ip_family_set = 0, is_ip4 = 1;
19449
19450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19451     {
19452       if (unformat (i, "ip4"))
19453         {
19454           ip_family_set = 1;
19455           is_ip4 = 1;
19456         }
19457       else if (unformat (i, "ip6"))
19458         {
19459           ip_family_set = 1;
19460           is_ip4 = 0;
19461         }
19462       else
19463         {
19464           errmsg ("parse error '%U'", format_unformat_error, i);
19465           return -99;
19466         }
19467     }
19468
19469   if (!ip_family_set)
19470     {
19471       errmsg ("ip family not set!");
19472       return -99;
19473     }
19474
19475   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19476   mp->is_ip4 = is_ip4;
19477
19478   /* send it... */
19479   S (mp);
19480
19481   /* Wait for a reply... */
19482   W (ret);
19483   return ret;
19484 }
19485
19486 static int
19487 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19488 {
19489   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19490   int ret;
19491
19492   if (!vam->json_output)
19493     {
19494       print (vam->ofp, "VNIs");
19495     }
19496
19497   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19498
19499   /* send it... */
19500   S (mp);
19501
19502   /* Wait for a reply... */
19503   W (ret);
19504   return ret;
19505 }
19506
19507 static int
19508 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19509 {
19510   unformat_input_t *i = vam->input;
19511   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19512   int ret = 0;
19513   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19514   struct in_addr ip4;
19515   struct in6_addr ip6;
19516   u32 table_id = 0, nh_sw_if_index = ~0;
19517
19518   clib_memset (&ip4, 0, sizeof (ip4));
19519   clib_memset (&ip6, 0, sizeof (ip6));
19520
19521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19522     {
19523       if (unformat (i, "del"))
19524         is_add = 0;
19525       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19526                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19527         {
19528           ip_set = 1;
19529           is_ip4 = 1;
19530         }
19531       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19532                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19533         {
19534           ip_set = 1;
19535           is_ip4 = 0;
19536         }
19537       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19538         {
19539           ip_set = 1;
19540           is_ip4 = 1;
19541           nh_sw_if_index = ~0;
19542         }
19543       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19544         {
19545           ip_set = 1;
19546           is_ip4 = 0;
19547           nh_sw_if_index = ~0;
19548         }
19549       else if (unformat (i, "table %d", &table_id))
19550         ;
19551       else
19552         {
19553           errmsg ("parse error '%U'", format_unformat_error, i);
19554           return -99;
19555         }
19556     }
19557
19558   if (!ip_set)
19559     {
19560       errmsg ("nh addr not set!");
19561       return -99;
19562     }
19563
19564   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19565   mp->is_add = is_add;
19566   mp->table_id = clib_host_to_net_u32 (table_id);
19567   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19568   mp->is_ip4 = is_ip4;
19569   if (is_ip4)
19570     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19571   else
19572     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19573
19574   /* send it... */
19575   S (mp);
19576
19577   /* Wait for a reply... */
19578   W (ret);
19579   return ret;
19580 }
19581
19582 static int
19583 api_one_map_server_dump (vat_main_t * vam)
19584 {
19585   vl_api_one_map_server_dump_t *mp;
19586   vl_api_control_ping_t *mp_ping;
19587   int ret;
19588
19589   if (!vam->json_output)
19590     {
19591       print (vam->ofp, "%=20s", "Map server");
19592     }
19593
19594   M (ONE_MAP_SERVER_DUMP, mp);
19595   /* send it... */
19596   S (mp);
19597
19598   /* Use a control ping for synchronization */
19599   MPING (CONTROL_PING, mp_ping);
19600   S (mp_ping);
19601
19602   /* Wait for a reply... */
19603   W (ret);
19604   return ret;
19605 }
19606
19607 #define api_lisp_map_server_dump api_one_map_server_dump
19608
19609 static int
19610 api_one_map_resolver_dump (vat_main_t * vam)
19611 {
19612   vl_api_one_map_resolver_dump_t *mp;
19613   vl_api_control_ping_t *mp_ping;
19614   int ret;
19615
19616   if (!vam->json_output)
19617     {
19618       print (vam->ofp, "%=20s", "Map resolver");
19619     }
19620
19621   M (ONE_MAP_RESOLVER_DUMP, mp);
19622   /* send it... */
19623   S (mp);
19624
19625   /* Use a control ping for synchronization */
19626   MPING (CONTROL_PING, mp_ping);
19627   S (mp_ping);
19628
19629   /* Wait for a reply... */
19630   W (ret);
19631   return ret;
19632 }
19633
19634 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19635
19636 static int
19637 api_one_stats_flush (vat_main_t * vam)
19638 {
19639   vl_api_one_stats_flush_t *mp;
19640   int ret = 0;
19641
19642   M (ONE_STATS_FLUSH, mp);
19643   S (mp);
19644   W (ret);
19645   return ret;
19646 }
19647
19648 static int
19649 api_one_stats_dump (vat_main_t * vam)
19650 {
19651   vl_api_one_stats_dump_t *mp;
19652   vl_api_control_ping_t *mp_ping;
19653   int ret;
19654
19655   M (ONE_STATS_DUMP, mp);
19656   /* send it... */
19657   S (mp);
19658
19659   /* Use a control ping for synchronization */
19660   MPING (CONTROL_PING, mp_ping);
19661   S (mp_ping);
19662
19663   /* Wait for a reply... */
19664   W (ret);
19665   return ret;
19666 }
19667
19668 static int
19669 api_show_one_status (vat_main_t * vam)
19670 {
19671   vl_api_show_one_status_t *mp;
19672   int ret;
19673
19674   if (!vam->json_output)
19675     {
19676       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19677     }
19678
19679   M (SHOW_ONE_STATUS, mp);
19680   /* send it... */
19681   S (mp);
19682   /* Wait for a reply... */
19683   W (ret);
19684   return ret;
19685 }
19686
19687 #define api_show_lisp_status api_show_one_status
19688
19689 static int
19690 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19691 {
19692   vl_api_gpe_fwd_entry_path_dump_t *mp;
19693   vl_api_control_ping_t *mp_ping;
19694   unformat_input_t *i = vam->input;
19695   u32 fwd_entry_index = ~0;
19696   int ret;
19697
19698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19699     {
19700       if (unformat (i, "index %d", &fwd_entry_index))
19701         ;
19702       else
19703         break;
19704     }
19705
19706   if (~0 == fwd_entry_index)
19707     {
19708       errmsg ("no index specified!");
19709       return -99;
19710     }
19711
19712   if (!vam->json_output)
19713     {
19714       print (vam->ofp, "first line");
19715     }
19716
19717   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19718
19719   /* send it... */
19720   S (mp);
19721   /* Use a control ping for synchronization */
19722   MPING (CONTROL_PING, mp_ping);
19723   S (mp_ping);
19724
19725   /* Wait for a reply... */
19726   W (ret);
19727   return ret;
19728 }
19729
19730 static int
19731 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19732 {
19733   vl_api_one_get_map_request_itr_rlocs_t *mp;
19734   int ret;
19735
19736   if (!vam->json_output)
19737     {
19738       print (vam->ofp, "%=20s", "itr-rlocs:");
19739     }
19740
19741   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19742   /* send it... */
19743   S (mp);
19744   /* Wait for a reply... */
19745   W (ret);
19746   return ret;
19747 }
19748
19749 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19750
19751 static int
19752 api_af_packet_create (vat_main_t * vam)
19753 {
19754   unformat_input_t *i = vam->input;
19755   vl_api_af_packet_create_t *mp;
19756   u8 *host_if_name = 0;
19757   u8 hw_addr[6];
19758   u8 random_hw_addr = 1;
19759   int ret;
19760
19761   clib_memset (hw_addr, 0, sizeof (hw_addr));
19762
19763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19764     {
19765       if (unformat (i, "name %s", &host_if_name))
19766         vec_add1 (host_if_name, 0);
19767       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19768         random_hw_addr = 0;
19769       else
19770         break;
19771     }
19772
19773   if (!vec_len (host_if_name))
19774     {
19775       errmsg ("host-interface name must be specified");
19776       return -99;
19777     }
19778
19779   if (vec_len (host_if_name) > 64)
19780     {
19781       errmsg ("host-interface name too long");
19782       return -99;
19783     }
19784
19785   M (AF_PACKET_CREATE, mp);
19786
19787   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19788   clib_memcpy (mp->hw_addr, hw_addr, 6);
19789   mp->use_random_hw_addr = random_hw_addr;
19790   vec_free (host_if_name);
19791
19792   S (mp);
19793
19794   /* *INDENT-OFF* */
19795   W2 (ret,
19796       ({
19797         if (ret == 0)
19798           fprintf (vam->ofp ? vam->ofp : stderr,
19799                    " new sw_if_index = %d\n", vam->sw_if_index);
19800       }));
19801   /* *INDENT-ON* */
19802   return ret;
19803 }
19804
19805 static int
19806 api_af_packet_delete (vat_main_t * vam)
19807 {
19808   unformat_input_t *i = vam->input;
19809   vl_api_af_packet_delete_t *mp;
19810   u8 *host_if_name = 0;
19811   int ret;
19812
19813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19814     {
19815       if (unformat (i, "name %s", &host_if_name))
19816         vec_add1 (host_if_name, 0);
19817       else
19818         break;
19819     }
19820
19821   if (!vec_len (host_if_name))
19822     {
19823       errmsg ("host-interface name must be specified");
19824       return -99;
19825     }
19826
19827   if (vec_len (host_if_name) > 64)
19828     {
19829       errmsg ("host-interface name too long");
19830       return -99;
19831     }
19832
19833   M (AF_PACKET_DELETE, mp);
19834
19835   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19836   vec_free (host_if_name);
19837
19838   S (mp);
19839   W (ret);
19840   return ret;
19841 }
19842
19843 static void vl_api_af_packet_details_t_handler
19844   (vl_api_af_packet_details_t * mp)
19845 {
19846   vat_main_t *vam = &vat_main;
19847
19848   print (vam->ofp, "%-16s %d",
19849          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19850 }
19851
19852 static void vl_api_af_packet_details_t_handler_json
19853   (vl_api_af_packet_details_t * mp)
19854 {
19855   vat_main_t *vam = &vat_main;
19856   vat_json_node_t *node = NULL;
19857
19858   if (VAT_JSON_ARRAY != vam->json_tree.type)
19859     {
19860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19861       vat_json_init_array (&vam->json_tree);
19862     }
19863   node = vat_json_array_add (&vam->json_tree);
19864
19865   vat_json_init_object (node);
19866   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19867   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19868 }
19869
19870 static int
19871 api_af_packet_dump (vat_main_t * vam)
19872 {
19873   vl_api_af_packet_dump_t *mp;
19874   vl_api_control_ping_t *mp_ping;
19875   int ret;
19876
19877   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19878   /* Get list of tap interfaces */
19879   M (AF_PACKET_DUMP, mp);
19880   S (mp);
19881
19882   /* Use a control ping for synchronization */
19883   MPING (CONTROL_PING, mp_ping);
19884   S (mp_ping);
19885
19886   W (ret);
19887   return ret;
19888 }
19889
19890 static int
19891 api_policer_add_del (vat_main_t * vam)
19892 {
19893   unformat_input_t *i = vam->input;
19894   vl_api_policer_add_del_t *mp;
19895   u8 is_add = 1;
19896   u8 *name = 0;
19897   u32 cir = 0;
19898   u32 eir = 0;
19899   u64 cb = 0;
19900   u64 eb = 0;
19901   u8 rate_type = 0;
19902   u8 round_type = 0;
19903   u8 type = 0;
19904   u8 color_aware = 0;
19905   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19906   int ret;
19907
19908   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19909   conform_action.dscp = 0;
19910   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19911   exceed_action.dscp = 0;
19912   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19913   violate_action.dscp = 0;
19914
19915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19916     {
19917       if (unformat (i, "del"))
19918         is_add = 0;
19919       else if (unformat (i, "name %s", &name))
19920         vec_add1 (name, 0);
19921       else if (unformat (i, "cir %u", &cir))
19922         ;
19923       else if (unformat (i, "eir %u", &eir))
19924         ;
19925       else if (unformat (i, "cb %u", &cb))
19926         ;
19927       else if (unformat (i, "eb %u", &eb))
19928         ;
19929       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19930                          &rate_type))
19931         ;
19932       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19933                          &round_type))
19934         ;
19935       else if (unformat (i, "type %U", unformat_policer_type, &type))
19936         ;
19937       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19938                          &conform_action))
19939         ;
19940       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19941                          &exceed_action))
19942         ;
19943       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19944                          &violate_action))
19945         ;
19946       else if (unformat (i, "color-aware"))
19947         color_aware = 1;
19948       else
19949         break;
19950     }
19951
19952   if (!vec_len (name))
19953     {
19954       errmsg ("policer name must be specified");
19955       return -99;
19956     }
19957
19958   if (vec_len (name) > 64)
19959     {
19960       errmsg ("policer name too long");
19961       return -99;
19962     }
19963
19964   M (POLICER_ADD_DEL, mp);
19965
19966   clib_memcpy (mp->name, name, vec_len (name));
19967   vec_free (name);
19968   mp->is_add = is_add;
19969   mp->cir = ntohl (cir);
19970   mp->eir = ntohl (eir);
19971   mp->cb = clib_net_to_host_u64 (cb);
19972   mp->eb = clib_net_to_host_u64 (eb);
19973   mp->rate_type = rate_type;
19974   mp->round_type = round_type;
19975   mp->type = type;
19976   mp->conform_action_type = conform_action.action_type;
19977   mp->conform_dscp = conform_action.dscp;
19978   mp->exceed_action_type = exceed_action.action_type;
19979   mp->exceed_dscp = exceed_action.dscp;
19980   mp->violate_action_type = violate_action.action_type;
19981   mp->violate_dscp = violate_action.dscp;
19982   mp->color_aware = color_aware;
19983
19984   S (mp);
19985   W (ret);
19986   return ret;
19987 }
19988
19989 static int
19990 api_policer_dump (vat_main_t * vam)
19991 {
19992   unformat_input_t *i = vam->input;
19993   vl_api_policer_dump_t *mp;
19994   vl_api_control_ping_t *mp_ping;
19995   u8 *match_name = 0;
19996   u8 match_name_valid = 0;
19997   int ret;
19998
19999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20000     {
20001       if (unformat (i, "name %s", &match_name))
20002         {
20003           vec_add1 (match_name, 0);
20004           match_name_valid = 1;
20005         }
20006       else
20007         break;
20008     }
20009
20010   M (POLICER_DUMP, mp);
20011   mp->match_name_valid = match_name_valid;
20012   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20013   vec_free (match_name);
20014   /* send it... */
20015   S (mp);
20016
20017   /* Use a control ping for synchronization */
20018   MPING (CONTROL_PING, mp_ping);
20019   S (mp_ping);
20020
20021   /* Wait for a reply... */
20022   W (ret);
20023   return ret;
20024 }
20025
20026 static int
20027 api_policer_classify_set_interface (vat_main_t * vam)
20028 {
20029   unformat_input_t *i = vam->input;
20030   vl_api_policer_classify_set_interface_t *mp;
20031   u32 sw_if_index;
20032   int sw_if_index_set;
20033   u32 ip4_table_index = ~0;
20034   u32 ip6_table_index = ~0;
20035   u32 l2_table_index = ~0;
20036   u8 is_add = 1;
20037   int ret;
20038
20039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20040     {
20041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20042         sw_if_index_set = 1;
20043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20044         sw_if_index_set = 1;
20045       else if (unformat (i, "del"))
20046         is_add = 0;
20047       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20048         ;
20049       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20050         ;
20051       else if (unformat (i, "l2-table %d", &l2_table_index))
20052         ;
20053       else
20054         {
20055           clib_warning ("parse error '%U'", format_unformat_error, i);
20056           return -99;
20057         }
20058     }
20059
20060   if (sw_if_index_set == 0)
20061     {
20062       errmsg ("missing interface name or sw_if_index");
20063       return -99;
20064     }
20065
20066   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20067
20068   mp->sw_if_index = ntohl (sw_if_index);
20069   mp->ip4_table_index = ntohl (ip4_table_index);
20070   mp->ip6_table_index = ntohl (ip6_table_index);
20071   mp->l2_table_index = ntohl (l2_table_index);
20072   mp->is_add = is_add;
20073
20074   S (mp);
20075   W (ret);
20076   return ret;
20077 }
20078
20079 static int
20080 api_policer_classify_dump (vat_main_t * vam)
20081 {
20082   unformat_input_t *i = vam->input;
20083   vl_api_policer_classify_dump_t *mp;
20084   vl_api_control_ping_t *mp_ping;
20085   u8 type = POLICER_CLASSIFY_N_TABLES;
20086   int ret;
20087
20088   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20089     ;
20090   else
20091     {
20092       errmsg ("classify table type must be specified");
20093       return -99;
20094     }
20095
20096   if (!vam->json_output)
20097     {
20098       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20099     }
20100
20101   M (POLICER_CLASSIFY_DUMP, mp);
20102   mp->type = type;
20103   /* send it... */
20104   S (mp);
20105
20106   /* Use a control ping for synchronization */
20107   MPING (CONTROL_PING, mp_ping);
20108   S (mp_ping);
20109
20110   /* Wait for a reply... */
20111   W (ret);
20112   return ret;
20113 }
20114
20115 static int
20116 api_netmap_create (vat_main_t * vam)
20117 {
20118   unformat_input_t *i = vam->input;
20119   vl_api_netmap_create_t *mp;
20120   u8 *if_name = 0;
20121   u8 hw_addr[6];
20122   u8 random_hw_addr = 1;
20123   u8 is_pipe = 0;
20124   u8 is_master = 0;
20125   int ret;
20126
20127   clib_memset (hw_addr, 0, sizeof (hw_addr));
20128
20129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20130     {
20131       if (unformat (i, "name %s", &if_name))
20132         vec_add1 (if_name, 0);
20133       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20134         random_hw_addr = 0;
20135       else if (unformat (i, "pipe"))
20136         is_pipe = 1;
20137       else if (unformat (i, "master"))
20138         is_master = 1;
20139       else if (unformat (i, "slave"))
20140         is_master = 0;
20141       else
20142         break;
20143     }
20144
20145   if (!vec_len (if_name))
20146     {
20147       errmsg ("interface name must be specified");
20148       return -99;
20149     }
20150
20151   if (vec_len (if_name) > 64)
20152     {
20153       errmsg ("interface name too long");
20154       return -99;
20155     }
20156
20157   M (NETMAP_CREATE, mp);
20158
20159   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20160   clib_memcpy (mp->hw_addr, hw_addr, 6);
20161   mp->use_random_hw_addr = random_hw_addr;
20162   mp->is_pipe = is_pipe;
20163   mp->is_master = is_master;
20164   vec_free (if_name);
20165
20166   S (mp);
20167   W (ret);
20168   return ret;
20169 }
20170
20171 static int
20172 api_netmap_delete (vat_main_t * vam)
20173 {
20174   unformat_input_t *i = vam->input;
20175   vl_api_netmap_delete_t *mp;
20176   u8 *if_name = 0;
20177   int ret;
20178
20179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20180     {
20181       if (unformat (i, "name %s", &if_name))
20182         vec_add1 (if_name, 0);
20183       else
20184         break;
20185     }
20186
20187   if (!vec_len (if_name))
20188     {
20189       errmsg ("interface name must be specified");
20190       return -99;
20191     }
20192
20193   if (vec_len (if_name) > 64)
20194     {
20195       errmsg ("interface name too long");
20196       return -99;
20197     }
20198
20199   M (NETMAP_DELETE, mp);
20200
20201   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20202   vec_free (if_name);
20203
20204   S (mp);
20205   W (ret);
20206   return ret;
20207 }
20208
20209 static void
20210 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20211 {
20212   if (fp->afi == IP46_TYPE_IP6)
20213     print (vam->ofp,
20214            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20215            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20216            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20217            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20218            format_ip6_address, fp->next_hop);
20219   else if (fp->afi == IP46_TYPE_IP4)
20220     print (vam->ofp,
20221            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20222            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20223            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20224            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20225            format_ip4_address, fp->next_hop);
20226 }
20227
20228 static void
20229 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20230                                  vl_api_fib_path_t * fp)
20231 {
20232   struct in_addr ip4;
20233   struct in6_addr ip6;
20234
20235   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20236   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20237   vat_json_object_add_uint (node, "is_local", fp->is_local);
20238   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20239   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20240   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20241   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20242   if (fp->afi == IP46_TYPE_IP4)
20243     {
20244       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20245       vat_json_object_add_ip4 (node, "next_hop", ip4);
20246     }
20247   else if (fp->afi == IP46_TYPE_IP6)
20248     {
20249       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20250       vat_json_object_add_ip6 (node, "next_hop", ip6);
20251     }
20252 }
20253
20254 static void
20255 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20256 {
20257   vat_main_t *vam = &vat_main;
20258   int count = ntohl (mp->mt_count);
20259   vl_api_fib_path_t *fp;
20260   i32 i;
20261
20262   print (vam->ofp, "[%d]: sw_if_index %d via:",
20263          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20264   fp = mp->mt_paths;
20265   for (i = 0; i < count; i++)
20266     {
20267       vl_api_mpls_fib_path_print (vam, fp);
20268       fp++;
20269     }
20270
20271   print (vam->ofp, "");
20272 }
20273
20274 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20275 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20276
20277 static void
20278 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20279 {
20280   vat_main_t *vam = &vat_main;
20281   vat_json_node_t *node = NULL;
20282   int count = ntohl (mp->mt_count);
20283   vl_api_fib_path_t *fp;
20284   i32 i;
20285
20286   if (VAT_JSON_ARRAY != vam->json_tree.type)
20287     {
20288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20289       vat_json_init_array (&vam->json_tree);
20290     }
20291   node = vat_json_array_add (&vam->json_tree);
20292
20293   vat_json_init_object (node);
20294   vat_json_object_add_uint (node, "tunnel_index",
20295                             ntohl (mp->mt_tunnel_index));
20296   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20297
20298   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20299
20300   fp = mp->mt_paths;
20301   for (i = 0; i < count; i++)
20302     {
20303       vl_api_mpls_fib_path_json_print (node, fp);
20304       fp++;
20305     }
20306 }
20307
20308 static int
20309 api_mpls_tunnel_dump (vat_main_t * vam)
20310 {
20311   vl_api_mpls_tunnel_dump_t *mp;
20312   vl_api_control_ping_t *mp_ping;
20313   u32 sw_if_index = ~0;
20314   int ret;
20315
20316   /* Parse args required to build the message */
20317   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20318     {
20319       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20320         ;
20321     }
20322
20323   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20324
20325   M (MPLS_TUNNEL_DUMP, mp);
20326   mp->sw_if_index = htonl (sw_if_index);
20327   S (mp);
20328
20329   /* Use a control ping for synchronization */
20330   MPING (CONTROL_PING, mp_ping);
20331   S (mp_ping);
20332
20333   W (ret);
20334   return ret;
20335 }
20336
20337 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20338 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20339
20340
20341 static void
20342 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   int count = ntohl (mp->count);
20346   vl_api_fib_path_t *fp;
20347   int i;
20348
20349   print (vam->ofp,
20350          "table-id %d, label %u, ess_bit %u",
20351          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20352   fp = mp->path;
20353   for (i = 0; i < count; i++)
20354     {
20355       vl_api_mpls_fib_path_print (vam, fp);
20356       fp++;
20357     }
20358 }
20359
20360 static void vl_api_mpls_fib_details_t_handler_json
20361   (vl_api_mpls_fib_details_t * mp)
20362 {
20363   vat_main_t *vam = &vat_main;
20364   int count = ntohl (mp->count);
20365   vat_json_node_t *node = NULL;
20366   vl_api_fib_path_t *fp;
20367   int i;
20368
20369   if (VAT_JSON_ARRAY != vam->json_tree.type)
20370     {
20371       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20372       vat_json_init_array (&vam->json_tree);
20373     }
20374   node = vat_json_array_add (&vam->json_tree);
20375
20376   vat_json_init_object (node);
20377   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20378   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20379   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20380   vat_json_object_add_uint (node, "path_count", count);
20381   fp = mp->path;
20382   for (i = 0; i < count; i++)
20383     {
20384       vl_api_mpls_fib_path_json_print (node, fp);
20385       fp++;
20386     }
20387 }
20388
20389 static int
20390 api_mpls_fib_dump (vat_main_t * vam)
20391 {
20392   vl_api_mpls_fib_dump_t *mp;
20393   vl_api_control_ping_t *mp_ping;
20394   int ret;
20395
20396   M (MPLS_FIB_DUMP, mp);
20397   S (mp);
20398
20399   /* Use a control ping for synchronization */
20400   MPING (CONTROL_PING, mp_ping);
20401   S (mp_ping);
20402
20403   W (ret);
20404   return ret;
20405 }
20406
20407 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20408 #define vl_api_ip_fib_details_t_print vl_noop_handler
20409
20410 static void
20411 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20412 {
20413   vat_main_t *vam = &vat_main;
20414   int count = ntohl (mp->count);
20415   vl_api_fib_path_t *fp;
20416   int i;
20417
20418   print (vam->ofp,
20419          "table-id %d, prefix %U/%d stats-index %d",
20420          ntohl (mp->table_id), format_ip4_address, mp->address,
20421          mp->address_length, ntohl (mp->stats_index));
20422   fp = mp->path;
20423   for (i = 0; i < count; i++)
20424     {
20425       if (fp->afi == IP46_TYPE_IP6)
20426         print (vam->ofp,
20427                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20428                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20429                "next_hop_table %d",
20430                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20431                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20432                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20433       else if (fp->afi == IP46_TYPE_IP4)
20434         print (vam->ofp,
20435                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20436                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20437                "next_hop_table %d",
20438                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20439                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20440                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20441       fp++;
20442     }
20443 }
20444
20445 static void vl_api_ip_fib_details_t_handler_json
20446   (vl_api_ip_fib_details_t * mp)
20447 {
20448   vat_main_t *vam = &vat_main;
20449   int count = ntohl (mp->count);
20450   vat_json_node_t *node = NULL;
20451   struct in_addr ip4;
20452   struct in6_addr ip6;
20453   vl_api_fib_path_t *fp;
20454   int i;
20455
20456   if (VAT_JSON_ARRAY != vam->json_tree.type)
20457     {
20458       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20459       vat_json_init_array (&vam->json_tree);
20460     }
20461   node = vat_json_array_add (&vam->json_tree);
20462
20463   vat_json_init_object (node);
20464   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20465   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20466   vat_json_object_add_ip4 (node, "prefix", ip4);
20467   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20468   vat_json_object_add_uint (node, "path_count", count);
20469   fp = mp->path;
20470   for (i = 0; i < count; i++)
20471     {
20472       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20473       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20474       vat_json_object_add_uint (node, "is_local", fp->is_local);
20475       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20476       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20477       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20478       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20479       if (fp->afi == IP46_TYPE_IP4)
20480         {
20481           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20482           vat_json_object_add_ip4 (node, "next_hop", ip4);
20483         }
20484       else if (fp->afi == IP46_TYPE_IP6)
20485         {
20486           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20487           vat_json_object_add_ip6 (node, "next_hop", ip6);
20488         }
20489     }
20490 }
20491
20492 static int
20493 api_ip_fib_dump (vat_main_t * vam)
20494 {
20495   vl_api_ip_fib_dump_t *mp;
20496   vl_api_control_ping_t *mp_ping;
20497   int ret;
20498
20499   M (IP_FIB_DUMP, mp);
20500   S (mp);
20501
20502   /* Use a control ping for synchronization */
20503   MPING (CONTROL_PING, mp_ping);
20504   S (mp_ping);
20505
20506   W (ret);
20507   return ret;
20508 }
20509
20510 static int
20511 api_ip_mfib_dump (vat_main_t * vam)
20512 {
20513   vl_api_ip_mfib_dump_t *mp;
20514   vl_api_control_ping_t *mp_ping;
20515   int ret;
20516
20517   M (IP_MFIB_DUMP, mp);
20518   S (mp);
20519
20520   /* Use a control ping for synchronization */
20521   MPING (CONTROL_PING, mp_ping);
20522   S (mp_ping);
20523
20524   W (ret);
20525   return ret;
20526 }
20527
20528 static void vl_api_ip_neighbor_details_t_handler
20529   (vl_api_ip_neighbor_details_t * mp)
20530 {
20531   vat_main_t *vam = &vat_main;
20532
20533   print (vam->ofp, "%c %U %U",
20534          (mp->is_static) ? 'S' : 'D',
20535          format_ethernet_address, &mp->mac_address,
20536          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20537          &mp->ip_address);
20538 }
20539
20540 static void vl_api_ip_neighbor_details_t_handler_json
20541   (vl_api_ip_neighbor_details_t * mp)
20542 {
20543
20544   vat_main_t *vam = &vat_main;
20545   vat_json_node_t *node;
20546   struct in_addr ip4;
20547   struct in6_addr ip6;
20548
20549   if (VAT_JSON_ARRAY != vam->json_tree.type)
20550     {
20551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20552       vat_json_init_array (&vam->json_tree);
20553     }
20554   node = vat_json_array_add (&vam->json_tree);
20555
20556   vat_json_init_object (node);
20557   vat_json_object_add_string_copy (node, "flag",
20558                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20559                                    "dynamic");
20560
20561   vat_json_object_add_string_copy (node, "link_layer",
20562                                    format (0, "%U", format_ethernet_address,
20563                                            &mp->mac_address));
20564
20565   if (mp->is_ipv6)
20566     {
20567       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20568       vat_json_object_add_ip6 (node, "ip_address", ip6);
20569     }
20570   else
20571     {
20572       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20573       vat_json_object_add_ip4 (node, "ip_address", ip4);
20574     }
20575 }
20576
20577 static int
20578 api_ip_neighbor_dump (vat_main_t * vam)
20579 {
20580   unformat_input_t *i = vam->input;
20581   vl_api_ip_neighbor_dump_t *mp;
20582   vl_api_control_ping_t *mp_ping;
20583   u8 is_ipv6 = 0;
20584   u32 sw_if_index = ~0;
20585   int ret;
20586
20587   /* Parse args required to build the message */
20588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20589     {
20590       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20591         ;
20592       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20593         ;
20594       else if (unformat (i, "ip6"))
20595         is_ipv6 = 1;
20596       else
20597         break;
20598     }
20599
20600   if (sw_if_index == ~0)
20601     {
20602       errmsg ("missing interface name or sw_if_index");
20603       return -99;
20604     }
20605
20606   M (IP_NEIGHBOR_DUMP, mp);
20607   mp->is_ipv6 = (u8) is_ipv6;
20608   mp->sw_if_index = ntohl (sw_if_index);
20609   S (mp);
20610
20611   /* Use a control ping for synchronization */
20612   MPING (CONTROL_PING, mp_ping);
20613   S (mp_ping);
20614
20615   W (ret);
20616   return ret;
20617 }
20618
20619 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20620 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20621
20622 static void
20623 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20624 {
20625   vat_main_t *vam = &vat_main;
20626   int count = ntohl (mp->count);
20627   vl_api_fib_path_t *fp;
20628   int i;
20629
20630   print (vam->ofp,
20631          "table-id %d, prefix %U/%d stats-index %d",
20632          ntohl (mp->table_id), format_ip6_address, mp->address,
20633          mp->address_length, ntohl (mp->stats_index));
20634   fp = mp->path;
20635   for (i = 0; i < count; i++)
20636     {
20637       if (fp->afi == IP46_TYPE_IP6)
20638         print (vam->ofp,
20639                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20640                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20641                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20642                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20643                format_ip6_address, fp->next_hop);
20644       else if (fp->afi == IP46_TYPE_IP4)
20645         print (vam->ofp,
20646                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20647                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20648                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20649                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20650                format_ip4_address, fp->next_hop);
20651       fp++;
20652     }
20653 }
20654
20655 static void vl_api_ip6_fib_details_t_handler_json
20656   (vl_api_ip6_fib_details_t * mp)
20657 {
20658   vat_main_t *vam = &vat_main;
20659   int count = ntohl (mp->count);
20660   vat_json_node_t *node = NULL;
20661   struct in_addr ip4;
20662   struct in6_addr ip6;
20663   vl_api_fib_path_t *fp;
20664   int i;
20665
20666   if (VAT_JSON_ARRAY != vam->json_tree.type)
20667     {
20668       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20669       vat_json_init_array (&vam->json_tree);
20670     }
20671   node = vat_json_array_add (&vam->json_tree);
20672
20673   vat_json_init_object (node);
20674   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20675   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20676   vat_json_object_add_ip6 (node, "prefix", ip6);
20677   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20678   vat_json_object_add_uint (node, "path_count", count);
20679   fp = mp->path;
20680   for (i = 0; i < count; i++)
20681     {
20682       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20683       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20684       vat_json_object_add_uint (node, "is_local", fp->is_local);
20685       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20686       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20687       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20688       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20689       if (fp->afi == IP46_TYPE_IP4)
20690         {
20691           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20692           vat_json_object_add_ip4 (node, "next_hop", ip4);
20693         }
20694       else if (fp->afi == IP46_TYPE_IP6)
20695         {
20696           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20697           vat_json_object_add_ip6 (node, "next_hop", ip6);
20698         }
20699     }
20700 }
20701
20702 static int
20703 api_ip6_fib_dump (vat_main_t * vam)
20704 {
20705   vl_api_ip6_fib_dump_t *mp;
20706   vl_api_control_ping_t *mp_ping;
20707   int ret;
20708
20709   M (IP6_FIB_DUMP, mp);
20710   S (mp);
20711
20712   /* Use a control ping for synchronization */
20713   MPING (CONTROL_PING, mp_ping);
20714   S (mp_ping);
20715
20716   W (ret);
20717   return ret;
20718 }
20719
20720 static int
20721 api_ip6_mfib_dump (vat_main_t * vam)
20722 {
20723   vl_api_ip6_mfib_dump_t *mp;
20724   vl_api_control_ping_t *mp_ping;
20725   int ret;
20726
20727   M (IP6_MFIB_DUMP, mp);
20728   S (mp);
20729
20730   /* Use a control ping for synchronization */
20731   MPING (CONTROL_PING, mp_ping);
20732   S (mp_ping);
20733
20734   W (ret);
20735   return ret;
20736 }
20737
20738 int
20739 api_classify_table_ids (vat_main_t * vam)
20740 {
20741   vl_api_classify_table_ids_t *mp;
20742   int ret;
20743
20744   /* Construct the API message */
20745   M (CLASSIFY_TABLE_IDS, mp);
20746   mp->context = 0;
20747
20748   S (mp);
20749   W (ret);
20750   return ret;
20751 }
20752
20753 int
20754 api_classify_table_by_interface (vat_main_t * vam)
20755 {
20756   unformat_input_t *input = vam->input;
20757   vl_api_classify_table_by_interface_t *mp;
20758
20759   u32 sw_if_index = ~0;
20760   int ret;
20761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20762     {
20763       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20764         ;
20765       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20766         ;
20767       else
20768         break;
20769     }
20770   if (sw_if_index == ~0)
20771     {
20772       errmsg ("missing interface name or sw_if_index");
20773       return -99;
20774     }
20775
20776   /* Construct the API message */
20777   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20778   mp->context = 0;
20779   mp->sw_if_index = ntohl (sw_if_index);
20780
20781   S (mp);
20782   W (ret);
20783   return ret;
20784 }
20785
20786 int
20787 api_classify_table_info (vat_main_t * vam)
20788 {
20789   unformat_input_t *input = vam->input;
20790   vl_api_classify_table_info_t *mp;
20791
20792   u32 table_id = ~0;
20793   int ret;
20794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20795     {
20796       if (unformat (input, "table_id %d", &table_id))
20797         ;
20798       else
20799         break;
20800     }
20801   if (table_id == ~0)
20802     {
20803       errmsg ("missing table id");
20804       return -99;
20805     }
20806
20807   /* Construct the API message */
20808   M (CLASSIFY_TABLE_INFO, mp);
20809   mp->context = 0;
20810   mp->table_id = ntohl (table_id);
20811
20812   S (mp);
20813   W (ret);
20814   return ret;
20815 }
20816
20817 int
20818 api_classify_session_dump (vat_main_t * vam)
20819 {
20820   unformat_input_t *input = vam->input;
20821   vl_api_classify_session_dump_t *mp;
20822   vl_api_control_ping_t *mp_ping;
20823
20824   u32 table_id = ~0;
20825   int ret;
20826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20827     {
20828       if (unformat (input, "table_id %d", &table_id))
20829         ;
20830       else
20831         break;
20832     }
20833   if (table_id == ~0)
20834     {
20835       errmsg ("missing table id");
20836       return -99;
20837     }
20838
20839   /* Construct the API message */
20840   M (CLASSIFY_SESSION_DUMP, mp);
20841   mp->context = 0;
20842   mp->table_id = ntohl (table_id);
20843   S (mp);
20844
20845   /* Use a control ping for synchronization */
20846   MPING (CONTROL_PING, mp_ping);
20847   S (mp_ping);
20848
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static void
20854 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20855 {
20856   vat_main_t *vam = &vat_main;
20857
20858   print (vam->ofp, "collector_address %U, collector_port %d, "
20859          "src_address %U, vrf_id %d, path_mtu %u, "
20860          "template_interval %u, udp_checksum %d",
20861          format_ip4_address, mp->collector_address,
20862          ntohs (mp->collector_port),
20863          format_ip4_address, mp->src_address,
20864          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20865          ntohl (mp->template_interval), mp->udp_checksum);
20866
20867   vam->retval = 0;
20868   vam->result_ready = 1;
20869 }
20870
20871 static void
20872   vl_api_ipfix_exporter_details_t_handler_json
20873   (vl_api_ipfix_exporter_details_t * mp)
20874 {
20875   vat_main_t *vam = &vat_main;
20876   vat_json_node_t node;
20877   struct in_addr collector_address;
20878   struct in_addr src_address;
20879
20880   vat_json_init_object (&node);
20881   clib_memcpy (&collector_address, &mp->collector_address,
20882                sizeof (collector_address));
20883   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20884   vat_json_object_add_uint (&node, "collector_port",
20885                             ntohs (mp->collector_port));
20886   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20887   vat_json_object_add_ip4 (&node, "src_address", src_address);
20888   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20889   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20890   vat_json_object_add_uint (&node, "template_interval",
20891                             ntohl (mp->template_interval));
20892   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20893
20894   vat_json_print (vam->ofp, &node);
20895   vat_json_free (&node);
20896   vam->retval = 0;
20897   vam->result_ready = 1;
20898 }
20899
20900 int
20901 api_ipfix_exporter_dump (vat_main_t * vam)
20902 {
20903   vl_api_ipfix_exporter_dump_t *mp;
20904   int ret;
20905
20906   /* Construct the API message */
20907   M (IPFIX_EXPORTER_DUMP, mp);
20908   mp->context = 0;
20909
20910   S (mp);
20911   W (ret);
20912   return ret;
20913 }
20914
20915 static int
20916 api_ipfix_classify_stream_dump (vat_main_t * vam)
20917 {
20918   vl_api_ipfix_classify_stream_dump_t *mp;
20919   int ret;
20920
20921   /* Construct the API message */
20922   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20923   mp->context = 0;
20924
20925   S (mp);
20926   W (ret);
20927   return ret;
20928   /* NOTREACHED */
20929   return 0;
20930 }
20931
20932 static void
20933   vl_api_ipfix_classify_stream_details_t_handler
20934   (vl_api_ipfix_classify_stream_details_t * mp)
20935 {
20936   vat_main_t *vam = &vat_main;
20937   print (vam->ofp, "domain_id %d, src_port %d",
20938          ntohl (mp->domain_id), ntohs (mp->src_port));
20939   vam->retval = 0;
20940   vam->result_ready = 1;
20941 }
20942
20943 static void
20944   vl_api_ipfix_classify_stream_details_t_handler_json
20945   (vl_api_ipfix_classify_stream_details_t * mp)
20946 {
20947   vat_main_t *vam = &vat_main;
20948   vat_json_node_t node;
20949
20950   vat_json_init_object (&node);
20951   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20952   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20953
20954   vat_json_print (vam->ofp, &node);
20955   vat_json_free (&node);
20956   vam->retval = 0;
20957   vam->result_ready = 1;
20958 }
20959
20960 static int
20961 api_ipfix_classify_table_dump (vat_main_t * vam)
20962 {
20963   vl_api_ipfix_classify_table_dump_t *mp;
20964   vl_api_control_ping_t *mp_ping;
20965   int ret;
20966
20967   if (!vam->json_output)
20968     {
20969       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20970              "transport_protocol");
20971     }
20972
20973   /* Construct the API message */
20974   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20975
20976   /* send it... */
20977   S (mp);
20978
20979   /* Use a control ping for synchronization */
20980   MPING (CONTROL_PING, mp_ping);
20981   S (mp_ping);
20982
20983   W (ret);
20984   return ret;
20985 }
20986
20987 static void
20988   vl_api_ipfix_classify_table_details_t_handler
20989   (vl_api_ipfix_classify_table_details_t * mp)
20990 {
20991   vat_main_t *vam = &vat_main;
20992   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20993          mp->transport_protocol);
20994 }
20995
20996 static void
20997   vl_api_ipfix_classify_table_details_t_handler_json
20998   (vl_api_ipfix_classify_table_details_t * mp)
20999 {
21000   vat_json_node_t *node = NULL;
21001   vat_main_t *vam = &vat_main;
21002
21003   if (VAT_JSON_ARRAY != vam->json_tree.type)
21004     {
21005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21006       vat_json_init_array (&vam->json_tree);
21007     }
21008
21009   node = vat_json_array_add (&vam->json_tree);
21010   vat_json_init_object (node);
21011
21012   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21013   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21014   vat_json_object_add_uint (node, "transport_protocol",
21015                             mp->transport_protocol);
21016 }
21017
21018 static int
21019 api_sw_interface_span_enable_disable (vat_main_t * vam)
21020 {
21021   unformat_input_t *i = vam->input;
21022   vl_api_sw_interface_span_enable_disable_t *mp;
21023   u32 src_sw_if_index = ~0;
21024   u32 dst_sw_if_index = ~0;
21025   u8 state = 3;
21026   int ret;
21027   u8 is_l2 = 0;
21028
21029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21030     {
21031       if (unformat
21032           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21033         ;
21034       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21035         ;
21036       else
21037         if (unformat
21038             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21039         ;
21040       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21041         ;
21042       else if (unformat (i, "disable"))
21043         state = 0;
21044       else if (unformat (i, "rx"))
21045         state = 1;
21046       else if (unformat (i, "tx"))
21047         state = 2;
21048       else if (unformat (i, "both"))
21049         state = 3;
21050       else if (unformat (i, "l2"))
21051         is_l2 = 1;
21052       else
21053         break;
21054     }
21055
21056   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21057
21058   mp->sw_if_index_from = htonl (src_sw_if_index);
21059   mp->sw_if_index_to = htonl (dst_sw_if_index);
21060   mp->state = state;
21061   mp->is_l2 = is_l2;
21062
21063   S (mp);
21064   W (ret);
21065   return ret;
21066 }
21067
21068 static void
21069 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21070                                             * mp)
21071 {
21072   vat_main_t *vam = &vat_main;
21073   u8 *sw_if_from_name = 0;
21074   u8 *sw_if_to_name = 0;
21075   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21076   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21077   char *states[] = { "none", "rx", "tx", "both" };
21078   hash_pair_t *p;
21079
21080   /* *INDENT-OFF* */
21081   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21082   ({
21083     if ((u32) p->value[0] == sw_if_index_from)
21084       {
21085         sw_if_from_name = (u8 *)(p->key);
21086         if (sw_if_to_name)
21087           break;
21088       }
21089     if ((u32) p->value[0] == sw_if_index_to)
21090       {
21091         sw_if_to_name = (u8 *)(p->key);
21092         if (sw_if_from_name)
21093           break;
21094       }
21095   }));
21096   /* *INDENT-ON* */
21097   print (vam->ofp, "%20s => %20s (%s) %s",
21098          sw_if_from_name, sw_if_to_name, states[mp->state],
21099          mp->is_l2 ? "l2" : "device");
21100 }
21101
21102 static void
21103   vl_api_sw_interface_span_details_t_handler_json
21104   (vl_api_sw_interface_span_details_t * mp)
21105 {
21106   vat_main_t *vam = &vat_main;
21107   vat_json_node_t *node = NULL;
21108   u8 *sw_if_from_name = 0;
21109   u8 *sw_if_to_name = 0;
21110   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21111   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21112   hash_pair_t *p;
21113
21114   /* *INDENT-OFF* */
21115   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21116   ({
21117     if ((u32) p->value[0] == sw_if_index_from)
21118       {
21119         sw_if_from_name = (u8 *)(p->key);
21120         if (sw_if_to_name)
21121           break;
21122       }
21123     if ((u32) p->value[0] == sw_if_index_to)
21124       {
21125         sw_if_to_name = (u8 *)(p->key);
21126         if (sw_if_from_name)
21127           break;
21128       }
21129   }));
21130   /* *INDENT-ON* */
21131
21132   if (VAT_JSON_ARRAY != vam->json_tree.type)
21133     {
21134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21135       vat_json_init_array (&vam->json_tree);
21136     }
21137   node = vat_json_array_add (&vam->json_tree);
21138
21139   vat_json_init_object (node);
21140   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21141   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21142   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21143   if (0 != sw_if_to_name)
21144     {
21145       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21146     }
21147   vat_json_object_add_uint (node, "state", mp->state);
21148   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21149 }
21150
21151 static int
21152 api_sw_interface_span_dump (vat_main_t * vam)
21153 {
21154   unformat_input_t *input = vam->input;
21155   vl_api_sw_interface_span_dump_t *mp;
21156   vl_api_control_ping_t *mp_ping;
21157   u8 is_l2 = 0;
21158   int ret;
21159
21160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21161     {
21162       if (unformat (input, "l2"))
21163         is_l2 = 1;
21164       else
21165         break;
21166     }
21167
21168   M (SW_INTERFACE_SPAN_DUMP, mp);
21169   mp->is_l2 = is_l2;
21170   S (mp);
21171
21172   /* Use a control ping for synchronization */
21173   MPING (CONTROL_PING, mp_ping);
21174   S (mp_ping);
21175
21176   W (ret);
21177   return ret;
21178 }
21179
21180 int
21181 api_pg_create_interface (vat_main_t * vam)
21182 {
21183   unformat_input_t *input = vam->input;
21184   vl_api_pg_create_interface_t *mp;
21185
21186   u32 if_id = ~0;
21187   int ret;
21188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21189     {
21190       if (unformat (input, "if_id %d", &if_id))
21191         ;
21192       else
21193         break;
21194     }
21195   if (if_id == ~0)
21196     {
21197       errmsg ("missing pg interface index");
21198       return -99;
21199     }
21200
21201   /* Construct the API message */
21202   M (PG_CREATE_INTERFACE, mp);
21203   mp->context = 0;
21204   mp->interface_id = ntohl (if_id);
21205
21206   S (mp);
21207   W (ret);
21208   return ret;
21209 }
21210
21211 int
21212 api_pg_capture (vat_main_t * vam)
21213 {
21214   unformat_input_t *input = vam->input;
21215   vl_api_pg_capture_t *mp;
21216
21217   u32 if_id = ~0;
21218   u8 enable = 1;
21219   u32 count = 1;
21220   u8 pcap_file_set = 0;
21221   u8 *pcap_file = 0;
21222   int ret;
21223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21224     {
21225       if (unformat (input, "if_id %d", &if_id))
21226         ;
21227       else if (unformat (input, "pcap %s", &pcap_file))
21228         pcap_file_set = 1;
21229       else if (unformat (input, "count %d", &count))
21230         ;
21231       else if (unformat (input, "disable"))
21232         enable = 0;
21233       else
21234         break;
21235     }
21236   if (if_id == ~0)
21237     {
21238       errmsg ("missing pg interface index");
21239       return -99;
21240     }
21241   if (pcap_file_set > 0)
21242     {
21243       if (vec_len (pcap_file) > 255)
21244         {
21245           errmsg ("pcap file name is too long");
21246           return -99;
21247         }
21248     }
21249
21250   u32 name_len = vec_len (pcap_file);
21251   /* Construct the API message */
21252   M (PG_CAPTURE, mp);
21253   mp->context = 0;
21254   mp->interface_id = ntohl (if_id);
21255   mp->is_enabled = enable;
21256   mp->count = ntohl (count);
21257   mp->pcap_name_length = ntohl (name_len);
21258   if (pcap_file_set != 0)
21259     {
21260       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21261     }
21262   vec_free (pcap_file);
21263
21264   S (mp);
21265   W (ret);
21266   return ret;
21267 }
21268
21269 int
21270 api_pg_enable_disable (vat_main_t * vam)
21271 {
21272   unformat_input_t *input = vam->input;
21273   vl_api_pg_enable_disable_t *mp;
21274
21275   u8 enable = 1;
21276   u8 stream_name_set = 0;
21277   u8 *stream_name = 0;
21278   int ret;
21279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21280     {
21281       if (unformat (input, "stream %s", &stream_name))
21282         stream_name_set = 1;
21283       else if (unformat (input, "disable"))
21284         enable = 0;
21285       else
21286         break;
21287     }
21288
21289   if (stream_name_set > 0)
21290     {
21291       if (vec_len (stream_name) > 255)
21292         {
21293           errmsg ("stream name too long");
21294           return -99;
21295         }
21296     }
21297
21298   u32 name_len = vec_len (stream_name);
21299   /* Construct the API message */
21300   M (PG_ENABLE_DISABLE, mp);
21301   mp->context = 0;
21302   mp->is_enabled = enable;
21303   if (stream_name_set != 0)
21304     {
21305       mp->stream_name_length = ntohl (name_len);
21306       clib_memcpy (mp->stream_name, stream_name, name_len);
21307     }
21308   vec_free (stream_name);
21309
21310   S (mp);
21311   W (ret);
21312   return ret;
21313 }
21314
21315 int
21316 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21317 {
21318   unformat_input_t *input = vam->input;
21319   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21320
21321   u16 *low_ports = 0;
21322   u16 *high_ports = 0;
21323   u16 this_low;
21324   u16 this_hi;
21325   ip4_address_t ip4_addr;
21326   ip6_address_t ip6_addr;
21327   u32 length;
21328   u32 tmp, tmp2;
21329   u8 prefix_set = 0;
21330   u32 vrf_id = ~0;
21331   u8 is_add = 1;
21332   u8 is_ipv6 = 0;
21333   int ret;
21334
21335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21336     {
21337       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21338         {
21339           prefix_set = 1;
21340         }
21341       else
21342         if (unformat
21343             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21344         {
21345           prefix_set = 1;
21346           is_ipv6 = 1;
21347         }
21348       else if (unformat (input, "vrf %d", &vrf_id))
21349         ;
21350       else if (unformat (input, "del"))
21351         is_add = 0;
21352       else if (unformat (input, "port %d", &tmp))
21353         {
21354           if (tmp == 0 || tmp > 65535)
21355             {
21356               errmsg ("port %d out of range", tmp);
21357               return -99;
21358             }
21359           this_low = tmp;
21360           this_hi = this_low + 1;
21361           vec_add1 (low_ports, this_low);
21362           vec_add1 (high_ports, this_hi);
21363         }
21364       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21365         {
21366           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21367             {
21368               errmsg ("incorrect range parameters");
21369               return -99;
21370             }
21371           this_low = tmp;
21372           /* Note: in debug CLI +1 is added to high before
21373              passing to real fn that does "the work"
21374              (ip_source_and_port_range_check_add_del).
21375              This fn is a wrapper around the binary API fn a
21376              control plane will call, which expects this increment
21377              to have occurred. Hence letting the binary API control
21378              plane fn do the increment for consistency between VAT
21379              and other control planes.
21380            */
21381           this_hi = tmp2;
21382           vec_add1 (low_ports, this_low);
21383           vec_add1 (high_ports, this_hi);
21384         }
21385       else
21386         break;
21387     }
21388
21389   if (prefix_set == 0)
21390     {
21391       errmsg ("<address>/<mask> not specified");
21392       return -99;
21393     }
21394
21395   if (vrf_id == ~0)
21396     {
21397       errmsg ("VRF ID required, not specified");
21398       return -99;
21399     }
21400
21401   if (vrf_id == 0)
21402     {
21403       errmsg
21404         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21405       return -99;
21406     }
21407
21408   if (vec_len (low_ports) == 0)
21409     {
21410       errmsg ("At least one port or port range required");
21411       return -99;
21412     }
21413
21414   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21415
21416   mp->is_add = is_add;
21417
21418   if (is_ipv6)
21419     {
21420       mp->is_ipv6 = 1;
21421       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21422     }
21423   else
21424     {
21425       mp->is_ipv6 = 0;
21426       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21427     }
21428
21429   mp->mask_length = length;
21430   mp->number_of_ranges = vec_len (low_ports);
21431
21432   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21433   vec_free (low_ports);
21434
21435   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21436   vec_free (high_ports);
21437
21438   mp->vrf_id = ntohl (vrf_id);
21439
21440   S (mp);
21441   W (ret);
21442   return ret;
21443 }
21444
21445 int
21446 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21447 {
21448   unformat_input_t *input = vam->input;
21449   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21450   u32 sw_if_index = ~0;
21451   int vrf_set = 0;
21452   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21453   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21454   u8 is_add = 1;
21455   int ret;
21456
21457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21458     {
21459       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21460         ;
21461       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21462         ;
21463       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21464         vrf_set = 1;
21465       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21466         vrf_set = 1;
21467       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21468         vrf_set = 1;
21469       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21470         vrf_set = 1;
21471       else if (unformat (input, "del"))
21472         is_add = 0;
21473       else
21474         break;
21475     }
21476
21477   if (sw_if_index == ~0)
21478     {
21479       errmsg ("Interface required but not specified");
21480       return -99;
21481     }
21482
21483   if (vrf_set == 0)
21484     {
21485       errmsg ("VRF ID required but not specified");
21486       return -99;
21487     }
21488
21489   if (tcp_out_vrf_id == 0
21490       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21491     {
21492       errmsg
21493         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21494       return -99;
21495     }
21496
21497   /* Construct the API message */
21498   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21499
21500   mp->sw_if_index = ntohl (sw_if_index);
21501   mp->is_add = is_add;
21502   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21503   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21504   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21505   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21506
21507   /* send it... */
21508   S (mp);
21509
21510   /* Wait for a reply... */
21511   W (ret);
21512   return ret;
21513 }
21514
21515 static int
21516 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21517 {
21518   unformat_input_t *i = vam->input;
21519   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21520   u32 local_sa_id = 0;
21521   u32 remote_sa_id = 0;
21522   ip4_address_t src_address;
21523   ip4_address_t dst_address;
21524   u8 is_add = 1;
21525   int ret;
21526
21527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21528     {
21529       if (unformat (i, "local_sa %d", &local_sa_id))
21530         ;
21531       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21532         ;
21533       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21534         ;
21535       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21536         ;
21537       else if (unformat (i, "del"))
21538         is_add = 0;
21539       else
21540         {
21541           clib_warning ("parse error '%U'", format_unformat_error, i);
21542           return -99;
21543         }
21544     }
21545
21546   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21547
21548   mp->local_sa_id = ntohl (local_sa_id);
21549   mp->remote_sa_id = ntohl (remote_sa_id);
21550   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21551   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21552   mp->is_add = is_add;
21553
21554   S (mp);
21555   W (ret);
21556   return ret;
21557 }
21558
21559 static int
21560 api_set_punt (vat_main_t * vam)
21561 {
21562   unformat_input_t *i = vam->input;
21563   vl_api_set_punt_t *mp;
21564   u32 ipv = ~0;
21565   u32 protocol = ~0;
21566   u32 port = ~0;
21567   int is_add = 1;
21568   int ret;
21569
21570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21571     {
21572       if (unformat (i, "ip %d", &ipv))
21573         ;
21574       else if (unformat (i, "protocol %d", &protocol))
21575         ;
21576       else if (unformat (i, "port %d", &port))
21577         ;
21578       else if (unformat (i, "del"))
21579         is_add = 0;
21580       else
21581         {
21582           clib_warning ("parse error '%U'", format_unformat_error, i);
21583           return -99;
21584         }
21585     }
21586
21587   M (SET_PUNT, mp);
21588
21589   mp->is_add = (u8) is_add;
21590   mp->punt.ipv = (u8) ipv;
21591   mp->punt.l4_protocol = (u8) protocol;
21592   mp->punt.l4_port = htons ((u16) port);
21593
21594   S (mp);
21595   W (ret);
21596   return ret;
21597 }
21598
21599 static void vl_api_ipsec_gre_tunnel_details_t_handler
21600   (vl_api_ipsec_gre_tunnel_details_t * mp)
21601 {
21602   vat_main_t *vam = &vat_main;
21603
21604   print (vam->ofp, "%11d%15U%15U%14d%14d",
21605          ntohl (mp->sw_if_index),
21606          format_ip4_address, &mp->src_address,
21607          format_ip4_address, &mp->dst_address,
21608          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21609 }
21610
21611 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21612   (vl_api_ipsec_gre_tunnel_details_t * mp)
21613 {
21614   vat_main_t *vam = &vat_main;
21615   vat_json_node_t *node = NULL;
21616   struct in_addr ip4;
21617
21618   if (VAT_JSON_ARRAY != vam->json_tree.type)
21619     {
21620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21621       vat_json_init_array (&vam->json_tree);
21622     }
21623   node = vat_json_array_add (&vam->json_tree);
21624
21625   vat_json_init_object (node);
21626   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21627   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21628   vat_json_object_add_ip4 (node, "src_address", ip4);
21629   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21630   vat_json_object_add_ip4 (node, "dst_address", ip4);
21631   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21632   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21633 }
21634
21635 static int
21636 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21637 {
21638   unformat_input_t *i = vam->input;
21639   vl_api_ipsec_gre_tunnel_dump_t *mp;
21640   vl_api_control_ping_t *mp_ping;
21641   u32 sw_if_index;
21642   u8 sw_if_index_set = 0;
21643   int ret;
21644
21645   /* Parse args required to build the message */
21646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21647     {
21648       if (unformat (i, "sw_if_index %d", &sw_if_index))
21649         sw_if_index_set = 1;
21650       else
21651         break;
21652     }
21653
21654   if (sw_if_index_set == 0)
21655     {
21656       sw_if_index = ~0;
21657     }
21658
21659   if (!vam->json_output)
21660     {
21661       print (vam->ofp, "%11s%15s%15s%14s%14s",
21662              "sw_if_index", "src_address", "dst_address",
21663              "local_sa_id", "remote_sa_id");
21664     }
21665
21666   /* Get list of gre-tunnel interfaces */
21667   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21668
21669   mp->sw_if_index = htonl (sw_if_index);
21670
21671   S (mp);
21672
21673   /* Use a control ping for synchronization */
21674   MPING (CONTROL_PING, mp_ping);
21675   S (mp_ping);
21676
21677   W (ret);
21678   return ret;
21679 }
21680
21681 static int
21682 api_delete_subif (vat_main_t * vam)
21683 {
21684   unformat_input_t *i = vam->input;
21685   vl_api_delete_subif_t *mp;
21686   u32 sw_if_index = ~0;
21687   int ret;
21688
21689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21690     {
21691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21692         ;
21693       if (unformat (i, "sw_if_index %d", &sw_if_index))
21694         ;
21695       else
21696         break;
21697     }
21698
21699   if (sw_if_index == ~0)
21700     {
21701       errmsg ("missing sw_if_index");
21702       return -99;
21703     }
21704
21705   /* Construct the API message */
21706   M (DELETE_SUBIF, mp);
21707   mp->sw_if_index = ntohl (sw_if_index);
21708
21709   S (mp);
21710   W (ret);
21711   return ret;
21712 }
21713
21714 #define foreach_pbb_vtr_op      \
21715 _("disable",  L2_VTR_DISABLED)  \
21716 _("pop",  L2_VTR_POP_2)         \
21717 _("push",  L2_VTR_PUSH_2)
21718
21719 static int
21720 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21721 {
21722   unformat_input_t *i = vam->input;
21723   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21724   u32 sw_if_index = ~0, vtr_op = ~0;
21725   u16 outer_tag = ~0;
21726   u8 dmac[6], smac[6];
21727   u8 dmac_set = 0, smac_set = 0;
21728   u16 vlanid = 0;
21729   u32 sid = ~0;
21730   u32 tmp;
21731   int ret;
21732
21733   /* Shut up coverity */
21734   clib_memset (dmac, 0, sizeof (dmac));
21735   clib_memset (smac, 0, sizeof (smac));
21736
21737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21738     {
21739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21740         ;
21741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21742         ;
21743       else if (unformat (i, "vtr_op %d", &vtr_op))
21744         ;
21745 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21746       foreach_pbb_vtr_op
21747 #undef _
21748         else if (unformat (i, "translate_pbb_stag"))
21749         {
21750           if (unformat (i, "%d", &tmp))
21751             {
21752               vtr_op = L2_VTR_TRANSLATE_2_1;
21753               outer_tag = tmp;
21754             }
21755           else
21756             {
21757               errmsg
21758                 ("translate_pbb_stag operation requires outer tag definition");
21759               return -99;
21760             }
21761         }
21762       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21763         dmac_set++;
21764       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21765         smac_set++;
21766       else if (unformat (i, "sid %d", &sid))
21767         ;
21768       else if (unformat (i, "vlanid %d", &tmp))
21769         vlanid = tmp;
21770       else
21771         {
21772           clib_warning ("parse error '%U'", format_unformat_error, i);
21773           return -99;
21774         }
21775     }
21776
21777   if ((sw_if_index == ~0) || (vtr_op == ~0))
21778     {
21779       errmsg ("missing sw_if_index or vtr operation");
21780       return -99;
21781     }
21782   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21783       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21784     {
21785       errmsg
21786         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21787       return -99;
21788     }
21789
21790   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21791   mp->sw_if_index = ntohl (sw_if_index);
21792   mp->vtr_op = ntohl (vtr_op);
21793   mp->outer_tag = ntohs (outer_tag);
21794   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21795   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21796   mp->b_vlanid = ntohs (vlanid);
21797   mp->i_sid = ntohl (sid);
21798
21799   S (mp);
21800   W (ret);
21801   return ret;
21802 }
21803
21804 static int
21805 api_flow_classify_set_interface (vat_main_t * vam)
21806 {
21807   unformat_input_t *i = vam->input;
21808   vl_api_flow_classify_set_interface_t *mp;
21809   u32 sw_if_index;
21810   int sw_if_index_set;
21811   u32 ip4_table_index = ~0;
21812   u32 ip6_table_index = ~0;
21813   u8 is_add = 1;
21814   int ret;
21815
21816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21817     {
21818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21819         sw_if_index_set = 1;
21820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21821         sw_if_index_set = 1;
21822       else if (unformat (i, "del"))
21823         is_add = 0;
21824       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21825         ;
21826       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21827         ;
21828       else
21829         {
21830           clib_warning ("parse error '%U'", format_unformat_error, i);
21831           return -99;
21832         }
21833     }
21834
21835   if (sw_if_index_set == 0)
21836     {
21837       errmsg ("missing interface name or sw_if_index");
21838       return -99;
21839     }
21840
21841   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21842
21843   mp->sw_if_index = ntohl (sw_if_index);
21844   mp->ip4_table_index = ntohl (ip4_table_index);
21845   mp->ip6_table_index = ntohl (ip6_table_index);
21846   mp->is_add = is_add;
21847
21848   S (mp);
21849   W (ret);
21850   return ret;
21851 }
21852
21853 static int
21854 api_flow_classify_dump (vat_main_t * vam)
21855 {
21856   unformat_input_t *i = vam->input;
21857   vl_api_flow_classify_dump_t *mp;
21858   vl_api_control_ping_t *mp_ping;
21859   u8 type = FLOW_CLASSIFY_N_TABLES;
21860   int ret;
21861
21862   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21863     ;
21864   else
21865     {
21866       errmsg ("classify table type must be specified");
21867       return -99;
21868     }
21869
21870   if (!vam->json_output)
21871     {
21872       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21873     }
21874
21875   M (FLOW_CLASSIFY_DUMP, mp);
21876   mp->type = type;
21877   /* send it... */
21878   S (mp);
21879
21880   /* Use a control ping for synchronization */
21881   MPING (CONTROL_PING, mp_ping);
21882   S (mp_ping);
21883
21884   /* Wait for a reply... */
21885   W (ret);
21886   return ret;
21887 }
21888
21889 static int
21890 api_feature_enable_disable (vat_main_t * vam)
21891 {
21892   unformat_input_t *i = vam->input;
21893   vl_api_feature_enable_disable_t *mp;
21894   u8 *arc_name = 0;
21895   u8 *feature_name = 0;
21896   u32 sw_if_index = ~0;
21897   u8 enable = 1;
21898   int ret;
21899
21900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21901     {
21902       if (unformat (i, "arc_name %s", &arc_name))
21903         ;
21904       else if (unformat (i, "feature_name %s", &feature_name))
21905         ;
21906       else
21907         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21908         ;
21909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21910         ;
21911       else if (unformat (i, "disable"))
21912         enable = 0;
21913       else
21914         break;
21915     }
21916
21917   if (arc_name == 0)
21918     {
21919       errmsg ("missing arc name");
21920       return -99;
21921     }
21922   if (vec_len (arc_name) > 63)
21923     {
21924       errmsg ("arc name too long");
21925     }
21926
21927   if (feature_name == 0)
21928     {
21929       errmsg ("missing feature name");
21930       return -99;
21931     }
21932   if (vec_len (feature_name) > 63)
21933     {
21934       errmsg ("feature name too long");
21935     }
21936
21937   if (sw_if_index == ~0)
21938     {
21939       errmsg ("missing interface name or sw_if_index");
21940       return -99;
21941     }
21942
21943   /* Construct the API message */
21944   M (FEATURE_ENABLE_DISABLE, mp);
21945   mp->sw_if_index = ntohl (sw_if_index);
21946   mp->enable = enable;
21947   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21948   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21949   vec_free (arc_name);
21950   vec_free (feature_name);
21951
21952   S (mp);
21953   W (ret);
21954   return ret;
21955 }
21956
21957 static int
21958 api_sw_interface_tag_add_del (vat_main_t * vam)
21959 {
21960   unformat_input_t *i = vam->input;
21961   vl_api_sw_interface_tag_add_del_t *mp;
21962   u32 sw_if_index = ~0;
21963   u8 *tag = 0;
21964   u8 enable = 1;
21965   int ret;
21966
21967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21968     {
21969       if (unformat (i, "tag %s", &tag))
21970         ;
21971       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21972         ;
21973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21974         ;
21975       else if (unformat (i, "del"))
21976         enable = 0;
21977       else
21978         break;
21979     }
21980
21981   if (sw_if_index == ~0)
21982     {
21983       errmsg ("missing interface name or sw_if_index");
21984       return -99;
21985     }
21986
21987   if (enable && (tag == 0))
21988     {
21989       errmsg ("no tag specified");
21990       return -99;
21991     }
21992
21993   /* Construct the API message */
21994   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21995   mp->sw_if_index = ntohl (sw_if_index);
21996   mp->is_add = enable;
21997   if (enable)
21998     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21999   vec_free (tag);
22000
22001   S (mp);
22002   W (ret);
22003   return ret;
22004 }
22005
22006 static void vl_api_l2_xconnect_details_t_handler
22007   (vl_api_l2_xconnect_details_t * mp)
22008 {
22009   vat_main_t *vam = &vat_main;
22010
22011   print (vam->ofp, "%15d%15d",
22012          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22013 }
22014
22015 static void vl_api_l2_xconnect_details_t_handler_json
22016   (vl_api_l2_xconnect_details_t * mp)
22017 {
22018   vat_main_t *vam = &vat_main;
22019   vat_json_node_t *node = NULL;
22020
22021   if (VAT_JSON_ARRAY != vam->json_tree.type)
22022     {
22023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22024       vat_json_init_array (&vam->json_tree);
22025     }
22026   node = vat_json_array_add (&vam->json_tree);
22027
22028   vat_json_init_object (node);
22029   vat_json_object_add_uint (node, "rx_sw_if_index",
22030                             ntohl (mp->rx_sw_if_index));
22031   vat_json_object_add_uint (node, "tx_sw_if_index",
22032                             ntohl (mp->tx_sw_if_index));
22033 }
22034
22035 static int
22036 api_l2_xconnect_dump (vat_main_t * vam)
22037 {
22038   vl_api_l2_xconnect_dump_t *mp;
22039   vl_api_control_ping_t *mp_ping;
22040   int ret;
22041
22042   if (!vam->json_output)
22043     {
22044       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22045     }
22046
22047   M (L2_XCONNECT_DUMP, mp);
22048
22049   S (mp);
22050
22051   /* Use a control ping for synchronization */
22052   MPING (CONTROL_PING, mp_ping);
22053   S (mp_ping);
22054
22055   W (ret);
22056   return ret;
22057 }
22058
22059 static int
22060 api_hw_interface_set_mtu (vat_main_t * vam)
22061 {
22062   unformat_input_t *i = vam->input;
22063   vl_api_hw_interface_set_mtu_t *mp;
22064   u32 sw_if_index = ~0;
22065   u32 mtu = 0;
22066   int ret;
22067
22068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22069     {
22070       if (unformat (i, "mtu %d", &mtu))
22071         ;
22072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22073         ;
22074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22075         ;
22076       else
22077         break;
22078     }
22079
22080   if (sw_if_index == ~0)
22081     {
22082       errmsg ("missing interface name or sw_if_index");
22083       return -99;
22084     }
22085
22086   if (mtu == 0)
22087     {
22088       errmsg ("no mtu specified");
22089       return -99;
22090     }
22091
22092   /* Construct the API message */
22093   M (HW_INTERFACE_SET_MTU, mp);
22094   mp->sw_if_index = ntohl (sw_if_index);
22095   mp->mtu = ntohs ((u16) mtu);
22096
22097   S (mp);
22098   W (ret);
22099   return ret;
22100 }
22101
22102 static int
22103 api_p2p_ethernet_add (vat_main_t * vam)
22104 {
22105   unformat_input_t *i = vam->input;
22106   vl_api_p2p_ethernet_add_t *mp;
22107   u32 parent_if_index = ~0;
22108   u32 sub_id = ~0;
22109   u8 remote_mac[6];
22110   u8 mac_set = 0;
22111   int ret;
22112
22113   clib_memset (remote_mac, 0, sizeof (remote_mac));
22114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22115     {
22116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22117         ;
22118       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22119         ;
22120       else
22121         if (unformat
22122             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22123         mac_set++;
22124       else if (unformat (i, "sub_id %d", &sub_id))
22125         ;
22126       else
22127         {
22128           clib_warning ("parse error '%U'", format_unformat_error, i);
22129           return -99;
22130         }
22131     }
22132
22133   if (parent_if_index == ~0)
22134     {
22135       errmsg ("missing interface name or sw_if_index");
22136       return -99;
22137     }
22138   if (mac_set == 0)
22139     {
22140       errmsg ("missing remote mac address");
22141       return -99;
22142     }
22143   if (sub_id == ~0)
22144     {
22145       errmsg ("missing sub-interface id");
22146       return -99;
22147     }
22148
22149   M (P2P_ETHERNET_ADD, mp);
22150   mp->parent_if_index = ntohl (parent_if_index);
22151   mp->subif_id = ntohl (sub_id);
22152   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22153
22154   S (mp);
22155   W (ret);
22156   return ret;
22157 }
22158
22159 static int
22160 api_p2p_ethernet_del (vat_main_t * vam)
22161 {
22162   unformat_input_t *i = vam->input;
22163   vl_api_p2p_ethernet_del_t *mp;
22164   u32 parent_if_index = ~0;
22165   u8 remote_mac[6];
22166   u8 mac_set = 0;
22167   int ret;
22168
22169   clib_memset (remote_mac, 0, sizeof (remote_mac));
22170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22171     {
22172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22173         ;
22174       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22175         ;
22176       else
22177         if (unformat
22178             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22179         mac_set++;
22180       else
22181         {
22182           clib_warning ("parse error '%U'", format_unformat_error, i);
22183           return -99;
22184         }
22185     }
22186
22187   if (parent_if_index == ~0)
22188     {
22189       errmsg ("missing interface name or sw_if_index");
22190       return -99;
22191     }
22192   if (mac_set == 0)
22193     {
22194       errmsg ("missing remote mac address");
22195       return -99;
22196     }
22197
22198   M (P2P_ETHERNET_DEL, mp);
22199   mp->parent_if_index = ntohl (parent_if_index);
22200   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22201
22202   S (mp);
22203   W (ret);
22204   return ret;
22205 }
22206
22207 static int
22208 api_lldp_config (vat_main_t * vam)
22209 {
22210   unformat_input_t *i = vam->input;
22211   vl_api_lldp_config_t *mp;
22212   int tx_hold = 0;
22213   int tx_interval = 0;
22214   u8 *sys_name = NULL;
22215   int ret;
22216
22217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22218     {
22219       if (unformat (i, "system-name %s", &sys_name))
22220         ;
22221       else if (unformat (i, "tx-hold %d", &tx_hold))
22222         ;
22223       else if (unformat (i, "tx-interval %d", &tx_interval))
22224         ;
22225       else
22226         {
22227           clib_warning ("parse error '%U'", format_unformat_error, i);
22228           return -99;
22229         }
22230     }
22231
22232   vec_add1 (sys_name, 0);
22233
22234   M (LLDP_CONFIG, mp);
22235   mp->tx_hold = htonl (tx_hold);
22236   mp->tx_interval = htonl (tx_interval);
22237   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22238   vec_free (sys_name);
22239
22240   S (mp);
22241   W (ret);
22242   return ret;
22243 }
22244
22245 static int
22246 api_sw_interface_set_lldp (vat_main_t * vam)
22247 {
22248   unformat_input_t *i = vam->input;
22249   vl_api_sw_interface_set_lldp_t *mp;
22250   u32 sw_if_index = ~0;
22251   u32 enable = 1;
22252   u8 *port_desc = NULL, *mgmt_oid = NULL;
22253   ip4_address_t ip4_addr;
22254   ip6_address_t ip6_addr;
22255   int ret;
22256
22257   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22258   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22259
22260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22261     {
22262       if (unformat (i, "disable"))
22263         enable = 0;
22264       else
22265         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22266         ;
22267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22268         ;
22269       else if (unformat (i, "port-desc %s", &port_desc))
22270         ;
22271       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22272         ;
22273       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22274         ;
22275       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22276         ;
22277       else
22278         break;
22279     }
22280
22281   if (sw_if_index == ~0)
22282     {
22283       errmsg ("missing interface name or sw_if_index");
22284       return -99;
22285     }
22286
22287   /* Construct the API message */
22288   vec_add1 (port_desc, 0);
22289   vec_add1 (mgmt_oid, 0);
22290   M (SW_INTERFACE_SET_LLDP, mp);
22291   mp->sw_if_index = ntohl (sw_if_index);
22292   mp->enable = enable;
22293   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22294   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22295   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22296   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22297   vec_free (port_desc);
22298   vec_free (mgmt_oid);
22299
22300   S (mp);
22301   W (ret);
22302   return ret;
22303 }
22304
22305 static int
22306 api_tcp_configure_src_addresses (vat_main_t * vam)
22307 {
22308   vl_api_tcp_configure_src_addresses_t *mp;
22309   unformat_input_t *i = vam->input;
22310   ip4_address_t v4first, v4last;
22311   ip6_address_t v6first, v6last;
22312   u8 range_set = 0;
22313   u32 vrf_id = 0;
22314   int ret;
22315
22316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22317     {
22318       if (unformat (i, "%U - %U",
22319                     unformat_ip4_address, &v4first,
22320                     unformat_ip4_address, &v4last))
22321         {
22322           if (range_set)
22323             {
22324               errmsg ("one range per message (range already set)");
22325               return -99;
22326             }
22327           range_set = 1;
22328         }
22329       else if (unformat (i, "%U - %U",
22330                          unformat_ip6_address, &v6first,
22331                          unformat_ip6_address, &v6last))
22332         {
22333           if (range_set)
22334             {
22335               errmsg ("one range per message (range already set)");
22336               return -99;
22337             }
22338           range_set = 2;
22339         }
22340       else if (unformat (i, "vrf %d", &vrf_id))
22341         ;
22342       else
22343         break;
22344     }
22345
22346   if (range_set == 0)
22347     {
22348       errmsg ("address range not set");
22349       return -99;
22350     }
22351
22352   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22353   mp->vrf_id = ntohl (vrf_id);
22354   /* ipv6? */
22355   if (range_set == 2)
22356     {
22357       mp->is_ipv6 = 1;
22358       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22359       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22360     }
22361   else
22362     {
22363       mp->is_ipv6 = 0;
22364       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22365       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22366     }
22367   S (mp);
22368   W (ret);
22369   return ret;
22370 }
22371
22372 static void vl_api_app_namespace_add_del_reply_t_handler
22373   (vl_api_app_namespace_add_del_reply_t * mp)
22374 {
22375   vat_main_t *vam = &vat_main;
22376   i32 retval = ntohl (mp->retval);
22377   if (vam->async_mode)
22378     {
22379       vam->async_errors += (retval < 0);
22380     }
22381   else
22382     {
22383       vam->retval = retval;
22384       if (retval == 0)
22385         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22386       vam->result_ready = 1;
22387     }
22388 }
22389
22390 static void vl_api_app_namespace_add_del_reply_t_handler_json
22391   (vl_api_app_namespace_add_del_reply_t * mp)
22392 {
22393   vat_main_t *vam = &vat_main;
22394   vat_json_node_t node;
22395
22396   vat_json_init_object (&node);
22397   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22398   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22399
22400   vat_json_print (vam->ofp, &node);
22401   vat_json_free (&node);
22402
22403   vam->retval = ntohl (mp->retval);
22404   vam->result_ready = 1;
22405 }
22406
22407 static int
22408 api_app_namespace_add_del (vat_main_t * vam)
22409 {
22410   vl_api_app_namespace_add_del_t *mp;
22411   unformat_input_t *i = vam->input;
22412   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22413   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22414   u64 secret;
22415   int ret;
22416
22417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22418     {
22419       if (unformat (i, "id %_%v%_", &ns_id))
22420         ;
22421       else if (unformat (i, "secret %lu", &secret))
22422         secret_set = 1;
22423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22424         sw_if_index_set = 1;
22425       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22426         ;
22427       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22428         ;
22429       else
22430         break;
22431     }
22432   if (!ns_id || !secret_set || !sw_if_index_set)
22433     {
22434       errmsg ("namespace id, secret and sw_if_index must be set");
22435       return -99;
22436     }
22437   if (vec_len (ns_id) > 64)
22438     {
22439       errmsg ("namespace id too long");
22440       return -99;
22441     }
22442   M (APP_NAMESPACE_ADD_DEL, mp);
22443
22444   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22445   mp->namespace_id_len = vec_len (ns_id);
22446   mp->secret = clib_host_to_net_u64 (secret);
22447   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22448   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22449   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22450   vec_free (ns_id);
22451   S (mp);
22452   W (ret);
22453   return ret;
22454 }
22455
22456 static int
22457 api_sock_init_shm (vat_main_t * vam)
22458 {
22459 #if VPP_API_TEST_BUILTIN == 0
22460   unformat_input_t *i = vam->input;
22461   vl_api_shm_elem_config_t *config = 0;
22462   u64 size = 64 << 20;
22463   int rv;
22464
22465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22466     {
22467       if (unformat (i, "size %U", unformat_memory_size, &size))
22468         ;
22469       else
22470         break;
22471     }
22472
22473   /*
22474    * Canned custom ring allocator config.
22475    * Should probably parse all of this
22476    */
22477   vec_validate (config, 6);
22478   config[0].type = VL_API_VLIB_RING;
22479   config[0].size = 256;
22480   config[0].count = 32;
22481
22482   config[1].type = VL_API_VLIB_RING;
22483   config[1].size = 1024;
22484   config[1].count = 16;
22485
22486   config[2].type = VL_API_VLIB_RING;
22487   config[2].size = 4096;
22488   config[2].count = 2;
22489
22490   config[3].type = VL_API_CLIENT_RING;
22491   config[3].size = 256;
22492   config[3].count = 32;
22493
22494   config[4].type = VL_API_CLIENT_RING;
22495   config[4].size = 1024;
22496   config[4].count = 16;
22497
22498   config[5].type = VL_API_CLIENT_RING;
22499   config[5].size = 4096;
22500   config[5].count = 2;
22501
22502   config[6].type = VL_API_QUEUE;
22503   config[6].count = 128;
22504   config[6].size = sizeof (uword);
22505
22506   rv = vl_socket_client_init_shm (config);
22507   if (!rv)
22508     vam->client_index_invalid = 1;
22509   return rv;
22510 #else
22511   return -99;
22512 #endif
22513 }
22514
22515 static int
22516 api_dns_enable_disable (vat_main_t * vam)
22517 {
22518   unformat_input_t *line_input = vam->input;
22519   vl_api_dns_enable_disable_t *mp;
22520   u8 enable_disable = 1;
22521   int ret;
22522
22523   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22524     {
22525       if (unformat (line_input, "disable"))
22526         enable_disable = 0;
22527       if (unformat (line_input, "enable"))
22528         enable_disable = 1;
22529       else
22530         break;
22531     }
22532
22533   /* Construct the API message */
22534   M (DNS_ENABLE_DISABLE, mp);
22535   mp->enable = enable_disable;
22536
22537   /* send it... */
22538   S (mp);
22539   /* Wait for the reply */
22540   W (ret);
22541   return ret;
22542 }
22543
22544 static int
22545 api_dns_resolve_name (vat_main_t * vam)
22546 {
22547   unformat_input_t *line_input = vam->input;
22548   vl_api_dns_resolve_name_t *mp;
22549   u8 *name = 0;
22550   int ret;
22551
22552   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22553     {
22554       if (unformat (line_input, "%s", &name))
22555         ;
22556       else
22557         break;
22558     }
22559
22560   if (vec_len (name) > 127)
22561     {
22562       errmsg ("name too long");
22563       return -99;
22564     }
22565
22566   /* Construct the API message */
22567   M (DNS_RESOLVE_NAME, mp);
22568   memcpy (mp->name, name, vec_len (name));
22569   vec_free (name);
22570
22571   /* send it... */
22572   S (mp);
22573   /* Wait for the reply */
22574   W (ret);
22575   return ret;
22576 }
22577
22578 static int
22579 api_dns_resolve_ip (vat_main_t * vam)
22580 {
22581   unformat_input_t *line_input = vam->input;
22582   vl_api_dns_resolve_ip_t *mp;
22583   int is_ip6 = -1;
22584   ip4_address_t addr4;
22585   ip6_address_t addr6;
22586   int ret;
22587
22588   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22589     {
22590       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22591         is_ip6 = 1;
22592       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22593         is_ip6 = 0;
22594       else
22595         break;
22596     }
22597
22598   if (is_ip6 == -1)
22599     {
22600       errmsg ("missing address");
22601       return -99;
22602     }
22603
22604   /* Construct the API message */
22605   M (DNS_RESOLVE_IP, mp);
22606   mp->is_ip6 = is_ip6;
22607   if (is_ip6)
22608     memcpy (mp->address, &addr6, sizeof (addr6));
22609   else
22610     memcpy (mp->address, &addr4, sizeof (addr4));
22611
22612   /* send it... */
22613   S (mp);
22614   /* Wait for the reply */
22615   W (ret);
22616   return ret;
22617 }
22618
22619 static int
22620 api_dns_name_server_add_del (vat_main_t * vam)
22621 {
22622   unformat_input_t *i = vam->input;
22623   vl_api_dns_name_server_add_del_t *mp;
22624   u8 is_add = 1;
22625   ip6_address_t ip6_server;
22626   ip4_address_t ip4_server;
22627   int ip6_set = 0;
22628   int ip4_set = 0;
22629   int ret = 0;
22630
22631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22632     {
22633       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22634         ip6_set = 1;
22635       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22636         ip4_set = 1;
22637       else if (unformat (i, "del"))
22638         is_add = 0;
22639       else
22640         {
22641           clib_warning ("parse error '%U'", format_unformat_error, i);
22642           return -99;
22643         }
22644     }
22645
22646   if (ip4_set && ip6_set)
22647     {
22648       errmsg ("Only one server address allowed per message");
22649       return -99;
22650     }
22651   if ((ip4_set + ip6_set) == 0)
22652     {
22653       errmsg ("Server address required");
22654       return -99;
22655     }
22656
22657   /* Construct the API message */
22658   M (DNS_NAME_SERVER_ADD_DEL, mp);
22659
22660   if (ip6_set)
22661     {
22662       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22663       mp->is_ip6 = 1;
22664     }
22665   else
22666     {
22667       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22668       mp->is_ip6 = 0;
22669     }
22670
22671   mp->is_add = is_add;
22672
22673   /* send it... */
22674   S (mp);
22675
22676   /* Wait for a reply, return good/bad news  */
22677   W (ret);
22678   return ret;
22679 }
22680
22681 static void
22682 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22683 {
22684   vat_main_t *vam = &vat_main;
22685
22686   if (mp->is_ip4)
22687     {
22688       print (vam->ofp,
22689              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22690              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22691              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22692              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22693              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22694              clib_net_to_host_u32 (mp->action_index), mp->tag);
22695     }
22696   else
22697     {
22698       print (vam->ofp,
22699              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22700              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22701              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22702              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22703              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22704              clib_net_to_host_u32 (mp->action_index), mp->tag);
22705     }
22706 }
22707
22708 static void
22709 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22710                                              mp)
22711 {
22712   vat_main_t *vam = &vat_main;
22713   vat_json_node_t *node = NULL;
22714   struct in6_addr ip6;
22715   struct in_addr ip4;
22716
22717   if (VAT_JSON_ARRAY != vam->json_tree.type)
22718     {
22719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22720       vat_json_init_array (&vam->json_tree);
22721     }
22722   node = vat_json_array_add (&vam->json_tree);
22723   vat_json_init_object (node);
22724
22725   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22726   vat_json_object_add_uint (node, "appns_index",
22727                             clib_net_to_host_u32 (mp->appns_index));
22728   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22729   vat_json_object_add_uint (node, "scope", mp->scope);
22730   vat_json_object_add_uint (node, "action_index",
22731                             clib_net_to_host_u32 (mp->action_index));
22732   vat_json_object_add_uint (node, "lcl_port",
22733                             clib_net_to_host_u16 (mp->lcl_port));
22734   vat_json_object_add_uint (node, "rmt_port",
22735                             clib_net_to_host_u16 (mp->rmt_port));
22736   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22737   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22738   vat_json_object_add_string_copy (node, "tag", mp->tag);
22739   if (mp->is_ip4)
22740     {
22741       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22742       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22743       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22744       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22745     }
22746   else
22747     {
22748       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22749       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22750       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22751       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22752     }
22753 }
22754
22755 static int
22756 api_session_rule_add_del (vat_main_t * vam)
22757 {
22758   vl_api_session_rule_add_del_t *mp;
22759   unformat_input_t *i = vam->input;
22760   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22761   u32 appns_index = 0, scope = 0;
22762   ip4_address_t lcl_ip4, rmt_ip4;
22763   ip6_address_t lcl_ip6, rmt_ip6;
22764   u8 is_ip4 = 1, conn_set = 0;
22765   u8 is_add = 1, *tag = 0;
22766   int ret;
22767
22768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22769     {
22770       if (unformat (i, "del"))
22771         is_add = 0;
22772       else if (unformat (i, "add"))
22773         ;
22774       else if (unformat (i, "proto tcp"))
22775         proto = 0;
22776       else if (unformat (i, "proto udp"))
22777         proto = 1;
22778       else if (unformat (i, "appns %d", &appns_index))
22779         ;
22780       else if (unformat (i, "scope %d", &scope))
22781         ;
22782       else if (unformat (i, "tag %_%v%_", &tag))
22783         ;
22784       else
22785         if (unformat
22786             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22787              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22788              &rmt_port))
22789         {
22790           is_ip4 = 1;
22791           conn_set = 1;
22792         }
22793       else
22794         if (unformat
22795             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22796              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22797              &rmt_port))
22798         {
22799           is_ip4 = 0;
22800           conn_set = 1;
22801         }
22802       else if (unformat (i, "action %d", &action))
22803         ;
22804       else
22805         break;
22806     }
22807   if (proto == ~0 || !conn_set || action == ~0)
22808     {
22809       errmsg ("transport proto, connection and action must be set");
22810       return -99;
22811     }
22812
22813   if (scope > 3)
22814     {
22815       errmsg ("scope should be 0-3");
22816       return -99;
22817     }
22818
22819   M (SESSION_RULE_ADD_DEL, mp);
22820
22821   mp->is_ip4 = is_ip4;
22822   mp->transport_proto = proto;
22823   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22824   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22825   mp->lcl_plen = lcl_plen;
22826   mp->rmt_plen = rmt_plen;
22827   mp->action_index = clib_host_to_net_u32 (action);
22828   mp->appns_index = clib_host_to_net_u32 (appns_index);
22829   mp->scope = scope;
22830   mp->is_add = is_add;
22831   if (is_ip4)
22832     {
22833       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22834       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22835     }
22836   else
22837     {
22838       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22839       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22840     }
22841   if (tag)
22842     {
22843       clib_memcpy (mp->tag, tag, vec_len (tag));
22844       vec_free (tag);
22845     }
22846
22847   S (mp);
22848   W (ret);
22849   return ret;
22850 }
22851
22852 static int
22853 api_session_rules_dump (vat_main_t * vam)
22854 {
22855   vl_api_session_rules_dump_t *mp;
22856   vl_api_control_ping_t *mp_ping;
22857   int ret;
22858
22859   if (!vam->json_output)
22860     {
22861       print (vam->ofp, "%=20s", "Session Rules");
22862     }
22863
22864   M (SESSION_RULES_DUMP, mp);
22865   /* send it... */
22866   S (mp);
22867
22868   /* Use a control ping for synchronization */
22869   MPING (CONTROL_PING, mp_ping);
22870   S (mp_ping);
22871
22872   /* Wait for a reply... */
22873   W (ret);
22874   return ret;
22875 }
22876
22877 static int
22878 api_ip_container_proxy_add_del (vat_main_t * vam)
22879 {
22880   vl_api_ip_container_proxy_add_del_t *mp;
22881   unformat_input_t *i = vam->input;
22882   u32 plen = ~0, sw_if_index = ~0;
22883   ip4_address_t ip4;
22884   ip6_address_t ip6;
22885   u8 is_ip4 = 1;
22886   u8 is_add = 1;
22887   int ret;
22888
22889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22890     {
22891       if (unformat (i, "del"))
22892         is_add = 0;
22893       else if (unformat (i, "add"))
22894         ;
22895       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22896         {
22897           is_ip4 = 1;
22898           plen = 32;
22899         }
22900       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22901         {
22902           is_ip4 = 0;
22903           plen = 128;
22904         }
22905       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22906         ;
22907       else
22908         break;
22909     }
22910   if (sw_if_index == ~0 || plen == ~0)
22911     {
22912       errmsg ("address and sw_if_index must be set");
22913       return -99;
22914     }
22915
22916   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22917
22918   mp->is_ip4 = is_ip4;
22919   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22920   mp->plen = plen;
22921   mp->is_add = is_add;
22922   if (is_ip4)
22923     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22924   else
22925     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22926
22927   S (mp);
22928   W (ret);
22929   return ret;
22930 }
22931
22932 static int
22933 api_qos_record_enable_disable (vat_main_t * vam)
22934 {
22935   unformat_input_t *i = vam->input;
22936   vl_api_qos_record_enable_disable_t *mp;
22937   u32 sw_if_index, qs = 0xff;
22938   u8 sw_if_index_set = 0;
22939   u8 enable = 1;
22940   int ret;
22941
22942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22943     {
22944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22945         sw_if_index_set = 1;
22946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22947         sw_if_index_set = 1;
22948       else if (unformat (i, "%U", unformat_qos_source, &qs))
22949         ;
22950       else if (unformat (i, "disable"))
22951         enable = 0;
22952       else
22953         {
22954           clib_warning ("parse error '%U'", format_unformat_error, i);
22955           return -99;
22956         }
22957     }
22958
22959   if (sw_if_index_set == 0)
22960     {
22961       errmsg ("missing interface name or sw_if_index");
22962       return -99;
22963     }
22964   if (qs == 0xff)
22965     {
22966       errmsg ("input location must be specified");
22967       return -99;
22968     }
22969
22970   M (QOS_RECORD_ENABLE_DISABLE, mp);
22971
22972   mp->sw_if_index = ntohl (sw_if_index);
22973   mp->input_source = qs;
22974   mp->enable = enable;
22975
22976   S (mp);
22977   W (ret);
22978   return ret;
22979 }
22980
22981
22982 static int
22983 q_or_quit (vat_main_t * vam)
22984 {
22985 #if VPP_API_TEST_BUILTIN == 0
22986   longjmp (vam->jump_buf, 1);
22987 #endif
22988   return 0;                     /* not so much */
22989 }
22990
22991 static int
22992 q (vat_main_t * vam)
22993 {
22994   return q_or_quit (vam);
22995 }
22996
22997 static int
22998 quit (vat_main_t * vam)
22999 {
23000   return q_or_quit (vam);
23001 }
23002
23003 static int
23004 comment (vat_main_t * vam)
23005 {
23006   return 0;
23007 }
23008
23009 static int
23010 statseg (vat_main_t * vam)
23011 {
23012   ssvm_private_t *ssvmp = &vam->stat_segment;
23013   ssvm_shared_header_t *shared_header = ssvmp->sh;
23014   vlib_counter_t **counters;
23015   u64 thread0_index1_packets;
23016   u64 thread0_index1_bytes;
23017   f64 vector_rate, input_rate;
23018   uword *p;
23019
23020   uword *counter_vector_by_name;
23021   if (vam->stat_segment_lockp == 0)
23022     {
23023       errmsg ("Stat segment not mapped...");
23024       return -99;
23025     }
23026
23027   /* look up "/if/rx for sw_if_index 1 as a test */
23028
23029   clib_spinlock_lock (vam->stat_segment_lockp);
23030
23031   counter_vector_by_name = (uword *) shared_header->opaque[1];
23032
23033   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23034   if (p == 0)
23035     {
23036       clib_spinlock_unlock (vam->stat_segment_lockp);
23037       errmsg ("/if/tx not found?");
23038       return -99;
23039     }
23040
23041   /* Fish per-thread vector of combined counters from shared memory */
23042   counters = (vlib_counter_t **) p[0];
23043
23044   if (vec_len (counters[0]) < 2)
23045     {
23046       clib_spinlock_unlock (vam->stat_segment_lockp);
23047       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23048       return -99;
23049     }
23050
23051   /* Read thread 0 sw_if_index 1 counter */
23052   thread0_index1_packets = counters[0][1].packets;
23053   thread0_index1_bytes = counters[0][1].bytes;
23054
23055   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23056   if (p == 0)
23057     {
23058       clib_spinlock_unlock (vam->stat_segment_lockp);
23059       errmsg ("vector_rate not found?");
23060       return -99;
23061     }
23062
23063   vector_rate = *(f64 *) (p[0]);
23064   p = hash_get_mem (counter_vector_by_name, "input_rate");
23065   if (p == 0)
23066     {
23067       clib_spinlock_unlock (vam->stat_segment_lockp);
23068       errmsg ("input_rate not found?");
23069       return -99;
23070     }
23071   input_rate = *(f64 *) (p[0]);
23072
23073   clib_spinlock_unlock (vam->stat_segment_lockp);
23074
23075   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23076          vector_rate, input_rate);
23077   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23078          thread0_index1_packets, thread0_index1_bytes);
23079
23080   return 0;
23081 }
23082
23083 static int
23084 cmd_cmp (void *a1, void *a2)
23085 {
23086   u8 **c1 = a1;
23087   u8 **c2 = a2;
23088
23089   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23090 }
23091
23092 static int
23093 help (vat_main_t * vam)
23094 {
23095   u8 **cmds = 0;
23096   u8 *name = 0;
23097   hash_pair_t *p;
23098   unformat_input_t *i = vam->input;
23099   int j;
23100
23101   if (unformat (i, "%s", &name))
23102     {
23103       uword *hs;
23104
23105       vec_add1 (name, 0);
23106
23107       hs = hash_get_mem (vam->help_by_name, name);
23108       if (hs)
23109         print (vam->ofp, "usage: %s %s", name, hs[0]);
23110       else
23111         print (vam->ofp, "No such msg / command '%s'", name);
23112       vec_free (name);
23113       return 0;
23114     }
23115
23116   print (vam->ofp, "Help is available for the following:");
23117
23118     /* *INDENT-OFF* */
23119     hash_foreach_pair (p, vam->function_by_name,
23120     ({
23121       vec_add1 (cmds, (u8 *)(p->key));
23122     }));
23123     /* *INDENT-ON* */
23124
23125   vec_sort_with_function (cmds, cmd_cmp);
23126
23127   for (j = 0; j < vec_len (cmds); j++)
23128     print (vam->ofp, "%s", cmds[j]);
23129
23130   vec_free (cmds);
23131   return 0;
23132 }
23133
23134 static int
23135 set (vat_main_t * vam)
23136 {
23137   u8 *name = 0, *value = 0;
23138   unformat_input_t *i = vam->input;
23139
23140   if (unformat (i, "%s", &name))
23141     {
23142       /* The input buffer is a vector, not a string. */
23143       value = vec_dup (i->buffer);
23144       vec_delete (value, i->index, 0);
23145       /* Almost certainly has a trailing newline */
23146       if (value[vec_len (value) - 1] == '\n')
23147         value[vec_len (value) - 1] = 0;
23148       /* Make sure it's a proper string, one way or the other */
23149       vec_add1 (value, 0);
23150       (void) clib_macro_set_value (&vam->macro_main,
23151                                    (char *) name, (char *) value);
23152     }
23153   else
23154     errmsg ("usage: set <name> <value>");
23155
23156   vec_free (name);
23157   vec_free (value);
23158   return 0;
23159 }
23160
23161 static int
23162 unset (vat_main_t * vam)
23163 {
23164   u8 *name = 0;
23165
23166   if (unformat (vam->input, "%s", &name))
23167     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23168       errmsg ("unset: %s wasn't set", name);
23169   vec_free (name);
23170   return 0;
23171 }
23172
23173 typedef struct
23174 {
23175   u8 *name;
23176   u8 *value;
23177 } macro_sort_t;
23178
23179
23180 static int
23181 macro_sort_cmp (void *a1, void *a2)
23182 {
23183   macro_sort_t *s1 = a1;
23184   macro_sort_t *s2 = a2;
23185
23186   return strcmp ((char *) (s1->name), (char *) (s2->name));
23187 }
23188
23189 static int
23190 dump_macro_table (vat_main_t * vam)
23191 {
23192   macro_sort_t *sort_me = 0, *sm;
23193   int i;
23194   hash_pair_t *p;
23195
23196     /* *INDENT-OFF* */
23197     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23198     ({
23199       vec_add2 (sort_me, sm, 1);
23200       sm->name = (u8 *)(p->key);
23201       sm->value = (u8 *) (p->value[0]);
23202     }));
23203     /* *INDENT-ON* */
23204
23205   vec_sort_with_function (sort_me, macro_sort_cmp);
23206
23207   if (vec_len (sort_me))
23208     print (vam->ofp, "%-15s%s", "Name", "Value");
23209   else
23210     print (vam->ofp, "The macro table is empty...");
23211
23212   for (i = 0; i < vec_len (sort_me); i++)
23213     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23214   return 0;
23215 }
23216
23217 static int
23218 dump_node_table (vat_main_t * vam)
23219 {
23220   int i, j;
23221   vlib_node_t *node, *next_node;
23222
23223   if (vec_len (vam->graph_nodes) == 0)
23224     {
23225       print (vam->ofp, "Node table empty, issue get_node_graph...");
23226       return 0;
23227     }
23228
23229   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23230     {
23231       node = vam->graph_nodes[0][i];
23232       print (vam->ofp, "[%d] %s", i, node->name);
23233       for (j = 0; j < vec_len (node->next_nodes); j++)
23234         {
23235           if (node->next_nodes[j] != ~0)
23236             {
23237               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23238               print (vam->ofp, "  [%d] %s", j, next_node->name);
23239             }
23240         }
23241     }
23242   return 0;
23243 }
23244
23245 static int
23246 value_sort_cmp (void *a1, void *a2)
23247 {
23248   name_sort_t *n1 = a1;
23249   name_sort_t *n2 = a2;
23250
23251   if (n1->value < n2->value)
23252     return -1;
23253   if (n1->value > n2->value)
23254     return 1;
23255   return 0;
23256 }
23257
23258
23259 static int
23260 dump_msg_api_table (vat_main_t * vam)
23261 {
23262   api_main_t *am = &api_main;
23263   name_sort_t *nses = 0, *ns;
23264   hash_pair_t *hp;
23265   int i;
23266
23267   /* *INDENT-OFF* */
23268   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23269   ({
23270     vec_add2 (nses, ns, 1);
23271     ns->name = (u8 *)(hp->key);
23272     ns->value = (u32) hp->value[0];
23273   }));
23274   /* *INDENT-ON* */
23275
23276   vec_sort_with_function (nses, value_sort_cmp);
23277
23278   for (i = 0; i < vec_len (nses); i++)
23279     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23280   vec_free (nses);
23281   return 0;
23282 }
23283
23284 static int
23285 get_msg_id (vat_main_t * vam)
23286 {
23287   u8 *name_and_crc;
23288   u32 message_index;
23289
23290   if (unformat (vam->input, "%s", &name_and_crc))
23291     {
23292       message_index = vl_msg_api_get_msg_index (name_and_crc);
23293       if (message_index == ~0)
23294         {
23295           print (vam->ofp, " '%s' not found", name_and_crc);
23296           return 0;
23297         }
23298       print (vam->ofp, " '%s' has message index %d",
23299              name_and_crc, message_index);
23300       return 0;
23301     }
23302   errmsg ("name_and_crc required...");
23303   return 0;
23304 }
23305
23306 static int
23307 search_node_table (vat_main_t * vam)
23308 {
23309   unformat_input_t *line_input = vam->input;
23310   u8 *node_to_find;
23311   int j;
23312   vlib_node_t *node, *next_node;
23313   uword *p;
23314
23315   if (vam->graph_node_index_by_name == 0)
23316     {
23317       print (vam->ofp, "Node table empty, issue get_node_graph...");
23318       return 0;
23319     }
23320
23321   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23322     {
23323       if (unformat (line_input, "%s", &node_to_find))
23324         {
23325           vec_add1 (node_to_find, 0);
23326           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23327           if (p == 0)
23328             {
23329               print (vam->ofp, "%s not found...", node_to_find);
23330               goto out;
23331             }
23332           node = vam->graph_nodes[0][p[0]];
23333           print (vam->ofp, "[%d] %s", p[0], node->name);
23334           for (j = 0; j < vec_len (node->next_nodes); j++)
23335             {
23336               if (node->next_nodes[j] != ~0)
23337                 {
23338                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23339                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23340                 }
23341             }
23342         }
23343
23344       else
23345         {
23346           clib_warning ("parse error '%U'", format_unformat_error,
23347                         line_input);
23348           return -99;
23349         }
23350
23351     out:
23352       vec_free (node_to_find);
23353
23354     }
23355
23356   return 0;
23357 }
23358
23359
23360 static int
23361 script (vat_main_t * vam)
23362 {
23363 #if (VPP_API_TEST_BUILTIN==0)
23364   u8 *s = 0;
23365   char *save_current_file;
23366   unformat_input_t save_input;
23367   jmp_buf save_jump_buf;
23368   u32 save_line_number;
23369
23370   FILE *new_fp, *save_ifp;
23371
23372   if (unformat (vam->input, "%s", &s))
23373     {
23374       new_fp = fopen ((char *) s, "r");
23375       if (new_fp == 0)
23376         {
23377           errmsg ("Couldn't open script file %s", s);
23378           vec_free (s);
23379           return -99;
23380         }
23381     }
23382   else
23383     {
23384       errmsg ("Missing script name");
23385       return -99;
23386     }
23387
23388   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23389   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23390   save_ifp = vam->ifp;
23391   save_line_number = vam->input_line_number;
23392   save_current_file = (char *) vam->current_file;
23393
23394   vam->input_line_number = 0;
23395   vam->ifp = new_fp;
23396   vam->current_file = s;
23397   do_one_file (vam);
23398
23399   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23400   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23401   vam->ifp = save_ifp;
23402   vam->input_line_number = save_line_number;
23403   vam->current_file = (u8 *) save_current_file;
23404   vec_free (s);
23405
23406   return 0;
23407 #else
23408   clib_warning ("use the exec command...");
23409   return -99;
23410 #endif
23411 }
23412
23413 static int
23414 echo (vat_main_t * vam)
23415 {
23416   print (vam->ofp, "%v", vam->input->buffer);
23417   return 0;
23418 }
23419
23420 /* List of API message constructors, CLI names map to api_xxx */
23421 #define foreach_vpe_api_msg                                             \
23422 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23423 _(sw_interface_dump,"")                                                 \
23424 _(sw_interface_set_flags,                                               \
23425   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23426 _(sw_interface_add_del_address,                                         \
23427   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23428 _(sw_interface_set_rx_mode,                                             \
23429   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23430 _(sw_interface_set_rx_placement,                                        \
23431   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23432 _(sw_interface_rx_placement_dump,                                       \
23433   "[<intfc> | sw_if_index <id>]")                                         \
23434 _(sw_interface_set_table,                                               \
23435   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23436 _(sw_interface_set_mpls_enable,                                         \
23437   "<intfc> | sw_if_index [disable | dis]")                              \
23438 _(sw_interface_set_vpath,                                               \
23439   "<intfc> | sw_if_index <id> enable | disable")                        \
23440 _(sw_interface_set_vxlan_bypass,                                        \
23441   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23442 _(sw_interface_set_geneve_bypass,                                       \
23443   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23444 _(sw_interface_set_l2_xconnect,                                         \
23445   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23446   "enable | disable")                                                   \
23447 _(sw_interface_set_l2_bridge,                                           \
23448   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23449   "[shg <split-horizon-group>] [bvi]\n"                                 \
23450   "enable | disable")                                                   \
23451 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23452 _(bridge_domain_add_del,                                                \
23453   "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") \
23454 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23455 _(l2fib_add_del,                                                        \
23456   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23457 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23458 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23459 _(l2_flags,                                                             \
23460   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23461 _(bridge_flags,                                                         \
23462   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23463 _(tap_connect,                                                          \
23464   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23465 _(tap_modify,                                                           \
23466   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23467 _(tap_delete,                                                           \
23468   "<vpp-if-name> | sw_if_index <id>")                                   \
23469 _(sw_interface_tap_dump, "")                                            \
23470 _(tap_create_v2,                                                        \
23471   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23472 _(tap_delete_v2,                                                        \
23473   "<vpp-if-name> | sw_if_index <id>")                                   \
23474 _(sw_interface_tap_v2_dump, "")                                         \
23475 _(virtio_pci_create,                                                    \
23476   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
23477 _(virtio_pci_delete,                                                    \
23478   "<vpp-if-name> | sw_if_index <id>")                                   \
23479 _(sw_interface_virtio_pci_dump, "")                                     \
23480 _(bond_create,                                                          \
23481   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23482   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
23483   "[id <if-id>]")                                                       \
23484 _(bond_delete,                                                          \
23485   "<vpp-if-name> | sw_if_index <id>")                                   \
23486 _(bond_enslave,                                                         \
23487   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23488 _(bond_detach_slave,                                                    \
23489   "sw_if_index <n>")                                                    \
23490 _(sw_interface_bond_dump, "")                                           \
23491 _(sw_interface_slave_dump,                                              \
23492   "<vpp-if-name> | sw_if_index <id>")                                   \
23493 _(ip_table_add_del,                                                     \
23494   "table <n> [ipv6] [add | del]\n")                                     \
23495 _(ip_add_del_route,                                                     \
23496   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23497   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23498   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23499   "[multipath] [count <n>] [del]")                                      \
23500 _(ip_mroute_add_del,                                                    \
23501   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23502   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23503 _(mpls_table_add_del,                                                   \
23504   "table <n> [add | del]\n")                                            \
23505 _(mpls_route_add_del,                                                   \
23506   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23507   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23508   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23509   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23510   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23511   "[count <n>] [del]")                                                  \
23512 _(mpls_ip_bind_unbind,                                                  \
23513   "<label> <addr/len>")                                                 \
23514 _(mpls_tunnel_add_del,                                                  \
23515   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23516   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23517   "[l2-only]  [out-label <n>]")                                         \
23518 _(sr_mpls_policy_add,                                                   \
23519   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23520 _(sr_mpls_policy_del,                                                   \
23521   "bsid <id>")                                                          \
23522 _(bier_table_add_del,                                                   \
23523   "<label> <sub-domain> <set> <bsl> [del]")                             \
23524 _(bier_route_add_del,                                                   \
23525   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23526   "[<intfc> | sw_if_index <id>]"                                        \
23527   "[weight <n>] [del] [multipath]")                                     \
23528 _(proxy_arp_add_del,                                                    \
23529   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23530 _(proxy_arp_intfc_enable_disable,                                       \
23531   "<intfc> | sw_if_index <id> enable | disable")                        \
23532 _(sw_interface_set_unnumbered,                                          \
23533   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23534 _(ip_neighbor_add_del,                                                  \
23535   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23536   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23537 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23538 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23539   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23540   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23541   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23542 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23543 _(reset_fib, "vrf <n> [ipv6]")                                          \
23544 _(dhcp_proxy_config,                                                    \
23545   "svr <v46-address> src <v46-address>\n"                               \
23546    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23547 _(dhcp_proxy_set_vss,                                                   \
23548   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23549 _(dhcp_proxy_dump, "ip6")                                               \
23550 _(dhcp_client_config,                                                   \
23551   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23552 _(set_ip_flow_hash,                                                     \
23553   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23554 _(sw_interface_ip6_enable_disable,                                      \
23555   "<intfc> | sw_if_index <id> enable | disable")                        \
23556 _(ip6nd_proxy_add_del,                                                  \
23557   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23558 _(ip6nd_proxy_dump, "")                                                 \
23559 _(sw_interface_ip6nd_ra_prefix,                                         \
23560   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23561   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23562   "[nolink] [isno]")                                                    \
23563 _(sw_interface_ip6nd_ra_config,                                         \
23564   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23565   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23566   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23567 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23568 _(l2_patch_add_del,                                                     \
23569   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23570   "enable | disable")                                                   \
23571 _(sr_localsid_add_del,                                                  \
23572   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23573   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23574 _(classify_add_del_table,                                               \
23575   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23576   " [del] [del-chain] mask <mask-value>\n"                              \
23577   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23578   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23579 _(classify_add_del_session,                                             \
23580   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23581   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23582   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23583   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23584 _(classify_set_interface_ip_table,                                      \
23585   "<intfc> | sw_if_index <nn> table <nn>")                              \
23586 _(classify_set_interface_l2_tables,                                     \
23587   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23588   "  [other-table <nn>]")                                               \
23589 _(get_node_index, "node <node-name")                                    \
23590 _(add_node_next, "node <node-name> next <next-node-name>")              \
23591 _(l2tpv3_create_tunnel,                                                 \
23592   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23593   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23594   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23595 _(l2tpv3_set_tunnel_cookies,                                            \
23596   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23597   "[new_remote_cookie <nn>]\n")                                         \
23598 _(l2tpv3_interface_enable_disable,                                      \
23599   "<intfc> | sw_if_index <nn> enable | disable")                        \
23600 _(l2tpv3_set_lookup_key,                                                \
23601   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23602 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23603 _(vxlan_offload_rx,                                                     \
23604   "hw { <interface name> | hw_if_index <nn>} "                          \
23605   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23606 _(vxlan_add_del_tunnel,                                                 \
23607   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23608   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23609   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23610 _(geneve_add_del_tunnel,                                                \
23611   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23612   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23613   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23614 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23615 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23616 _(gre_add_del_tunnel,                                                   \
23617   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23618   "[teb | erspan <session-id>] [del]")                                  \
23619 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23620 _(l2_fib_clear_table, "")                                               \
23621 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23622 _(l2_interface_vlan_tag_rewrite,                                        \
23623   "<intfc> | sw_if_index <nn> \n"                                       \
23624   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23625   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23626 _(create_vhost_user_if,                                                 \
23627         "socket <filename> [server] [renumber <dev_instance>] "         \
23628         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23629         "[mac <mac_address>]")                                          \
23630 _(modify_vhost_user_if,                                                 \
23631         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23632         "[server] [renumber <dev_instance>]")                           \
23633 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23634 _(sw_interface_vhost_user_dump, "")                                     \
23635 _(show_version, "")                                                     \
23636 _(show_threads, "")                                                     \
23637 _(vxlan_gpe_add_del_tunnel,                                             \
23638   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23639   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23640   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23641   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23642 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23643 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23644 _(interface_name_renumber,                                              \
23645   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23646 _(input_acl_set_interface,                                              \
23647   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23648   "  [l2-table <nn>] [del]")                                            \
23649 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23650 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23651   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23652 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23653 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23654 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23655 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23656 _(ip_dump, "ipv4 | ipv6")                                               \
23657 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23658 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23659   "  spid_id <n> ")                                                     \
23660 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23661   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23662   "  integ_alg <alg> integ_key <hex>")                                  \
23663 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23664   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23665   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23666   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23667 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23668 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23669   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23670   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23671   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23672   "  [instance <n>]")     \
23673 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23674 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23675   "  <alg> <hex>\n")                                                    \
23676 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23677 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23678 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23679   "(auth_data 0x<data> | auth_data <data>)")                            \
23680 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23681   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23682 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23683   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23684   "(local|remote)")                                                     \
23685 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23686 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23687 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23688 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23689 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23690 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23691 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23692 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23693 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23694 _(delete_loopback,"sw_if_index <nn>")                                   \
23695 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23696 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
23697 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
23698 _(want_interface_events,  "enable|disable")                             \
23699 _(get_first_msg_id, "client <name>")                                    \
23700 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23701 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23702   "fib-id <nn> [ip4][ip6][default]")                                    \
23703 _(get_node_graph, " ")                                                  \
23704 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23705 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23706 _(ioam_disable, "")                                                     \
23707 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23708                             " sw_if_index <sw_if_index> p <priority> "  \
23709                             "w <weight>] [del]")                        \
23710 _(one_add_del_locator, "locator-set <locator_name> "                    \
23711                         "iface <intf> | sw_if_index <sw_if_index> "     \
23712                         "p <priority> w <weight> [del]")                \
23713 _(one_add_del_local_eid,"vni <vni> eid "                                \
23714                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23715                          "locator-set <locator_name> [del]"             \
23716                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23717 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23718 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23719 _(one_enable_disable, "enable|disable")                                 \
23720 _(one_map_register_enable_disable, "enable|disable")                    \
23721 _(one_map_register_fallback_threshold, "<value>")                       \
23722 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23723 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23724                                "[seid <seid>] "                         \
23725                                "rloc <locator> p <prio> "               \
23726                                "w <weight> [rloc <loc> ... ] "          \
23727                                "action <action> [del-all]")             \
23728 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23729                           "<local-eid>")                                \
23730 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23731 _(one_use_petr, "ip-address> | disable")                                \
23732 _(one_map_request_mode, "src-dst|dst-only")                             \
23733 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23734 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23735 _(one_locator_set_dump, "[local | remote]")                             \
23736 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23737 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23738                        "[local] | [remote]")                            \
23739 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23740 _(one_ndp_bd_get, "")                                                   \
23741 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23742 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23743 _(one_l2_arp_bd_get, "")                                                \
23744 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23745 _(one_stats_enable_disable, "enable|disable")                           \
23746 _(show_one_stats_enable_disable, "")                                    \
23747 _(one_eid_table_vni_dump, "")                                           \
23748 _(one_eid_table_map_dump, "l2|l3")                                      \
23749 _(one_map_resolver_dump, "")                                            \
23750 _(one_map_server_dump, "")                                              \
23751 _(one_adjacencies_get, "vni <vni>")                                     \
23752 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23753 _(show_one_rloc_probe_state, "")                                        \
23754 _(show_one_map_register_state, "")                                      \
23755 _(show_one_status, "")                                                  \
23756 _(one_stats_dump, "")                                                   \
23757 _(one_stats_flush, "")                                                  \
23758 _(one_get_map_request_itr_rlocs, "")                                    \
23759 _(one_map_register_set_ttl, "<ttl>")                                    \
23760 _(one_set_transport_protocol, "udp|api")                                \
23761 _(one_get_transport_protocol, "")                                       \
23762 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23763 _(one_show_xtr_mode, "")                                                \
23764 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23765 _(one_show_pitr_mode, "")                                               \
23766 _(one_enable_disable_petr_mode, "enable|disable")                       \
23767 _(one_show_petr_mode, "")                                               \
23768 _(show_one_nsh_mapping, "")                                             \
23769 _(show_one_pitr, "")                                                    \
23770 _(show_one_use_petr, "")                                                \
23771 _(show_one_map_request_mode, "")                                        \
23772 _(show_one_map_register_ttl, "")                                        \
23773 _(show_one_map_register_fallback_threshold, "")                         \
23774 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23775                             " sw_if_index <sw_if_index> p <priority> "  \
23776                             "w <weight>] [del]")                        \
23777 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23778                         "iface <intf> | sw_if_index <sw_if_index> "     \
23779                         "p <priority> w <weight> [del]")                \
23780 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23781                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23782                          "locator-set <locator_name> [del]"             \
23783                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23784 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23785 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23786 _(lisp_enable_disable, "enable|disable")                                \
23787 _(lisp_map_register_enable_disable, "enable|disable")                   \
23788 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23789 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23790                                "[seid <seid>] "                         \
23791                                "rloc <locator> p <prio> "               \
23792                                "w <weight> [rloc <loc> ... ] "          \
23793                                "action <action> [del-all]")             \
23794 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23795                           "<local-eid>")                                \
23796 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23797 _(lisp_use_petr, "<ip-address> | disable")                              \
23798 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23799 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23800 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23801 _(lisp_locator_set_dump, "[local | remote]")                            \
23802 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23803 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23804                        "[local] | [remote]")                            \
23805 _(lisp_eid_table_vni_dump, "")                                          \
23806 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23807 _(lisp_map_resolver_dump, "")                                           \
23808 _(lisp_map_server_dump, "")                                             \
23809 _(lisp_adjacencies_get, "vni <vni>")                                    \
23810 _(gpe_fwd_entry_vnis_get, "")                                           \
23811 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23812 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23813                                 "[table <table-id>]")                   \
23814 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23815 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23816 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23817 _(gpe_get_encap_mode, "")                                               \
23818 _(lisp_gpe_add_del_iface, "up|down")                                    \
23819 _(lisp_gpe_enable_disable, "enable|disable")                            \
23820 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23821   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23822 _(show_lisp_rloc_probe_state, "")                                       \
23823 _(show_lisp_map_register_state, "")                                     \
23824 _(show_lisp_status, "")                                                 \
23825 _(lisp_get_map_request_itr_rlocs, "")                                   \
23826 _(show_lisp_pitr, "")                                                   \
23827 _(show_lisp_use_petr, "")                                               \
23828 _(show_lisp_map_request_mode, "")                                       \
23829 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23830 _(af_packet_delete, "name <host interface name>")                       \
23831 _(af_packet_dump, "")                                                   \
23832 _(policer_add_del, "name <policer name> <params> [del]")                \
23833 _(policer_dump, "[name <policer name>]")                                \
23834 _(policer_classify_set_interface,                                       \
23835   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23836   "  [l2-table <nn>] [del]")                                            \
23837 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23838 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23839     "[master|slave]")                                                   \
23840 _(netmap_delete, "name <interface name>")                               \
23841 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23842 _(mpls_fib_dump, "")                                                    \
23843 _(classify_table_ids, "")                                               \
23844 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23845 _(classify_table_info, "table_id <nn>")                                 \
23846 _(classify_session_dump, "table_id <nn>")                               \
23847 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23848     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23849     "[template_interval <nn>] [udp_checksum]")                          \
23850 _(ipfix_exporter_dump, "")                                              \
23851 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23852 _(ipfix_classify_stream_dump, "")                                       \
23853 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23854 _(ipfix_classify_table_dump, "")                                        \
23855 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23856 _(sw_interface_span_dump, "[l2]")                                           \
23857 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23858 _(pg_create_interface, "if_id <nn>")                                    \
23859 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23860 _(pg_enable_disable, "[stream <id>] disable")                           \
23861 _(ip_source_and_port_range_check_add_del,                               \
23862   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23863 _(ip_source_and_port_range_check_interface_add_del,                     \
23864   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23865   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23866 _(ipsec_gre_add_del_tunnel,                                             \
23867   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23868 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23869 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23870 _(l2_interface_pbb_tag_rewrite,                                         \
23871   "<intfc> | sw_if_index <nn> \n"                                       \
23872   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23873   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23874 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23875 _(flow_classify_set_interface,                                          \
23876   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23877 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23878 _(ip_fib_dump, "")                                                      \
23879 _(ip_mfib_dump, "")                                                     \
23880 _(ip6_fib_dump, "")                                                     \
23881 _(ip6_mfib_dump, "")                                                    \
23882 _(feature_enable_disable, "arc_name <arc_name> "                        \
23883   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23884 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23885 "[disable]")                                                            \
23886 _(l2_xconnect_dump, "")                                                 \
23887 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23888 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23889 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23890 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23891 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23892 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23893 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23894   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23895 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23896 _(sock_init_shm, "size <nnn>")                                          \
23897 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23898 _(dns_enable_disable, "[enable][disable]")                              \
23899 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23900 _(dns_resolve_name, "<hostname>")                                       \
23901 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23902 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23903 _(dns_resolve_name, "<hostname>")                                       \
23904 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23905   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23906 _(session_rules_dump, "")                                               \
23907 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23908 _(output_acl_set_interface,                                             \
23909   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23910   "  [l2-table <nn>] [del]")                                            \
23911 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23912
23913 /* List of command functions, CLI names map directly to functions */
23914 #define foreach_cli_function                                    \
23915 _(comment, "usage: comment <ignore-rest-of-line>")              \
23916 _(dump_interface_table, "usage: dump_interface_table")          \
23917 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23918 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23919 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23920 _(dump_macro_table, "usage: dump_macro_table ")                 \
23921 _(dump_node_table, "usage: dump_node_table")                    \
23922 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23923 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23924 _(echo, "usage: echo <message>")                                \
23925 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23926 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23927 _(help, "usage: help")                                          \
23928 _(q, "usage: quit")                                             \
23929 _(quit, "usage: quit")                                          \
23930 _(search_node_table, "usage: search_node_table <name>...")      \
23931 _(set, "usage: set <variable-name> <value>")                    \
23932 _(script, "usage: script <file-name>")                          \
23933 _(statseg, "usage: statseg");                                   \
23934 _(unset, "usage: unset <variable-name>")
23935
23936 #define _(N,n)                                  \
23937     static void vl_api_##n##_t_handler_uni      \
23938     (vl_api_##n##_t * mp)                       \
23939     {                                           \
23940         vat_main_t * vam = &vat_main;           \
23941         if (vam->json_output) {                 \
23942             vl_api_##n##_t_handler_json(mp);    \
23943         } else {                                \
23944             vl_api_##n##_t_handler(mp);         \
23945         }                                       \
23946     }
23947 foreach_vpe_api_reply_msg;
23948 #if VPP_API_TEST_BUILTIN == 0
23949 foreach_standalone_reply_msg;
23950 #endif
23951 #undef _
23952
23953 void
23954 vat_api_hookup (vat_main_t * vam)
23955 {
23956 #define _(N,n)                                                  \
23957     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23958                            vl_api_##n##_t_handler_uni,          \
23959                            vl_noop_handler,                     \
23960                            vl_api_##n##_t_endian,               \
23961                            vl_api_##n##_t_print,                \
23962                            sizeof(vl_api_##n##_t), 1);
23963   foreach_vpe_api_reply_msg;
23964 #if VPP_API_TEST_BUILTIN == 0
23965   foreach_standalone_reply_msg;
23966 #endif
23967 #undef _
23968
23969 #if (VPP_API_TEST_BUILTIN==0)
23970   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23971
23972   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23973
23974   vam->function_by_name = hash_create_string (0, sizeof (uword));
23975
23976   vam->help_by_name = hash_create_string (0, sizeof (uword));
23977 #endif
23978
23979   /* API messages we can send */
23980 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23981   foreach_vpe_api_msg;
23982 #undef _
23983
23984   /* Help strings */
23985 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23986   foreach_vpe_api_msg;
23987 #undef _
23988
23989   /* CLI functions */
23990 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23991   foreach_cli_function;
23992 #undef _
23993
23994   /* Help strings */
23995 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23996   foreach_cli_function;
23997 #undef _
23998 }
23999
24000 #if VPP_API_TEST_BUILTIN
24001 static clib_error_t *
24002 vat_api_hookup_shim (vlib_main_t * vm)
24003 {
24004   vat_api_hookup (&vat_main);
24005   return 0;
24006 }
24007
24008 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24009 #endif
24010
24011 /*
24012  * fd.io coding-style-patch-verification: ON
24013  *
24014  * Local Variables:
24015  * eval: (c-set-style "gnu")
24016  * End:
24017  */